Box2D
new&&delete
使用new会调用构造函数使用delete会调用析构函数
malloc&&free
c的库函数,仅仅用来申请内存空间
构造:先构造父类后构造本身
析构:先析构本身后析构父类
1.属性框:显示物理攻击,防御值,生命值 要求:显示当前卡牌的属性
Box2D物理世界
世界表示一个范围,实际上也是一个刚体,需要设置边界,即为世界的范围
刚体:一个大一点的点
形状:有弹性、摩擦力等属性的物体
关节:连系刚体及限制其运动范围
夹具定义:设置刚体的物理属性如:密度、摩擦系数、恢复系数
夹具:类似于模具,将缸体套进去以适应它的条条框框
形状:刚体都是有形状的(除了世界等特殊的“刚体”)
注意:不能再监听函数中销毁刚体
世界使用步骤:
#include "Box2D/Box2D.h"
1️⃣设置重力:
b2Vec2 grivaty ;
grivaty.Set(0.0f, -9.8f);
2️⃣通过重力设置世界
world = new b2World(grivaty);
world->SetAllowSleeping(true);// 允许休眠
world->SetContinuousPhysics(true);// 允许连续碰撞
3️⃣开始着手设置世界的边界,边界也为刚体
// 设置边界(边界也是刚体) 注意每条边界都要设置夹具
b2Body * groundBody = world->CreateBody(&groundBodyDef);
// 创建物理世界的边界形状
b2EdgeShape groundBox;
// 下边界
groundBox.Set(b2Vec2(0, 0), b2Vec2(size.width/PTM, 0));
groundBody->CreateFixture(&groundBox,0);
// 上边界
groundBox.Set(b2Vec2(0, size.height/PTM),b2Vec2(size.width/PTM,size.height /PTM));
groundBody->CreateFixture(&groundBox,0);
// 左边界
groundBox.Set(b2Vec2(0, 0),b2Vec2(0,size.height /PTM));
groundBody->CreateFixture(&groundBox,0);
// 右边界
groundBox.Set(b2Vec2(size.width/PTM,0),b2Vec2(size.width/PTM,size.height /PTM));
// 创建夹具
groundBody->CreateFixture(&groundBox,0);
刚体的创建(需要建立在世界之上)
//设置动态刚体定义
b2BodyDef dynimacBodyDef;
dynimacBodyDef.type = b2_dynamicBody;
dynimacBodyDef.position.Set(p.x/PTM,p.y/PTM);
// 设置刚体
b2Body * body = world->CreateBody(&dynimacBodyDef);
// 设置一个形状
b2PolygonShape bodyShape ;
bodyShape.SetAsBox(1.0f, 1.0f);
// 设置 夹具定义
b2FixtureDef fixtureDef;
fixtureDef.shape = & bodyShape;
fixtureDef.density = 0.8f;//密度
fixtureDef.friction = 0.5f;//摩擦系数
fixtureDef.restitution = 0.6;//恢复系数
// 设置夹具
body->CreateFixture(&fixtureDef);
auto sp = Sprite::create("test.png");
sp->setPosition(p);
body->SetUserData(sp);// 将精灵与刚体产生联系
addChild(sp);
在时间调度器中更新精灵的文职与角度
float timeStep = 1/60.0f;
int32 ver=10;// 迭代器遍历次数 1秒10次
int32 pos=1;
world->Step(timeStep, ver, pos);
for (b2Body * b=world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData()!=NULL) {
Sprite * userdata = (Sprite *)b->GetUserData();
userdata->setPosition(Vec2(b->GetPosition().x*PTM, b->GetPosition().y*PTM));
userdata->setRotation(-1*CC_RADIANS_TO_DEGREES(b->GetAngle()));
// 删除刚体(在碰撞检测中给刚体的userdata设置Tag值,然后在update中通过tag值获得并删除)
// 因为在碰撞检测中不可以删除刚体,生命周期未结束,可能会被其他碰撞检测函数用到
if (userdata->getTag()==1001) {
world->DestroyBody(b);
userdata->removeFromParent();
}
}
}
碰撞检测
必须继承自b2ContackListener而且重写父类的四个碰撞检测函数
bool onTouchBegan(Touch *touch, Event *unused_event)override;
void addNewBoxAtPosition(Vec2 p);
void addNewCircleAtPosition(Vec2 p);
void addNewJointAtPosition(Vec2 p);
关键代码:Sprite * sp = (Sprite*)contact->GetFixtureA()->GetBody()->GetUserData();