Code archives/Miscellaneous/Overhead Spaceship Game
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| This is the source code of my first Blitz game, Space Corps Armageddon. I've only had Blitz a day and this was the program I wrote to learn with so there is room for lots of improvement, i've not commented very well as this was just a quicky game and isn't very long. The full game and media can be downloaded from http://www.bansheestudios.com | |||||
Global music
Global musicChannel
; Variable Declerations
Const shipsQ=100
Const bulletsQ=800
Const explosionsQ=5000
Const ringsQ=5
;Ship Graphic Size
Dim shipSize#(91) ;collision radius of ship type
;Ship Variables
Dim gfx(shipsQ) ;entity no.
Dim x#(shipsQ) ;position
Dim y#(shipsQ) ;position
Dim f#(shipsQ) ;facing
Dim a#(shipsQ) ;acceleration
Dim s#(shipsQ) ;speed
Dim t#(shipsQ) ;top speed
Dim h#(shipsQ) ;handling
Dim w(shipsQ,1) ;weapon Type
Dim wAmmo(shipsQ,1) ;weaponAmmo
Dim wDelay(shipsQ,1) ;weapon fire speed counter
Dim wMaxDelay(shipsQ,1) ;weapon fire speed constant
Dim mHp(shipsQ) ;original hit points
Dim hp(shipsQ) ;hit points
Dim armour(shipsQ) ;armour
Dim size#(shipsQ) ;size of ship
Dim ai(shipsQ) ;-1 = player, >0 = skill
Dim aiState(shipsQ) ;0=combat, 1=gunnery
Dim targ(shipsQ) ;target of AI
Dim damagePuff(shipsQ) ;time since last damage dirty puff
Dim aggression#(shipsQ,shipsQ) ;hate list
Dim side(shipsQ) ;team of ship
Dim radarImage(shipsQ) ;radarDot
;Gameplay Variables
Global camera ;camera entity no.
Global camX#
Global camZ#
Global backdrop ;backdrop entity no.
Dim pieX#(360) ; precalculated sin
Dim pieZ#(360) ; precalculated cos
Global lastTime# ;last frame timer() index
Global gameSpeed# ;framerate based movement index
;Weapon Variables
Global weaponCntr ;weapon entity last used
Dim weapGfx(bulletsQ) ;entity no.
Dim weapLife#(bulletsQ) ;weapon lifespan
Dim weapX#(bulletsQ) ;position
Dim weapY#(bulletsQ) ;position
Dim weapF#(bulletsQ) ;rotation
Dim weapID(bulletsQ) ;owner
Dim weapPay(bulletsQ) ;payload
Dim weapEmmitter#(bulletsQ) ;flame emmitter Frequency
Dim weapEmmitTime#(bulletsQ) ;flame emmitter Timer
Dim weapSpd#(bulletsQ) ;weapon speed
Dim weapAcc#(bulletsQ) ;weapon acceleration
Dim weapTrack(bulletsQ) ;weapon Tracking
Dim weapHoming#(bulletsQ) ;weapon Homing
Global redLaser ;brush no. of weapon
Global greenLaser ;brush no. of weapon
Global blueLaser ;brush no. of weapon
Global missile ;brush no. of weapon
Global torpedo ;brush no. of weapon
Global bomb ;brush no. of weapon
Global massDriver ;brush no. of weapon
Global xeonLaser ;brush no. of weapon
;Explosion Variables
Global expCntr ;explosion entity last used
Dim expBrush(25) ;brush no. of explosion animation
Dim expGfx(explosionsQ) ;entity no.
Dim expFrame(explosionsQ) ;frame displayed
Dim expFrameDelay#(explosionsQ) ;frame timer
;Ring Burst Variables
Global ringCntr ;ring entity last used
Dim ringGfx(ringsQ) ;entity no.
Dim ringLife#(ringsQ) ;ring duration counter
;Sound Variables
Global laserSnd
Global missileSnd
Global massSnd
Global xeonSnd
Global bangSnd
Dim impactSnd(5)
;menu
Dim logoG(25)
Global menuActive
Global menu
Global titleScreen
Global radar
Global hud
Global score
Global defeat
Global bronze
Global silver
Global gold
Global playerSpawn
Global redTime
Global blueTime
Global blueQty
Global redQty
Global powerTimer
Global redShips
Global blueShips
Global redSpawnSpeed
Global blueSpawnSpeed
;powerUps
Dim powerX(10)
Dim powerY(10)
Dim powerT(10)
Dim powerGfx(10)
Dim powerBrush(3)
Global powerCntr
Global playerShipHull
; Program Initialisation
init() ;setup display
initHud() ;setup HUD interface
readShipSizeFile(); setup ship size data array
initFacing() ;calculate pie
menuActive=10000
; Main Loop
gameTimer()
Repeat
gameTimer()
If KeyDown(1) Then End
respawn()
For sh=shipsQ To 2 Step-1
If hp(sh)>0
camTrack=sh
If side(sh)=1
blueQty=blueQty+1
Else
redQty=redQty+1
EndIf
aiCombat(sh)
move(sh)
EndIf
Next
If hp(1)>0
camTrack=1
blueQty=blueQty+1
control(1)
move(1)
pickups()
playerSpawn=10000
Else
playerSpawn=playerSpawn -gameSpeed
If playerSpawn<0 Then blueTime=99999999
EndIf
bullets()
explosions()
rings()
camera(camTrack)
Forever
Function respawn()
If redShips>0 And redQty<50
redTime=redTime +gameSpeed
If redTime>redSpawnSpeed
redTime=0
id=findFreeShip(2)
If id>0
redShips=redShips-1
initShip(id,Rnd(1,91),2)
x(id)=Rnd(40)-Rnd(40)
y(id)=50
f(id)=Rnd(90,270)
EndIf
EndIf
EndIf
If blueShips>0 And blueQty<50
blueTime=blueTime +gameSpeed
If blueTime>blueSpawnSpeed
blueTime=0
If playerSpawn<0
id=findFreeShip(1)
Else
id=findFreeShip(2)
EndIf
If id>1
initShip(id,Rnd(1,91),1)
ai(id)=-1
Else
If id>0
playerShipHull=playerShipHull-1
If playerShipHull<1 Then playerShipHull=1
initShip(id,playerShipHull,1)
EndIf
EndIf
If id>0
blueShips=blueShips-1
x(id)=Rnd(40)-Rnd(40)
y(id)=-50
f(id)=Rnd(90,270)
EndIf
EndIf
EndIf
powerTimer=powerTimer +gameSpeed
If powerTimer>30000
powerTimer=0
n=Rnd(2,shipsQ)
If hp(n)>0 Then placePowerUp(n)
EndIf
redQty=0
blueQty=0
End Function
Function findFreeShip(strt)
ret=0
For id=strt To shipsQ
If hp(id)<1
Ret=id
id=shipsQ+1
EndIf
Next
Return ret
End Function
Function camera(camTrack)
camX=x(camTrack)
If camX<-32.0
camX=-32.0
Else
If camX>32.0
camX=32.0
EndIf
EndIf
camZ=y(camTrack)
If camZ<-40.0
camZ=-40.0
Else
If camZ>40.0
camZ=40.0
EndIf
EndIf
PositionEntity camera,camX,camZ,0
RenderWorld
If menuActive=>10000
If redQty=0 Or blueQty=0 Then menuActive=0
If menuActive<30000
For combat=2 To 6
initShip(combat,Rnd(1,91),2)
initShip(combat+5,Rnd(1,91),1)
Next
menuActive=30000
EndIf
DrawImage menu,432,282
If GetKey()>0
menuActive=0
begin()
EndIf
Else
If redQty+redShips<1
If menuActive=0 Then musicChannel=PlaySound(music)
menuActive=menuActive +gameSpeed
FlushKeys
If blueQty+blueShips<10
DrawImage bronze,361,299
Else
If blueQty+blueShips<20
DrawImage silver,361,299
Else
DrawImage gold,361,299
EndIf
EndIf
Text 506,447,"Score "+score
Else
If blueQty+blueShips<1
If menuActive=0 Then musicChannel=PlaySound(music)
FlushKeys
menuActive=menuActive +gameSpeed
DrawImage defeat,361,299
Text 506,447,"Score "+score
Else
If hp(1)>0 Or blueShips<1
DrawImage hud,10,10
Color 255,255,0
Text 23,76,"Missiles "+wAmmo(camTrack,1),0,1
Text 158,55,"Hull",1
Text 158,75,hp(camTrack)+"/"+mHp(camTrack),1
Color 0,0,255
Text 76,88,"Blue "+blueQty
Text 128,124,blueShips,1,1
Color 255,0,0
r$=("Red "+redQty)
Text 241-StringWidth(r$),88,r$
Text 190,124,redShips,1,1
Color 255,255,255
r$="Score "+score
Text 293-StringWidth(r$),76,r$,0,1
Else
DrawImage titleScreen,512-160,384-128
Text 512,384+98,"Respawn in "+(playerSpawn/1000)+"s",1
EndIf
EndIf
EndIf
EndIf
Text 10,748,"http://www.bansheestudios.com"
fps$=Int(1000/gameSpeed)+" fps"
Text 1014-StringWidth(fps$),748,fps$
radar(camTrack)
Flip 0
End Function
Function radar(camTrack)
DrawImage radar,820,5
For sh=1 To shipsQ
If hp(sh)>0
If sh<>camTrack
rng#=range2D(x(camTrack),y(camTrack),x(sh),y(sh))
If rng#<=44
bearing=f(camTrack)-ATan2(x(camTrack)-x(sh),y(camTrack)-y(sh))
While bearing<0
bearing=bearing+360
Wend
While bearing>360
bearing=bearing-360
Wend
xPos=pieX(bearing)*rng#
yPos=pieZ(bearing)*rng#
DrawImage radarImage(sh),917+xPos,97+yPos
EndIf
EndIf
EndIf
Next
End Function
; Realtime - Ship Functions
Function control(id) ;accept player control
If KeyDown(200) ;speed control
s(id)=s(id)+ (a(id) * gameSpeed#)
If s(id)>t(id) Then s(id)=t(id)
Else
If KeyDown(208)
s(id)=s(id)- (a(id) * gameSpeed)
If s(id)<0 Then s(id)=0
EndIf
EndIf
If KeyDown(203) ;bearing control
f(id)=f(id)- (h(id) * gameSpeed)
If f(id)<0 Then f(id)=f(id)+360
Else
If KeyDown(205)
f(id)=f(id)+ (h(id) * gameSpeed)
If f(id)>360 Then f(id)=f(id)-360
EndIf
EndIf
If wDelay(id,0)<0 ;main weapon delay
If KeyDown(57)
If wAmmo(id,0)<>0
wAmmo(id,0)=wAmmo(id,0)-1
wDelay(id,0)=wMaxDelay(id,0)
fireWeapon(id,0)
EndIf
EndIf
Else
wDelay(id,0)=wDelay(id,0) -gameSpeed
EndIf
If wDelay(id,1)<0 ;secondary weapon delay
If KeyDown(29)
If wAmmo(id,1)<>0
wAmmo(id,1)=wAmmo(id,1)-1
wDelay(id,1)=wMaxDelay(id,1)
fireWeapon(id,1)
EndIf
EndIf
Else
wDelay(id,1)=wDelay(id,1) -gameSpeed
EndIf
End Function
Function aiCombat(id) ;artificial intelligence
If hp(targ(id))<1 ;target acquisition
targ(id)=0
selectTarget(id)
EndIf
If targ(id)=0
SelectTarget(id)
Else
If aiState(id)<2 ;fighting AI
facing=Int(f(targ(id)))
aheadX#=x(targ(id))+ (pieX(facing) * s(targ(id)) * 500)
aheadZ#=y(targ(id))+ (pieZ(facing) * s(targ(id)) * 500)
Else
If aiState(id)=2 ;evasion AI
facing=f(targ(id))+90
If facing>360 Then facing=facing-360
Else
If aiState(id)=3
facing=f(targ(id))-90
If facing<0 Then facing=facing+360
EndIf
EndIf
aheadX#=x(targ(id))+ (pieX(facing) * 1500)
aheadZ#=y(targ(id))+ (pieZ(facing) * 1500)
EndIf
bearing=ATan2( aheadX-x(id) , aheadZ-y(id) )-f(id) ;AI aiming parameters
While bearing>360
bearing=bearing-360
Wend
While bearing<0
bearing=bearing+360
Wend
rng#=range2D( x(id),y(id) , aheadX,aheadZ )
If rng<10 ;range control
top#=(t(id)*(rng/10))-.0015
Else
top#=t(id)-.0015
EndIf
If top<=0
aiState(id)=2+Rnd(0,1)
top=0
EndIf
If s(id)>top
s(id)=s(id)- (a(id) * gameSpeed)
If s(id)<0 Then s(id)=0
Else
If aiState(id)=1 ;speed Control
s(id)=s(id)- (a(id) * gameSpeed)
If s(id)<0 Then s(id)=0
Else
If aiState(id)=2 Or aiState(id)=3
s(id)=s(id)+ (a(id) * gameSpeed)
If s(id)>t(id) Then s(id)=t(id)
If rng<2 Then aiState(id)=0
Else
If bearing>250 Or bearing<120
s(id)=s(id)+ (a(id) * gameSpeed#)
If s(id)>t(id) Then s(id)=t(id)
Else
If bearing>135 And bearing<225
s(id)=s(id)- (a(id) * gameSpeed)
If s(id)<0 Then s(id)=0
EndIf
EndIf
EndIf
EndIf
EndIf
If bearing>180 ;bearing control
If bearing<355
f(id)=f(id)- (h(id) * gameSpeed)
If f(id)<0 Then f(id)=f(id)+360
EndIf
Else
If bearing>5
f(id)=f(id)+ (h(id) * gameSpeed)
If f(id)>360 Then f(id)=f(id)-360
EndIf
EndIf
If wDelay(id,0)<0 ;main Weapon
If bearing>340 Or bearing<20
aiState(id)=0
If rng<8
If wAmmo(id,0)<>0
wAmmo(id,0)=wAmmo(id,0)-1
wDelay(id,0)=wMaxDelay(id,0)
fireWeapon(id,0)
EndIf
EndIf
EndIf
EndIf
wDelay(id,0)=wDelay(id,0) -gameSpeed ;primary weapon timer also serves fighting AI state
If wDelay(id,0)<-5000
wDelay(id,0)=0
aiState(id)=1
targ(id)=0
EndIf
If wDelay(id,1)<0 ;secondary Weapon
If rng<5
If bearing>355 Or bearing<5
If wAmmo(id,1)<>0
wAmmo(id,1)=wAmmo(id,1)-1
wDelay(id,1)=wMaxDelay(id,1)
fireWeapon(id,1)
EndIf
EndIf
EndIf
Else
wDelay(id,1)=wDelay(id,1) -gameSpeed
EndIf
EndIf
End Function
Function selectTarget(id) ;target selection
facing=Int(f(id))
aimX#=x(id)+ (pieX(facing) * 2)
aimZ#=y(id)+ (pieZ(facing) * 2)
targetRange#=9999
For sh=1 To shipsQ
If hp(sh)>0
If side(sh)<>side(id)
If sh<>id
rng#=range2D( aimX,aimZ , x(sh),y(sh) ) - aggression(id,sh)
If rng<targetRange
targetRange=rng
targ(id)=sh
EndIf
EndIf
EndIf
EndIf
Next
End Function
Function move(id) ;process movements of each ship
If damagePuff(id)<0 ;damage trail
damagePuff(id)=damagePuff(id)+50
chnc=Rnd(0,mHp(id))
If chnc>hp(id)
factor#=1-Sin( (hp(id)*90) /mHp(id))
makeExplosion( x(id),y(id), factor# ,1)
EndIf
Else
damagePuff(id)=damagePuff(id) -gameSpeed
EndIf
facing=Int(f(id)) ;movement
x(id)=x(id)+ (pieX(facing) * s(id) * gameSpeed)
y(id)=y(id)+ (pieZ(facing) * s(id) * gameSpeed)
If x(id)<-40.0
x(id)=-40.0
Else
If x(id)>40.0
x(id)=40.0
EndIf
EndIf
If y(id)<-46.0
y(id)=-46.0
Else
If y(id)>46.0
y(id)=46.0
EndIf
EndIf
PositionEntity gfx(id),x(id),y(id),10
RotateSprite gfx(id),-f(id)
End Function
Function placePowerUp(id)
powerCntr=powerCntr+1
If powerCntr=11 Then powerCntr=1
pType=Rnd(1,3)
If pType=>1 And pType<=3
powerX(powerCntr)=x(id)
powerY(powerCntr)=y(id)
powerT(powerCntr)=pType
PaintEntity powerGfx(powerCntr),powerBrush(pType)
PositionEntity powerGfx(powerCntr),powerX(powerCntr),powerY(powerCntr),10.35
ShowEntity powerGfx(powerCntr)
EndIf
End Function
Function pickups()
For pick=1 To 10
If powerT(pick)>0
If range2D(x(1),y(1),powerX(pick),powerY(pick))<size(1)/2
Select powerT(pick)
Case 1
hp(1)=mHp(1)
Case 2
playerShipHull=playerShipHull+5
If playerShipHull>91 Then playerShipHull=91
initShip(1,playerShipHull,1)
Case 3
wAmmo(1,1)=wAmmo(1,1)+10
End Select
HideEntity powerGfx(pick)
powerT(pick)=0
EndIf
EndIf
Next
End Function
Function fireWeapon(id,weapon) ;called when a weapon is fired to choose which weapon to launch
bulletCounter()
Select w(id,weapon)
Case 1
fireRedLaser(id)
Case 2
fireGreenLaser(id)
Case 3
fireBlueLaser(id)
Case 4
fireMissile(id)
Case 5
fireTorpedo(id)
Case 6
fireBomb(id)
Case 7
fireMassDriver(id)
Case 8
fireXeonLaser(id)
End Select
End Function
Function bulletCounter()
safety=0
Repeat
weaponCntr=weaponCntr+1
If weaponCntr>bulletsQ Then weaponCntr=1
safety=safety+1
If safety>bulletsQ Then weapLife(weaponCntr)=-1
Until weapLife(weaponCntr)<=0
End Function
Function fireRedLaser(id) ;Create a red laser bullet
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=2000
weapPay(weaponCntr)=Rnd(1,4)
weapEmmitter(weaponCntr)=0
weapSpd(weaponCntr)=0.005
weapAcc(weaponCntr)=0
weapTrack(weaponCntr)=0
PaintEntity weapGfx(weaponCntr),redLaser
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound laserSnd
End Function
Function fireGreenLaser(id) ;Create a green laser bullet
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=4000
weapPay(weaponCntr)=Rnd(1,6)
weapEmmitter(weaponCntr)=0
weapSpd(weaponCntr)=0.005
weapAcc(weaponCntr)=0
weapTrack(weaponCntr)=0
PaintEntity weapGfx(weaponCntr),greenLaser
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound laserSnd
End Function
Function fireBlueLaser(id) ;Create a blue laser bullet
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=6000
weapPay(weaponCntr)=Rnd(1,8)
weapEmmitter(weaponCntr)=0
weapSpd(weaponCntr)=0.005
weapAcc(weaponCntr)=0
weapTrack(weaponCntr)=0
PaintEntity weapGfx(weaponCntr),blueLaser
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound laserSnd
End Function
Function fireMissile(id) ;Create a missile
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=6000
weapPay(weaponCntr)=Rnd(3,8)
weapEmmitter(weaponCntr)=15
weapSpd(weaponCntr)=s(id)*.5
weapAcc(weaponCntr)=0.00003
weapTrack(weaponCntr)=0
PaintEntity weapGfx(weaponCntr),missile
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound missileSnd
End Function
Function fireTorpedo(id) ;Create a torpedo
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=20000
weapPay(weaponCntr)=Rnd(5,12)
weapEmmitter(weaponCntr)=10
weapSpd(weaponCntr)=s(id)*.33
weapAcc(weaponCntr)=0.00001
weapHoming(weaponCntr)=0.04
PaintEntity weapGfx(weaponCntr),missile
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
facing=Int(f(id))
aimX#=x(id)+ (pieX(facing) * 2)
aimZ#=y(id)+ (pieZ(facing) * 2)
targetRange#=9999
For sh=1 To shipsQ
If hp(sh)>0
If side(sh)<>side(id)
If sh<>id
rng#=range2D( aimX,aimZ , x(sh),y(sh) )
If rng<targetRange
targetRange=rng
weapTrack(weaponCntr)=sh
EndIf
EndIf
EndIf
EndIf
Next
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound missileSnd
End Function
Function fireBomb(id) ;Create a bomb
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=30000
weapPay(weaponCntr)=Rnd(9,16)
weapEmmitter(weaponCntr)=5
weapSpd(weaponCntr)=s(id)*.25
weapAcc(weaponCntr)=0.000005
weapHoming(weaponCntr)=0.06
PaintEntity weapGfx(weaponCntr),bomb
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
facing=Int(f(id))
aimX#=x(id)+ (pieX(facing) * 2)
aimZ#=y(id)+ (pieZ(facing) * 2)
targetRange#=9999
For sh=1 To shipsQ
If hp(sh)>0
If side(sh)<>side(id)
If sh<>id
rng#=range2D( aimX,aimZ , x(sh),y(sh) )
If rng<targetRange
targetRange=rng
weapTrack(weaponCntr)=sh
EndIf
EndIf
EndIf
EndIf
Next
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound missileSnd
End Function
Function fireMassDriver(id) ;Create a mass driver bullet
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)+Rnd(5)-Rnd(5)
If weapF(weaponCntr)>360.0 Then weapF(weaponCntr)=weapF(weaponCntr)-360.0
If weapF(weaponCntr)<0.0 Then weapF(weaponCntr)=weapF(weaponCntr)+360.0
weapID(weaponCntr)=id
weapLife#(weaponCntr)=1000
weapPay(weaponCntr)=Rnd(1,8)
weapEmmitter(weaponCntr)=0
weapSpd(weaponCntr)=0.008
weapAcc(weaponCntr)=-0.000025
weapTrack(weaponCntr)=0
PaintEntity weapGfx(weaponCntr),massDriver
RotateSprite weapGfx(weaponCntr),-weapF(weaponCntr)
ShowEntity weapGfx(weaponCntr)
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound massSnd
End Function
Function fireXeonLaser(id) ;Create a xeon laser bullet
weapX#(weaponCntr)=x(id)
weapY#(weaponCntr)=y(id)
weapF(weaponCntr)=f(id)
weapID(weaponCntr)=id
weapLife#(weaponCntr)=6000
weapPay(weaponCntr)=Rnd(1,20)
weapEmmitter(weaponCntr)=0
weapSpd(weaponCntr)=0.005
weapAcc(weaponCntr)=0
weapTrack(weaponCntr)=0
PaintEntity weapGfx(weaponCntr),xeonLaser
RotateSprite weapGfx(weaponCntr),-f(id)
ShowEntity weapGfx(weaponCntr)
If range2D(x(id),y(id),camX,camZ)<5 Then PlaySound xeonSnd
End Function
;Realtime - Bullet & Particle Functions
Function bullets() ;move Bullets
For b=1 To bulletsQ
If weapLife(b)>0
weapLife(b)=weapLife(b)-gameSpeed#
If weapTrack(b)>0
bearing=ATan2( x(weapTrack(b))-weapX(b) , y(weapTrack(b))-weapY(b) ) - weapF(b)
While bearing>360
bearing=bearing-360
Wend
While bearing<0
bearing=bearing+360
Wend
If bearing>180
If bearing<355
weapF(b)=weapF(b) -(gameSpeed*weapHoming(b))
If weapF(b)<0.0 Then weapF(b)=weapF(b)+360.0
EndIf
Else
If bearing>5
weapF(b)=weapF(b) +(gameSpeed*weapHoming(b))
If weapF(b)>360.0 Then weapF(b)=weapF(b)-360.0
EndIf
EndIf
RotateSprite weapGfx(b),-weapF(b)
EndIf
For spd=1 To 2
weapSpd(b)=weapSpd(b)+weapAcc(b)
facing=Int(weapF(b))
weapX(b)=weapX(b) +(pieX(facing) * weapSpd(b) * gameSpeed)
weapY(b)=weapY(b) +(pieZ(facing) * weapSpd(b) * gameSpeed)
For sh=1 To shipsQ
If hp(sh)>0
If weapID(b)<>sh
If range2D(weapX(b),weapY(b),x(sh),y(sh))<size(sh)
If side(weapID(b))=side(sh)
targ(weapID(b))=0
aiState(weapID(b))=2+Rnd(1)
Else
weapLife(b)=0.0
bearing=Int(ATan2(weapX(b)-x(sh),weapY(b)-y(sh)))
While bearing>360
bearing=bearing-360
Wend
While bearing<0
bearing=bearing+360
Wend
If bearing=>315 Or bearing<45
damage=weapPay(b)-(armour(sh)+2)
Else
If bearing=>225 And bearing<315
damage=weapPay(b)-armour(sh)
Else
If bearing=>45 And bearing<135
damage=weapPay(b)-armour(sh)
Else
damage=(weapPay(b)+3)-armour(sh)
EndIf
EndIf
EndIf
If damage<0 Then damage=0
hp(sh)=hp(sh)-damage
If damage>2 Then aiState(sh)=2+Rnd(0,1)
aggression(sh,weapID(b))=aggression(sh,weapID(b)) +(damage*.1)
selectTarget(sh)
explosion#=(damage+1.0)/10
expX#=x(sh)+ ( pieX(bearing) * size(sh) )
expZ#=y(sh)+ ( pieZ(bearing) * size(sh) )
If hp(sh)<1
makeRing(sh)
makeExplosion(expX#,expZ#,1.0,0)
makeExplosion(x(sh),y(sh),size(sh)*5,0)
HideEntity gfx(sh)
If range2D(x(sh),y(sh),camX,camZ)<15 Then PlaySound bangSnd
If side(sh)=2
If weapID(b)=1 Or aggression(sh,1)>mHp(sh)*.3
score=score+mHp(sh)
placePowerUp(sh)
playerShipHull=playerShipHull+1
EndIf
redSpawnSpeed=redSpawnSpeed-500
If redSpawnSpeed<1000 Then redSpawnSpeed=1000
blueSpawnSpeed=blueSpawnSpeed+400
If blueSpawnSpeed>10000 Then blueSpawnSpeed=10000
Else
blueSpawnSpeed=blueSpawnSpeed-500
If blueSpawnSpeed<1000 Then blueSpawnSpeed=1000
redSpawnSpeed=redSpawnSpeed+400
If redSpawnSpeed>10000 Then redSpawnSpeed=10000
EndIf
Else
If damage>0
If weapID(b)=1 And side(sh)=2 Then score=score+damage
makeExplosion(expX#,expZ#,explosion,0)
If range2D(expX,expZ,camX,camZ)<7 Then PlaySound impactSnd(Rnd(1,5))
EndIf
EndIf
spd=3
sh=101
EndIf
EndIf
EndIf
EndIf
Next
Next
If weapLife(b)<=0
HideEntity weapGfx(b)
Else
PositionEntity weapGfx(b),weapX(b),weapY(b),10.00000001
If weapEmmitter(b)>0
weapEmmitTime(b)=weapEmmitTime(b) -gameSpeed
If weapEmmitTime(b)<0
weapEmmitTime(b)= weapEmmitter(b)
makeExplosion(weapX(b),weapY(b),0.3,1)
EndIf
EndIf
EndIf
EndIf
Next
End Function
Function makeExplosion(x#,y#,sz#,layer) ;create new explosion entity
expCntr=expCntr+1
If expCntr>explosionsQ Then expCntr=1
expFrame(expCntr)=1
expFrameDelay(expCntr)=50
If layer=0
PositionEntity expGfx(expCntr),x#,y#,9.85
Else
PositionEntity expGfx(expCntr),x#,y#,10.15
EndIf
ScaleSprite expGfx(expCntr),sz#,sz#
PaintEntity expGfx(expCntr),expBrush(1)
ShowEntity expGfx(expCntr)
End Function
Function explosions() ;animate explosion entities
For ex=1 To explosionsQ
If ExpFrame(ex)>0
expFrameDelay(ex)=expFrameDelay(ex)-gameSpeed
If expFrameDelay(ex)<0
expFrame(ex)=expFrame(ex)+1
If expFrame(ex)<=25
PaintEntity expGfx(ex),expBrush(expFrame(ex))
expFrameDelay(ex)=50
Else
expFrame(ex)=0
HideEntity expGfx(ex)
EndIf
EndIf
EndIf
Next
End Function
Function makeRing(id) ;make a ring burst
ringCntr=ringCntr+1
If ringCntr>ringsQ Then ringCntr=1
PositionEntity ringGfx(ringCntr),x(id),y(id),10
RotateEntity ringGfx(ringCntr),Rnd(-67,67),Rnd(-67,67),Rnd(-67,67)
ShowEntity ringGfx(ringCntr)
ringLife(ringCntr)=1
End Function
Function rings()
For ring=1 To ringsQ
If ringLife(ring)>0
ringLife(ring)=ringLife(ring) +gameSpeed
If ringLife(ring)<1000
scale#=ringLife(ring)*.05
ScaleEntity ringGfx(ring),scale,scale,scale
Else
ringLife(ring)=0
HideEntity ringGfx(ring)
EndIf
EndIf
Next
End Function
;UDF's
Function gameTimer() ;calculate time interlude between frames
time=Float(MilliSecs())
gameSpeed=time-lastTime
lastTime=time
End Function
Function range2D(ax#,az#,bx#,bz#)
dx#=Abs(ax#-bx#)
dz#=Abs(az#-bz#)
Return Sqr((dx#*dx#)+(dz#*dz#))
End Function
; Program Setup
Function init() ;setup graphics for game
;setup display
Graphics3D 1024,768
SetBuffer BackBuffer()
camera=CreateCamera()
intro()
;make a background
backdrop=LoadSprite("Backdrop/backdrop1.jpg")
PositionEntity backdrop,0,0,35
ScaleSprite backdrop,67,67
;setup weapons
redLaser=LoadBrush("Weapons/redLaser.png",2)
greenLaser=LoadBrush("Weapons/greenLaser.png",2)
blueLaser=LoadBrush("Weapons/blueLaser.png",2)
missile=LoadBrush("Weapons/missile.png",2)
torpedo=LoadBrush("Weapons/bomb2.png",2)
bomb=LoadBrush("Weapons/bomb1.png",2)
massDriver=LoadBrush("Weapons/massDriver.png",2)
xeonLaser=LoadBrush("Weapons/xeonLaser.png",2)
For weapon=1 To bulletsQ
weapGfx(weapon)=CreateSprite()
HideEntity weapGfx(weapon)
HandleSprite weapGfx(weapon),0,0
ScaleSprite weapGfx(weapon),0.34,0.34
Next
;setup explosion brushes
For ex=1 To 25
expBrush(ex)=LoadBrush("Explosion/dth"+Str(ex)+".bmp",2)
Next
;setup explosion entities
For ex=1 To explosionsQ
expGfx(ex)=CreateSprite()
RotateSprite expGfx(ex),Rnd(1.0,360.0)
HideEntity expGfx(ex)
EntityAlpha expGfx(ex),0.35
HandleSprite expGfx(ex),0,0
Next
;setup ring burst
For ring=1 To ringsQ
ringGfx(ring)=LoadSprite("Explosion/ringBurst.png",1)
SpriteViewMode ringGfx(ring),4
HideEntity ringGfx(ring)
EntityAlpha ringGfx(ring),0.4
Next
;powerUps
For power=1 To 10
powerGfx(power)=CreateSprite()
HideEntity powerGfx(power)
Next
laserSnd=LoadSound("SFX\laser.wav")
missileSnd=LoadSound("SFX\missileLaunch.wav")
massSnd=LoadSound("SFX\massDriver.wav")
xeonSnd=LoadSound("SFX\xeonLaser.wav")
bangSnd=LoadSound("SFX\bang1.wav")
impactSnd(1)=LoadSound("SFX\impact1.wav")
impactSnd(2)=LoadSound("SFX\impact2.wav")
impactSnd(3)=LoadSound("SFX\impact3.wav")
impactSnd(4)=LoadSound("SFX\impact4.wav")
impactSnd(5)=LoadSound("SFX\impact5.wav")
End Function
Function initFacing() ;calculate pie
For facing=0 To 360
pieX(facing)=Sin(facing)
pieZ(facing)=Cos(facing)
Next
End Function
Function initShip(id,class,team) ;create a ship
If gfx(id)>0 Then FreeEntity gfx(id)
If team=1
gfx(id)=LoadSprite("Ships\"+Str(class)+".png",2)
radarImage(id)=LoadImage("UI\blue.png")
Else
gfx(id)=LoadSprite("Ships\r"+Str(class)+".png",2)
radarImage(id)=LoadImage("UI\red.png")
EndIf
For clear=1 To shipsQ
aggression(id,clear)=0
Next
side(id)=team
a(id)=0.000006-(shipSize(class)*0.000003)
t(id)=0.012-shipSize(class)*0.006
h(id)=(0.15-(shipSize(class)*0.1))*1.3
size(id)=shipSize(class)
armour(id)=Int(shipSize(class)*3.5)
hp(id)=(shipSize(class)*100)+class
If id<>1 Then armour(id)=armour(id)-1
If armour(id)<0 Then armour(id)=0
f(id)=Rnd(1,360)
ai(id)=1
mhp(id)=hp(id)
If class<30
w(id,0)=1
wMaxDelay(id,0)=250-class
w(id,1)=4
wMaxDelay(id,1)=750-(class*3)
wAmmo(id,1)=size(id)*20
Else
If class<60
n=Rnd(1)
If n=0
w(id,0)=2
wMaxDelay(id,0)=250-class
Else
w(id,0)=8
wMaxDelay(id,0)=1000-(class*4)
EndIf
w(id,1)=5
wMaxDelay(id,1)=750-(class*3)
wAmmo(id,1)=size(id)*15
Else
n=Rnd(1)
If n=0
w(id,0)=3
wMaxDelay(id,0)=250-class
Else
w(id,0)=7
wMaxDelay(id,0)=150-(class*.67)
EndIf
w(id,1)=6
wMaxDelay(id,1)=1050-(class*4)
wAmmo(id,1)=size(id)*10
EndIf
EndIf
wAmmo(id,0)=-1
End Function
Function readShipSizeFile()
fileHandle=ReadFile("ShipSize.dat")
For sh=1 To 91
sizeX=ReadByte(fileHandle)
sizeZ=ReadByte(fileHandle)
shipSize(sh)=(sizeX+sizeZ)
shipSize(sh)=shipSize(sh)*0.01388888
Next
CloseFile fileHandle
End Function
Function initHud()
titleScreen=LoadImage("UI\SpaceCorpsTitle.png")
radar=LoadImage("UI\Radar.png")
hud=LoadImage("UI\hud.png")
bronze=LoadImage("UI\bronze.png")
silver=LoadImage("UI\silver.png")
gold=LoadImage("UI\gold.png")
defeat=LoadImage("UI\defeat.png")
menu=LoadImage("UI\menu.png")
powerBrush(1)=LoadBrush("UI\repair.png",2)
powerBrush(2)=LoadBrush("UI\upgrade.png",2)
powerBrush(3)=LoadBrush("UI\missile.jpg",2)
End Function
Function intro()
music=LoadSound("SFX\theme.wav")
LoopSound music
musicChannel=PlaySound(music)
logo=LoadBrush("UI\logo.png",2)
gameTimer()
For lo=1 To 25
logoG(lo)=CreateSprite()
ScaleSprite logoG(lo),64,25
EntityAlpha logoG(lo),.0004
PaintEntity logoG(lo),logo
Next
tim=0
shade#=0
gameTimer()
Repeat
gameTimer()
tim=tim +gameSpeed
shuddertim=tim
If Shuddertim>3000 Then shuddertim=3000
factor#=3000-shuddertim
For lo=1 To 25
xPos#=(Rnd(30.0)-Rnd(20.0) * factor) /3000
yPos#=(Rnd(30.0)-Rnd(20.0) * factor) /3000
PositionEntity logoG(lo),xPos,yPos,100
Next
RenderWorld
If tim>3000
shade=shade +(gameSpeed*.1)
If shade>255 Then shade=255
Color shade,shade,shade
Text 512,600,"Space Corps: Armageddon",1,1
EndIf
Flip 0
Until tim>4500
For lo=1 To 25
FreeEntity logoG(lo)
Next
FreeBrush logo
Cls
FlushKeys
End Function
Function begin()
StopChannel musicChannel
For id=1 To shipsQ
If gfx(id)>0
FreeEntity gfx(id)
gfx(id)=0
EndIf
hp(id)=-1
Next
For id=1 To weaponsQ
weapLife(id)=0
HideEntity weapGfx(id)
Next
SeedRnd MilliSecs()
playerShipHull=25
redSpawnSpeed=5000
blueSpawnSpeed=5000
redShips=99
blueShips=99
initShip(1,playerShipHull,1) ;make a ship
initShip(2,playerShipHull-5,2) ;make an enemy
ai(1)=-1
x(1)=Rnd(40)-Rnd(40)
y(1)=-65
f(1)=Rnd(90,270)
x(2)=Rnd(40)-Rnd(40)
y(2)=65
End Function |
Comments
| ||
| The key functions are: function gameTimer() This function calculates the "gameSpeed" variable which is the time in milliseconds between each frame update, this variable is then used throughout the program as the standards meens of incrementation. funciton respawn() This function pops new ships in to the game. It keeps track of numerous timers for different events and will create new ships and bonus'. function aiCombat() This is a complex function and deals with the rendering of the decision making processess. There are 3 aiStates() to know to understand this function: 0 = normal hunt & kill 1 = stationary hunt & kill (prevents endless circling) 2-3 = evasion AI function move() This function renders realtime data shared between AI & player entities, it also draws the ship sprites to the screen. function control() I offer no explanation for this one. function bullets() This is a massively complex function for such a simple task, but this is because it inter-relates into both the aiCombat() and the respawn(), aswell as handling the AI of the bullets themselves. The first section deals with WeapTrack() and is the AI routine for the homing missile and the torpedo's. The forNext spd() section deals with the bullet movement and is repeated twice for extra accuracy under slow frame rates, if the bullet is fired from the same team it interfaces with the aiState() in order to seperate the ships incase of a "hunter pack" forming behind a lone enemy, the function then goes on to calculate the armour facing and effect damage which can also impact the AI of enemies and adjust respawn timers as appropriate. function explosions() & function rings() These functions animate the particle effects in the game. function camera() This is effectively a display function and also handles the menus and dialogues within the game, the menu has been written using mutually exclusive states so that un-needed code is not checked for execution. This was done out of habbit and is meant to increase speed. All other functions are sub-functions and should be relatively simple and/or self explanatory. Please dont be shy to tell me i'm doing something wrong ! I'm still new to Blitz :) This source code is intellectual property of Banshee Studios and is given freely without limitations. |
| ||
| Hi, Great job!!! Thanks for share... |
| ||
A small optimisation:Function range2D(ax#,az#,bx#,bz#) dx#=Abs(ax#-bx#) dz#=Abs(az#-bz#) Return Sqr((dx#*dx#)+(dz#*dz#)) End FunctionCan be replaced with: Function range2D(ax#,az#,bx#,bz#) dx#=ax#-bx# dz#=az#-bz# Return Sqr((dx#*dx#)+(dz#*dz#)) End Function And I ran a timetest with your sourcecode, because I experienced some slowdowns with the exe. I found that when there is 100 ships active, the function bullets take out as much time as the rest of the code, no wonder: For all bullets For all ships is quite a heavy loop, but not heavy enought for me to see the slowdown when runnig the source code. Also the exe is smaller than a 1.87 B3D exe, have you upgraded to the latest version of B3D? Did you compile without debug on? Have you compressed the exe in some way? |
| ||
| yup I compiled it with the download version, having literally just bought and downloaded Blitz I did not realise that there was an update to download also, thanks for letting me know about the speed issue between versions, i'll recompile the .exe for the general public during the week when I get a chance. |
Code Archives Forum