2016-03-21 101 views
1

我爲一個名爲Ogar的項目製作了一個bot,這是一個用Node.js編寫的Agar.io服務器實現。計算避開障礙物的圓角

這個機器人有一個障礙,一個叫做病毒的綠色尖刺細胞(見插圖)。我需要編程這個機器人來避免這個障礙,但我沒有運氣。由於插圖中有很多目標,因此它基於更新。

Illustration of what I want

這裏是我結束了到現在爲止的代碼。

BotPlayer.prototype.avoidObstacles = function(cell, angle) { 
    // Sum up all of the vector angles of obstacles to cell and react against it 
    var angleSum = 0; 
    var collided = this.collisionFromList(cell, this.obstacles); 
    if (collided.length == 0) return angle; // Not to return NaN 

    for (var i = 0; i < collided.length; i++) { 
     angleSum += this.angle(cell.position, collided[i].position); 
    } 

    angleSum /= collided.length; // Average out the angle sum 

    // TODO: Find closest available edge 
    angleSum += Math.PI/2; 

    return angle + angleSum; 
}; 

這樣確實可以在大多數情況下,但有時機器人完全忽略障礙(this.collisionFromList(cell, this.obstacles);是完全沒有問題),並最終通過它從字面上去(爆炸成大量細胞)。

BotPlayer.prototype對這種計算有很多有用的功能。見this link

我不需要任何尋路爭吵,只是這個簡單的避免措施。

+0

如果有三個等距的障礙,你的機器人正朝着往中間的障礙,那不是你的計算保留BOT往中間的障礙物去角? –

回答

1

還有一種替代方法可以讓你嘗試做什麼。該方法是使用吸引子來描述系統中的實體。你的「機器人」是agent,它有一個位置,它知道世界上的其他實體和它們的吸引力。說你的目的地有+1 attraction強制和障礙有-X attraction強制,有效地排斥「bot」(agent)。

這裏有一個決策的僞代碼:

/** 
* @param {Array.<{position:Vector2, attraction:Number}>} entities 
*/ 
Agent.prototype.calculateDirectionVector = function(entities){ 
    var agentPosition = this.position; 
    var result = new Vector2(0,0); 

    entities.forEach(function(entity){ 
     //calculate separation between agent and entity 
     var displacement = entity.position.clone().sub(agentPosition); 
     //figure out distance between entities 
     var distance = displacement.length(); 
     //dampen influence of attraction linearly with distance 
     var influence = entity.attraction/distance; 
     //produce force vector exerted by this entity on the agent 
     var force = displacement.normalize().multiplyScalar(influence); 
     //add up forces on the entity 
     result.add(force); 
    }); 

    //normalize the resulting vector 
    result.normalize(); 

    return result; 
} 
+0

一個很棒的解決方案!非常感謝! – Luka967

0

這是一個很大的啓發式,但如果你希望保持這種邏輯,那麼考慮考慮到病毒的笛卡爾距離,因爲你顯然可以訪問它們的位置。

功能是BotPlayer.prototype.getDistBotPlayer.prototype.getAccDist

可以使用閾值DIST_MIN和簡單if或使用功能類似angle/distance(更好),以減少對角的影響遙遠的病毒都有。