如何找出敌人要遵循的草书路径

时间:2015-08-24 07:38:10

标签: algorithm pseudocode path-finding

问题

我正在制作一个游戏,其中敌人出现在屏幕的某个点上,然后沿着平滑的曲线路径并在某个时刻消失。我可以让它们沿着直线路径行进,但无法弄清楚如何使它们遵循图像中描绘的路径。

尝试

我从抛物线开始并成功实施。我只是使用抛物线方程逐渐计算坐标。我不知道应该是什么路径的等式。

我想要什么

我不是要求代码。我只是希望有人向我解释一般技术。如果你还想展示一些代码,那么对于你可以使用的这个特定问题,我不会特别喜欢编程语言C,Java甚至是伪代码。

enter image description here

2 个答案:

答案 0 :(得分:1)

如果您想生成所需的螺旋路径。

  • 总时间
  • 多少完整轮换
  • 最大半径

所以,总时间 T_f = 5秒,旋转 R_f = 2.5 * 2 * PI ,距离开始的最终距离 D_f = 200px

function SpiralEnemy(spawnX, spawnY, time) {
  this.startX = spawnX;
  this.startY = spawnY;
  this.startTime = time;
  // these will change and be used for rendering
  this.x = this.startX;
  this.y = this.startY;
  this.done = false;
  // constants we figured out above
  var TFinal = 5.0;
  var RFinal = -2.6 * 2 * Math.PI;
  var RStart = -Math.PI / 2;
  var DFinal = 100;
  // the update function called every animation tick with the current time
  this.update = function(t) { 
    var delta = t - this.startTime;
    if(delta > TFinal) {
      this.done = true;
      return;
    }
    // find out how far along you are in the animation
    var percent = delta / TFinal;
    // what is your current angle of rotation (in radians)
    var angle = RStart + RFinal * percent;
    // how far from your start point should you be
    var dist = DFinal * percent;
    // update your coordinates
    this.x = this.startX + Math.cos(angle) * dist;
    this.y = this.startY + Math.sin(angle) * dist;
  };
}

编辑这是一个混淆http://jsfiddle.net/pxb3824z/

的混蛋

编辑2 这是一个循环(而不是螺旋)版本http://jsfiddle.net/dpbLxuz7/

循环代码将动画分为开始的一半和结尾的两部分。

开始一半:角度= Math.tan(T_percent)* 2 和dist = 速度+速度*(1 - T_percent)

结束一半:角度= -Math.tan(1 - T_percent)* 2 和dist = **速度+速度* T_percent

对于两个半部,T_percent归一化为(0,1.0)。

function LoopEnemy(spawnX, spawnY, time) {
  this.startX = spawnX;
  this.startY = spawnY;
  this.startTime = time;
  // these will change and be used for rendering
  this.x = this.startX;
  this.y = this.startY;
  this.last = time;
  this.done = false;
  // constants we figured out above
  var TFinal = 5.0;
  var RFinal = -2 * Math.PI;
  var RStart = 0;
  var Speed = 50; // px per second
  // the update function called every animation tick with the current time
  this.update = function(t) { 
    var delta = t - this.startTime;
    if(delta > TFinal) {
      this.done = true;
      return;
    }
    // find out how far along you are in the animation
    var percent = delta / TFinal;
    var localDelta = t - this.last;
    // what is your current angle of rotation (in radians)
    var angle = RStart;
    var dist = Speed * localDelta;
    if(percent <= 0.5) {
      percent = percent / 0.5;
      angle -= Math.tan(percent) * 2;
      dist += dist * (1 - percent);
    } else {
      percent = (percent - 0.5) / 0.5;
      angle -= -Math.tan(1 - percent) * 2;
      dist += dist * percent;
    }
    // update your coordinates
    this.last = t;
    this.x = this.x + Math.cos(angle) * dist;
    this.y = this.y + Math.sin(angle) * dist;
  };
}

获得行进的确切距离和环路的高度是一项更多的工作。我随意选择了50px / sec的速度,它给出了〜+ 145的最终x偏移量和〜+ 114的循环高度,距离和高度将从这些值线性缩放(例如:速度= 25将具有~73处的最终x和〜57的环高度

答案 1 :(得分:1)

首先,您需要用一组点随时间表示每条曲线,例如:
- 在T(0)处,对象应位于(X0,Y0) - 在T(1)处,对象应位于(X1,Y1)。

你拥有的点越多,你得到的曲线就越平滑。

然后你将使用这些点集生成两个公式 - 一个用于X,另一个用于Y-,使用任何Interpolation方法,如La-grange's Interpolation公式:

enter image description here

  • 请注意,您应将'y'替换为时间T,并将'x'替换为X代表X公式,将Y替换为Y公式。

我知道你希望得到一个简单的等式,但不幸的是,你需要花费大量的精力来简化每个等式,我的建议除非值得,否则不要这样做。

如果您正在寻找一个更简单的方程式,以便在游戏的每个帧中都能很好地运行,那么您应该阅读SPline方法,这个方法是将曲线分成更小的段,并制作一个简单的方程式对于每个细分,例如:

线性样条线:

enter image description here

  • 每个段包含2个点,这将在每两个点之间画一条线。
  • 结果会是这样的: enter image description here

或者您可以使用二次样条或三次样条曲线来获得更平滑的曲线,但这会降低您的游戏性能。您可以阅读有关这些方法的更多信息here

我认为线性样条曲线对你来说很合适,每条曲线都有合理的点数。

  • 请将问题标题更改为更通用。