Cocos2d-x之物理世界(物体之间的碰撞)

Cocos2d-x之物理世界(物体之间的碰撞)

在HelloWorldScene.h中添加如下内容,并让其继承public b2ContactListener

private:

    b2Body *groundBody;//创建一个地板

public:

//继承的b2ContactListener实现

virtual void BeginContact(b2Contact* contact);

HelloWorldScene。cpp

  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 //定义中间的比例为80(box2d和cocos2d的转换比例)
 10 #define RATIO 80.0f
 11 
 12 Scene* HelloWorld::createScene()
 13 {
 14     // 'scene' is an autorelease object
 15     auto scene = Scene::create();
 16     
 17     // 'layer' is an autorelease object
 18     auto layer = HelloWorld::create();
 19 
 20     // add layer as a child to scene
 21     scene->addChild(layer);
 22 
 23     // return the scene
 24     return scene;
 25 }
 26 
 27 // on "init" you need to initialize your instance
 28 bool HelloWorld::init()
 29 {
 30     //////////////////////////////
 31     // 1. super init first
 32     if ( !Layer::init() )
 33     {
 34         return false;
 35     }
 36     //创建一个世界,b2world(二维矢量类型的,指定世界的加速度的方向
 37     //b2Vec2(加速度的方向,向下的,所以x轴没有为0,y轴为-10))这样才能往下落
 38     world = new b2World(b2Vec2(0, -10));
 39     
 40     //设置链接的监听器
 41     world->SetContactListener(this);
 42     
 43     
 44     
 45 //    //添加一个矩形,然后调用scheduleUpdate方法,实现矩形的下落,随着重力加速向下运动
 46 //    addRect();
 47     
 48     //添加一个地板
 49     addGround();
 50     
 51     //复制矩形的代码后,他只是不受重力的影响
 52 //    //让矩形在x轴平移
 53 //    addRect(0, 5, b2_kinematicBody);
 54 
 55 //    //让矩形在y轴向上移动,然后向下加速运动
 56 //    addRect(8, 5, b2_dynamicBody);
 57     
 58     //让矩形在y轴向上移动,然后向下加速运动
 59     addRect(5, 3, b2_dynamicBody);
 60     
 61     
 62     //调用update方法,实现每帧都改变物理世界中的物体
 63     scheduleUpdate();
 64 
 65     return true;
 66 }
 67 
 68 
 69 //实现模拟物理世界的方法(当前一帧与上一帧的时间差)
 70 void HelloWorld::update(float dt){
 71     
 72     //使用这个step方法来一步一步的模拟我们的物理世界
 73     //(时间差(当前一步与最后一步的时间差,即当前一帧与上一帧的时间差),
 74     //速度迭代,模拟物理世界的过程中难免会有误差,所以就用速度迭代的次数来避免误差,官方建议8次,
 75     //位置的迭代,官方建议3次)
 76     world->Step(dt, 8, 3);
 77     
 78     //为了获取矩形,所以在这里定义一个Sprite
 79     Sprite *s;
 80     
 81     //获取移动的矩形
 82     //在这里获取到所有的子集的对象
 83     //遍历所有的子集对象,
 84     for (b2Body *b = world->GetBodyList(); b; b = b->GetNext()) {
 85 //        //判断,因为只有一个动态的物体,所以可以这么判断,否则,要用别的方法
 86 //        if (b->GetType() == b2_dynamicBody) {
 87         //让所有的类型都要刷新
 88             //获取到移动的物体的y 位置
 89 //            log("%f",b->GetPosition().y);
 90         
 91             if (b->GetUserData()) {
 92                 s = (Sprite*)b->GetUserData();
 93                 
 94                 //让Sprite与body同步
 95                 s->setPosition(b->GetPosition().x * RATIO, b->GetPosition().y * RATIO);
 96             }
 97 //        }
 98     }
 99 }
