本博客例子参考:raywenderlich
我将上面obj-c的翻译成了C++,改动很少。首先在win32下新建新工程
修改HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "Box2D/Box2D.h" class HelloWorld : public cocos2d::CCLayer { public: HelloWorld(); ~HelloWorld(); virtual bool init(); CREATE_FUNC(HelloWorld); static cocos2d::CCScene* scene(); void menuCloseCallback(CCObject* pSender); virtual void update(float dt); // 启动重力感应后,重力方向改变会回调didAccelerate void didAccelerate(cocos2d::CCAcceleration* pAccelerationValue); public: b2World *m_world; cocos2d::CCSprite *m_ball; }; #endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h" using namespace cocos2d; #define PTM_RATIO 32 HelloWorld::HelloWorld() { m_world = NULL; m_ball = NULL; } HelloWorld::~HelloWorld() { delete m_world; m_ball = NULL; } CCScene* HelloWorld::scene() { CCScene * scene = NULL; do { // 'scene' is an autorelease object scene = CCScene::create(); CC_BREAK_IF(! scene); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); CC_BREAK_IF(! layer); // add layer as a child to scene scene->addChild(layer); } while (0); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { bool bRet = false; do { CC_BREAK_IF(! CCLayer::init()); // quit menu CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); CC_BREAK_IF(! pCloseItem); pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20)); CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); CC_BREAK_IF(! pMenu); this->addChild(pMenu, 1); // window size CCSize size = CCDirector::sharedDirector()->getWinSize(); // add a sprite m_ball = CCSprite::create("Ball.jpg"); this->addChild(m_ball); m_ball->setPosition(ccp(100, 100)); b2Vec2 gravity = b2Vec2(0.0f, -30.0f); // 重力系数 m_world = new b2World(gravity); // 创建重力 // create edge ground b2BodyDef groundBodyDef; // 边缘刚体定义 b2Body *groundBody = m_world->CreateBody(&groundBodyDef); // 创建边缘刚体 b2PolygonShape groundBox; // bottom groundBox.SetAsBox(size.width / PTM_RATIO, 0, b2Vec2(0, 0), 0); groundBody->CreateFixture(&groundBox, 0); // up groundBox.SetAsBox(size.width / PTM_RATIO, 0, b2Vec2(0,size.height/PTM_RATIO), 0); groundBody->CreateFixture(&groundBox, 0); // left groundBox.SetAsBox(0, size.height / PTM_RATIO, b2Vec2(0,0), 0); groundBody->CreateFixture(&groundBox, 0); // right groundBox.SetAsBox(0, size.height / PTM_RATIO, b2Vec2(size.width/PTM_RATIO,0), 0); groundBody->CreateFixture(&groundBox, 0); // create ball body an shape b2BodyDef ballBodyDef; ballBodyDef.type = b2_dynamicBody; // 刚体类型:动态 ballBodyDef.position.Set(100 / PTM_RATIO, 100 / PTM_RATIO); // 设置位置 ballBodyDef.userData = m_ball; // 绑定数据:精灵 b2Body *body = m_world->CreateBody(&ballBodyDef); // 创建刚体 b2CircleShape circle; // 圆形定义 circle.m_radius = 26.0 / PTM_RATIO; // 半径 b2FixtureDef ballFixtureDef; // 定制器 ballFixtureDef.shape = &circle; // 绑定圆形 ballFixtureDef.density = 1.0f; // 密度 ballFixtureDef.friction = 0.2f; // 摩擦系数 ballFixtureDef.restitution = 0.8f; // 恢复:用于弹力的 body->CreateFixture(&ballFixtureDef); this->setAccelerometerEnabled(true); // 在层里启用重力感应 this->scheduleUpdate(); bRet = true; } while (0); return bRet; } void HelloWorld::menuCloseCallback(CCObject* pSender) { // "close" menu item clicked CCDirector::sharedDirector()->end(); } void HelloWorld::update(float dt) { int velocityIterations = 8; int positionIterations = 1; m_world->Step(dt, velocityIterations, positionIterations); for (b2Body *b = m_world->GetBodyList(); b; b = b->GetNext()) { if (b->GetUserData() != NULL) { CCSprite *ballData = (CCSprite*) b->GetUserData(); ballData->setPosition(ccp(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO)); ballData->setRotation(CC_RADIANS_TO_DEGREES(b->GetAngle())); } } } void HelloWorld::didAccelerate(CCAcceleration* pAccelerationValue) { b2Vec2 gravity(- pAccelerationValue->y * 15, pAccelerationValue->x * 15); m_world->SetGravity(gravity); }
运行效果如下:
在移植到android真机调试时,发现重力感应方向并不对,
这里我将didAccelerate的实现,重新设置重力修改成如下:
b2Vec2 gravity(pAccelerationValue->x * 15, pAccelerationValue->y * 15);
m_world->SetGravity(gravity);
它就能正确感应了。