2016-03-21 103 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(更好),以减少对角的影响遥远的病毒都有。