现在的位置: 首页 > 综合 > 正文

box2d弹球 cocos2d-x重力感应(cocos2d-x2.1)

2017年12月16日 ⁄ 综合 ⁄ 共 3853字 ⁄ 字号 评论关闭

本博客例子参考: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__

HelloWorldScene.cpp代码如下:

#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);

它就能正确感应了。

抱歉!评论已关闭.