我一直试图为小行星游戏制作人工智能,但已经卡住了。游戏中的其他所有内容都已设置好(即小行星创建并沿着随机方向行进,碰撞检测,船只和子弹。)人工智能每150毫秒循环一次,只能告诉船向左转,向右转,向上移动并射击
以下是我目前使用的代码片段:
// 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 :(得分:0)
这里没有足够的上下文,需要真正看到更多代码。我正在研究的非常高级的概念是两个步骤 - 1.移动小行星对象(在不同的线程上移动用户/ AI移动船),2。检查小行星的位置与每次运动(事件处理程序)中船舶的位置(用于碰撞)。另外 - 你提到'打击它',你是否试图预测碰撞发生之前?如果是这样,你需要考虑小行星和船的先前/最近的运动来“预测”他们未来的运动。
答案 1 :(得分:0)
考虑以下事项:在任何时刻,你都有小行星和船的位置及其速度。然后,在时间t(150ms的间隔),小行星的位置将是
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 )
我建议你阅读更多关于碰撞检测的内容
答案 2 :(得分:0)
想象一下你的物体在三个维度上的运动,其中第三个是时间;如果这些3D线在一起足够接近(小于它们的半径之和,假设物体都是圆圈),它们最终会发生碰撞。
这两条3D线可以由点(x,y,0)和方向矢量(vx,vy,1)定义;然后,您可以应用众所周知的几何体来找到两条“倾斜”3D线之间的最近距离;我不知道它,但here's an article给出了
D = | c·(a×b)| / | a×b |
其中小写变量是向量,c是位置之间的差异, a 和 b 是两个方向向量。
请注意,如果对象在过去的中碰撞当前轨迹,则会产生误报;我不知道如何解决这个问题,但即使你把它留在里面也可能不会干扰你的AI。也许有一种方法可以测试“绝对分开”,或者也许该公式中分子的符号是有意义的。