【麦可网】Cocos2d-X跨平台游戏开发---学习笔记
第二十四课:Cocos2D-X物理引擎之Box2D1-7
=======================================================================================================================================================================
课程目标:
-学习Box2D
课程重点:
-Box2D概念
-Box2D常用操作
-使用物理编辑器
考核目标:
-能够使用Box2D常用操作
-使用物理编辑器完成物理对象编辑
=======================================================================================================================================================================
一、启动Box2D
1、选中你编译的工程,按Alt+Enter快捷键(或者右键,选Propreties),在弹出的菜单中选择C/C++-->Preprocossor,将PreprocessorDefinition下的CC_ENABLE_CHIPMUNK_INTEGRATION=1修改为CC_ENABLE_Box2D_INTEGRATION=1。
2、查看Linker-->Input下的AditionalDependencies里,有没有libBox2d.lib。如果没有,手动添加之。
3、libExtensions类库也对应修改1和2步骤
二、实例一:使用Box2D
HelloBox2D.h -------------------- #pragma once #include "cocos2d.h" #include "Box2D/Box2D.h" USING_NS_CC; class HelloBox2D : public cocos2d::CCLayer { private: CCTexture2D* m_pSpriteTexture; b2World* world; public: HelloBox2D(); ~HelloBox2D(); // Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp,so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloBox2D); virtual void ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent); void initPhysics(); void addNewSpriteAtPosition(CCPoint p); void updata(float dt); }; HelloBox2D.cpp -------------------- #include "HelloBox2D.h" #include "cocos-ext.h" using namespace cocos2d::extension; USING_NS_CC; enum{ kTagParentNode = 1,}; #define PTM_RATIO 32.0f CCScene* HelloBox2D::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloBox2D *layer = HelloBox2D::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } HelloBox2D::HelloBox2D(): m_pSpriteTexture(NULL),world(NULL) { } HelloBox2D::~HelloBox2D() { CC_SAFE_DELETE(world); } // on "init" you need to initialize your instance bool HelloBox2D::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } setTouchEnabled(true); setAccelerometerEnabled(true); this->initPhysics(); CCSpriteBatchNode* blocks = CCSpriteBatchNode::create("blocks.png",100); m_pSpriteTexture = blocks->getTexture(); addChild(blocks,kTagParentNode); //scheduleUpdate(); this->schedule(schedule_selector(HelloBox2D::updata)); return true; } void HelloBox2D::menuCloseCallback(CCObject* pSender) { } void HelloBox2D::ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent) { CCSetIterator it; CCTouch* touch; for (it=pTouches->begin(); it!=pTouches->end();it++) { touch = (CCTouch*)(*it); if (!touch) break; CCPoint location = touch->getLocation(); addNewSpriteAtPosition( location ); } } void HelloBox2D::initPhysics() { b2Vec2 gravity; gravity.Set(0.0f,-10.0f); world = new b2World(gravity); world->SetAllowSleeping(true); world->SetContinuousPhysics(true); //创建物理空间的范围 b2BodyDef groundBodyDef; groundBodyDef.position.Set(0,0); //创建刚体 b2Body* groundBody = world->CreateBody(&groundBodyDef); //创建形状 b2EdgeShape groundBox; //创建夹具 //将形状绑定到刚体上 //button groundBox.Set(b2Vec2(0,0),b2Vec2(480/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); //top groundBox.Set(b2Vec2(0,320/PTM_RATIO),320/PTM_RATIO)); groundBody->CreateFixture(&groundBox,0); //left groundBox.Set(b2Vec2(0,b2Vec2(0,0); //right groundBox.Set(b2Vec2(480/PTM_RATIO,0); } void HelloBox2D::addNewSpriteAtPosition(CCPoint p) { //定义刚体 b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(p.x/PTM_RATIO,p.y/PTM_RATIO); b2Body *body = world->CreateBody(&bodyDef); //定义多边形 b2PolygonShape dynamicBox; dynamicBox.SetAsBox(.5f,.5f); //定义夹具 b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicBox; //形状 fixtureDef.density = 1.0f; //密度 fixtureDef.friction = 0.3f; //摩擦系数 body->CreateFixture(&fixtureDef); CCNode* parent = this->getChildByTag(kTagParentNode); int idx = (CCRANDOM_0_1() < 0.5 ? 0 : 1); int idy = (CCRANDOM_0_1() < 0.5 ? 0 : 1); if (idx==0 && idy==0) { int a =100; body->SetUserData(&a); } CCPhysicsSprite* sprite = CCPhysicsSprite::createWithTexture(m_pSpriteTexture,CCRectMake(32*idx,32*idy,32,32)); parent->addChild(sprite); sprite->setB2Body(body); sprite->setPTMRatio(PTM_RATIO); //sprite->setPosition( ccp( p.x,p.y) );//添加上这句在快速创建物理精灵时会出错 } void HelloBox2D::updata(float dt) { int velocityIterations = 8; int positionIterations = 1; world->Step(dt,velocityIterations,positionIterations); #if 0 //遍历刚体 for (b2Body* b=world->GetBodyList(); b; b=b->GetNext()) { int* tmp = (int*)b->GetUserData(); if (*tmp == 100) { //千万不要在这里直接删除b指向的body对象,缓存后在后面删除 CCLOG("body is a"); } } //遍历碰撞点 for ( b2Contact* c=world->GetContactList(); c; c=c->GetNext() ) { ////千万不要在这里直接删除c指向的碰撞点对象,缓存后在后面删除 } #endif }
<strong>碰撞前后的状态</strong>
===================================================================
总结:
玩转物理引擎,直达愤怒小鸟。
开心一刻:
4岁的男孩亲3岁的女孩,
女孩很认真的问:“你亲了我会对我负责吗?”
男孩拍拍女孩的肩膀:“你放心,我们已不是一、两岁的孩子了。”
【麦可网】Cocos2d-X跨平台游戏开发---教程下载:http://pan.baidu.com/s/1kTio1Av
【麦可网】Cocos2d-X跨平台游戏开发---笔记系列:http://blog.csdn.net/qiulanzhu