cocos2dx上两个物体接触和分离需注册监听器_浙江联通时代畅想张
cocos2d吧
全部回复
仅看楼主
level 7
liuxijob 楼主
当两个物体接触到两个物体分离过程中,会发生一些事件,我们可以通过注册监听器EventListenerPhysicsContact来响应这些事件。
  首先看一下看HelloWorldScene.h文件,它的代码如下:
  [html] view plaincopyprint?
  #define __HELLOWORLD_SCENE_H__
  #include "cocos2d.h"
  USING_NS_CC;
  class HelloWorld : public cocos2d::Layer
  {
  public:
  static cocos2d::Scene* createScene();
  virtual bool init();
  virtual bool onTouchBegan(cocos2dhttp://beijing.liebiao.com/zhuangxiu/138802077.html::Touch* touch, cocos2d::Event* event);
  virtual void onEnter();
  virtual void onExit();
  CREATE_FUNC(HelloWorld);
  void addNewSpriteAtPosition(Vec2 p);
  };
  #endif // __HELLOWORLD_SCENE_H__
  #ifndef __HELLOWORLD_SCENE_H__
  #define __HELLOWORLD_SCENE_H__
  #include "cocos2d.h"
  USING_NS_CC;
  class HelloWorld : public cocos2d::Layerhttp://sjbbs.zol.com.cn/11/11_108245.html
  {http://www.yzw.cc/space/blog/286516.html
  public:
  static cocos2d::Scene* createScene();
  virtual bool init();
  virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
  virtual void onEnter();
  virtual void onExit();
  CREATE_FUNC(HelloWorld);
  void addNewSpriteAtPosition(Vec2 p);
  };
  #endif // __HELLOWORLD_SCENE_H__
  上述浙江联通时代畅想张海波的日志上说的代码声明了onEnter和onExit函数,用来处理层进入和退出回调函数。我们会在onEnter函数注册EventListenerPhysicsContact监听器,以便于响应碰撞检测事件,在onExit函数中注销这些监听器。
  HelloWorldScene.cpp中创建物理世界和指定世界的边界语句是在HelloWorld::createScene()和HelloWorld::init()函数中,这两个函数类似于上一节的HelloPhysicsWorld实例,这里不再解释这些函数代码了。
  HelloWorldScene.cpp中与碰撞检测相关的代码是在onEnter和onExit函数中,代码如下:
  [html] view plaincopyprint?
   在CODE上查看代码片
   派生到我的代码片
  void HelloWorld::onEnter()
  {
  Layer::onEnter();
  auto listener = EventListenerPhysicsContact::create();
  listener->onContactBegin = [](PhysicsContact& contact) ①
  {
  auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode(); ②
  auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode(); ③
  if (spriteA && spriteA->getTag() == 1
  && spriteB && spriteB->getTag() == 1) ④
  {
  spriteA->setColor(Color3B::YELLOW);
  spriteB->setColor(Color3B::YELLOW);
  }
  log("onContactBegin");
  return true;
  };
  listener->onContactPreSolve = [] (PhysicsContact& contact,
  PhysicsContactPreSolve& solve) { ⑤
  log("onContactPreSolve");
  return true;
  };
  listener->onContactPostSolve = [] (PhysicsContact& contact,
  const PhysicsContactPostSolve& solve) ⑥
  log("onContactPostSolve");
  };
  listener->onContactSeperate = [](PhysicsContact& contact) { ⑦
  auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode();
  auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode();
  if (spriteA && spriteA->getTag() == 1
  && spriteB && spriteB->getTag() == 1)
  {
  spriteA->setColor(Color3B::WHITE);
  spriteB->setColor(Color3B::WHITE);
  }
  log("onContactSeperate");
  };
  Director::getInstance()->getEventDispatcher()->
  addEventListenerWithFixedPriority(listener,1); ⑧
  }
  void HelloWorld::onExit()
  {
  Layer::onExit();
  log("HelloWorld onExit");
  Director::getInstance()->getEventDispatcher()->removeAllEventListeners(); ⑨
  }
  void HelloWorld::onEnter()
  {
  Layer::onEnter();
  auto listener = EventListenerPhysicsContact::create();
  listener->onContactBegin = [](PhysicsContact& contact) ①
  {
  auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode(); ②
  auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode(); ③
  if (spriteA && spriteA->getTag() == 1
  && spriteB && spriteB->getTag() == 1) ④
  {
  spriteA->setColor(Color3B::YELLOW);
  spriteB->setColor(Color3B::YELLOW);
  }
  log("onContactBegin");
  return true;
  };
  listener->onContactPreSolve = [] (PhysicsContact& contact,
  PhysicsContactPreSolve& solve) { ⑤
  log("onContactPreSolve");
  return true;
  };
  listener->onContactPostSolve = [] (PhysicsContact& contact,
  const PhysicsContactPostSolve& solve) ⑥
  log("onContactPostSolve");
  };
  listener->onContactSeperate = [](PhysicsContact& contact) { ⑦
  auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode();
  auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode();
  if (spriteA && spriteA->getTag() == 1
  && spriteB && spriteB->getTag() == 1)
  {
  spriteA->setColor(Color3B::WHITE);
  spriteB->setColor(Color3B::WHITE);
  }
  log("onContactSeperate");
  };
  Director::getInstance()->getEventDispatcher()->
  addEventListenerWithFixedPriority(listener,1); ⑧
  }
  void HelloWorld::onExit()
  {
  Layer::onExit();
  log("HelloWorld onExit");
  Director::getInstance()->getEventDispatcher()->removeAllEventListeners(http://bj.51tie.com/kuaicanwaimai/f17111152.shtml); ⑨
  }
  上述代码的onEnter()函数是进入场景时候回调的函数,我们可以在这里通过auto listener = EventListenerPhysicsContact::create()语句创建物体碰撞检测事件监听器对象。接下来通过第①、⑥、⑤、⑦行使用Lambda表达式定义了事件处理的匿名函数。
  代码第②和第③行是从接触点中取出互相接触的两个节点对象,它的取值过程有点复杂,首先接触点使用getShapeA()和getShapeB()函数获得物体形状,在通过形状的getBody()函数获得物体,通过物体的getNode()函数获得与形状相关的节点对象。第④行代码是进行判断,判断从接触点取出的节点对象是否存在,并且判断是否tag属性为1。
  上面代码第⑧行addEventListenerWithFixedPriority是指定固定的事件优先级注册监听器,事件优先级决定事件响应的优先级别,值越小优先级越高。
  代码第⑨行是在退出层回调函数onExit()中注销所有的监听事件。(浙江联通时代畅想张海波的日志)
2014年12月18日 06点12分 1
1