码迷,mamicode.com
首页 > 其他好文 > 详细

cocos2dx box2d使用(一)

时间:2014-05-19 12:12:35      阅读:293      评论:0      收藏:0      [点我收藏+]

标签:class   c   tar   ext   http   int   

出处:https://www.evernote.com/shard/s262/sh/bf561bda-0458-4502-835b-903846f81d68/68e6634bddec74c5a2d5f8dd839eba0a

本例子使用的是cocos2d-x 3.0版本

  1. 首先创建一个cocos2d的c++工程,这里就不多做说明了!本例子的项目名称是MyGame
  2. 其次,在MyGame的工程设置里Build Settings下,把CC_ENABLE_CHIPMUNK_INTEGRATION=1改为CC_ENABLE_BOX2D_INTEGRATION=1,同样把项目所引入的cocos2d的工程里改一下,但cocos2d的工程修改的地方有点特别!bubuko.com,布布扣如上图的工程,非target!
  3. 到此,box2d的环境已经设定好了!
现在工程已经创建完成了,环境也设定好了,下代码工程:
bubuko.com,布布扣
创建一个layer,用于放置所有的box2d对像和项目的精灵
其中的头文件如下:
//
//  Box2dTest.h
//  MyGame
//
//  Created by Poche on 5/17/14.
//
//

#ifndef __MyGame__Box2dTest__
#define __MyGame__Box2dTest__

#include "cocos2d.h"
#include
 "Box2D/Box2D.h"

class Box2dTest : public cocos2d::Layer {
public:
    Box2dTest();
   
 virtual ~Box2dTest();
   
 CREATE_FUNC(Box2dTest);
   
   
 /**
     *@brief
初始化box2d测试layerbox2d世界是独立于cocosscene
     *
     *@Modified by poche at 2014-05-18 18:00:17
     *
     *@return
是否初始化成功
    **/

   
 bool init();
   
 /**
     *@brief
初始化box2d世界
     *
     *@Modified by poche at 2014-05-18 18:01:43
    **/

   
 void initWorld();
private:
   
 b2World *m_world;   /// box2d世界
   
 /// layer上的点击加调
   
 CC_SYNTHESIZE_RETAIN(cocos2d::EventListenerTouchAllAtOnce*, m_touchListener,_touchListener);
public:
   
 /**
     *@brief
添加精灵到指定坐标
     *
     *@Modified by poche at 2014-05-18 18:02:44
     *@param point
 坐标
    **/

   
 void AddSprite(cocos2d::Point point);
   
 /**
     *@brief
每帧检查box2d物体并且更新cocos的精灵的状态(位置等)
     *
     *@Modified by poche at 2014-05-18 18:03:25
     *@param dt
 时间间隔
    **/

   
 void update(float dt);
   
 /**
     *@brief
添加点击回调事件
     *
     *@Modified by poche at 2014-05-18 18:04:39
    **/

   
 void addLayerTouchListener();
   
 /**
     *@brief
点击结束后的加调方法
     *
     *@Modified by poche at 2014-05-18 18:04:56
     *@param touches
 点击集合
     *@param event
 事件类型
    **/

   
 void touchesEnd(const std::vector<cocos2d::Touch*> touches, cocos2d::Event *event);
   
 virtual void onExit();
};

#endif /* defined(__MyGame__Box2dTest__) */
 
下面看一下.cpp的代码:
//
//  Box2dTest.cpp
//  MyGame
//
//  Created by Poche on 5/17/14.
//
//

#include "Box2dTest.h"
USING_NS_CC
;

/// box2d里,其用到的单位是现实中的单位,米等
/// 所以在游戏里,我们需要作出转换
/// cocos2d里,每32个像素就相当box2d里的一米
#define PTM_RATIO 32

const int tagSprite = 1;

Box2dTest::Box2dTest()
:
 m_touchListener(NULL)
{
   
}

Box2dTest::~Box2dTest() {
   
 CC_SAFE_RELEASE(m_touchListener);
   
 /// 记得移除对像,要不然会泄露
   
 delete m_world;
   
 m_world = NULL;
}

