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