滑鼠與body的互動就靠這個mouse 關節了。
在使用中:主要分成3步:
步1:mousedown : 這個時期,調用world->queryaabb。它有一個回調接口,并根據滑鼠指針指定一個aabb的極小區域。
有3個細節需注意:
細節1:滑鼠的xy值是螢幕坐标系統的,要轉換成stage坐标系統(stage->screentostagecoordinates),然後再轉成box2d的機關xy值;
細節2:aabb極小區域是多小?當然是越小越好(比如:0.001f ,機關是米的,或者1個像素的差)x-0.001f, y-0.001f, x+0.001f,y+0.001f。這樣就形成了一個極小區域。但實際測試時發現,回調函數被調用時,滑鼠距離我們的目标body還有3-5個像素,這可能會造成視覺上的困惑。為解決這個問題,我一般在回調函數中再對其進行“(滑鼠)點的測試”,即fixture->testpoint(x,y)方法。用它來實作測試我們的fixture是否被擊中,以嚴格的擊中測試來定位fixture擊中與否,以此來建立滑鼠關節會更符合視覺習慣。
細節3:bodyb是操作目标,bodya一般是靜态body;我第一次使用時将這兩個搞混了,結果發生崩潰異常。(參見後面的圖1)
步2:mousedrag:在這個時間,隻是簡單設定目标位置就行。注意坐标的轉換與機關的轉換。
步3:mouseup:這個時間是銷毀滑鼠關節。一般要注意将關節對象的引用置空(=null)。
最後還要根據執行個體的body屬性,特别調節如下參數,以保證mouse關節行為不是那麼怪異!
mousejointdef.dampingratio = 1;
mousejointdef.frequencyhz = 60; 、、調大些,會使用命中時顯的更靈敏。
mousejointdef.maxforce = 5000;、、力要足夠大,否則可能因為幹不過重力而出現不期望的效果,比如“向下掉”。
mousejointdef.collideconnected = true;、、一般都設定為true,連接配接的body也要有碰撞,預設值為false,如果為false,它可能會“向下掉,且掉到地闆下面去了”。
下圖是圖1:

代碼參考:
@override
public boolean reportfixture(fixture fixture) {
// 如果不是這個類型,直接轉換會抛異常
// kwletter kwletter = (kwletter)fixture.getbody().getuserdata();
// 修改成如下代碼
object object = fixture.getbody().getuserdata();
if (object instanceof kwletter) {
kwletter kwletter = (kwletter)object;
if (null == m_mousejoint && kwletter.hit(m_mousex2d, m_mousey2d)) {
gdx.app.debug("reportfixture", "kwletter="+kwletter);
mousejointdef mousejointdef = new mousejointdef();
// mousejointdef.dampingratio = 1;
// mousejointdef.frequencyhz = 1;
// mousejointdef.maxforce = 5;
mousejointdef.target.set(new vector2(m_mousex2d, m_mousey2d));
mousejointdef.bodya = m_kwground.getbody();
mousejointdef.bodyb = kwletter.getbody();//目标
m_mousejoint = (mousejoint)m_world.createjoint(mousejointdef);
}
}
return false;
}
public boolean hit(float x2d, float y2d)
{
return m_fixture.testpoint(x2d, y2d);