标签:c style class blog code java
既然已有了cocos2d-x,为什么还要Box2d呢,是因为cocos2d-x作为一个图像引擎,只是用于显示图像,图像之间可以任意的重合,如果想要做到类物理学的碰撞等运动效果,就需要用到Box2d这个物理引擎用来模仿物理世界中的物体;
本讲主要简单讲述如何创建动态物体,静态物体,漂浮物体,以及它们与图像的绑定;
下面直接通过一个例子来看三种物体的创建方法;
首先需要说明的一点是:在Box2d中,使用的单位是米,而不是像素,所以,在进行位置转换的时候,需要按比例缩放,Box2d中,比较理想的距离大小是10米,所以,得对屏幕宽高进行一定的比例缩放(如下面例子中定义的RADIO,就是我定义的比例);
HelloWorldScene.cpp
#include "HelloWorldScene.h" #define RADIO 80 Scene* HelloWorld::createScene() { // ‘scene‘ is an autorelease object auto scene = Scene::create(); // ‘layer‘ is an autorelease object auto layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } world = new b2World(b2Vec2(0,-10)); //x 方向加速度为0,y方向加速度为10 world->SetContactListener(this); // 添加物体撞击事件监听 addGround(); addRect(); scheduleUpdate(); // 开始执行handler,第帧执行一次update方法 return true; } void HelloWorld::update(float dt){ world->Step(dt,8,3); // 三个参数分别表示当前帧和最后一帧之间的时间间隔,由于update方法是程序每一帧执行一次,所以直接传入帧频dt;
//第二个参数表示速度迭代次数,官方建议8;
//第三个参数表示位置迭代次数,官方建议3; Sprite *s; for(b2Body *b = world->GetBodyList();b;b= b->GetNext()){ if(b->GetUserData()){ s = (Sprite*)b->GetUserData(); s->setPosition(b->GetPosition().x * RADIO ,b->GetPosition().y *RADIO); // 更新物体的位置 } } } void HelloWorld::BeginContact(b2Contact* contact){ // b2ContactListener物体发生碰撞时的回调接口 log("contact?"); if(contact->GetFixtureA()->GetBody() == ground ||contact->GetFixtureB()->GetBody() == ground){ log("yeah,contacted!"); } } void HelloWorld::addRect(){ // 添加一个动态的Rect,并且绑定一个Sprite; b2BodyDef def; def.type = b2_dynamicBody; // 指定type为动态物体 @1 def.position = b2Vec2(3,1); // 起始位置(3,1) def.linearVelocity = b2Vec2(0,10); // (初始)线性速度,如果type为漂浮的,则物体会没这个方向做匀速运动,如果为动态,则会进行预先设定的加速度进行速度变换; b2PolygonShape shape; shape.SetAsBox(0.5,0.5); // 设置一个Shape,两个参数分别表示左半边和上半边的大小,所以,这里两个0.5其实就定义了一个1x1的块 b2FixtureDef fixtureDef; fixtureDef.density = 1; // 指定物体密度 fixtureDef.friction = 0.3; // 指定物体摩擦 fixtureDef.shape = &shape; // 指定物体的shape b2Body *body = world->CreateBody(&def); auto s = Sprite::create(); s->setTextureRect(Rect(0 , 0, 30, 30)); // 设置sprite所显示的区域 addChild(s); body->CreateFixture(&fixtureDef); // 设置FixtureDef之后,两个物体之间就会有碰撞的效果了,如果没有碰撞的效果,则物体会一直沿某一个方向不停运动; body->SetUserData(s); // 将Sprite绑定到物体上 } void HelloWorld::addGround(){ //添加一个静态物体,在为里为添加到底部,阻止上一步中创建的自由落体的物体 b2BodyDef def; def.type = b2_staticBody; def.position = b2Vec2(0, 0); b2PolygonShape shape; shape.SetAsBox(400/RADIO, 10 / RADIO); // 设置物体大小 ground = world->CreateBody(&def); auto s = Sprite::create(); s->setTextureRect(Rect(0,0,1600,40)); b2FixtureDef fixtureDef; fixtureDef.density = 0.5; fixtureDef.friction = 0.3; fixtureDef.shape = &shape; addChild(s); ground->CreateFixture(&fixtureDef); ground->SetUserData(&def); }
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include <Box2D/Box2D.h> USING_NS_CC; class HelloWorld : public Layer,public b2ContactListener { private : b2World *world; b2Body *ground; public: // there‘s no ‘id‘ in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here‘s a difference. Method ‘init‘ in cocos2d-x returns bool, instead of returning ‘id‘ in cocos2d-iphone virtual bool init(); // a selector callback void menuCloseCallback(cocos2d::Ref* pSender); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); virtual void update(float dt); void addRect(); void addGround(); /// Called when two fixtures begin to touch. virtual void BeginContact(b2Contact* contact) ; }; #endif // __HELLOWORLD_SCENE_H__
@1: 这里的type有三种类型如下
Cocos2d-x 系列八之Box2d入门,布布扣,bubuko.com
标签:c style class blog code java
原文地址:http://www.cnblogs.com/a284628487/p/3755555.html