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;
#define
winSize
Director::getInstance()->getWinSize()
#define
CCLog
cocos2d::log
#endif
2.编写TBack.h
#ifndef
__TBack_H__
#define
__TBack_H__
#include
"T32.h"
class
TBack :
public
Layer
{
public:
CREATE_FUNC(TBack);
bool
init();
};
#endif
3编写TBack.cpp
#include
"TBack.h"
bool
TBack::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);
return
true;
}
4.编写T06Box2D.h
#ifndef
__T06Box2D_H__
#define
__T06Box2D_H__
#include
"T32.h"
#include
"Box2D/Box2D.h"
class
T06Box2D :
public
Layer
{
public:
CREATE_FUNC(T06Box2D);
bool
init();
b2World*
_world;
b2Body*
_bat;
void
update(float);
};
#endif
5编写:T06Box2D.cpp
#include
"T06Box2D.h"
#define
PTM_RATIO 32.0f
bool
T06Box2D::init()
{
Layer::init();
//创建世界,后面的-9.8表示向下的重力加速度为9.8
//b2Vec2 gravity(0,-9.8f);
//这个表示没有重力加速度
b2Vec2
gravity(0,0.0f);
_world =
new
b2World(gravity);
{
b2BodyDef
def;
//这里是一个动态的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相一致,是圆形的
b2CircleShape
shape;
//设置半径
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);
}
//加个地板
{
b2BodyDef
def;
// def.position.Set(0, 0);
b2Body*
body =
_world->CreateBody(&def);
//设置边界类型的形状
b2EdgeShape
shape;
//设置地板的开始点和结束点
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);
}
//加个天花板
{
b2BodyDef
def;
def.position.Set(0,
winSize.height
/ PTM_RATIO);
b2Body*
body =
_world->CreateBody(&def);
b2EdgeShape
shape;
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);
}
//左挡板
{
b2BodyDef
def;
//def.position.Set(0, winSize.height / PTM_RATIO);
b2Body*
body =
_world->CreateBody(&def);
b2EdgeShape
shape;
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);
//弹性系数
}
//右挡板
{
b2BodyDef
def;
def.position.Set(winSize.width
/ PTM_RATIO, 0);
b2Body*
body =
_world->CreateBody(&def);
b2EdgeShape
shape;
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);
}
//球拍
{
b2BodyDef
def;
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);
Size
batSize =
Size(100,30);
Size
content =
sprite->getContentSize();
sprite->setScale(batSize.width
/ content.width,
batSize.height
/ content.height);
b2PolygonShape
shape;
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*){return
true; };
ev->onTouchMoved
= [&](Touch*
touch,
Event*){
float
dx =
touch->getDelta().x
/ PTM_RATIO;
b2Vec2
pos =
_bat->GetPosition();
pos.x
+= dx;
//下面的函数等价于setPosition()
_bat->SetTransform(pos,
0);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);
}
scheduleUpdate();
return
true;
}
void
T06Box2D::update(float
dt)
{
//时间在流逝
_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"
class
TMenu :
public
Layer
{
public:
CREATE_FUNC(TMenu);
bool
init();
bool
TouchBegan(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"
static
const
char*
title[] = {
"T01CPP11",
"T02Vector",
"T03Map",
"T04Label",
"T06Box2D"
};
bool
TMenu::init()
{
Layer::init();
Menu*
menu =
Menu::create();
addChild(menu);
for (int
i = 0;
i <
sizeof(title)
/ sizeof(*title);
++i)
{
MenuItemFont*
item =
MenuItemFont::create(title[i],
[](Ref*
sender){
MenuItem*
item = (MenuItem*)sender;
int
i =
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();
//
触摸
auto
ev =
EventListenerTouchOneByOne::create();
#if 0
ev->onTouchBegan
= [](Touch*,
Event*){
return
true;
};
#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);
return
true;
}
bool
TMenu::TouchBegan(/*TMEnu*
this, */Touch*,
Event*)
{
return
true;
}
8.编写AppDelegate.cpp
#include
"AppDelegate.h"
#include
"TMenu.h"
#include
"TBack.h"
USING_NS_CC;
AppDelegate::AppDelegate()
{
}
AppDelegate::~AppDelegate()
{
}
bool
AppDelegate::applicationDidFinishLaunching()
{
// initialize director
auto
director =
Director::getInstance();
auto
glview =
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
auto
scene =
Scene::create();
scene->addChild(TMenu::create());
scene->addChild(TBack::create());
// run
director->runWithScene(scene);
return
true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void
AppDelegate::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
void
AppDelegate::applicationWillEnterForeground()
{
Director::getInstance()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
运行效果: