## Starcontrol like melee AI aiming

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
lillo
Posts: 447
Joined: May 27, 2005 8:00
Location: Rome, Italy
Contact:

### Starcontrol like melee AI aiming

I'm on the last month of work on my master thesis (I graduate on mid-december!), and I've tried to stay out of anything that is not related to the thesis code-wise... but today, don't ask me why, I thought about the Starcontrol II melee AI and wondered how the smart aiming was done... You know, in that game the enemy ship did not fire a bullet directed towards the instantaneous player ship position, but rather it predicted where the player was going to be at his current velocity and direction, aiming there instead, also considering the bullet speed.
I couldn't resist to sit down with paper and pencil to analyze the problem from a mathematical point of view (my engineer soul calling), and when I solved it I coded the small demo attached here:

Code: Select all

`option explicit#include "fbgfx.bi"#define SCR_W         640#define SCR_H         480#define SCR_B         16const BULLET_SPEED as single = 3.7const PLAYER_SPEED as single = 2.4const PLAYER_ACCEL as single = 0.15type OBJECT   active as integer   x as single   y as single   vx as single   vy as singleend typedeclare function get_fire_angle(byval src as OBJECT ptr, byval dest as OBJECT ptr, byval speed as single) as doubledeclare sub rest(byval t as single)'':::::function get_fire_angle(byval src as OBJECT ptr, byval dest as OBJECT ptr, byval speed as single) as double   dim as single t, dx, dy, delta, cosine, sine   speed *= speed   dx = dest->x - src->x   dy = dest->y - src->y   delta = (speed * ((dx * dx) + (dy * dy))) - (((dest->vx * dy) - (dest->vy * dx)) * ((dest->vx * dy) - (dest->vy * dx)))   t = -(dest->vx * dx) - (dest->vy * dy) - sqr(delta)   t /= ((dest->vx * dest->vx) + (dest->vy * dest->vy) - speed)   cosine = dx + (dest->vx * t)   sine   = dy + (dest->vy * t)   function = atan2(-sine, cosine)end function'':::::sub rest(byval t as single)   dim as single start   start = timer   while timer < start + t: wendend sub   '':::::   dim as OBJECT turret, bullet, player   dim as integer page   dim as single angle   screenres SCR_W, SCR_H, SCR_B, 2   randomize(timer)   player.x = rnd*SCR_W   player.y = rnd*SCR_H   turret.x = SCR_W / 2   turret.y = SCR_H / 2   do      screenset page, page xor 1      page xor= 1      cls      circle(player.x, player.y), 4, rgb(255, 255, 255),,, 1, F      circle(turret.x, turret.y), 4, rgb(255, 128, 0),,, 1, F      if (bullet.active) then         circle(bullet.x, bullet.y), 4, rgb(255, 0, 0),,, 1, F         bullet.x += bullet.vx         bullet.y += bullet.vy      end if      if (multikey(SC_LEFT) and (player.vx > -PLAYER_SPEED)) then player.vx -= PLAYER_ACCEL      if (multikey(SC_RIGHT) and (player.vx < PLAYER_SPEED)) then player.vx += PLAYER_ACCEL      if (multikey(SC_UP)   and (player.vy > -PLAYER_SPEED)) then player.vy -= PLAYER_ACCEL      if (multikey(SC_DOWN)  and (player.vy < PLAYER_SPEED)) then player.vy += PLAYER_ACCEL      player.x += player.vx      player.y += player.vy      rest 0.02      angle = get_fire_angle(@turret, @player, BULLET_SPEED)      line(turret.x, turret.y)-(turret.x + (cos(angle) * SCR_W), turret.y - (sin(angle) * SCR_W)), rgb(128, 0, 0)      if (multikey(SC_SPACE)) then         bullet.x = turret.x         bullet.y = turret.y         bullet.vx = cos(angle) * BULLET_SPEED         bullet.vy = -sin(angle) * BULLET_SPEED         bullet.active = 1      end if   loop while not multikey(SC_ESCAPE)`

Use the arrow keys to accelerate the "ship" in a given direction, and hit space to let the "turret" at the center of the screen to fire at you. The red line is the current aim of the turret, given your position/velocity and the bullet speed.
The get_fire_angle() function always succeeds as long as the bullet speed is always higher than the player speed (it would not make sense anyway in this case as if the bullet is slower than the player it can never catch him)
Hope you can make good use of this code :)
Now I'm going back to my thesis...

EDIT: optimized and cleaned up code a bit
Posts: 230
Joined: May 27, 2005 15:14
Contact:

### Great piece of code there, lillo!! ^-^=b

I gotta tell ‘ya, that code of yours just placed in this thread sure knows what it is doing, in that the firing of the turret towards the white ship is actually a *lot* smarter than it looks. EXCELLENT job on it!!! :D

Look, I sure hope you ace your master thesis successfully and graduate indeed, my man lillo! And welcome back to the official FB forums, by the way!! ^_-=b !
rdc
Posts: 1713
Joined: May 27, 2005 17:22
Location: Texas, USA
Contact:
That could come in very handy. Thanks for the example. Good luck on the thesis!
SotSvart
Posts: 262
Joined: May 27, 2005 9:03
Location: Norway
Contact:
Exellent pice of code! This could come in handy indeed. Good luck with your master thesis.
jupiter3888
Posts: 103
Joined: Jun 30, 2005 3:54