box2d——2.新增滑鼠關節MouseJoint和box2d基礎概念
阿新 • • 發佈:2019-01-25
上一節添加了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屬性允許存放一個任意型別的指標指向我們自定義的資料。