Box2D
让游戏看起更加真实,比如东西掉下来等等,不用去Moveto模拟
#define PTM_RATIO 32.0f
bool T06Box2D::init()
{
Layer::init();
// 创建世界
// b2Vec2 gravity(0, -9.8f);
b2Vec2 gravity(0, 0.0f);//x,y方向得到力
_world = new b2World(gravity);
{
b2BodyDef def;
def.type = b2_dynamicBody; //类型设为动态的
//重力系统的位置跟我们屏幕位置不一样,所以我们要设置一个比例关系
def.position.Set(winSize.width / 2/PTM_RATIO, winSize.height / 2/PTM_RATIO);
//创建物体,创建一个物体都是在世界里面创建的
b2Body* body = _world->CreateBody(&def);
// 让body受力
body->SetLinearVelocity(b2Vec2(10, 20));
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 /*密度系数*/);//密度系数0---1.
fixture->SetFriction(0.0f); // 摩擦系数 0--1, 0代表没有摩擦
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); // 弹性系数, 1没有消耗,每次弹起高度都一样,越小越有消耗。
}
// 加个天花板
{
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->SetRestitution(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*){ //注意这里要加&哦,不然不能访问_bat.
float dx = touch->getDelta().x / PTM_RATIO;
b2Vec2 pos = _bat->GetPosition();
pos.x += dx;
_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();
}
}