box2d——2.加入鼠标关节MouseJoint和box2d基础概念
上一节加入了tiles积木,但不能进行鼠标操作。
以下加入鼠标相关的控制。
【加入鼠标关节】
b2MouseJoint *mMouseJoint
【处理按键响应】
设置开启触屏之类的就不说了。在触屏開始的时候要查询相交的形状,依据其夹具fixture获得物体。然后创建它与地面间的鼠标关节。
bool CBaseLayer::ccTouchBegan(CCTouch* touch, CCEvent* event) { CCPoint nodePos = convertToNodeSpace(touch->getLocation()); mMouseWorldPos = b2Vec2(nodePos.x, nodePos.y); if (mMouseJoint) return false; // 构造一个小点击盒子 b2AABB aabb; b2Vec2 d; d.Set(0.001f, 0.001f); aabb.lowerBound = mMouseWorldPos - d; aabb.upperBound = mMouseWorldPos + d; // 向物理世界查询覆盖的形状 CQueryCallback callback(mMouseWorldPos); mWorld->QueryAABB(&callback, aabb); if (callback.mFixture) { // 创建鼠标关节 b2Body *body = callback.mFixture->GetBody(); b2MouseJointDef md; md.bodyA = mGroundBody; // 世界边界 md.bodyB = body; md.target = mMouseWorldPos;// 拖动的坐标 md.maxForce = 1000.0f * body->GetMass(); // 拖动的力 mMouseJoint = (b2MouseJoint *)mWorld->CreateJoint(&md); // 设置睡眠(这里awake为true表示sleep...) body->SetAwake(true); return true; } return false; }然后在鼠标移动的时候更新鼠标关节的目标位置,并在触屏结束的时候删除鼠标关节。
void CBaseLayer::ccTouchMoved(CCTouch* touch, CCEvent* event) { CCPoint nodePos = convertToNodeSpace(touch->getLocation()); mMouseWorldPos = b2Vec2(nodePos.x, nodePos.y); if (mMouseJoint) mMouseJoint->SetTarget(mMouseWorldPos); } void CBaseLayer::ccTouchEnded(CCTouch* touch, CCEvent* event) { if (mMouseJoint) { mWorld->DestroyJoint(mMouseJoint); mMouseJoint = NULL; } }
从b2QueryCallback派生一个查询回调的类来存储要处理的查询结果:
// 查询的回调 class CQueryCallback : public b2QueryCallback { public: CQueryCallback(const b2Vec2& point) { mPoint = point; mFixture = NULL; } bool ReportFixture(b2Fixture* fixture) { b2Body* body = fixture->GetBody(); if (body->GetType() == b2_dynamicBody) { // 该点是否在形状内 bool inside = fixture->TestPoint(mPoint); if (inside) { mFixture = fixture; // We are done, terminate the query. return false; } } // Continue the query. return true; } b2Vec2 mPoint; b2Fixture *mFixture; };
【效果图和代码下载】
b2World世界:物理世界就是物体、形状和约束相互作用的集合
b2Body物体
b2Fixture夹具:用于把形状附加到物体上的关系
b2Shape形状:物体的形状。依附于五条的2d碰撞几何结构。有摩擦力friction和恢复力restitution等材质性质
约束:消除物体自由度的物理连接。2d世界中,一个物体有x、y方向和旋转角度3个自由度。
b2Joint关节:用于把两个或多个物体固定到一起的约束。
包含旋转、棱柱和距离等。可限制一个关节的活动范围,可通过关节驱动所连接物体的转动。
box2d针对大小0.1~10单位长度的物体作了优化,所以定义一个转换PTM_RATIO=32,表示像素/米,以便把物体尺寸在cocos2dx与box2d间转换。
一个物体可附加多个夹具。每一个夹具代表一个特定密度、形状的部件,而物体的主要特征则表现为整个物体在空间的位置和速度信息。
b2body的userData属性同意存放一个随意类型的指针指向我们自己定义的数据。