Cocos2d-x 物理引擎及碰撞
Posted changchou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cocos2d-x 物理引擎及碰撞相关的知识,希望对你有一定的参考价值。
基础知识:
1 #ifndef __HELLOWORLD_SCENE_H__ 2 #define __HELLOWORLD_SCENE_H__ 3 4 #include "cocos2d.h" 5 6 class HelloWorld : public cocos2d::Layer 7 { 8 private: 9 Size visibleSize; 10 public: 11 // there‘s no ‘id‘ in cpp, so we recommend returning the class instance pointer 12 static cocos2d::Scene* createScene(); 13 14 // Here‘s a difference. Method ‘init‘ in cocos2d-x returns bool, instead of returning ‘id‘ in cocos2d-iphone 15 virtual bool init(); 16 17 // implement the "static create()" method manually 18 CREATE_FUNC(HelloWorld); 19 20 //物理引擎所需的入口 21 virtual void onEnter(); 22 23 //物理引擎的物理边界 24 void addEdges(); 25 26 //物理引擎添加物理元素 --- 方法重载1 27 void addBall(float postionX, float positionY); 28 29 //物理引擎动态添加物理元素 --- 方法重载2 30 void addBall(Vec2 position); 31 }; 32 33 #endif // __HELLOWORLD_SCENE_H__
1 #include "HelloWorldScene.h" 2 #include "cocostudio/CocoStudio.h" 3 #include "ui/CocosGUI.h" 4 5 USING_NS_CC; 6 7 using namespace cocostudio::timeline; 8 9 Scene* HelloWorld::createScene() 10 { 11 // ‘scene‘ is an autorelease object 12 //auto scene = Scene::create(); 13 14 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ 15 16 //34.Cocos2d - x v3物理引擎 17 18 19 //创建带有物理引擎的Scene 20 auto scene = Scene::createWithPhysics(); 21 scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); 22 23 // ‘layer‘ is an autorelease object 24 auto layer = HelloWorld::create(); 25 26 // add layer as a child to scene 27 scene->addChild(layer); 28 29 // return the scene 30 return scene; 31 } 32 33 // on "init" you need to initialize your instance 34 bool HelloWorld::init() 35 { 36 // 1. super init first 37 if ( !Layer::init() ) 38 { 39 return false; 40 } 41 42 visibleSize = Director::getInstance()->getVisibleSize(); 43 44 return true; 45 } 46 47 //物理引擎 应用程序入口 48 void HelloWorld::onEnter(){ 49 50 //父类onEnter 51 Layer::onEnter(); 52 53 //添加一个物理元素 54 addBall(visibleSize.width / 2, visibleSize.height / 2); 55 56 //添加物理边界 57 addEdges(); 58 59 //动态添加物理元素 60 auto listener = EventListenerTouchOneByOne::create(); 61 listener->onTouchBegan = [this](Touch *touch, Event *e){ 62 63 this->addBall(touch->getLocation()); 64 65 return false; 66 }; 67 _eventDispatcher->addEventListenerWithSceneGraphpriority(listener, this); 68 } 69 70 //物理引擎的物理边界 71 void HelloWorld::addEdges(){ 72 73 //创建边界框 74 auto body = PhysicsBody::createEdgeBox(visibleSize); 75 //auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);//边界框宽度 --- 可现实边界线 76 77 //用来承载边界框的图形 78 auto edgeShape = Node::create(); 79 edgeShape->setPhysicsBody(body); 80 edgeShape->setPosition(visibleSize / 2); 81 addChild(edgeShape); 82 } 83 84 //物理引擎添加物理元素 85 void HelloWorld::addBall(float postionX, float positionY){ 86 //创建一个Sprite对象 87 auto b = Sprite::create("ball.png"); 88 b->setScale(0.2); 89 //设置物理Body 90 b->setPhysicsBody(PhysicsBody::createBox(b->getContentSize())); 91 b->cocos2d::Node::setPosition(postionX, positionY); 92 addChild(b); 93 } 94 95 //物理引擎添加物理元素 --- 方法重载 96 void HelloWorld::addBall(Vec2 position){ 97 addBall(position.x, position.y); 98 }
碰撞测试:
1 #ifndef __HELLOWORLD_SCENE_H__ 2 #define __HELLOWORLD_SCENE_H__ 3 4 #include "cocos2d.h" 5 6 class HelloWorld : public cocos2d::Layer 7 { 8 private: 9 10 Size visibleSize; 11 12 public: 13 // there‘s no ‘id‘ in cpp, so we recommend returning the class instance pointer 14 static cocos2d::Scene* createScene(); 15 16 // Here‘s a difference. Method ‘init‘ in cocos2d-x returns bool, instead of returning ‘id‘ in cocos2d-iphone 17 virtual bool init(); 18 19 // implement the "static create()" method manually 20 CREATE_FUNC(HelloWorld); 21 22 //物理引擎入口 23 virtual void onEnter(); 24 25 void addBox(Vec2 position); 26 }; 27 28 #endif // __HELLOWORLD_SCENE_H__
1 #include "HelloWorldScene.h" 2 #include "cocostudio/CocoStudio.h" 3 #include "ui/CocosGUI.h" 4 5 USING_NS_CC; 6 7 using namespace cocostudio::timeline; 8 9 10 #define RED_BIT_MASK 0x4 11 #define GREEN_BIT_MASK 0x2 12 #define BLUE_BIT_MASK 0x1 13 #define EDGE_BIT_MASK 0x8 14 15 Scene* HelloWorld::createScene() 16 { 17 //支持物理引擎的Scene 18 auto scene = Scene::createWithPhysics(); 19 //显示物理引擎调试界面 --- 有红框 20 scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); 21 22 //设置更大的重力加速度 23 scene->getPhysicsWorld()->setGravity(Vec2(0, -1000)); 24 25 auto layer = HelloWorld::create(); 26 27 scene->addChild(layer); 28 29 return scene; 30 } 31 32 bool HelloWorld::init() 33 { 34 if ( !Layer::init() ) 35 { 36 return false; 37 } 38 39 visibleSize = Director::getInstance()->getVisibleSize(); 40 41 //动态添加Box 42 auto listener = EventListenerTouchOneByOne::create(); 43 listener->onTouchBegan = [this](Touch *touch, Event *e){ 44 45 this->addBox(touch->getLocation()); 46 47 return false; 48 }; 49 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); 50 51 //碰撞监听 52 auto contactListener = EventListenerPhysicsContact::create(); 53 contactListener->onContactBegin = [](PhysicsContact &contact){ 54 55 switch (contact.getShapeA()->getBody()->getContactTestBitmask() | 56 contact.getShapeB()->getBody()->getContactTestBitmask()) 57 { 58 case RED_BIT_MASK | BLUE_BIT_MASK: 59 log("red rect contact blue rect"); 60 break; 61 case RED_BIT_MASK | GREEN_BIT_MASK: 62 log("red rect contact green rect"); 63 break; 64 case GREEN_BIT_MASK | BLUE_BIT_MASK: 65 log("green rect contact blue rect"); 66 break; 67 case RED_BIT_MASK | EDGE_BIT_MASK: 68 log("red rect hit edge"); 69 break; 70 case GREEN_BIT_MASK | EDGE_BIT_MASK: 71 log("green rect hit edge"); 72 break; 73 case BLUE_BIT_MASK | EDGE_BIT_MASK: 74 log("blue rect hit edge"); 75 break; 76 case RED_BIT_MASK: 77 log("two red rect contact"); 78 break; 79 case GREEN_BIT_MASK: 80 log("two green rect contact"); 81 break; 82 case BLUE_BIT_MASK: 83 log("two blue rect contact"); 84 break; 85 default: 86 break; 87 } 88 return true; 89 }; 90 _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this); 91 92 93 return true; 94 } 95 96 //物理引擎入口实现 97 void HelloWorld::onEnter(){ 98 99 Layer::onEnter(); 100 101 //添加物理边界 102 auto bounds = Node::create(); 103 bounds->setContentSize(visibleSize); 104 bounds->setPhysicsBody(PhysicsBody::createEdgeBox(bounds->getContentSize())); 105 //bounds->setPosition(visibleSize / 2);//Node锚点是(0,0) 106 bounds->getPhysicsBody()->setContactTestBitmask(EDGE_BIT_MASK); 107 addChild(bounds); 108 109 addBox(visibleSize / 2); 110 } 111 112 void HelloWorld::addBox(Vec2 position){ 113 auto r = Sprite::create(); 114 r->setTextureRect(Rect(0, 0, 50, 50)); 115 r->setPhysicsBody(PhysicsBody::createBox(r->getContentSize())); 116 addChild(r); 117 r->setPosition(position); 118 119 //随机产生3种颜色的Box 120 switch (rand() % 3) 121 { 122 case 0: 123 r->setColor(Color3B(255, 0, 0)); 124 r->getPhysicsBody()->setContactTestBitmask(RED_BIT_MASK); 125 break; 126 case 1: 127 r->setColor(Color3B(0, 255, 0)); 128 r->getPhysicsBody()->setContactTestBitmask(GREEN_BIT_MASK); 129 break; 130 case 2: 131 r->setColor(Color3B(0, 0, 255)); 132 r->getPhysicsBody()->setContactTestBitmask(BLUE_BIT_MASK); 133 break; 134 default: 135 break; 136 } 137 }
以上是关于Cocos2d-x 物理引擎及碰撞的主要内容,如果未能解决你的问题,请参考以下文章
Cocos2d-x 3.0中 物理碰撞检測中onContactBegin回调函数不响应问题