Here's a little missile commander-like game, but this time the AI defends the city while you attack from above. Click and drag to shoot, or hold the control key to have the computer shoot randomly.
The AI will use the function above to try to intercept and destroy the missiles before they reach the ground.
Every once in a while you'll have a missile that makes it to the ground. When that happens, you're score will increase by 1.
sync on
sync rate 100
cls
hide mouse
set display mode 1024,768,32
global turnspeed#=15.0
set display mode 1024,768,32
type v2
x as float
y as float
endtype
type missile_type
v as v2
p as v2
angle
thrust as float
targeted as integer
side as integer
exist as boolean
launch_pad as integer
endtype
global missile_amount=300
dim missile(missile_amount) as missile_type
global launch_pad_amount=3
type launch_pad_type
p as v2
endtype
dim launch_pad(launch_pad_amount) as launch_pad_type
launch_pad(1).p.x=screen width()/2
launch_pad(1).p.y=screen height()-100
launch_pad(2).p.x=50
launch_pad(2).p.y=screen height()-50
launch_pad(3).p.x=screen width()-50
launch_pad(3).p.y=screen height()-50
`launch_pad(4).p.x=screen width()/4.0
`launch_pad(4).p.y=screen height()-50
`launch_pad(5).p.x=screen width()*3.0/4.0
`launch_pad(5).p.y=screen height()-50
global time#=0
global hit_time#=0
global score=0
do
cls
time#=(timer()-timer0)/1000.0
`time#=1
timer0=timer()
`show some information
print "FPS:",screen fps()
print "score:",score
`angle#=rocketAI(p_x#,p_y#,p_vx#,p_vy#,p_angle#,p_a#*upkey()*0.5,x#,y#,vx#,vy#,angle#,a#,turnspeed#)
for n=1 to missile_amount
if missile(n).exist=1
for n2=n+1 to missile_amount
if missile(n2).exist=1 and missile(n).side<>missile(n2).side
if (missile(n).p.x-missile(n2).p.x)^2+(missile(n).p.y-missile(n2).p.y)^2<20^2
missile(n).exist=0
missile(n2).exist=0
endif
endif
next n2
missile(n).p.x=missile(n).p.x+missile(n).v.x*time#
missile(n).p.y=missile(n).p.y+missile(n).v.y*time#
missile(n).v.x=missile(n).v.x+missile(n).thrust*cos(missile(n).angle)*time#
missile(n).v.y=missile(n).v.y+missile(n).thrust*sin(missile(n).angle)*time#+9.8*time#*10.0
if missile(n).side=1
ink rgb(0,255,0),0
line missile(n).p.x-30*cos(missile(n).angle),missile(n).p.y-30*sin(missile(n).angle),missile(n).p.x+30*cos(missile(n).angle),missile(n).p.y+30*sin(missile(n).angle)
if missile(n).p.y>screen height()-3
inc score
missile(n).exist=0
endif
else
ink rgb(255,0,0),0
if missile(n).p.y>screen height()-3
missile(n).exist=0
endif
line missile(n).p.x,missile(n).p.y,missile(n).p.x+20*cos(missile(n).angle),missile(n).p.y+20*sin(missile(n).angle)
endif
endif
next n
if controlkey()=0
if mouseclick()=0 and mouse_click=0
fx#=fx#+mousemovex()
if fx#<0 then fx#=0
if fx#>screen width() then fx#=screen width()
circle fx#,0,2
endif
if mouseclick()=1 and mouse_click=0
position mouse fx#,0
startx#=fx#
starty#=0
mouse_click=1
endif
if mouseclick()=1 and mouse_click=1
ink rgb(255,0,0),0
line startx#,starty#,mousex(),mousey()
endif
if mouseclick()=0 and mouse_click=1
mouse_click=0
endx#=mousex()
endy#=mousey()
shoot_missile(startx#,starty#,(endx#-startx#),(endy#-starty#))
fx#=mousex()
m=mousemovex()
endif
mouse_click=mouseclick()
else
if rnd(5)=0
shoot_missile(rnd(screen width()-100)+50,0,rnd(400)-200,rnd(400)+200)
endif
endif
ink rgb(0,0,255),0
for l=1 to launch_pad_amount
circle launch_pad(l).p.x,launch_pad(l).p.y,30
next l
Defender_AI()
sync
loop
function changeangle(ta#,a#,amt#)
ta#=wrapvalue(ta#)
a#=wrapvalue(a#)
if ta#-a#>180 then dec ta#,360
if ta#-a#<-180 then dec a#,360
if abs(a#-ta#)<amt# then exitfunction ta#
if a#>ta# then exitfunction a#-amt#
t#=a#+amt#
endfunction t#
rem rocketAI(Target X, Target Y, Current X, Current Y, Velocity X, Velocity Y, Acceleration, Current Angle, Turn Speed)
function Defender_AI()
for n=1 to missile_amount
if missile(n).exist=1
if missile(n).side=1
missile(n).angle=atanfull(missile(n).v.y,missile(n).v.x)
` if missile(n).targeted=0
if rnd(10)=0
m=launch_rocket(1,n)
rocketAI2(n,m)
launch_from=1
min_time#=hit_time#
missile(m).exist=0
for l=2 to launch_pad_amount
m=launch_rocket(l,n)
rocketAI2(n,m)
if hit_time#<min_time#
min_time#=hit_time#
launch_from=l
endif
missile(m).exist=0
next l
if missile(n).targeted=0
m=launch_rocket(launch_from,n)
rocketAI2(n,m)
missile(n).targeted=m
missile(m).targeted=n
missile(m).launch_pad=launch_from
else
if missile(missile(n).targeted).launch_pad<>launch_from
m=launch_rocket(launch_from,n)
rocketAI2(n,m)
missile(n).targeted=m
missile(m).targeted=n
endif
endif
` endif
else
if missile(missile(n).targeted).exist=0
missile(n).targeted=0
endif
endif
endif
if missile(n).side=2
if missile(n).targeted>0
if missile(missile(n).targeted).exist=0
missile(n).exist=0
else
rocketAI2(missile(n).targeted,n)
endif
endif
endif
endif
next n
endfunction
function launch_rocket(launch_pad_num,target_missile)
m=free_missile()
missile(m).exist=1
missile(m).p.x=launch_pad(launch_pad_num).p.x
missile(m).p.y=launch_pad(launch_pad_num).p.y
angle#=atanfull(missile(target_missile).p.y-launch_pad(launch_pad_num).p.y,missile(target_missile).p.x-launch_pad(launch_pad_num).p.x)
missile(m).v.x=0
missile(m).v.y=200*sin(angle#)
missile(m).angle=angle#
missile(m).thrust=1400
missile(m).side=2
endfunction m
function shoot_missile(px#,py#,vx#,vy#)
m=free_missile()
missile(m).exist=1
missile(m).p.x=px#
missile(m).p.y=py#
missile(m).v.x=vx#
missile(m).v.y=vy#
missile(m).angle=atanfull(vy#,vx#)
missile(m).thrust=10
missile(m).targeted=0
missile(m).side=1
endfunction
function free_missile()
for n=1 to missile_amount
if missile(n).exist=0
exitfunction n
endif
next n
endfunction -1
function rocketAI2(target_missile,my_missile)
missile(my_missile).angle=rocketAI(missile(target_missile).p.x,missile(target_missile).p.y,missile(target_missile).v.x,missile(target_missile).v.y,missile(target_missile).angle,missile(target_missile).thrust,missile(my_missile).p.x,missile(my_missile).p.y,missile(my_missile).v.x,missile(my_missile).v.y,missile(my_missile).angle,missile(my_missile).thrust,turnspeed#)
endfunction hit_time#
function rocketAI(tx#,ty#,tvx#,tvy#,tangle#,ta#,x#,y#,vx#,vy#,angle#, a#,turnspeed#)
dx#=tx#-x#
dy#=ty#-y#
vx#=vx#-tvx#
vy#=vy#-tvy#
tax#=ta#*cos(tangle#)
tay#=ta#*sin(tangle#)
ax#=dx#
ay#=dy#
total#=sqrt(ax#^2+ay#^2)
ax#=ax#*A#/total#
ay#=ay#*A#/total#
`we iterate 15 times
for n=1 to 10
`given an x-acceleration, this will find the time it takes to get to the target's x coordinate
qa#=ax#/2
qb#=vx#
if qb#=0 then qb#=0.0001`otherwise weird things happen when vx#=0
qc#=x#-tx#
in#=qb#^2-4*qa#*qc#
redo=0
if in#<0 then in#=0.0;redo=1
time1#=(-qb#+sqrt(in#))/(2*qa#)
`we want a positive time, so we try something else:
if time1#<0.0 or redo=1
ax#=0-ax#
qa#=0-qa#
qb#=0-qb#
qc#=0-qc#
in#=qb#^2-4*qa#*qc#
if in#<0 then in#=0.0
time1#=(-qb#+sqrt(in#))/(2*qa#)
endif
`now do the same for the y-component
qa#=ay#/2
qb#=vy#
if qb#=0 then qb#=0.0001
qc#=y#-ty#
in#=qb#^2-4*qa#*qc#
redo=0
if in#<0 then in#=0.0;redo=1
time2#=(-qb#+sqrt(in#))/(2*qa#)
if time2#<0.0 or redo=1
ay#=0-ay#
qa#=0-qa#
qb#=0-qb#
qc#=0-qc#
in#=qb#^2-4*qa#*qc#
if in#<0 then in#=0.0
time2#=(-qb#+sqrt(in#))/(2*qa#)
endif
`average out the times
hit_time#=(time1#+time2#)/2.0
`now based on the average time, find the x and y components of the acceleration
ax#=2.0*(tx#-x#-vx#*hit_time#)/hit_time#^2
ay#=2.0*(ty#-y#-vy#*hit_time#)/hit_time#^2
`make the accerleration the right amount
total#=sqrt(ax#^2+ay#^2)
ax#=ax#*A#/total#
ay#=ay#*A#/total#
`repeat
next n
ax#=ax#+tax#
ay#=ay#+tay#
targetangle#=atanfull(ay#,ax#)
angle#=changeangle(targetangle#,angle#,turnspeed#)
endfunction angle#