DM6
2004.07.27, 06:00 AM
Trying to write AI to keep an enemy ship from colliding with asteroids in a top-down Asteroids-style space game. Physics engine is integrated with verlet's method (a la Jakobsen). Trying a dynamical solution instead of a search. My method is to predict the future positions of the asteroids and ship and add the velocity vectors of the asteroids with which a collision is predicted.
(updated code)
void astgame::ShipAI(int t)
{
float m, n, o, p;
float dist[theRoids.size()];
float ang[theRoids.size()];
int temp[9] = {0,-1,-1,-1,-1,-1,-1,-1,-1};
for (unsigned int i = 0; i < theRoids.size(); i++)
{
m = theShip.pos[0] + t*(theShip.GetPosDiff(0));
n = theShip.pos[1] + t*(theShip.GetPosDiff(1));
o = theRoids[i].pos[0] + t*(theRoids[i].GetPosDiff(0));
p = theRoids[i].pos[1] + t*(theRoids[i].GetPosDiff(1));
dist[i] = getDist(m,n,o,p);
ang[i] = getAngle(m,n,o,p);
if (dist[i] < 100)
{
// Add the asteroid's index if it is closer than 100 pixels
temp[temp[0] + 1] = i;
temp[0] += 1;
}
}
float tx, ty;
for (int j = 0; j < temp[0]; j++)
{
tx += dist[temp[j]] * cos(ang[temp[j]]);
ty += dist[temp[j]] * sin(ang[temp[j]]);
}
float targetangle = 3.*pi/2.0 + atan2(ty,tx);
if (targetangle < 0) targetangle += 2.0*pi;
if (targetangle > 2.0*pi) targetangle -= 2.0*pi;
int dangerFlag = 0;
if (temp[0] != 0) dangerFlag = 1;
if (dangerFlag && theShip.angle > targetangle)
{
theShip.turning = 1;
theShip.thrustOn = 0;
}
if (dangerFlag && theShip.angle < targetangle)
{
theShip.turning = -1;
theShip.thrustOn = 0;
}
if (dangerFlag && (theShip.angle - targetangle)*(theShip.angle - targetangle) < .01)
{
theShip.thrustOn = 1;
theShip.turning = 0;
}
if (!dangerFlag)
{
theShip.thrustOn = 0;
}
}
Ship behaves as though it has some semblance of awareness, but I think my angles are messed up. Can someone tell me what I'm doing wrong?
Many thanks
-Duncan
(updated code)
void astgame::ShipAI(int t)
{
float m, n, o, p;
float dist[theRoids.size()];
float ang[theRoids.size()];
int temp[9] = {0,-1,-1,-1,-1,-1,-1,-1,-1};
for (unsigned int i = 0; i < theRoids.size(); i++)
{
m = theShip.pos[0] + t*(theShip.GetPosDiff(0));
n = theShip.pos[1] + t*(theShip.GetPosDiff(1));
o = theRoids[i].pos[0] + t*(theRoids[i].GetPosDiff(0));
p = theRoids[i].pos[1] + t*(theRoids[i].GetPosDiff(1));
dist[i] = getDist(m,n,o,p);
ang[i] = getAngle(m,n,o,p);
if (dist[i] < 100)
{
// Add the asteroid's index if it is closer than 100 pixels
temp[temp[0] + 1] = i;
temp[0] += 1;
}
}
float tx, ty;
for (int j = 0; j < temp[0]; j++)
{
tx += dist[temp[j]] * cos(ang[temp[j]]);
ty += dist[temp[j]] * sin(ang[temp[j]]);
}
float targetangle = 3.*pi/2.0 + atan2(ty,tx);
if (targetangle < 0) targetangle += 2.0*pi;
if (targetangle > 2.0*pi) targetangle -= 2.0*pi;
int dangerFlag = 0;
if (temp[0] != 0) dangerFlag = 1;
if (dangerFlag && theShip.angle > targetangle)
{
theShip.turning = 1;
theShip.thrustOn = 0;
}
if (dangerFlag && theShip.angle < targetangle)
{
theShip.turning = -1;
theShip.thrustOn = 0;
}
if (dangerFlag && (theShip.angle - targetangle)*(theShip.angle - targetangle) < .01)
{
theShip.thrustOn = 1;
theShip.turning = 0;
}
if (!dangerFlag)
{
theShip.thrustOn = 0;
}
}
Ship behaves as though it has some semblance of awareness, but I think my angles are messed up. Can someone tell me what I'm doing wrong?
Many thanks
-Duncan