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;

 

#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();

}

 

运行效果:

 

 

时间: 2024-09-08 09:47:47

2.Cocos2dx 3.2中的重力系统Box2D的相关文章

【ANDROID游戏开发二十】物理游戏之重力系统开发,让你的游戏变得有质有量!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/354.html 今天群里一哥哥说急需关于物理游戏方面的资料,so~下午就随手写了一个简单的圆形自由落体Demo,正好一起分享给大家学习下吧: 先大概说一下,之前的文章中,给大家介绍过重力传感器,那么和今天要说的重力系统,其实是一样的! 在重力传感器中,虽然我也实现了一个圆形会根据手机反转的角度而拥有不同的速度,但是

Android 物理游戏之重力系统开发示例代码

本节为大家提供有关物理游戏的知识,讲解了一个简单的圆形自由落体Demo的编写.本文要介绍的重力系统实际上是类似的. 在重力传感器中,虽然我也实现了一个圆形会根据手机反转的角度而拥有不同的速度,但是其内置加速度算法都是Android os封装好的,而今天我们要讲的重力系统就是去模拟这个加速度,从而让一个自由落体的圆形,感觉跟现实中的皮球一样有质有量!下落的时候速度加快,反弹起来以后速度慢慢减下来. 先贴上两张效果截图,让大家有一个直观的了解,之后再详加讲解: 圆形自由落体Demo简介 当你点击模拟

Android开发中的重力传感器用法实例详解

本文实例讲述了Android开发中的重力传感器用法.分享给大家供大家参考,具体如下: 重力传感器与方向传感器的开发步骤类似,只要理清了期中的x,y,z的值之后就可以根据他们的变化来进行编程了,首先来看一副图 假设当地的重力加速度值为g 当手机正面朝上的时候,z的值为q,反面朝上的时候,z的值为-g 当手机右侧面朝上的时候,x的值为g,右侧面朝上的时候,x的值为-g 当手机上侧面朝上的时候,y的值为g,右侧面朝上的时候,y的值为-g 了解了重力传感器中X,Y,Z的含义之后下面我们就开始学习如何使用

java web应用中新起一个线程 在线程中怎么获取系统登录的数据

问题描述 java web应用中新起一个线程 在线程中怎么获取系统登录的数据 java web应用中新起一个线程 在线程中怎么获取系统登录的数据,系统登录用的是Spring Secrity 解决方案 可以使用缓存,自己写一个缓存类.或者使用Redis.

Delphi中如何取得系统支持的颜色数

在自己的软件中经常需要得知运行本软件的系统支持的颜色数.例如有的软件在16Bits的颜色数的计算机上开发而成,程序的颜色调试得非常漂亮,但是到了一台只支持16色的计算机上,程序变得非常难看.这就需要得到系统的颜色数. Delphi中如何取得系统的颜色数呢?下面的程序就解决这个问题. function GetSysColorNum:Integer; Var ScreenDc:HDC; NumBitsPixel:Integer; begin Result:=0; ScreenDc:=GetDC(0)

sql语句-SQL语句创建的表不在新建的数据库中而在系统数据库中,

问题描述 SQL语句创建的表不在新建的数据库中而在系统数据库中, SQL语句创建的表不在新建的数据库中而在系统数据库中, 怎么让表在新建的数据库呢 解决方案 肯定你写错了,或者数据库连接到了系统库,或者sql中指明了写到系统库了 解决方案二: 你没写 use database; database是你的数据库 解决方案三: 创建表前,先写需要创建在哪个数据库中.USE DATABASE GO......CREATE TABLENAME() 解决方案四: 先要使用自己的数据库 use databas

网页设计中的栅格系统

栅格系统的形成 1692年,新登基的法国国王路易十四感到法国的印刷水平强差人意,因此命令成立一个管理印刷的皇家特别委员会.他们的首要任务是设计出科学的.合理的, 重视功能性的新字体.委员会由数学家尼古拉斯加宗(Nicolas Jaugeon)担任领导,他们以罗马体为基础,采用方格为设计依据,每个字体方格分为64个基本方各单位,每个方各单位再分成36个小格,这样,一个印 刷版面就有 2304个小格组成,在这个严谨的几何网格网络中设计字体的形状,版面的编排,试验传达功能的效能,这是是世界上最早对字体

access中显示MSysObjects系统表的设置方法

  这篇文章主要介绍了access中显示MSysObjects系统表的设置方法,在一些特别的环境中需要显示MSysObjects系统表,需要的朋友可以参考下 默认access的系统表MSysObjects等是不显示的,需要手动设置access显示MSysObjects等系统表.   设置方法如下: 1. 打开Access 2. 点击"工具"菜单,选择"选项" 3. 在"视图"页上,将"系统对象"勾上 4. 点击"确定

如何在Vmware虚拟机中安装XP系统

  如何在Vmware虚拟机中安装XP系统 1.新建一个虚拟机,文件-新建虚拟机; 2.我们选择标准向导新建虚拟机,下一步; 3.有三个选项,光盘安装,镜像安装,稍后安装,我们选稍后安装; 4.选择想安装的操作系统名称,我们选windows; 5.选择windows版本,windows xp; 6.填写虚拟机名称,默认为你选择的windows版本名,可以修改,选择虚拟机文件存放地址;