100 
101 
102 
103 //创建矩形,并且让其随着重力开始运动,有加速度的向下移动
104 void HelloWorld::addRect(){
105     
106     //config box2d
107     ///*******************************************************************
108     //定义一个b2BodyDef物体
109     b2BodyDef def;
110     
111 //    //指定def的初始化的position,x轴是0,y轴是10,代表着从10往下落
112 //    def.position = b2Vec2(0, 10);
113     //定义完比例后开始修改位置,因为最高为6米,所以y轴定义为5,x轴最大为10米
114     def.position = b2Vec2(3, 5);
115     
116     //配置物体的属性
117     //b2_dynamicBody是枚举类型的,代表运动的物体,
118     //还有b2_staticBody  代表静态的物体
119     //还有b2_kinematicBody  代表悬浮的物体
120     def.type = b2_dynamicBody;//此时这是个运动的物体
121     
122     //创建一个物体(物体的相关的定义)
123     b2Body *body = world->CreateBody(&def);
124     
125     ///*******************************************************************
126     
127     
128     
129     
130     //指定物体的fixture
131     ///*******************************************************************
132     
133     b2PolygonShape shape;
134     shape.SetAsBox(0.5, 0.5);//设置一个一米的箱子
135     
136     
137     b2FixtureDef fixtureDef;
138     //指定fixtuer的属性
139     fixtureDef.density = 1;//密度
140     fixtureDef.friction = 0.3;//摩擦系数
141     fixtureDef.shape = &shape;
142     body->CreateFixture(&fixtureDef);
143     
144     ///*******************************************************************
145     
146     
147     
148     
149     
150     //config cocos shape
151     ///*******************************************************************
152     //定义一个图形
153     auto s = Sprite::create();
154 //    //指定他的Texture图形区域
155 //    s->setTextureRect(Rect(0, 0, 80, 80));
156 
157     //指定加入fixture的图形的区域
158     s->setTextureRect(Rect(0, 0, 0.5 * 2 * RATIO, 0.5 * 2 * RATIO));
159     
160     //将其添加到层中
161     addChild(s);
162     
163     //配置位置
164     //cocos2d的图形区域的位置是(800 x 600)
165     //box2d的范围单位是米,官方文档上的比较精确的范围是10米之内
166     //意味着800px的位置当成10米是比较合理的,所以中间的比例是80
167     
168 //    //因为每一帧都同步了,所以此处可以不要了,
169 //    //因为update中的s->setPosition(b->GetPosition().x * RATIO,
170 //    //b->GetPosition().y * RATIO);所以就不要了
171 //    //配置s的位置
172 //    s->setPosition(Point(def.position.x * RATIO, def.position.y * RATIO));
173     
174     //将图形和body相关起来
175     body->SetUserData(s);//这样就将图形和body绑定起来了
176     
177     ///*******************************************************************
178 }
179 
180 
181 
182 
183 //直接复制上面的代码
184 //创建矩形,并且让其随着重力开始运动,有加速度的向下移动
185 void HelloWorld::addRect(float positionx, float positiony, b2BodyType type){
186     
187     //config box2d
188     ///*******************************************************************
189     //定义一个b2BodyDef物体
190     b2BodyDef def;
191     
192     //    //指定def的初始化的position,x轴是0,y轴是10,代表着从10往下落
193     //    def.position = b2Vec2(0, 10);
194     //定义完比例后开始修改位置,因为最高为6米,所以y轴定义为5,x轴最大为10米
195     def.position = b2Vec2(positionx, positiony);
196     
197 //    //设置矩形的线性初速度,x轴平移
198 //    def.linearVelocity = b2Vec2(1, 0);
199 
200     //设置矩形的线性速度,y轴向上的速度
201     def.linearVelocity = b2Vec2(0, 10);
202     
203     
204     //配置物体的属性
205     //b2_dynamicBody是枚举类型的,代表运动的物体,
206     //还有b2_staticBody  代表静态的物体
207     //还有b2_kinematicBody  代表悬浮的物体
208     def.type = type;//此时这是个运动的物体
209     
210     //创建一个物体(物体的相关的定义)
211     b2Body *body = world->CreateBody(&def);
212     
213     ///*******************************************************************
214     
215     
216     
217     
218     //指定物体的fixture
219     ///*******************************************************************
220     
221     b2PolygonShape shape;
222     shape.SetAsBox(0.5, 0.5);//设置一个一米的箱子
223     
224     
225     b2FixtureDef fixtureDef;
226     //指定fixtuer的属性
227     fixtureDef.density = 1;//密度
228     fixtureDef.friction = 0.3;//摩擦系数
229     fixtureDef.shape = &shape;
230     body->CreateFixture(&fixtureDef);
231     
232     ///*******************************************************************
233     
234     
235     
236     
237     
238     //config cocos shape
239     ///*******************************************************************
240     //定义一个图形
241     auto s = Sprite::create();
242     //    //指定他的Texture图形区域
243     //    s->setTextureRect(Rect(0, 0, 80, 80));
244     
245     //指定加入fixture的图形的区域
246     s->setTextureRect(Rect(0, 0, 0.5 * 2 * RATIO, 0.5 * 2 * RATIO));
247     
248     //将其添加到层中
249     addChild(s);
250     
251     //配置位置
252     //cocos2d的图形区域的位置是(800 x 600)
253     //box2d的范围单位是米,官方文档上的比较精确的范围是10米之内
254     //意味着800px的位置当成10米是比较合理的,所以中间的比例是80
255     
256     //    //因为每一帧都同步了,所以此处可以不要了,
257     //    //因为update中的s->setPosition(b->GetPosition().x * RATIO,
258     //    //b->GetPosition().y * RATIO);所以就不要了
259     //    //配置s的位置
260     //    s->setPosition(Point(def.position.x * RATIO, def.position.y * RATIO));
261     
262     //将图形和body相关起来
263     body->SetUserData(s);//这样就将图形和body绑定起来了
264     
265     ///*******************************************************************
266     
267     
268     
269     
270 }
271 
272 
273 //添加一个地板
274 void HelloWorld::addGround(){
275     
276     //创建一个静态的物体
277     
278     b2BodyDef def;
279     //指定位置
280 //    def.position = b2Vec2(0, 0);
281     //为了让创建的地板铺满底部,
282     def.position = b2Vec2(400 / RATIO, 0);
283     //指定def的类型,静态的物体
284     def.type = b2_staticBody;
285     
286 //    b2Body *body = world->CreateBody(&def);    
287     groundBody = world->CreateBody(&def);
288     
289     
290     b2PolygonShape groundShape;
291     //默认情况下指的是半宽和半高,单位为米
292     groundShape.SetAsBox(400 / RATIO, 0.5);
293     
294     b2FixtureDef fixuredef;
295     //指定fixture的属性
296     fixuredef.density = 1;//密度
297     fixuredef.friction = 0.3;//摩擦系数
298     //为其指定一个图形区域,让其与其他图形有一个碰撞的作用
299     fixuredef.shape = &groundShape;
300     
301 //    body->CreateFixture(&fixuredef);
302     groundBody->CreateFixture(&fixuredef);
303     
304     
305 }
306 
307 
308 
309 void HelloWorld::BeginContact(b2Contact *contact){
310     
311     //链接的两个对象的fixture
312     //不管怎么样,最终都要落到地板上
313     if (contact->GetFixtureA()->GetBody() == groundBody || contact->GetFixtureB()->GetBody() == groundBody) {
314         log("有物体落在地板上*——*");
315     }
316     
317     
318 }
原文地址:https://www.cnblogs.com/dudu580231/p/4388903.html