首页 > 代码库 > 2.Cocos2dx 3.2中的重力系统Box2D

2.Cocos2dx 3.2中的重力系统Box2D



1添加Box2D相关的库

步骤1:右击项目所在的解决方案à添加—>现有项目àE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\external\Box2D\proj.win32\Box2D.vcxproj

步骤2:右击项目à生成依赖项à项目依赖项à将关于libBox2D的复选框选中

步骤3:为项目添加libBox2D的库

方法:右击项目à属性à链接器à输入—>附加依赖项à编辑,添加上libBox2d.libà确定

案例说明:

1.编写T32.h

#ifndef__T32_H__

#define__T32_H__

 

#include"cocos2d.h"

USING_NS_CC;

 

#definewinSizeDirector::getInstance()->getWinSize()

#defineCCLogcocos2d::log

 

#endif

2.编写TBack.h

 

#ifndef__TBack_H__

#define__TBack_H__

 

#include"T32.h"

 

classTBack :publicLayer

{

public:

   CREATE_FUNC(TBack);

 

   boolinit();

};

 

#endif

3编写TBack.cpp

#include"TBack.h"

 

 

boolTBack::init()

{

   Layer::init();

 

   setLocalZOrder(100);

 

   Menu*menu =Menu::create();

 

   MenuItemImage*item =MenuItemImage::create("CloseNormal.png","CloseSelected.png",

       [](Ref*){

       Director::getInstance()->popScene();

   });

 

   menu->addChild(item);

   item->setPosition(winSize.width / 2 - item->getBoundingBox().size.width / 2,

       item->getBoundingBox().size.height / 2 - winSize.height / 2);

 

   addChild(menu);

 

   returntrue;

}

4.编写T06Box2D.h

#ifndef__T06Box2D_H__

#define__T06Box2D_H__

#include"T32.h"

#include"Box2D/Box2D.h"

 

classT06Box2D :publicLayer

{

public:

   CREATE_FUNC(T06Box2D);

   boolinit();

 

   b2World*_world;

   b2Body*_bat;

   voidupdate(float);

};

 

#endif

5编写:T06Box2D.cpp

#include"T06Box2D.h"

 

#definePTM_RATIO 32.0f

 

boolT06Box2D::init()

