cocos2d_x_05_Box2D物理引擎
一、认识Box2D
帮助文档,共69页
二、创建一个物理世界
先导入主头文件
#include <Box2D/Box2D.h>
三、物理世界一览
像素转成米 的比例因子 就是32
三、运动的物体
刚体的类型有三种:动态的、静态的、漂浮的(不受重力影响)
结构体b2BodyDef,构造刚体时,必须指定的、定义一个刚体所需的參数
cocos2d的像素和box2d的世界 长度转换
当box2d中世界长度为10米 为最佳模拟
b2FixtureDef
一个 b2FixtureDef 是依附在刚体 身上的物理特质的属性
一个刚体 有多个 b2FixtureDef
每个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
加入一个刚体的三步曲:
通过world创建一个body (參数是一个结构体b2BodyDef)
为body设置Fixture属性 (參数是一个b2FixtureDef结构体)
创建一个精灵,并将其绑定到body的UserData
glview->setDesignResolutionSize
(480,320,ResolutionPolicy::SHOW_ALL)表示:
游戏编写时,依照480*320的屏幕分辨率来的;
当执行在不同的屏幕分辨率下时,
会依据实际的屏幕分辨率 与 编写时的分辨率 的缩放比例因子,进行图像绘制
ResolutionPolicy::SHOW_ALL表示完整显示
界面上的全部元素
即:宽高等比缩放,但缩放比例取宽比和高比之中小的那一个。
四、漂浮的物体 b2_kinematicBody
创建一个漂浮的物体,不受重力影响,向右漂浮动
addRectBody(1,5,b2_kinematicBody);
#pragma mark - 加入一个刚体
// 加入一个精巧的或运动的Rect刚体,通过參数type指定,x和y是世界坐标中的位置
void Box2DScene::addRectBody(float x, float y, b2BodyType body_type)
{
// 1.1 结构体b2BodyDef
// 每个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处
def.position = b2Vec2(x, y);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = body_type;
// 设置【b2BodyDef】的 线速度 y = 10 ,表示物体向上飞
if(body_type == b2_dynamicBody){
// 动态物体 自由落体
def.linearVelocity = b2Vec2(0, 9.8);
}else{
// 漂浮物体 向右飘动
def.linearVelocity = b2Vec2(1, 0);
}
// 设置【b2BodyDef】的 子弹效应 (防止碰撞检測时 由于速度 太快,而失效;如本应反弹,结果陷入地板内)
// def.bullet = true;
// 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每个刚体都有自身的 b2BodyDef属性
b2Body* body = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边形
b2PolygonShape shape;
shape.SetAsBox(0.5, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixtureDef;
// 每个 b2FixtureDef都有一个成员shape
fixtureDef.shape = &shape;
// 密度
fixtureDef.density = 1;
// 摩擦系数
fixtureDef.friction = 0.3;
// 为刚体 加入一个 b2FixtureDef
body->CreateFixture(&fixtureDef);
// *************************************************
// 3、创建并加入一个 cocos2d 的精灵
auto s = Sprite::create();
// 0.5是物理世界中的精灵大小 单位是 米
// 即在物理世界中,精灵 是一个1米 * 1米的方块
s->setTextureRect(Rect(0, 0, 0.5*2*RATIO, 0.5*2*RATIO));
// 加入到图层Layer
addChild(s);
// *************************************************
// 4、绑定 cocos2d界面上的精灵
body->SetUserData(s);
}
五、精巧的物体 如地板
#pragma mark - 加入一个地板
void Box2DScene::addGroundBody()
{
// 1.1 结构体b2BodyDef
// 每一个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处 这个是在
log("宽:%f",winSize.width);
// 位置
def.position = b2Vec2(480/RATIO,0);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = b2_staticBody;
// 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每一个刚体都有自身的 b2BodyDef属性
groundBody = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边
b2PolygonShape groundShape;
// 尺寸: 在物理世界中的 半长和 半宽 多少米
groundShape.SetAsBox(480/RATIO, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixureDef;
// 形状
fixureDef.shape = &groundShape;
// 密度
fixureDef.density = 1;
// 摩擦系数
fixureDef.friction = 0.3;
groundBody->CreateFixture(&fixureDef);
}
六、物体间的碰撞检測
首先, 设置碰撞检測 的侦听者 为当前Layer
world->SetContactListener(this);
让场景继承b2ContactListener(实现接口)
实现接口中的方法:
virtual
void BeginContact(b2Contact* contact);
b2Contact类中有一个方法,能够得到刚体:
contact->GetFixtureA()->GetBody()
接口中的方法,固定写法
完整代码
//
// Box2DScene.h
// 01_cocos2d-x
//
// Created by beyond on 14-10-5.
//
//
#ifndef ___1_cocos2d_x__Box2DScene__
#define ___1_cocos2d_x__Box2DScene__
#include "cocos2d.h"
// 1、导入物理世界 主头文件
#include <Box2D/Box2D.h>
USING_NS_CC;
// 注意 这儿,继承的是 Layer
// 要想进行碰撞检測,必须 实现接口
class Box2DScene : public cocos2d::Layer,public b2ContactListener
{
private:
// 2、成员变量:物理世界,參数 指定x和y的重力方向
b2World *world;
// 由于 要碰撞检測,所以
b2Body *groundBody;
// 屏幕尺寸
Size winSize;
public:
// c++里面没有id类型, 所以 返回类的实例对象的 指针
static cocos2d::Scene* createScene();
// 下面是 不同点:cocos2d-x的 'init' 方法 返回 bool
// 而cocos2d-iphone 返回 'id' 类型
virtual bool init();
// 宏 自己主动实现 "静态的 create()方法"
CREATE_FUNC(Box2DScene);
// 4、在时钟方法里,模拟世界的执行 step
virtual void update(float dt);
// 5、加入一个精巧的或运动的Rect刚体,通过參数type指定,x和y是世界坐标中的位置
void addRectBody(float x,float y,b2BodyType body_type);
// 6、加入一个地板
void addGroundBody();
// 7、碰撞检測
// 接口中的方法,是一个固定定法
virtual void BeginContact(b2Contact* contact);
};
#endif /* defined(___1_cocos2d_x__Box2DScene__) */
//
// Box2DScene.cpp
// 01_cocos2d-x
//
// Created by beyond on 14-10-5.
//
//
#include "Box2DScene.h"
// cocos2d 为宽960 * 高640
// box2d世界为宽10米 * 6.67米 (由于10米是比較理想的模拟情况)
// 因此 像素转成米 的比例是 96
// 假设,要把 像素转成米 仅仅要 像素/RATIO
// 假设,要把 米转成像素 仅仅要 米*RATIO (把物理世界中的刚体 在界面上更新坐标时)
#define RATIO 960.0/10.0f
USING_NS_CC;
Scene* Box2DScene::createScene()
{
// 'scene' 自己主动释放
// 创建一个scene
auto scene = Scene::create();
// 'layer' 自己主动释放
auto layer = Box2DScene::create();
// 将图层 加入到场景中
scene->addChild(layer);
// 返回 填充好图层的 场景
return scene;
}
// 在 "init" 方法中,实例化自己要用的精灵对象
bool Box2DScene::init()
{
// 1. 调用父类的init , cpp 没有super,直接写父类名
if ( !Layer::init() ) return false;
// 屏幕尺寸
winSize = Director::getInstance()->getVisibleSize();
// 2、创建一个物理世界,參数 是x y 方向的重力加速度,负数表示 重力向下
world = new b2World(b2Vec2(0,-9.8));
// 设置碰撞检測 的侦听者 为当前Layer
world->SetContactListener(this);
// 3、开启时钟方法,在时钟方法中,让世界 向前执行
scheduleUpdate();
// 4、创建并加入一个执行的物体 RectBody
// 參数 x 5 y 3,x和y是世界坐标中的位置,类型是 b2_dynamicBody
addRectBody(5,3,b2_dynamicBody);
// 5、加入一个地板
addGroundBody();
// 6、创建一个漂浮的物体
addRectBody(1,5,b2_kinematicBody);
return true;
}
#pragma mark - 加入一个刚体
// 加入一个精巧的或运动的Rect刚体,通过參数type指定,x和y是世界坐标中的位置
void Box2DScene::addRectBody(float x, float y, b2BodyType body_type)
{
// 1.1 结构体b2BodyDef
// 每一个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处
def.position = b2Vec2(x, y);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = body_type;
// 设置【b2BodyDef】的 线速度 y = 10 ,表示物体向上飞
if(body_type == b2_dynamicBody){
// 动态物体 自由落体
def.linearVelocity = b2Vec2(0, 9.8);
}else{
// 漂浮物体 向右飘动
def.linearVelocity = b2Vec2(1, 0);
}
// 设置【b2BodyDef】的 子弹效应 (防止碰撞检測时 由于速度 太快,而失效;如本应反弹,结果陷入地板内)
// def.bullet = true;
// 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每一个刚体都有自身的 b2BodyDef属性
b2Body* body = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边形
b2PolygonShape shape;
shape.SetAsBox(0.5, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixtureDef;
// 每一个 b2FixtureDef都有一个成员shape
fixtureDef.shape = &shape;
// 密度
fixtureDef.density = 1;
// 摩擦系数
fixtureDef.friction = 0.3;
// 为刚体 加入一个 b2FixtureDef
body->CreateFixture(&fixtureDef);
// *************************************************
// 3、创建并加入一个 cocos2d 的精灵
auto s = Sprite::create();
// 0.5是物理世界中的精灵大小 单位是 米
// 即在物理世界中,精灵 是一个1米 * 1米的方块
s->setTextureRect(Rect(0, 0, 0.5*2*RATIO, 0.5*2*RATIO));
// 加入到图层Layer
addChild(s);
// *************************************************
// 4、绑定 cocos2d界面上的精灵
body->SetUserData(s);
}
#pragma mark - 加入一个地板
void Box2DScene::addGroundBody()
{
// 1.1 结构体b2BodyDef
// 每一个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处 这个是在
log("宽:%f",winSize.width);
// 位置
def.position = b2Vec2(480/RATIO,0);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = b2_staticBody;
// 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每一个刚体都有自身的 b2BodyDef属性
groundBody = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边
b2PolygonShape groundShape;
// 尺寸: 在物理世界中的 半长和 半宽 多少米
groundShape.SetAsBox(480/RATIO, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixureDef;
// 形状
fixureDef.shape = &groundShape;
// 密度
fixureDef.density = 1;
// 摩擦系数
fixureDef.friction = 0.3;
groundBody->CreateFixture(&fixureDef);
}
#pragma mark - 时钟方法
void Box2DScene::update(float dt)
{
// 1、让物理世界 的时间和位置向前迭代
// 參数:时间差,速度迭代,位置迭代;官方推荐 8和3
world->Step(dt,8,3);
// 2、取出世界中的全部刚体,改变其位置
Sprite *s;
// 链表
for (b2Body *b = world->GetBodyList(); b; b=b->GetNext()) {
// log("y:%f米",b->GetPosition().y);
if (b->GetUserData()) {
// 刚体绑定的 精灵
s = (Sprite*)b->GetUserData();
// 更新精灵 在cocos2d中的位置 ; 单位要从米转成像素 仅仅需 米*RATIO 就可以
s->setPosition(b->GetPosition().x*RATIO, b->GetPosition().y*RATIO);
}
}
}
#pragma mark - 碰撞检測
// 接口中的方法,是一个固定定法
void Box2DScene::BeginContact(b2Contact *contact){
// 碰撞有一方 是地板,则说明 检測到了碰撞
b2Fixture *A = contact->GetFixtureA();
b2Body *aBody = A->GetBody();
b2Fixture *B = contact->GetFixtureB();
b2Body *bBody = B->GetBody();
if (aBody == groundBody||bBody == groundBody) {
log("有物体落在了地板上");
}
}
#include <Box2D/Box2D.h>
一个 b2FixtureDef 是依附在刚体 身上的物理特质的属性
一个刚体 有多个 b2FixtureDef
每个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
界面上的全部元素
创建一个漂浮的物体,不受重力影响,向右漂浮动
addRectBody(1,5,b2_kinematicBody);
#pragma mark - 加入一个刚体
// 加入一个精巧的或运动的Rect刚体,通过參数type指定,x和y是世界坐标中的位置
void Box2DScene::addRectBody(float x, float y, b2BodyType body_type)
{
// 1.1 结构体b2BodyDef
// 每个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处
def.position = b2Vec2(x, y);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = body_type; // 设置【b2BodyDef】的 线速度 y = 10 ,表示物体向上飞
if(body_type == b2_dynamicBody){
// 动态物体 自由落体
def.linearVelocity = b2Vec2(0, 9.8);
}else{
// 漂浮物体 向右飘动
def.linearVelocity = b2Vec2(1, 0);
}
// 设置【b2BodyDef】的 子弹效应 (防止碰撞检測时 由于速度 太快,而失效;如本应反弹,结果陷入地板内)
// def.bullet = true; // 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每个刚体都有自身的 b2BodyDef属性
b2Body* body = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边形
b2PolygonShape shape;
shape.SetAsBox(0.5, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixtureDef;
// 每个 b2FixtureDef都有一个成员shape
fixtureDef.shape = &shape;
// 密度
fixtureDef.density = 1;
// 摩擦系数
fixtureDef.friction = 0.3;
// 为刚体 加入一个 b2FixtureDef
body->CreateFixture(&fixtureDef);
// *************************************************
// 3、创建并加入一个 cocos2d 的精灵
auto s = Sprite::create();
// 0.5是物理世界中的精灵大小 单位是 米
// 即在物理世界中,精灵 是一个1米 * 1米的方块
s->setTextureRect(Rect(0, 0, 0.5*2*RATIO, 0.5*2*RATIO));
// 加入到图层Layer
addChild(s);
// *************************************************
// 4、绑定 cocos2d界面上的精灵
body->SetUserData(s); }
#pragma mark - 加入一个地板
void Box2DScene::addGroundBody()
{
// 1.1 结构体b2BodyDef
// 每一个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处 这个是在
log("宽:%f",winSize.width);
// 位置
def.position = b2Vec2(480/RATIO,0);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = b2_staticBody;
// 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每一个刚体都有自身的 b2BodyDef属性
groundBody = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边
b2PolygonShape groundShape;
// 尺寸: 在物理世界中的 半长和 半宽 多少米
groundShape.SetAsBox(480/RATIO, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixureDef;
// 形状
fixureDef.shape = &groundShape;
// 密度
fixureDef.density = 1;
// 摩擦系数
fixureDef.friction = 0.3;
groundBody->CreateFixture(&fixureDef);
}
首先, 设置碰撞检測 的侦听者 为当前Layer
world->SetContactListener(this);
virtual
void BeginContact(b2Contact* contact);
contact->GetFixtureA()->GetBody()
//
// Box2DScene.h
// 01_cocos2d-x
//
// Created by beyond on 14-10-5.
//
// #ifndef ___1_cocos2d_x__Box2DScene__
#define ___1_cocos2d_x__Box2DScene__ #include "cocos2d.h"
// 1、导入物理世界 主头文件
#include <Box2D/Box2D.h> USING_NS_CC;
// 注意 这儿,继承的是 Layer
// 要想进行碰撞检測,必须 实现接口
class Box2DScene : public cocos2d::Layer,public b2ContactListener
{
private:
// 2、成员变量:物理世界,參数 指定x和y的重力方向
b2World *world;
// 由于 要碰撞检測,所以
b2Body *groundBody; // 屏幕尺寸
Size winSize; public:
// c++里面没有id类型, 所以 返回类的实例对象的 指针
static cocos2d::Scene* createScene();
// 下面是 不同点:cocos2d-x的 'init' 方法 返回 bool
// 而cocos2d-iphone 返回 'id' 类型
virtual bool init();
// 宏 自己主动实现 "静态的 create()方法"
CREATE_FUNC(Box2DScene); // 4、在时钟方法里,模拟世界的执行 step
virtual void update(float dt); // 5、加入一个精巧的或运动的Rect刚体,通过參数type指定,x和y是世界坐标中的位置
void addRectBody(float x,float y,b2BodyType body_type);
// 6、加入一个地板
void addGroundBody(); // 7、碰撞检測
// 接口中的方法,是一个固定定法
virtual void BeginContact(b2Contact* contact); }; #endif /* defined(___1_cocos2d_x__Box2DScene__) */
//
// Box2DScene.cpp
// 01_cocos2d-x
//
// Created by beyond on 14-10-5.
//
// #include "Box2DScene.h"
// cocos2d 为宽960 * 高640
// box2d世界为宽10米 * 6.67米 (由于10米是比較理想的模拟情况)
// 因此 像素转成米 的比例是 96
// 假设,要把 像素转成米 仅仅要 像素/RATIO
// 假设,要把 米转成像素 仅仅要 米*RATIO (把物理世界中的刚体 在界面上更新坐标时)
#define RATIO 960.0/10.0f USING_NS_CC;
Scene* Box2DScene::createScene()
{
// 'scene' 自己主动释放
// 创建一个scene
auto scene = Scene::create();
// 'layer' 自己主动释放
auto layer = Box2DScene::create();
// 将图层 加入到场景中
scene->addChild(layer);
// 返回 填充好图层的 场景
return scene;
} // 在 "init" 方法中,实例化自己要用的精灵对象
bool Box2DScene::init()
{
// 1. 调用父类的init , cpp 没有super,直接写父类名
if ( !Layer::init() ) return false;
// 屏幕尺寸
winSize = Director::getInstance()->getVisibleSize(); // 2、创建一个物理世界,參数 是x y 方向的重力加速度,负数表示 重力向下
world = new b2World(b2Vec2(0,-9.8));
// 设置碰撞检測 的侦听者 为当前Layer
world->SetContactListener(this); // 3、开启时钟方法,在时钟方法中,让世界 向前执行
scheduleUpdate(); // 4、创建并加入一个执行的物体 RectBody
// 參数 x 5 y 3,x和y是世界坐标中的位置,类型是 b2_dynamicBody
addRectBody(5,3,b2_dynamicBody); // 5、加入一个地板
addGroundBody(); // 6、创建一个漂浮的物体
addRectBody(1,5,b2_kinematicBody);
return true;
}
#pragma mark - 加入一个刚体
// 加入一个精巧的或运动的Rect刚体,通过參数type指定,x和y是世界坐标中的位置
void Box2DScene::addRectBody(float x, float y, b2BodyType body_type)
{
// 1.1 结构体b2BodyDef
// 每一个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处
def.position = b2Vec2(x, y);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = body_type; // 设置【b2BodyDef】的 线速度 y = 10 ,表示物体向上飞
if(body_type == b2_dynamicBody){
// 动态物体 自由落体
def.linearVelocity = b2Vec2(0, 9.8);
}else{
// 漂浮物体 向右飘动
def.linearVelocity = b2Vec2(1, 0);
}
// 设置【b2BodyDef】的 子弹效应 (防止碰撞检測时 由于速度 太快,而失效;如本应反弹,结果陷入地板内)
// def.bullet = true; // 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每一个刚体都有自身的 b2BodyDef属性
b2Body* body = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边形
b2PolygonShape shape;
shape.SetAsBox(0.5, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixtureDef;
// 每一个 b2FixtureDef都有一个成员shape
fixtureDef.shape = &shape;
// 密度
fixtureDef.density = 1;
// 摩擦系数
fixtureDef.friction = 0.3;
// 为刚体 加入一个 b2FixtureDef
body->CreateFixture(&fixtureDef);
// *************************************************
// 3、创建并加入一个 cocos2d 的精灵
auto s = Sprite::create();
// 0.5是物理世界中的精灵大小 单位是 米
// 即在物理世界中,精灵 是一个1米 * 1米的方块
s->setTextureRect(Rect(0, 0, 0.5*2*RATIO, 0.5*2*RATIO));
// 加入到图层Layer
addChild(s);
// *************************************************
// 4、绑定 cocos2d界面上的精灵
body->SetUserData(s); }
#pragma mark - 加入一个地板
void Box2DScene::addGroundBody()
{
// 1.1 结构体b2BodyDef
// 每一个刚体都有自身的 固有的 必须的 b2BodyDef属性
b2BodyDef def;
// 在世界坐标中 的位置:第x米,第y米处 这个是在
log("宽:%f",winSize.width);
// 位置
def.position = b2Vec2(480/RATIO,0);
// 设置【b2BodyDef】的 类型 (运动的或精巧的或漂浮的)
def.type = b2_staticBody;
// 1.2 通过调用world的方法,创建一个Body物体
// 參数 是一个 b2BodyDef,它是构造一个刚体必须的、固有的东东
// 由于,每一个刚体都有自身的 b2BodyDef属性
groundBody = world->CreateBody(&def);
// *************************************************
// 2.1 形状分为 圆和多边
b2PolygonShape groundShape;
// 尺寸: 在物理世界中的 半长和 半宽 多少米
groundShape.SetAsBox(480/RATIO, 0.5);
// 2.2 一个刚体 有多个 b2FixtureDef
// 一个 b2FixtureDef 是依附在刚体 身上的物理物质的属性
// 每一个 b2FixtureDef 又有形状shape、密度、摩擦系数等成员属性
b2FixtureDef fixureDef;
// 形状
fixureDef.shape = &groundShape;
// 密度
fixureDef.density = 1;
// 摩擦系数
fixureDef.friction = 0.3;
groundBody->CreateFixture(&fixureDef);
} #pragma mark - 时钟方法
void Box2DScene::update(float dt)
{
// 1、让物理世界 的时间和位置向前迭代
// 參数:时间差,速度迭代,位置迭代;官方推荐 8和3
world->Step(dt,8,3); // 2、取出世界中的全部刚体,改变其位置
Sprite *s;
// 链表
for (b2Body *b = world->GetBodyList(); b; b=b->GetNext()) { // log("y:%f米",b->GetPosition().y);
if (b->GetUserData()) {
// 刚体绑定的 精灵
s = (Sprite*)b->GetUserData();
// 更新精灵 在cocos2d中的位置 ; 单位要从米转成像素 仅仅需 米*RATIO 就可以
s->setPosition(b->GetPosition().x*RATIO, b->GetPosition().y*RATIO);
}
} }
#pragma mark - 碰撞检測
// 接口中的方法,是一个固定定法
void Box2DScene::BeginContact(b2Contact *contact){
// 碰撞有一方 是地板,则说明 检測到了碰撞
b2Fixture *A = contact->GetFixtureA();
b2Body *aBody = A->GetBody();
b2Fixture *B = contact->GetFixtureB();
b2Body *bBody = B->GetBody();
if (aBody == groundBody||bBody == groundBody) {
log("有物体落在了地板上");
}
}
cocos2d_x_05_Box2D物理引擎的更多相关文章
- Unity3D游戏开发初探—3.初步了解U3D物理引擎
一.什么是物理引擎? 四个世纪前,物理学家牛顿发现了万有引力,并延伸出三大牛顿定理,为之后的物理学界的发展奠定了强大的理论基础.牛顿有句话是这么说的:“如果说我看得比较远的话,那是因为我站在巨人的肩膀 ...
- Verlet-js JavaScript 物理引擎
subprotocol最近在Github上开源了verlet-js.地址为https://github.com/subprotocol/verlet-js.verlet-js是一个集成Verlet的物 ...
- 制作简单的2D物理引擎(一)——动力学基础
一切的基础 点 在二维平面中,点$P$就是坐标$(x,y)$,点集就是一系列坐标的集合$\{P_1,P_2,...,P_n\}$,不过这个集合是有序的(顺时针). 向量 加减运算 $$\vec{P}\ ...
- 制作简单的2D物理引擎(零)
最近发现了Github上的开源物理引擎项目Matter.js,对它很感兴趣,发现源码并不算长,算上注释大约1万行左右,值得剖析一番.Matter.js实现一个最小化的2D物理引擎,性能不错,故打算用C ...
- [原创]cocos2d-x研习录-第三阶 特性之物理引擎
游戏物理引擎是指在游戏中涉及物理现象的逻辑处理,它用于模拟现实世界的各种物理规律(如赛车碰撞.子弹飞行.物体掉落等),让玩家能够在游戏中有真实的体验. Cocos2D-x中支持Box2D和Chipmu ...
- Bullet物理引擎在OpenGL中的应用
Bullet物理引擎在OpenGL中的应用 在开发OpenGL的应用之时, 难免要遇到使用物理来模拟OpenGL中的场景内容. 由于OpenGL仅仅是一个关于图形的开发接口, 因此需要通过第三方库来实 ...
- 基于HTML5的WebGL结合Box2DJS物理引擎应用
上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是 ...
- 基于HT for Web 3D呈现Box2DJS物理引擎
上篇我们基于HT for Web呈现了A* Search Algorithm的3D寻路效果,这篇我们将采用HT for Web 3D来呈现Box2DJS物理引擎的碰撞效果,同上篇其实Box2DJS只是 ...
- Matter.js – 你不能错过的 2D 物理引擎
Matter.js 是一个 JavaScript 2D 刚体物理引擎的网页.Matter.Engine 模块包含用于创建和操作引擎的方法.这个引擎是一个管理更新和渲染世界的模拟控制器. Matter. ...
随机推荐
- Eclipse用法和技巧十:显示代码outline
在一个文件中快速找到某一个方法或者某一个作用域,可以使用 Ctrl+O或者Ctrl+F3,快速显示当前代码的outline,进行快速查找.效果如下: 这里主要是补充一些后续操作,能更加方 ...
- QString ini ;转义符
ini如果value字符串中存在:,通过双引号即可转义 [a] b=sdc";"gf
- QtWebkit中如何将网页内容转为图片
原地址:http://www.cnblogs.com/baizx/archive/2010/07/31/1789573.html 如何将webkit中的渲染结果也就是网页画面转换为图片 用抓图软件 ...
- Godiva_百度百科
Godiva_百度百科 北京 三里屯 北京市朝阳区三里屯路19号院10号楼一层S10-13单元及二层S10-22单元 100027 北京朝阳大悦城北京市朝阳区朝阳北路101号朝阳大悦城1号商业楼1F- ...
- uva 10951 - Polynomial GCD(欧几里得)
题目链接:uva 10951 - Polynomial GCD 题目大意:给出n和两个多项式,求两个多项式在全部操作均模n的情况下最大公约数是多少. 解题思路:欧几里得算法,就是为多项式这个数据类型重 ...
- innerXml,outerXml,innerText的不同
原文:innerXml,outerXml,innerText的不同 昨天看到咱们园子里有一个仁兄写的关于xml的有关操作,在读的过程中,由于是初学者有不明白的地方就查资料,发现自己多innerXml, ...
- Transformations 方块转换
题目是中文题,就不做什么解释了,纯模拟题,主要要搞清楚这几种装换方式下标的变化: 第一种:顺时针旋转90度: c[j][n-i+1]=a[i][j]; 第二种:旋转180度: c[n-i+1][n-j ...
- cpp check 分析
1 FileTabCharacterCheck 为什么检查: 因为对于一个TAB而言,所空的空格不定是固定的,如果在机器A上设置了是4个空格,显示正常,而在机器B上阅读,B机器是100个空格为一个TA ...
- 不使用webview,用手机浏览器的android app
需求:wap站在手机上以App的形式打开,但不要嵌套WebView,只能以浏览器打开 package com.gzz.whyinzi; import android.net.Uri; import a ...
- Swift编程语言学习3.1排列
Swift 语言提供经典的数组和字典两种集合类型来存储集合数据.数组用来按顺序存储同样类型的数据.字典尽管无序存储同样类型数据值可是须要由独有的标识符引用和寻址(就是键值对). Swift 语言里的数 ...