2012-03-19 84 views
1

我一直在尝试为小行星游戏制作人工智能,但已陷入困境。游戏中的其他一切都会建立起来(例如,小行星创建并沿着随机方向前进,碰撞检测,船和子弹)。AI每隔150ms循环一次,只能告诉船左转,右转,向上移动并拍摄。检测对象是否会在2D空间中发生碰撞

这里是我的代码片段,我使用至今:

   // Convert points to positive 
       float asteroid_x = Math.Abs(asteroid.X); 
       float asteroid_y = Math.Abs(asteroid.Y); 

       float ship_x = Math.Abs(ship.X); 
       float ship_y = Math.Abs(ship.Y); 

       // Calculate difference in X and Y using positive values 
       float dx = asteroid_x - ship_x; 
       float dy = asteroid_y - ship_y; 

       // Get velocities of asteroid 
       float vx = asteroid.VX; 
       float vy = asteroid.VY; 

使用这些变量(DX,DY,VX,VY)我需要计算,如果小行星会打船。我一直在尝试使用三角函数,但它一直认为它会在没有时触及。我一直在试图使用的公式为:

  float equation1a = (dy/vy) - (dx/vx); 
      float equation1 = ((dy/dx) - (vy/vx)); 

我则一直在试图使用IF语句,以确定是否它会打或没有,但我不知道如何去做正常。在这次IF声明之后,我想进入AI来转动和射击小行星或逃避它。

感谢您的任何帮助。

编辑:船舶或小行星的X和Y值也可以是负值,船在起点(0,0)上开始。

EDIT2:这一切变得有点进一步,现在又拿出这样的:

// Determine if asteroid will collide 
int turns_ahead = 100; 
bool collision = false; 
int least_turns = 500; 
for (int i = 0; i < turns_ahead; i++) 
{ 
    PointF asteroid_pos_next = NextPosition(new PointF(asteroid.X, asteroid.Y), new PointF(asteroid.VX, asteroid.VY), i); 

    if (asteroid.CollidesWith(asteroid_pos_next.X, asteroid_pos_next.Y, ship.R)) 
    { 
     collision = true; 
    } 
} 

而接下来的位置使用此功能计算出:

// ----------------------------------------------------------------- 
    // Function to find position of object in X turns (turns_ahead) 
    // ----------------------------------------------------------------- 
    private static PointF NextPosition(PointF current_pos, PointF velocity, int turns_ahead) 
    { 
     float next_x_pos = current_pos.X + (velocity.X * turns_ahead); 

     float next_y_pos = current_pos.Y + (velocity.Y * turns_ahead); 

     // IFs to deal with screen wrap-around 
     if (next_x_pos < -Form1.maxX) 
     { 
      next_x_pos = Form1.maxX; 
      if (next_y_pos < 0) 
       next_y_pos += Form1.maxY; 
      else 
       next_y_pos -= Form1.maxY; 
     } 
     else if (next_x_pos > Form1.maxX) 
     { 
      next_x_pos = -Form1.maxX; 
      if (next_y_pos < 0) 
       next_y_pos += Form1.maxY; 
      else 
       next_y_pos -= Form1.maxY; 
     } 

     if (next_y_pos < -Form1.maxY) 
     { 
      next_y_pos = Form1.maxY; 
      if (next_x_pos < 0) 
       next_x_pos += Form1.maxX; 
      else 
       next_x_pos -= Form1.maxX; 
     } 
     else if (next_y_pos > Form1.maxY) 
     { 
      next_y_pos = -Form1.maxY; 
      if (next_x_pos < 0) 
       next_x_pos += Form1.maxX; 
      else 
       next_x_pos -= Form1.maxX; 
     } 

     PointF next_pos = new PointF(next_x_pos, next_y_pos); 

     return next_pos; 
    } 

的collidesWith是一个函数在其他地方用于检测子弹/船是否撞击到小行星。我不确定我的下一个位置函数是否正确,但是如果小行星包围X/Y值似乎卡住了maxX/maxY值?

+0

这与AI完全没有关系(根本不是)。 – ziggystar 2012-03-19 20:29:27

+0

这是一个班级项目吗?我刚才看到一个类似的问题:http://stackoverflow.com/questions/9773255/c-sharp-collision-test-of-a-ship-and-asteriod – 2012-03-19 20:34:58

+0

当船只必须搬出时,AI部分进来/拍摄。是的,它是一个课程项目的一部分,对不起,我应该说。我的讲师给我们提供了一些错误的公式,所以很容易混淆,尽管 – 2012-03-19 20:38:18

回答

0

请考虑以下几点:在任何时候你都有小行星和船的位置及其速度。然后,在时间t(的150毫秒的时间间隔),小行星的位置将

asteroid_x + asteroid.vx * t 
asteroid_y + asteroid.vy * t 

和船舶的位置将

ship_x + ship.vx * t 
ship_y + ship.vy * t 

所以,你可以到T只是想迭代(0〜 100),并检查小行星和船舶在任何时候是否在彼此的某个距离内(例如他们的半径之和) - 这意味着碰撞。

p.s.距离由

sqrt((asteroid_x - ship_x)^2 + (astroid_y - ship_y)^2) 

给我建议你一般也

+0

最后使用了这个基本概念,所以谢谢! – 2012-03-19 20:38:52

0

这里没有足够的上下文,需要真的看到更多的代码。我将要处理的非常高层次的概念是两个步骤 - 1.移动小行星物体(在不同的线程上移动到用户/ AI移动船上),2.检查小行星的位置,每次移动(事件处理程序)时船舶的位置(用于碰撞)。另外 - 你提到'打它',你是否试图预测碰撞发生之前?如果是这样,你需要考虑小行星和船舶的前一次/最近的移动,以“预测”他们未来的移动。

0

想象一下你的对象的议案在3个维度,其中,第三是时间阅读更多关于碰撞检测;如果3D中的这些线条足够接近(小于它们的半径的总和,假定对象都是圆形),它们最终会发生碰撞。

这两条3D线可以由点(x,y,0)和方向矢量(vx,vy,1)定义;然后可以应用众所周知的几何图形来找出两条“歪斜”3D线条之间的最近距离;我不知道它,但here's an article它给出

D = | c·(a×b)|/| a×b |

其中小写变量向量,c是位置之间的差,和一个b是两个方向矢量。

请注意,如果对象在过去的上碰撞了其当前轨迹,则会产生误报;我不知道如何解决这个问题,但即使你把它放在它里面也不会干扰你的AI。也许有一种方法可以测试“绝对分开”,或者该公式中分子的符号是有意义的。