{

   Layer::init();

 

   //创建世界,后面的-9.8表示向下的重力加速度为9.8

   //b2Vec2 gravity(0,-9.8f);

   //这个表示没有重力加速度

   b2Vec2gravity(0,0.0f);

   _world =newb2World(gravity);

 

   {

       b2BodyDefdef;

       //这里是一个动态的body,默认是静态的body

       def.type = b2_dynamicBody;

       //设置位置,要转换成重力场中的位置要除以PTM_RATIO

       def.position.Set(winSize.width / 2 / PTM_RATIO,winSize.height / 2 / PTM_RATIO);

   

       b2Body*body =_world->CreateBody(&def);

 

       //body受力

       body->SetLinearVelocity(b2Vec2(10,20));

 

       //显示body的精灵

       Sprite*sprite =Sprite::create("CloseNormal.png");

       addChild(sprite);

       sprite->setPosition(body->GetPosition().x*PTM_RATIO,body->GetPosition().y*PTM_RATIO);

 

       //设置body的形状,让它和sprite相一致,是圆形的

       b2CircleShapeshape;

       //设置半径

       shape.m_radius = sprite->getContentSize().width / 2 / PTM_RATIO;

       //后面的一个参数表示的是密度系数

       b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);

       //设置摩擦系统

       fixture->SetFriction(0.0f);

       //弹性系数

       fixture->SetRestitution(1.0f);

 

       //关联body和精灵

       body->SetUserData(sprite);

   }

 

   //加个地板

   {

       b2BodyDefdef;

       // def.position.Set(0, 0);

 

       b2Body*body =_world->CreateBody(&def);

       //设置边界类型的形状

       b2EdgeShapeshape;

       //设置地板的开始点和结束点

       shape.Set(b2Vec2(0, 0), b2Vec2(winSize.width / PTM_RATIO, 0));

 

       b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);

 

       //设置摩擦系数

       fixture->SetFriction(0.0f);

       //设置弹性系数

       fixture->SetRestitution(1.0f);

   }

 

   //加个天花板

   {

       b2BodyDefdef;

       def.position.Set(0,winSize.height / PTM_RATIO);

 

       b2Body*body =_world->CreateBody(&def);

       b2EdgeShapeshape;

       shape.Set(b2Vec2(0, 0), b2Vec2(winSize.width / PTM_RATIO, 0));

 

       b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);

 

       //摩擦系统

       fixture->SetFriction(0.0f);

       //弹性系数

       fixture->SetRestitution(1.0f);

   }

 

   //左挡板

   {

       b2BodyDefdef;

       //def.position.Set(0, winSize.height / PTM_RATIO);

 

       b2Body*body =_world->CreateBody(&def);

       b2EdgeShapeshape;

       shape.Set(b2Vec2(0, 0), b2Vec2(0,winSize.height / PTM_RATIO));

 

       b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);

 

       fixture->SetFriction(0.0f);//摩擦系统

       fixture->SetRestitution(1.0f);//弹性系数

   }

 

   //右挡板

   {

       b2BodyDefdef;

       def.position.Set(winSize.width / PTM_RATIO, 0);

 

       b2Body*body =_world->CreateBody(&def);

       b2EdgeShapeshape;

       shape.Set(b2Vec2(0, 0), b2Vec2(0,winSize.height / PTM_RATIO));

 

       b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);

       //摩擦系数

       fixture->SetFriction(0.0f);

       //弹性系数

       fixture->SetRestitution(1.0f);

   }

 

   //球拍

   {

       b2BodyDefdef;

       def.position.Set(winSize.width / 2 / PTM_RATIO,winSize.height / 4 / PTM_RATIO);

 

       b2Body*body =_world->CreateBody(&def);

       _bat =body;

 

       Sprite*sprite =Sprite::create("bat.png");

       body->SetUserData(sprite);

       addChild(sprite);

       sprite->setPosition(body->GetPosition().x*PTM_RATIO,body->GetPosition().y*PTM_RATIO);

 

       SizebatSize =Size(100,30);

       Sizecontent =sprite->getContentSize();

       sprite->setScale(batSize.width / content.width,batSize.height / content.height);

 

       b2PolygonShapeshape;

       shape.SetAsBox(batSize.width / 2 / PTM_RATIO,batSize.height / 2 / PTM_RATIO);

 

       b2Fixture*fixture =body->CreateFixture(&shape, 1.0f);

       //摩擦系统

       fixture->SetFriction(0.0f);

       //弹性系统

       fixture->SetRestitution(1.0f);

 

       //touch

       EventListenerTouchOneByOne*ev =EventListenerTouchOneByOne::create();

       ev->onTouchBegan = [](Touch*,Event*){returntrue; };

       ev->onTouchMoved = [&](Touch*touch,Event*){

           floatdx =touch->getDelta().x / PTM_RATIO;

 

           b2Vec2pos =_bat->GetPosition();

           pos.x += dx;

 

           //下面的函数等价于setPosition()

           _bat->SetTransform(pos, 0);

       };

 

       _eventDispatcher->addEventListenerWithSceneGraphPriority(ev,this);

   }

 

   scheduleUpdate();

   returntrue;

}

 

voidT06Box2D::update(floatdt)

{

     //时间在流逝

   _world->Step(dt, 8, 1);

 

   //遍历这个世界的body

   b2Body*body =_world->GetBodyList();

   while (body)

   {

       //设置body相关的精灵的位置

       Sprite*sprite = (Sprite*)body->GetUserData();

       if (sprite)

       {

           sprite->setPosition(body->GetPosition().x*PTM_RATIO,body->GetPosition().y*PTM_RATIO);

           sprite->setRotation(body->GetAngle()*180.0 / M_PI);

       }

 

       body =body->GetNext();

   }

}

 

6.编写TMenu.h

 

#ifndef__TMenu_H__

#define__TMenu_H__

 