bool Box2dTest::init() {
   
 /// 添加点击响应
   
 addLayerTouchListener();
   
 /// 初始化世界
   
 initWorld();
   
 return true;
}
void Box2dTest::initWorld() {
   
   
 auto size = Director::getInstance()->getWinSize();
   
 /// 设置box2d世界重力方向
   
 b2Vec2 gravity(0.0f, -10.0f);
   
 bool doSleep    = true;
   
   
 /// 生成box2d世界
   
 m_world = new b2World(gravity);
   
 /// 是否允许睡眠
   
 m_world->SetAllowSleeping(doSleep);
   
 m_world->SetContinuousPhysics(true);
   
   
 /// 地表物体定义
   
 b2BodyDef groundBodyDef;
   
 /// 通过地表物体定义生成地表物体
   
 b2Body* groundBody  = m_world->CreateBody(&groundBodyDef);
   
 /// 形状
   
 b2PolygonShape groundBox;
   
   
 /// 作为box形态布局
   
 /// 第一个参数  物体的宽
   
 /// 第二个参数  物体的高
   
 /// 第三个参数  物体的位置
   
 /// 第四个参数  物体中角度
   
 /// 墙底
    groundBox.
SetAsBox(size.width / PTM_RATIO, 0, b2Vec2(0, 0), 0);
   
 /// 把已经生成的物体放入世界中
   
 /// 第一个参数  要放入的物体
   
 /// 第二个参数  物体的质量
    groundBody->
CreateFixture(&groundBox, 0);
   
 /// 墙顶
    groundBox.
SetAsBox(size.width / PTM_RATIO, 0, b2Vec2(0, size.height / PTM_RATIO), 0);
    groundBody->
CreateFixture(&groundBox, 0);
   
 /// 左墙
    groundBox.
SetAsBox(0, size.height / PTM_RATIO, b2Vec2(0, 0), 0);
    groundBody->
CreateFixture(&groundBox, 0);
   
 /// 左墙
    groundBox.
SetAsBox(0, size.height / PTM_RATIO, b2Vec2(size.width / PTM_RATIO, 0), 0);
    groundBody->
CreateFixture(&groundBox, 0);
   
   
 /// cocos2d里的精灵
   
 auto brick  = SpriteBatchNode::create("CloseNormal.png");
   
 addChild(brick, 2, tagSprite);
   
   
 /// 每帧对cocos2d的精灵更新
   
 schedule(schedule_selector(Box2dTest::update));
}

void Box2dTest::AddSprite(cocos2d::Point point) {
   
 auto batch = (SpriteBatchNode*)getChildByTag(tagSprite);
   
   
 auto sprite = Sprite::createWithTexture(batch->getTexture(), Rect(0,0,32,32));
    batch->
addChild(sprite);
   
    sprite->
setPosition(Point(point.x, point.y));
   
   
 /// 创建动态物体
   
 /// 物体定义
   
 b2BodyDef bodyDef;
   
 /// 物体为动态物体
    bodyDef.
type = b2_dynamicBody;
   
 /// 物体的位置
    bodyDef.
position.Set(point.x / PTM_RATIO, point.y/ PTM_RATIO);
   
 /// 将已经生成的精灵捆绑到物体上
    bodyDef.
userData = sprite;
   
 /// 创建物体
   
 b2Body * body = m_world->CreateBody(&bodyDef);
   
   
 b2PolygonShape dynamicBox;
    dynamicBox.
SetAsBox(0.5f, 0.5f);
   
   
 b2FixtureDef fixtureDef;
    fixtureDef.
shape = &dynamicBox;
   
 /// 设置摩擦系数
    fixtureDef.
friction = 0.3f;
   
 /// 设置密度
    fixtureDef.
density = 1.0;
    body->
CreateFixture(&fixtureDef);
}

void Box2dTest::update(float dt) {
   
 int velocityIterations = 8;
   
 int positionIterations = 1;
   
   
 //每次游戏循环你都应该调用b2World::Step
   
 m_world->Step(dt, velocityIterations, positionIterations);
   
   
   
 for(b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
    {
       
 if(b->GetUserData() != NULL)
        {
           
 /// 更新cocos2d对像
           
 auto sprite = (Sprite*)b->GetUserData();
            sprite->
setPosition(Point(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO));
            sprite->
setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
        }
    }
}

void Box2dTest::addLayerTouchListener() {
   
 set_touchListener(EventListenerTouchAllAtOnce::create());
   
 get_touchListener()->onTouchesEnded = CC_CALLBACK_2(Box2dTest::touchesEnd, this);
   
 _eventDispatcher->addEventListenerWithSceneGraphPriority(get_touchListener(), this);
   
}

void Box2dTest::onExit() {
   
 Layer::onExit();
   
 unschedule(schedule_selector(Box2dTest::update));
   
 _eventDispatcher->removeEventListener(get_touchListener());
}

void Box2dTest::touchesEnd(const std::vector<cocos2d::Touch *> touches, cocos2d::Event *event) {

   
 for (auto& touch : touches)
    {
       
 auto location = touch->getLocationInView();
        location =
 Director::getInstance()->convertToGL(location);
       
       
 AddSprite(location);
    }
}
 
解释:
在这里要说说box2d中的单位,由于box2d中使用的是米作为长度单位。但在编程中,我们使用的图片都是使用像素作为基本单位。
凡是要向世界对象中添加物体的,都需要将像素单位转化为米单位。凡是要将世界对象中的物体显示在屏幕上时,要将物体的米单位转化为像素单位,在cocos2d里,大多用到的32个像素为一米,能否改就不得而知了!

SetAsBox 函数接收了半个宽度和半个高度,这样的话,地面盒就是 100 个单位宽(x 轴)以及 20 个单位高(y 轴)。Box2D 已被调谐使用米,千克和秒来作单位,所以你可以用米来考虑长度。然而, 改变单位系统是可能的。 

cocos2dx box2d使用(一),布布扣,bubuko.com

cocos2dx box2d使用(一)

标签:class   c   tar   ext   http   int   

原文地址:http://www.cnblogs.com/chiefCTO/p/3735526.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!