box2d简单介绍可参阅:http://blog.csdn.net/song_hui_xiang/article/details/34116399
写这篇文章主要是说明:对一个刚体施加一个力,用 GetWorldVector() 与不用的区别。刚开始学习box2d,因为这个问题被虐了好几天,贴出来一是分享,二是备忘。下面直接上代码:
.h
// // Game.h // HeroJump // // Created by XiangZi on 14-6-27. // // #ifndef __HeroJump__Game__ #define __HeroJump__Game__ #include "cocos2d.h" #include "Box2D.h" #include "cocos-ext.h"//用CCPhysicsSprite类需要导入此头文件 using namespace std; USING_NS_CC_EXT; USING_NS_CC; enum GameTag{ kTag, }; enum MenuTag{ }; enum GamezOrder{ zOrder, }; class Game : public CCLayer { public: ~Game(); Game(); static CCScene* scene(); void initPhysics(); virtual void draw(); void update(float dt); CCPhysicsSprite* createNewPhysicsSprite(const char *imageName); virtual void onEnter(); virtual void onExit(); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); private: b2World* world; CCSize size; }; #endif /* defined(__HeroJump__Game__) */
.cpp
// // Game.cpp // HeroJump // // Created by XiangZi on 14-6-27. // // #include "Game.h" #define PTM_RATIO 32 Game::Game() { setAccelerometerEnabled( true ); size = CCDirector::sharedDirector()->getWinSize(); //创建物理世界 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; // bottom groundBox.Set(b2Vec2(0,0), b2Vec2(size.width/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); // top groundBox.Set(b2Vec2(0,size.height/PTM_RATIO), b2Vec2(size.width/PTM_RATIO,size.height/PTM_RATIO)); groundBody->CreateFixture(&groundBox,0); // left groundBox.Set(b2Vec2(0,size.height/PTM_RATIO), b2Vec2(0,0)); groundBody->CreateFixture(&groundBox,0); // right groundBox.Set(b2Vec2(size.width/PTM_RATIO,size.height/PTM_RATIO), b2Vec2(size.width/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); this->initPhysics(); scheduleUpdate(); } Game::~Game() { delete world; world = NULL; } void Game::initPhysics() { CCPhysicsSprite* sprite = createNewPhysicsSprite("Icon.png"); sprite->setPosition(ccp(size.width/2, size.height/2)); this->addChild(sprite,1,1234); } //封装此方法用于创建一物理精灵 CCPhysicsSprite* Game::createNewPhysicsSprite(const char *imageName) { CCPhysicsSprite* physicsSprite = CCPhysicsSprite::create(imageName); b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; b2Body* body = world->CreateBody(&bodyDef); b2PolygonShape polygonShape; polygonShape.SetAsBox(physicsSprite->getContentSize().width/PTM_RATIO/2, physicsSprite->getContentSize().height/PTM_RATIO/2); b2FixtureDef fixtureDef; fixtureDef.shape = &polygonShape; fixtureDef.density = 5.5f; fixtureDef.friction = 0.3f; fixtureDef.restitution = 0.1f; body->CreateFixture(&fixtureDef); physicsSprite->setPTMRatio(PTM_RATIO); physicsSprite->setB2Body(body); return physicsSprite; } bool Game::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { CCPoint point = pTouch->getLocation(); CCPhysicsSprite* sprite = (CCPhysicsSprite*)this->getChildByTag(1234); b2Body* body = sprite->getB2Body(); float gravityX = 5.0f; float gravityY = 10.0f; //给body施加一个力。 GetWorldCenter()方法用来获取刚体的重心。 //b2Vec2 force = body->GetWorldVector(b2Vec2(-gravityX,gravityY)); 以此body的坐标系计算向量,body有转动向量方向也会随之转动。 b2Vec2 force = b2Vec2(-gravityX,gravityY); //以整个wrold世界的坐标系计算向量,不随单个body装动而转动。 if (point.x < size.width/2) {//点击屏幕左半边给予一个左上的速度 force.x = -gravityX; }else{//点击屏幕右半边给予一个右上的速度 force.x = gravityX; } //直接影响刚体的速度。setLinearVelocity添加的速度会覆盖刚体原有的速度。 body->SetLinearVelocity(b2Vec2_zero); body->SetAngularVelocity(0); body->SetAwake(true); body->SetLinearVelocity(force); return true; } void Game::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){} void Game::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){} void Game::onEnter() { CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false); CCLayer::onEnter(); } void Game::onExit() { CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); CCLayer::onExit(); } void Game::update(float dt) { int velocityIterations = 8; int positionIterations = 1; world->Step(1.0f/60.0f, velocityIterations, positionIterations); } void Game::draw() { CCLayer::draw(); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); kmGLPushMatrix(); world->DrawDebugData(); kmGLPopMatrix(); } CCScene* Game::scene() { CCScene *scene = CCScene::create(); CCLayer* layer = new Game(); scene->addChild(layer); layer->release(); return scene; }