【问题标题】:Moving a unit precisely along a path in x,y coordinates沿 x,y 坐标中的路径精确移动单位
【发布时间】:2010-01-26 22:10:38
【问题描述】:

我正在玩一个策略游戏,小队在地图上移动。每回合都会为小队分配一定的移动量,如果小队有目的地,则每回合都会应用积分,直到到达目的地。使用实际距离,因此如果小队在 x 或 y 方向移动一个位置,它使用一个点,但对角线移动需要约 1.4 个点。小队将实际位置保持为浮点数,然后将其四舍五入以允许在地图上绘制位置。

通过触摸小队并拖动到结束位置然后抬起笔或手指来描述路径。 (我现在在 iPhone 上执行此操作,但 Android/Qt/Windows Mobile 将工作相同)随着指针移动 x,y 点被记录,以便小队在前往最终目的地的途中获得中间目的地列表。我发现目的地的间距不均匀,但根据指针移动的速度可能会更远。遵循路径很重要,因为障碍物或地形在此游戏中很重要。我不是要重制 Flight Control,但这是一个类似的机制。

这是我一直在做的,但它似乎太复杂了(伪代码):

getDestination() {
- self.nextDestination = remove_from_array(destinations)
- self.gradient = delta y to destination / delta x to destination
- self.angle = atan(self.gradient)
- self.cosAngle = cos(self.angle)
- self.sinAngle = sin(self.angle)
}

move() {
- get movement allocation for this turn
- if self.nextDestination not valid
- - getNextDestination()
- while(nextDestination valid) && (movement allocation remains) {
- - find xStep and yStep using movement allocation and sinAngle/cosAngle calculated for current self.nextDestination
- - if current position + xStep crosses the destination
- - - find x movement remaining after self.nextDestination reached
- - - calculate remaining direct path movement allocation (xStep remaining / cosAngle)
- - - make self.position equal to self.nextDestination
- - else 
- - - apply xStep and yStep to current position
- }
- round squad's float coordinates to integer screen coordinates
- draw squad image on map
}

当然,这很简单,需要调整诸如标志之类的东西,以确保移动方向正确。如果 trig 是最好的方法,那么可以使用查找表,或者在现代设备上使用它可能并不重要。

有更好的方法建议吗?

  • 更新 - iPhone 在触发和跟踪数十个位置和轨迹方面的问题为零,如上文所述实现,并且无论如何它都会绘制浮点数。 Bresenham 方法更有效,trig 更精确。如果我要使用整数 Bresenham,我希望乘以 10 左右以保持更高的位置精度,从而有利于碰撞/地形检测。

【问题讨论】:

    标签: iphone android algorithm


    【解决方案1】:

    我认为Bresenham's line algorithm 是您所需要的。 Wikipedia 文章是一个很好的起点,您应该可以在某处找到更多示例代码。

    这是来自维基百科的伪代码

    function line(x0, x1, y0, y1)
     int deltax := x1 - x0
     int deltay := y1 - y0
     real error := 0
     real deltaerr := deltay / deltax    // Assume deltax != 0 (line is not vertical),
           // note that this division needs to be done in a way that preserves the fractional part
     int y := y0
     for x from x0 to x1
         plot(x,y)
         error := error + deltaerr
         if abs(error) ≥ 0.5 then
             y := y + 1
             error := error - 1.0
    

    【讨论】:

    • 谢谢 - 怀疑是这个,但需要指导。
    【解决方案2】:

    使用角度似乎适得其反,将计算保持在 X-Y 坐标系中会更简单。

    【讨论】:

      猜你喜欢
      • 2017-10-31
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      相关资源
      最近更新 更多