I've been watching a lot of Battlestar Galactica lately (maybe too much) and I ended up making this barebones spaceship fighter sim with enemy AI. I wouldn't call it a game because I didn't add weapons or a goal, just a minimal amount of physics, controls, camera, and AI. The AI fighters avoid asteroids very well (only rarely going into an asteroid) and they avoid each other most of the time while they all go after you.
Controls:
Pitch and Turn - mouse move. Center mouse on screen to stop all pitching and turning.
Roll - A/D
Thrust - W/S
Vertical movement thrusters - T/G
Left/Right movement thrusters - F/H
Edit: Decreased vertical and side thrusters by 33% and made the AI turn smoothly.
sync on
sync rate 0
set display mode 1024,768,32
color backdrop 0
cls
set camera range 1,2000
autocam off
global time as float
lasttimer=timer()
type xyz
x as float
y as float
z as float
endtype
type ship_type
v as xyz
health as float
typ as string
object
exist
turnspeed as float
rollspeed as float
pitchspeed as float
fthrust as float
rthrust as float
uthrust as float
vf as float
vr as float
vu as float
target
endtype
dim ship(50) as ship_type
make_ship(1,"Human")
position object ship(1).object,rnd(500)+250,rnd(500)+250,rnd(500)+250
for n=2 to 30
make_ship(n,"AI")
position object ship(n).object,rnd(500)+250,rnd(500)+250,rnd(500)+250
next n
type asteroid_type
object
exist
size as float
endtype
dim asteroid(100) as asteroid_type
for n=1 to 100
o=freeobj()
asteroid(n).object=o
asteroid(n).exist=1
asteroid(n).size=100+rnd(50)
make object sphere o,asteroid(n).size
scale object o,rnd(100)+50,rnd(100)+50,rnd(100)+50
position object o,rnd(1000),rnd(1000),rnd(1000)
next n
controlship=1
viewship=1
do
set cursor 0,0
print "FPS:",screen fps()
time=(timer()-lasttimer)*0.001
lasttimer=timer()
gosub inpt
gosub physics
gosub camera
gosub ai
sync
loop
function make_ship(num,typ$)
o=freeobj()
ship(num).exist=1
ship(num).v.x=0
ship(num).v.y=0
ship(num).v.z=0
ship(num).typ=typ$
ship(num).object=o
make object box o,2,1,3
ship(num).health=100
endfunction
function freeobj()
repeat
inc o
until object exist(o)=0
endfunction o
inpt:
ship(controlship).turnspeed=mousex()-screen width()/2.0
ship(controlship).pitchspeed=mousey()-screen height()/2.0
ship(controlship).rollspeed=curvevalue((keystate(32)-keystate(30))*180,ship(controlship).rollspeed,50)
ship(controlship).fthrust=curvevalue((keystate(17)*2.0-keystate(31)*1.0)*0.3,ship(controlship).fthrust,70)
ship(controlship).rthrust=curvevalue((keystate(35)-keystate(33))*0.2,ship(controlship).rthrust,70)
ship(controlship).uthrust=curvevalue((keystate(20)-keystate(34))*0.2,ship(controlship).uthrust,70)
return
physics:
for s=1 to 50
if ship(s).exist=1
o=ship(s).object
turn object right o,ship(s).turnspeed*time
pitch object down o,ship(s).pitchspeed*time
roll object right o,ship(s).rollspeed*time
position object o,object position x(o)+ship(s).v.x*time,object position y(o)+ship(s).v.y*time,object position z(o)+ship(s).v.z*time
fx#=object position x(o)
fy#=object position y(o)
fz#=object position z(o)
move object o,1
fx#=object position x(o)-fx#
fy#=object position y(o)-fy#
fz#=object position z(o)-fz#
move object o,-1
rx#=object position x(o)
ry#=object position y(o)
rz#=object position z(o)
move object right o,1
rx#=object position x(o)-rx#
ry#=object position y(o)-ry#
rz#=object position z(o)-rz#
move object right o,-1
ux#=object position x(o)
uy#=object position y(o)
uz#=object position z(o)
move object up o,1
ux#=object position x(o)-ux#
uy#=object position y(o)-uy#
uz#=object position z(o)-uz#
move object up o,-1
ship(s).vf=fx#*ship(s).v.x+fy#*ship(s).v.y+fz#*ship(s).v.z
ship(s).vr=rx#*ship(s).v.x+ry#*ship(s).v.y+rz#*ship(s).v.z
ship(s).vu=ux#*ship(s).v.x+uy#*ship(s).v.y+uz#*ship(s).v.z
ship(s).v.x=ship(s).v.x+ship(s).fthrust*fx#+ship(s).rthrust*rx#+ship(s).uthrust*ux#
ship(s).v.y=ship(s).v.y+ship(s).fthrust*fy#+ship(s).rthrust*ry#+ship(s).uthrust*uy#
ship(s).v.z=ship(s).v.z+ship(s).fthrust*fz#+ship(s).rthrust*rz#+ship(s).uthrust*uz#
ship(s).v.x=ship(s).v.x*0.9999
ship(s).v.y=ship(s).v.y*0.9999
ship(s).v.z=ship(s).v.z*0.9999
endif
next s
return
camera:
if viewship>0
o=ship(viewship).object
fx#=object position x(o)
fy#=object position y(o)
fz#=object position z(o)
move object o,1
fx#=object position x(o)-fx#
fy#=object position y(o)-fy#
fz#=object position z(o)-fz#
move object o,-1
rx#=object position x(o)
ry#=object position y(o)
rz#=object position z(o)
move object right o,1
rx#=object position x(o)-rx#
ry#=object position y(o)-ry#
rz#=object position z(o)-rz#
move object right o,-1
ux#=object position x(o)
uy#=object position y(o)
uz#=object position z(o)
move object up o,1
ux#=object position x(o)-ux#
uy#=object position y(o)-uy#
uz#=object position z(o)-uz#
move object up o,-1
o=ship(viewship).object
ink rgb(0,255,0),0
box screen width()/2.0-2,screen height()/2.0-2,screen width()/2.0+2,screen height()/2.0+2
position camera object position x(o),object position y(o), object position z(o)
set camera to object orientation o
pitch camera down 5
move camera -10
cx#=camera position x()
cy#=camera position y()
cz#=camera position z()
position camera object position x(o),object position y(o), object position z(o)
point camera object position x(o)+ship(viewship).v.x,object position y(o)+ship(viewship).v.y, object position z(o)+ship(viewship).v.z
speed#=sqrt(ship(viewship).v.x^2+ship(viewship).v.y^2+ship(viewship).v.z^2)
move camera -2*speed#/200.0
cx2#=camera position x()
cy2#=camera position y()
cz2#=camera position z()
set camera to object orientation o
wx#=cx2#
wy#=cy2#
wz#=cz2#
wx#=(cx#+cx2#)/2.0
wy#=(cy#+cy2#)/2.0
wz#=(cz#+cz2#)/2.0
dx#=wx#-object position x(o)
dy#=wy#-object position y(o)
dz#=wz#-object position z(o)
lz#=dx#*fx#+dy#*fy#+dz#*fz#
lx#=dx#*rx#+dy#*ry#+dz#*rz#
ly#=dx#*ux#+dy#*uy#+dz#*uz#
d#=sqrt(dx#^2+dy#^2+dz#^2)
nx#=dx#/d#
ny#=dy#/d#
nz#=dz#/d#
wx#=wx#+(10-d#)*nx#
wy#=wy#+(10-d#)*ny#
wz#=wz#+(10-d#)*nz#
print "Speed along relative Z axis:",ship(viewship).vf
print "Speed along relative X axis:",ship(viewship).vr
print "Speed along relative Y axis:",ship(viewship).vu
position camera wx#,wy#,wz#
set camera to object orientation o
turn camera left atanfull(lx#,-lz#)
pitch camera down atanfull(ly#,sqrt(lx#^2+lz#^2))
line screen width()/2.0,screen height()/2.0,screen width()/2.0+ship(viewship).vr,screen height()/2.0-ship(viewship).vu
ink rgb(255,0,0),0
line screen width()/2.0,screen height()/2.0,screen width()/2.0,screen height()/2.0-ship(viewship).vf
for n=1 to 50
if ship(n).exist=1
o=ship(n).object
if object in screen(o)
ink rgb(255,0,0),0
box object screen x(o)-2,object screen y(o)-2,object screen x(o)+2,object screen y(o)+2
endif
endif
next n
endif
return
ai:
for s=1 to 50
if ship(s).exist=1
if ship(s).typ="AI"
o=ship(s).object
if ship(s).target=0 or ship(ship(s).target).exist=0
mind2#=-1
for s2=1 to 50
if ship(s2).exist and ship(s2).typ="Human"
o2=ship(s2).object
d2#=(object position x(o2)-object position x(o))^2+(object position y(o2)-object position y(o))^2+(object position z(o2)-object position z(o))^2
if mind2#=-1
mind2#=d2#
mins=s2
else
if d2#<mind2#
mind2#=d2#
mins=s2
endif
endif
endif
next s2
ship(s).target=mins
endif
t_o=ship(ship(s).target).object
dx#=object position x(t_o)-object position x(o)
dy#=object position y(t_o)-object position y(o)
dz#=object position z(t_o)-object position z(o)
d#=sqrt(dx#^2+dy#^2+dz#^2)
nx#=dx#/d#
ny#=dy#/d#
nz#=dz#/d#
forcex#=nx#
forcey#=ny#
forcez#=nz#
for a=1 to 100
if asteroid(a).exist=1
a_o=asteroid(a).object
dx#=object position x(a_o)-object position x(o)
dy#=object position y(a_o)-object position y(o)
dz#=object position z(a_o)-object position z(o)
d#=sqrt(dx#^2+dy#^2+dz#^2)-asteroid(a).size*0.5
if d#<1 then d#=1
nx#=dx#/d#
ny#=dy#/d#
nz#=dz#/d#
a#=ship(s).v.x*nx#+ship(s).v.y*ny#+ship(s).v.z*nz#
if a#<0.5 then a#=0.5
forcex#=forcex#-asteroid(a).size*0.01*nx#/d#^2*a#
forcey#=forcey#-asteroid(a).size*0.01*ny#/d#^2*a#
forcez#=forcez#-asteroid(a).size*0.01*nz#/d#^2*a#
endif
next a
for s2=1 to 50
if ship(s2).exist=1
s_o=ship(s2).object
dx#=object position x(s_o)-object position x(o)
dy#=object position y(s_o)-object position y(o)
dz#=object position z(s_o)-object position z(o)
d#=sqrt(dx#^2+dy#^2+dz#^2)
nx#=dx#/d#
ny#=dy#/d#
nz#=dz#/d#
a#=ship(s).v.x*nx#+ship(s).v.y*ny#+ship(s).v.z*nz#
if a#<1 then a#=1
a#=1
b#=30
forcex#=forcex#-b#*nx#/d#^2*a#
forcey#=forcey#-b#*ny#/d#^2*a#
forcez#=forcez#-b#*nz#/d#^2*a#
endif
next s2
fx#=object position x(o)
fy#=object position y(o)
fz#=object position z(o)
move object o,1
fx#=object position x(o)-fx#
fy#=object position y(o)-fy#
fz#=object position z(o)-fz#
move object o,-1
rx#=object position x(o)
ry#=object position y(o)
rz#=object position z(o)
move object right o,1
rx#=object position x(o)-rx#
ry#=object position y(o)-ry#
rz#=object position z(o)-rz#
move object right o,-1
ux#=object position x(o)
uy#=object position y(o)
uz#=object position z(o)
move object up o,1
ux#=object position x(o)-ux#
uy#=object position y(o)-uy#
uz#=object position z(o)-uz#
move object up o,-1
dx#=forcex#
dy#=forcey#
dz#=forcez#
lz#=dx#*fx#+dy#*fy#+dz#*fz#
lx#=dx#*rx#+dy#*ry#+dz#*rz#
ly#=dx#*ux#+dy#*uy#+dz#*uz#
` print lx#
` print ly#
` print lz#
rvx#=(ship(s).v.x-ship(ship(s).target).v.x)
rvy#=(ship(s).v.y-ship(ship(s).target).v.y)
rvz#=(ship(s).v.z-ship(ship(s).target).v.z)
rvf#=fx#*rvx#+fy#*rvy#+fz#*rvz#
rvr#=rx#*rvx#+ry#*rvy#+rz#*rvz#
rvu#=ux#*rvx#+uy#*rvy#+uz#*rvz#
ship(s).turnspeed=curvevalue( abs(lx#)/lx#*120,ship(s).turnspeed,20)
ship(s).pitchspeed=curvevalue(-abs(ly#)/ly#*120,ship(s).pitchspeed,20)
ship(s).rollspeed=90
ship(s).fthrust=abs(lz#)/lz#*0.6
if ship(s).fthrust<-0.3 then ship(s).fthrust=-0.3
ship(s).rthrust=(lx#-ship(s).vr*abs(rvr#)*0.01)*0.2
ship(s).uthrust=(ly#-ship(s).vu*abs(rvu#)*0.01)*0.2
endif
endif
next s
return