您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x box2d 入门

2014-03-04 16:26 323 查看
个人原创,欢迎转载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();
}


是不是感觉没什么注释啊,好的代码不需要注释


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息