簡體   English   中英

在Box2Djs中解凍實體或阻止其退出世界

[英]Unfreeze bodies in Box2Djs or prevent from exiting world

我正在服務器端物理實驗中,用戶通過套接字控制對象。 當用戶將對象移動到世界邊界之外時,我遇到的問題就變成了結果。

我正在使用通過npm安裝的Box2Djs。

我創建了世界500x500,然后將以下偵聽器附加到該世界:

var boundaryListener = new b2d.b2BoundaryListener();
boundaryListener.Violation = function (body) {
    //we will move this body to the opposite side
    var position = body.GetWorldCenter();
    //snap to opposite side
    if (position.x < 0) {
        position.x = worldAABB.upperBound.x + position.x;
    }
    if (position.y < 0) {
        position.y = worldAABB.upperBound.y + position.y;
    }
    if (position.x > worldAABB.upperBound.x) {
        position.x -= worldAABB.upperBound.x;
    }
    if (position.y > worldAABB.upperBound.y) {
        position.y -= worldAABB.upperBound.y;
    }

    body.m_flags = body.m_flags & (~b2d.b2Body.e_frozenFlag); //does nothing :(
}
this.world.SetBoundaryListener(boundaryListener);

worldAABB是世界用作邊界的b2AABB。

問題是我注意到,當觸發邊界偵聽器時,標志設置為22,這是allowSleep,frozen和island標志。 似乎當b2Body通過世界邊界之外時,它被凍結了。 最后一行是通過弄亂內部標志來使身體解凍的嘗試,但是我有一種明顯的感覺,那就是這樣做的錯誤方法。

我如何解凍身體? 沒有任何功能可以清除我可以看到的凍結標志(javascript超過10,000行,所以老實說我還沒讀完整的東西),並且放置一些物體作為牆似乎沒有任何作用(用戶的對象直接通過了)他們)。

我的牆是這樣創建的:

//create walls
var wallShape = new b2d.b2PolygonDef();
wallShape.SetAsBox(500, 10);
wallShape.density = 0.0;
wallShape.friction = 0.3;

var bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(250, 20);
var north = this.world.CreateBody(bodyDef);
north.CreateShape(wallShape);

bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(250, 499);
var south = this.world.CreateBody(bodyDef);
south.CreateShape(wallShape);

bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(499,250);
bodyDef.angle = Math.PI / 2;
var east = this.world.CreateBody(bodyDef);
east.CreateShape(wallShape);

bodyDef = new b2d.b2BodyDef();
bodyDef.position.Set(1, 250);
bodyDef.angle = Math.PI / 2;
var west = this.world.CreateBody(bodyDef);
west.CreateShape(wallShape);

有人對如何解決此問題有任何見解嗎? 除了網站指向的Flash文檔(時間不匹配一半)和C ++文檔甚至不涉及凍結的信息外,我幾乎找不到在javascript中使用Box2D的文檔。

可能會有所幫助的是,世界沒有重力,所有物體都有一定的線性和角度阻尼(它應該是假想的空間感覺)。

我研究了Box2Djs的源代碼,然后發現了下一個問題。 每步Box2Djs都會檢查身體是否在世界邊界之內。 如果物體超出范圍,則其“結霜”,即將其排除在碰撞檢測之外。 出現以下代碼(Body.js第414行):

Freeze: function(){
    this.m_flags |= b2Body.e_frozenFlag;
    this.m_linearVelocity.SetZero();
    this.m_angularVelocity = 0.0;

    for (var s = this.m_shapeList; s != null; s = s.m_next)
    {
        s.DestroyProxy();
    }
}

請注意,此檢查在每個時間步均執行(b2Island.js 244)。 因此,如果您在邊界偵聽器中設置e_frozenFlag,它將不會執行任何操作:標記將在下一個時間步設置。 更重要的是,在身體凍結之后,它失去了速度,其形狀在廣泛的階段失去了代理(如您從上面的代碼中可以看到的)。 代理似乎無法自動恢復,因此,重置標志是不夠的。

我也沒有在Box2Djs界面或邏輯中解凍主體的地方找到。 手動執行此操作是一種骯臟的技巧,因為您應該訪問Box2Djs內部的BroadPhase。 不僅如此,它對您無濟於事,因為在凍結身體時會失去其速度。 但是,正如我所見,您需要繼續移動身體。

接下來是解決方案。 您應該完全避免物體發呆,以便在物體脫離世界邊界后保持其模擬狀態。 可以通過下一個技巧來完成。 首先,設置較大的世界邊界。 然后,設置接觸偵聽器,當身體接觸牆壁時,執行邊界違反邏輯。

如何在C ++中設置聯系偵聽器,您可以在此處看到: https ://www.iforce2d.net/b2dtut/collision-callbacks很抱歉,我不知道Java腳本,也不能說在Box2Djs中如何做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM