【麦可网】Cocos2d-X跨平台游戏开发---学习笔记
第二十五课:Cocos2D-X物理引擎之Box2D8-10
=======================================================================================================================================================================
课程目标:
-学习Box2D
课程重点:
-Box2D概念
-Box2D常用操作
-使用物理编辑器
考核目标:
-能够使用Box2D常用操作
-使用物理编辑器完成物理对象编辑
=======================================================================================================================================================================
一、物理编辑器
1.vertexHelper(mac)
2.PhysicsEditor
二、使用PhysicsEditor的实例
HelloPhysicEditor.h ------------------------------------- #pragma once #include "cocos2d.h" #include "Box2D/Box2D.h" USING_NS_CC; class HelloPhysicEditor : public cocos2d::CCLayer { private: CCTexture2D* m_pSpriteTexture; b2World* world; public: HelloPhysicEditor(); ~HelloPhysicEditor(); // 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(HelloPhysicEditor); virtual void ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent); void initPhysics(); void addNewSpriteAtPosition(CCPoint p); void updata(float dt); }; HelloPhysicEditor.cpp ------------------------------------- #include "HelloPhysicEditor.h" #include "cocos-ext.h" #include "GB2ShapeCache-x.h" using namespace cocos2d::extension; USING_NS_CC; enum{ kTagParentNode = 1,}; #define PTM_RATIO 32.0f string names[] = { "hotdog","drink","icecream","icecream2","icecream3","hamburger","orange" }; CCScene* HelloPhysicEditor::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloPhysicEditor *layer = HelloPhysicEditor::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } HelloPhysicEditor::HelloPhysicEditor(): m_pSpriteTexture(NULL),world(NULL) { //加载physicsEditor生成的文件 GB2ShapeCache::sharedGB2ShapeCache()->addShapesWithFile("physic_all.plist"); } HelloPhysicEditor::~HelloPhysicEditor() { CC_SAFE_DELETE(world); } // on "init" you need to initialize your instance bool HelloPhysicEditor::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(HelloPhysicEditor::updata)); return true; } void HelloPhysicEditor::menuCloseCallback(CCObject* pSender) { } void HelloPhysicEditor::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 HelloPhysicEditor::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 HelloPhysicEditor::addNewSpriteAtPosition(CCPoint p) { string name = names[rand()%7]; //定义刚体 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); GB2ShapeCache* sc = GB2ShapeCache::sharedGB2ShapeCache(); sc->addFixturesToBody(body,name.c_str()); //定义夹具 // 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) );//添加上这句在快速创建物理精灵时会出错 CCPhysicsSprite* sprite = CCPhysicsSprite::create( (name+".png").c_str()); this->addChild(sprite); sprite->setB2Body(body); sprite->setPTMRatio(PTM_RATIO); //sprite->setPosition( ccp(p.x,p.y) ); sprite->setAnchorPoint(sc->anchorPointForShape(name.c_str())); } void HelloPhysicEditor::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 } 视频中GB2ShapeCache-x.cpp的下载地址: http://download.csdn.net/download/yclmy/8408533
===================================================================
总结:
物理编辑器真的太方便啦!
开心一刻:
蝙蝠深爱麻雀,却被拒绝,
蝙蝠:“为什么,这一切都是为什么?”
麻雀:“俺妈说了,长得黑也就算了,总爱晚上出去的男人都不是好鸟!”
【麦可网】Cocos2d-X跨平台游戏开发---教程下载:http://pan.baidu.com/s/1kTio1Av
【麦可网】Cocos2d-X跨平台游戏开发---笔记系列:http://blog.csdn.net/qiulanzhu