#include"T32.h"

 

classTMenu :publicLayer

{

public:

   CREATE_FUNC(TMenu);

 

   boolinit();

 

   boolTouchBegan(Touch*,Event*);

};

 

#endif

7.编写:TMenu.cpp

#include"TMenu.h"

#include"TBack.h"

#include"T01CPP11.h"

#include"T02Vector.h"

#include"T03Map.h"

#include"T04Label.h"

#include"T06Box2D.h"

 

staticconstchar*title[] = {

   "T01CPP11",

   "T02Vector",

   "T03Map",

   "T04Label",

   "T06Box2D"

};

 

boolTMenu::init()

{

   Layer::init();

 

   Menu*menu =Menu::create();

   addChild(menu);

 

   for (inti = 0;i <sizeof(title) / sizeof(*title); ++i)

   {

       MenuItemFont*item =MenuItemFont::create(title[i], [](Ref*sender){

 

           MenuItem*item = (MenuItem*)sender;

           inti =item->getTag()-1000;

           Layer*l =NULL;

 

           if (title[i] == "T01CPP11") l =T01CPP11::create();

           if (title[i] == "T02Vector")l =T02Vector::create();

           if (title[i] == "T03Map")l =T03Map::create();

           if (title[i] == "T04Label")l =T04Label::create();

           if (title[i] == "T06Box2D")l =T06Box2D::create();

 

           if (l)

           {

               TBack*b =TBack::create();

               Scene*s =Scene::create();

               s->addChild(b);

               s->addChild(l);

               Director::getInstance()->pushScene(s);

           }

       });

       menu->addChild(item);

       item->setTag(1000 + i);

   }

 

   menu->alignItemsVertically();

 

   //触摸

   autoev =EventListenerTouchOneByOne::create();

#if 0

   ev->onTouchBegan = [](Touch*,Event*){

       returntrue;

   };

#endif

 

   //ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);

 

   ev->onTouchBegan = CC_CALLBACK_2(TMenu::TouchBegan,this);

 

   ev->onTouchMoved = [&](Touch*touch,Event*){

       setPositionY(getPositionY() + touch->getDelta().y);

   };

   _eventDispatcher->addEventListenerWithSceneGraphPriority(ev,this);

 

   returntrue;

}

 

boolTMenu::TouchBegan(/*TMEnu* this, */Touch*,Event*)

{

   returntrue;

}

8.编写AppDelegate.cpp

#include"AppDelegate.h"

#include"TMenu.h"

#include"TBack.h"

USING_NS_CC;

 

AppDelegate::AppDelegate() {

 

}

 

AppDelegate::~AppDelegate()

{

}

 

boolAppDelegate::applicationDidFinishLaunching() {

   // initialize director

   autodirector =Director::getInstance();

   autoglview =director->getOpenGLView();

   if(!glview) {

       glview =GLView::create("My Game");

       glview->setFrameSize(480, 320);

       director->setOpenGLView(glview);

   }

 

   glview->setDesignResolutionSize(480, 320, ResolutionPolicy::EXACT_FIT);

 

   // turn on display FPS

   director->setDisplayStats(true);

 

   // set FPS. the default value is 1.0/60 if you don‘t call this

   director->setAnimationInterval(1.0 / 60);

 

   // create a scene. it‘s an autorelease object

   autoscene =Scene::create();

   scene->addChild(TMenu::create());

   scene->addChild(TBack::create());

 

 

   // run

   director->runWithScene(scene);

 

   returntrue;

}

 

// This function will be called when the app is inactive. When comes a phone call,it‘s be invoked too

voidAppDelegate::applicationDidEnterBackground() {

   Director::getInstance()->stopAnimation();

 

   // if you use SimpleAudioEngine, it must be pause

   // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

}

 

// this function will be called when the app is active again

voidAppDelegate::applicationWillEnterForeground() {

   Director::getInstance()->startAnimation();

 

   // if you use SimpleAudioEngine, it must resume here

   // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

}

 

运行效果:

 

 

2.Cocos2dx 3.2中的重力系统Box2D