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中Box2D物理引擎:碰撞检測

关于Cocos2d-x物理引擎用到的类和使用

Cocos2d-x 3.0中 物理碰撞检測中onContactBegin回调函数不响应问题

Cocos2d-x碰撞检測

Cocos2d-x 3.0中 物理碰撞检测中onContactBegin回调函数不响应问题

Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检測