【发布时间】:2018-04-12 01:04:23
【问题描述】:
我正在尝试为我的游戏中的僵尸实现一个集群算法,以便它们聚集在一起,同时避免相互碰撞。到目前为止,它们总是直接向玩家移动,如果玩家移动很多,可能会导致它们堆叠在一起。
这让我得到了一些关于成群结队的小僵尸的反馈,因为玩家射击它们(它们是一击必杀)并且因为它们上面还有更多,所以他们一直告诉我它看起来子弹没有击中。
我一直在研究使用植绒算法,但问题是我的游戏不使用向量来进行敌人的移动。我只是将敌人的位置作为 (x,y) 对,在更新时,他们使用 atan2 计算他们的面对,然后根据这个 theta 的 cos 和 sin 值更新他们的位置。
我可以添加矢量移动,但这需要大量的重构,所以我希望看看是否有某种方法可以在没有它的情况下实现这个算法。这是我现在的算法。我知道有几个缺陷,但我预计至少会看到一些不同的行为——但僵尸的移动方式仍然完全相同。
public void move(GameState gs, int delta) {
theta = Calculate.Hypotenuse(position, Globals.player.getPosition());
int neighbors = 0;
float force = 0.0f;
for(Enemy e : ((EnemyController)gs.getEntity("enemyController")).getAliveEnemies()) {
if(!e.equals(this)) {
float dist = Calculate.Distance(position, e.getPosition());
if(dist < getSeparationDistance()) {
// Add separation strength to theta.
force += Zumby.SEPARATION_STRENGTH;
neighbors++;
} else if(dist < getCohesionDistance()) {
// Add cohesion strength to theta.
force += Zumby.COHESION_STRENGTH;
neighbors++;
}
}
}
if(neighbors > 0) {
force /= neighbors;
theta += force;
}
if(!moveBlocked) {
position.x += (float)Math.cos(theta) * Zumby.SPEED * delta;
position.y += (float)Math.sin(theta) * Zumby.SPEED * delta;
}
moveBlocked = false;
bounds.setCenterX(position.x);
bounds.setCenterY(position.y);
}
感谢您的帮助。
【问题讨论】:
-
使用(纯)极角表示而不是笛卡尔向量通常是一个非常糟糕的主意(您经常需要考虑 180 度的不连续性,尤其是在使用增量时)。此外,将正数
force添加到角度不会很有用 - 您需要考虑力作用的方向。此外,由于您已经将位置存储为(x, y),因此采用它应该相当方便仅此函数的向量。
标签: java algorithm game-physics