个人原创,欢迎转载http://blog.csdn.net/dawn_moon/article/details/20466245
天天飞翔,物理特性用了box2d来做的。关于box2d的入门教程网上有很多,推荐官方手册,中文版,地址。我不再做重复介绍,稍微写点自己理解的东西。
cocos2d-x可以和box2d的C++版完美融合,集成起来很方便。
#include "Box2D.h"
包含进来就可以了。这里有个问题,cocos2d-x2.2.1版本NDK编译安卓版本的时候,需要改下, 不然找不到box2d的头文件。
#include "Box2D/Box2D.h"
开启box2d的debug渲染
一般为了方便调试box2d,会将物理世界的物体绘制出来,官方有debug draw,cocos2dx里面有个debug的工具类GLESDebugDraw,在test工程里面,文件名GLES-Render.h,加入进来。
步骤如下:
1。需要有个box2d的物理世界b2World,一个debug渲染器,GLESDebugDraw。demo如下:
//
// TestBox.h
// TestBox2d
//
// Created by lerry on 14-3-4.
// Copyright (c) 2014年 GoonearTechnology Co.,Ltd. All rights reserved.
//
#ifndef __TestBox2d__TestBox__
#define __TestBox2d__TestBox__
#include "cocos2d.h"
#include "Box2D.h"
#include "GLES-Render.h"
#define RATIO 96
class TestBox : public cocos2d::CCLayer
{
cocos2d::CCSprite* role;
b2World* mWorld;
GLESDebugDraw* mDebugDraw;
cocos2d::CCSize visualSize;
private:
void draw();
void drawBox();
public:
~TestBox();
virtual void update(float dt);
virtual bool init();
virtual void onEnter();
virtual void onExit();
virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
virtual void ccTouchMoved(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
virtual void ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
void initWorld();
void setDebug(bool isDebug);
static cocos2d::CCScene* scene();
CREATE_FUNC(TestBox);
};
#endif /* defined(__TestBox2d__TestBox__) */
2。构建世界,构建世界盒子,开启debug模式
void TestBox::initWorld()
{
mWorld = new b2World(b2Vec2(0, -10));
mWorld->SetAllowSleeping(true);
mWorld->SetContinuousPhysics(true);
setDebug(true);
}
3。如果开启debug模式,启用debug绘制
void TestBox::setDebug(bool isDebug)
{
if (isDebug) {
mDebugDraw = new GLESDebugDraw(RATIO);
mWorld->SetDebugDraw(mDebugDraw);
uint32 flags = 0;
flags += b2Draw::e_shapeBit;
flags += b2Draw::e_jointBit;
flags += b2Draw::e_pairBit;
flags += b2Draw::e_centerOfMassBit;
mDebugDraw->SetFlags(flags);
draw();
}
}
void TestBox::draw()
{
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
mWorld->DrawDebugData();
kmGLPopMatrix();
}
4.init里面初始化世界,调用update函数即可。
代码如下:
//
// TestBox.cpp
// TestBox2d
//
// Created by lerry on 14-3-4.
// Copyright (c) 2014年 GoonearTechnology Co.,Ltd. All rights reserved.
//
#include "TestBox.h"
USING_NS_CC;
TestBox::~TestBox()
{
delete mWorld;
mWorld = NULL;
delete mDebugDraw;
mDebugDraw = NULL;
}
CCScene* TestBox::scene()
{
CCScene* s = CCScene::create();
TestBox* test = TestBox::create();
s->addChild(test);
return s;
}
bool TestBox::init()
{
if(!CCLayer::init())
{
return false;
}
visualSize = CCDirector::sharedDirector()->getVisibleSize();
initWorld();
drawBox();
scheduleUpdate();
return true;
}
void TestBox::update(float dt)
{
int velocityIterat = 8;
int positionIterat = 1;
mWorld->Step(dt, velocityIterat, positionIterat);
for(b2Body *b=mWorld->GetBodyList(); b; b=b->GetNext())
{
if(b->GetUserData()!=NULL)
{
CCSprite *sprite=(CCSprite*)b->GetUserData();
sprite->setPosition(ccp(b->GetPosition().x*RATIO,b->GetPosition().y*RATIO));
sprite->setRotation((-1)*CC_RADIANS_TO_DEGREES(b->GetAngle()));
}
}
}
void TestBox::drawBox()
{
{ // 地板
b2Body* ground = NULL;
b2BodyDef bd;
ground = mWorld->CreateBody(&bd);
// 底边
b2EdgeShape shape;
shape.Set(b2Vec2(0.1f, 0.1f), b2Vec2(visualSize.width / RATIO - 0.1f, 0.1f));
ground->CreateFixture(&shape, 0.0f);
shape.Set(b2Vec2(0.1f, 0.1f), b2Vec2(0.1f, visualSize.height / RATIO - 0.1f));
ground->CreateFixture(&shape, 0.0f);
shape.Set(b2Vec2(0.1f, visualSize.height / RATIO - 0.1f), b2Vec2(visualSize.width / RATIO - 0.1f, visualSize.height / RATIO - 0.1f));
ground->CreateFixture(&shape, 0.0f);
shape.Set(b2Vec2(visualSize.width / RATIO - 0.1f, 0.1f), b2Vec2(visualSize.width / RATIO - 0.1f, visualSize.height / RATIO - 0.1f));
ground->CreateFixture(&shape, 0.0f);
}
{
role = CCSprite::create("poop_1.png");
CCSize size = role->getContentSize();
role->setPosition(ccp(visualSize.width / 2, visualSize.height / 2));
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.userData = role;
bodyDef.position.Set(visualSize.width / 2 / RATIO, visualSize.height / 2 / RATIO);
b2Body* body = mWorld->CreateBody(&bodyDef);
b2PolygonShape shape;
shape.SetAsBox(size.width / 2 / RATIO, size.height / 2 / RATIO);
b2FixtureDef fixDef;
fixDef.shape = &shape;
body->CreateFixture(&fixDef);
addChild(role);
}
}
void TestBox::initWorld()
{
mWorld = new b2World(b2Vec2(0, -10));
mWorld->SetAllowSleeping(true);
mWorld->SetContinuousPhysics(true);
setDebug(true);
}
void TestBox::setDebug(bool isDebug)
{
if (isDebug) {
mDebugDraw = new GLESDebugDraw(RATIO);
mWorld->SetDebugDraw(mDebugDraw);
uint32 flags = 0;
flags += b2Draw::e_shapeBit;
flags += b2Draw::e_jointBit;
flags += b2Draw::e_pairBit;
flags += b2Draw::e_centerOfMassBit;
mDebugDraw->SetFlags(flags);
draw();
}
}
void TestBox::draw()
{
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
mWorld->DrawDebugData();
kmGLPopMatrix();
}
bool TestBox::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
{
CCLog("touch");
return true;
}
void TestBox::ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
{
}
void TestBox::ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
{
}
void TestBox::onEnter()
{
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
CCLayer::onEnter();
}
void TestBox::onExit()
{
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->removeDelegate(this);
CCLayer::onExit();
}
是不是感觉没什么注释啊,好的代码不需要注释