1. 程式人生 > >box2d——2.新增滑鼠關節MouseJoint和box2d基礎概念

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;
};

【效果圖和程式碼下載】


【box2的基本元件的概念】

b2World世界:物理世界就是物體、形狀和約束相互作用的集合

b2Body物體

b2Fixture夾具:用於把形狀附加到物體上的關係

b2Shape形狀:物體的形狀,依附於五條的2d碰撞幾何結構,有摩擦力friction和恢復力restitution等材質性質

約束:消除物體自由度的物理連線。2d世界中,一個物體有x、y方向和旋轉角度3個自由度。

b2Joint關節:用於把兩個或多個物體固定到一起的約束。包括旋轉、稜柱和距離等。可限制一個關節的活動範圍,可通過關節驅動所連線物體的轉動。

  box2d針對大小0.1~10單位長度的物體作了優化,所以定義一個轉換PTM_RATIO=32,表示畫素/米,以便把物體尺寸在cocos2dx與box2d間轉換。

  一個物體可附加多個夾具,每個夾具代表一個特定密度、形狀的部件,而物體的主要特徵則表現為整個物體在空間的位置和速度資訊。

  b2body的userData屬性允許存放一個任意型別的指標指向我們自定義的資料。