非标准迷宫中的最佳路径寻找技术

时间:2017-04-15 17:27:20

标签: java optimization path-finding maze

所以,我的问题是我目前正在开放世界中使用各种尺寸的瓷砖进行路径寻找技术。该对象需要找到一个到达无限世界内的目的地的最佳路径(它在飞行中生成),其中填充了各种大小的瓷砖(不是位于设定的网格上 - 它们可以具有任何位置和大小 - 以及既不必是整数)。 (该对象可以访问所有tile和ArrayList的数据)。现在有些因素会使这个问题变得更加困难:

  • 对象本身有一个大小,无法在切片中移动。因此,存在的路径可能太窄而物体无法通过。
  • 目标目的地本身可能是移动物体。
  • 有可能同时存在数十个这样的对象 - 因此算法必须在系统上亮起或者在程序的几个单独的滴答中计算路径。 / LI>

我尝试实施迷宫解决技术的解决方案,但主要问题是在大多数迷宫中,瓷砖只能有非常特定的坐标(例如整数)并且总是大小相同。

我还尝试将场景渲染为一个巨大的传统迷宫,其中瓷砖实际上是瓷砖的像素(因此,如果我有一个20x40的瓷砖,它就变成了20x40的1x1瓷砖块),但遇到了性能问题,但仍然没有解决问题的路径可能会缩小以适应对象。

编辑:

非常抱歉我以前的不良措辞,当我试图在没有完全理解问题的情况下急于求解时会发生这种情况。所以我现在使用的算法是让NPC的敌人在障碍物周围寻找玩家。这是一个场景的例子:

Sample scenerio

带箭头的黑色圆圈是玩家,黑色灌木般的斑点是NPC的敌人。所以这是我目前用于敌人AI的算法:

void move() { //part of the Enemy class, this function is called once each tick for every enemy
  PVector velocity = new PVector(speed*game.dt, 0); //speed is a pre-set float denoting the enemy's speed, game.dt is deltatim
  velocity.rotate(atan2(game.player.location.y-location.y, game.player.location.x-location.x)); //game.player.location is a PVector of the player's position, location is a PVector of this enemy's position

  boolean init_collision = getTileCollision(); //getTileCollision is a boolean of whether this enemy is colliding with any tile
  location.add(velocity);
  boolean collision = getTileCollision();
  if (!init_collision && collision) { //if the enemy happens to spawn inside a tile, let is move out of it before checking for collision
    location.sub(velocity);

    if (desired_heading != -1) { //desired heading is the angle, in radians, of which 90-degree angle the enemy wants to move in, by default set to -1 (see my descrition of this algorithm below)
      velocity = new PVector(speed*game.dt, 0);
      velocity.rotate(desired_heading);
      location.add(velocity);
      if (getTileCollision()) {
        location.sub(velocity);
        velocity = new PVector(speed*game.dt, 0);
        velocity.rotate(current_heading); //current heading the an angle, in radians, of which 90-degree angle the enemy is currently moving in. set to -1 by default but can not equal -1 if desired_heading is not -1
        location.add(velocity);
        if (getTileCollision()) {
          location.sub(velocity);
          desired_heading = -1;
          current_heading = -1;
        }
      } else {
        desired_heading = -1;
        current_heading = -1;
      }
    } else {
      float original_heading = velocity.heading();
      desired_heading = radians(round(degrees(velocity.heading())/90.0)*90.0); //round to the nearest 90 degrees
      velocity = new PVector(speed*game.dt, 0);
      velocity.rotate(desired_heading);
      location.add(velocity);
      if (getTileCollision()) {
        location.sub(velocity);
      }
      float turn = radians(90);
      while (true) { //if it cant move, try rotating 90 degrees and moving
        velocity.rotate(turn);
        location.add(velocity);
        if (!getTileCollision() && abs(round(degrees(current_heading)) - round(degrees(velocity.heading()))) != 180) {
          current_heading = velocity.heading();
          break;
        } else {
          location.sub(velocity);
        }
      }
    }
  } else {
    desired_heading = -1;
    current_heading = -1;
  }
}

所以我的可怕代码希望完成的是敌人首先尝试直接向玩家移动。如果它遇到一个障碍物,它会将其角度调整到最近的90度,设置desired_heading到此并尝试移动。如果它不能,它将再旋转90度等等,始终牢记原始的圆角。

这远远不能很好地工作,首先,旋转90度有50%的机会进入错误的方向,所以我尝试添加

if (abs(original_heading - velocity.heading()+turn) < abs(original_heading - velocity.heading()-turn)) {
    turn = radians(-90);
}

while (true)之前,但完全破坏了算法(有时候敌人会深思熟虑而不会再次移动)。

我做错了什么?我应该尝试不同的算法,还是这个算法有潜力?

我希望现在这是一个更好的问题......

0 个答案:

没有答案