Rem DB Classic Programming Challenge Entry Rem 20 July 2007 Rem TDK_Man's Missile Command V3 Gosub Setup T1=Timer() T2=Timer() Do Mx=MouseX(): My=MouseY(): Mc=MouseClick() Sprite 1,Mx-16,My-16,Sight If Mc=1 And MissilesLeft>0 and BulletInFlight = False Then Gosub Fire_Bullet If BulletInFlight = True Then Gosub Move_Bullet If Released < EnemyMissiles Then Gosub DropMissiles If (Timer()-T1) >= EMissileSpeed And Released > 0 Then Gosub MoveEnemyMissiles: T1=Timer() If BangsGoing > 0 Then Gosub GrowExplosions If (Timer()-T2) >= 50 Then Gosub UpdateScores: T2=Timer() Sync Loop End Rem ************************************************************** Rem *** Procedures *** Rem ************************************************************** DropMissiles: rem If Released < EnemyMissiles Rem Not All Missiles Released For This Level Rem Cities Are Sprites 101 to 106 ReleaseOne = Rnd(MissileFrequency): Rem Only release periodically If ReleaseOne = 10 Rem OK To release another so select a target 101 - 106 TargetLocked=0 Repeat TargetCity = Rnd(5)+1 If Sprite Exist(TargetCity+100) Inc CurrentEnemyMissile: Rem Starts at 0 so first is number 1 TargetLocked=1 Inc Released Endif Until TargetLocked=1: Rem Target Exists Rem Missile Start X/Y Position EMissilesSlot(CurrentEnemyMissile) = 1: Rem This slot in use Rem Missile End X/Y Position MX#(CurrentEnemyMissile) = Rnd(640): Rem Enemy Missile X Start Position MY#(CurrentEnemyMissile) = 32.0: Rem Enemy Missile Y Start Position MEndPointX = Sprite X(TargetCity+100)+16 MEndPointY = Sprite Y(TargetCity+100)+9 MXDist# = ABS(MEndPointX-MX#(CurrentEnemyMissile)) MYDist# = ABS(MEndPointY-MY#(CurrentEnemyMissile)) Sprite 300+CurrentEnemyMissile,MX#(CurrentEnemyMissile),MY#(CurrentEnemyMissile),EMissile XStep#(CurrentEnemyMissile) = (MXDist#/MYDist#): Rem *MissileSpeed#(CurrentEnemyMissile) If MX#(CurrentEnemyMissile) > MEndPointX Then XStep#(CurrentEnemyMissile) = 0-XStep#(CurrentEnemyMissile) Endif rem Endif Return MoveEnemyMissiles: For N=1 To EnemyMissiles If EMissilesSlot(N) = 1: Rem Missile Exists MX#(N)=MX#(N)+XStep#(N) MY#(N)=MY#(N)+1 Sprite 300+N,MX#(N),MY#(N),EMissile If MY#(N) > 455 EMissilesSlot(N) = 0: Rem Empty Enemy Missile Slot Delete Sprite 300+N: Rem Delete Enemy Missile Endif CityHit = Sprite Collision(300+N,0) If CityHit > 100 and CityHit < 107 EMissilesSlot(N) = 0: Rem Empty Enemy Missile Slot Delete Sprite 300+N: Rem Delete Enemy Missile Sprite CityHit+50,Sprite X(CityHit),439,BaseExplosion Delete Sprite CityHit: Rem Delete City Sprite Endif Endif Next N Return UpdateScores: S$=Str$(Score) While Len(S$) < 6 S$="0"+S$ EndWhile If Score > Hiscore then Hiscore=Score HS$=Str$(HiScore) While Len(HS$) < 6 HS$="0"+HS$ EndWhile Set Current Bitmap 1 CLS 0 Text 10,0,"Score: "+S$ Text 490,0,"HiScore: "+HS$ Get Image Menu,0,0,639,31 Set Current Bitmap 0 Sprite 500,0,0,Menu Set Sprite 500,0,0 Return Move_Bullet: If XDist# > YDist#: Rem X axis is longest distance If Left=0 Sprite 50,X#,BulletPosY#,Missile Inc X#,Speed# Inc BulletPosY#,Ratio# If X# >= EndPointX: Rem Reached Target BulletInFlight = False Sprite 50,-100,100,Missile: Rem Place off-screen for collision purposes Rem Initiate Explosion - Sprites 201 - 210 For N2=1 To 10: Rem Max number of missiles this level If Explosions(N2,0)=0: Rem First Empty Slot Explosions(N2,0)=20: Rem Starting Sprite Scale Size Explosions(N2,1)=EndPointX-1: Rem initial explosion X position Explosions(N2,2)=EndPointY-1: Rem initial explosion Y position Sprite 200+N2,Explosions(N2,1)-4,Explosions(N2,2)-4,Explosion Scale Sprite 200+N2,Explosions(N2,0) Inc BangsGoing Exit Endif Next N2 Endif Else Sprite 50,X#,BulletPosY#,Missile Inc X#,Speed# Inc BulletPosY#,Ratio# If X# <= EndPointX: Rem Reached Target BulletInFlight = False Sprite 50,-100,100,Missile: Rem Place off-screen for collision purposes Rem Initiate Explosion - Sprites 201 - 210 For N2=1 To 10 If Explosions(N2,0)=0: Rem First Empty Slot Explosions(N2,0)=20: Rem Starting Sprite Scale Size Explosions(N2,1)=EndPointX-1: Rem initial explosion X position Explosions(N2,2)=EndPointY-1: Rem initial explosion Y position Sprite 200+N2,Explosions(N2,1)-4,Explosions(N2,2)-4,Explosion Scale Sprite 200+N2,Explosions(N2,0) Inc BangsGoing Exit Endif Next N2 Endif Endif Else: Rem Y axis is longest distance Sprite 50,BulletPosX#,Y#,Missile Inc Y#,Speed# Inc BulletPosX#,Ratio# If Y# <= EndPointY: Rem Reached Target BulletInFlight = False Sprite 50,-100,100,Missile: Rem Place off-screen for collision purposes Rem Initiate Explosion - Sprites 201 - 210 For N2=1 To 10 If Explosions(N2,0)=0: Rem First Empty Slot Explosions(N2,0)=20: Rem Starting Sprite Scale Size Explosions(N2,1)=EndPointX-1: Rem initial explosion X position Explosions(N2,2)=EndPointY-1: Rem initial explosion Y position Sprite 200+N2,Explosions(N2,1)-4,Explosions(N2,2)-4,Explosion Scale Sprite 200+N2,Explosions(N2,0) Inc BangsGoing Exit Endif Next N2 Endif Endif Return Fire_Bullet: EndPointX=Mx: EndPointY=My: Speed# = 8.0: Left=0: Up=0 BulletPosX# = SpritePosX: BulletPosY# = SpritePosY XDist# = ABS(EndPointX-SpritePosX) YDist# = ABS(EndPointY-SpritePosY) Show Sprite 50 BulletInFlight = True If XDist# > YDist#: Rem X axis is longest distance Ratio# = (YDist#/XDist#)*Speed# If EndPointX<BulletPosX# Then Speed#=0-Speed#: Left=1: Rem Bullet moving left If EndPointY<BulletPosY# Then Ratio#=0-Ratio#: Up=1: Rem Bullet moving up X# = BulletPosX#: Rem Start X position of bullet Else: Rem Y axis is longest distance Ratio# = (XDist#/YDist#)*Speed# If EndPointX<BulletPosX# Then Ratio#=0-Ratio#: Left=1: Rem Bullet moving left If EndPointY<BulletPosY# Then Speed#=0-Speed#: Up=1: Rem Bullet moving up Y# = BulletPosY#: Rem Start X position of bullet Endif Rem Remove a missile from base Paste Image MissileBlank,MissileLeftPos(MissilesLeft,0),MissileLeftPos(MissilesLeft,1) Dec MissilesLeft Return GrowExplosions: For M3=1 To MaxMissiles If Explosions(M3,0) <> 0 Rem If not zero then slot being used for explosion Explosions(M3,0) = Explosions(M3,0)+2: Rem increase sprite scale value Scale Sprite 200+M3,Explosions(M3,0): Rem increase sprite size Sprite 200+M3,Explosions(M3,1)-Sprite Width(200+M3)/2,Explosions(M3,2)-Sprite Height(200+M3)/2,Explosion Rem Check for Explosion Colliding With Enemy Missile MissileHit = Sprite Collision(200+M3,0): Rem object this explosion colliding with If MissileHit > 300 And MissileHit <= 340: Rem Enemy Missile Intercepted rem EMissiles(MissileHit-300) = 0 EMissilesSlot(MissileHit-300) = 0 Delete Sprite MissileHit Inc Score,50 Dec EnemyMissilesLeft If EnemyMissilesLeft = 0 Rem End Of Level Gosub RestartLevel EndOfLevel=True Endif Endif If Explosions(M3,0) >= 400: Rem Reached max size Dec BangsGoing Sprite 200+M3,-400,100,Explosion Explosions(M3,0) = 0 Scale Sprite 200+M3,Explosions(M3,0) Endif Endif If EndOfLevel=True Then Exit Next M3 Return RestartLevel: Ink RGB(255,0,0),0: Center Text 320,200,"LEVEL COMPLETE!" Ink RGB(255,255,255),0: Center Text 318,198,"LEVEL COMPLETE!" T=Timer() Repeat Mx=MouseX(): My=MouseY() Sprite 1,Mx-16,My-16,Sight Sync Until Timer()-T >= 3000 For N=201 To 220 If Sprite Exist(N) Sprite N,-500,0,Sprite Image(N) Endif Next N For N=101 To 106 If Sprite Exist(N) Sprite N,-500,0,Sprite Image(N) Inc Score,100 Endif Next N For N=151 To 250 If Sprite Exist(N) Sprite N,-500,0,Sprite Image(N) Endif Next N CLS: Sync Rem Set Up Next Screen Dec EMissileSpeed,10 If EMissileSpeed < 0 Then EMissileSpeed = 0 Inc EnemyMissiles,2 EnemyMissilesLeft = EnemyMissiles Dec MissileFrequency,10 If MissileFrequency < 50 Then MissileFrequency = 50 BangsGoing = 0 Released = 0 CurrentEnemyMissile = 0 BulletInFlight = False MaxMissiles = 10 MissilesLeft = MaxMissiles EndOfLevel=False For N=1 To 10: Rem MaxMissiles Explosions(N,0) = 0 Explosions(N,1) = -200 Explosions(N,2) = 0 EMissilesSlot(N) = 0 Next N Inc Level Ink RGB(255,0,0),0: Center Text 320,200,"GET READY FOR LEVEL "+Str$(Level)+"..." Ink RGB(255,255,255),0: Center Text 318,198,"GET READY FOR LEVEL "+Str$(Level)+"..." T=Timer() Repeat Mx=MouseX(): My=MouseY() Sprite 1,Mx-16,My-16,Sight Sync Until Timer()-T >= 3000 CLS Gosub BuildScreen T=Timer() Return BuildScreen: Rem Player Base Paste Image Base,0,SH-42 Rem Player Cities For N=0 To 2 Sprite N+101,N*64+72,438,City: Rem 101 - 103 Next N For N=0 To 2 Sprite N+104,N*64+408,438,City Next N Rem Player Gun Paste Image Gun,315,434 Rem Player Missile Sprite 50,318,431,Missile Rem Off-Screen Explosion Sprites For N=1 To 10 Explosions(N,0)=0 Sprite 200+N,-100,100,Explosion Scale Sprite 200+N,Explosions(N,0) Next N Rem Lives Left Icons For N=0 To Lives-1 Paste Image Lives,N*20+3,463 Next N TLX=316: TLY=450: Num=0: Count=1 For Ny=0 To 3 For Nx=0 To Num Paste Image NumMissiles, Nx*14+TLX,TLY MissileLeftPos(Count,0)=Nx*14+TLX MissileLeftPos(Count,1)=TLY Inc Count Next Nx Inc Num: Dec TLX,7: Inc TLY,3 Next Ny Return Setup: SW=640: SH=480 Set Display Mode SW,SH,16: Wait 100 Sync On: Sync Rate 0: CLS 0: Wait 100 Sync: Wait 100 Randomize Timer() Set Text Font "Comic Sans MS" Set Text Size 24 Set Text Transparent Hide Mouse Rem Image Numbers City = 100 Base = 101 Sight = 102 Gun = 103 Missile = 104 EMissile = 105 Explosion = 106 Lives = 107 NumMissiles = 108 LivesBlank = 109 MissileBlank = 110 Menu = 111 BaseExplosion = 112 Rem Game Variables SpritePosX = 318: SpritePosY = 431 Lives = 3 MaxMissiles = 10 MissilesLeft = MaxMissiles MSpeed# = 1.0 EnemyMissiles = 6 EnemyMissilesLeft = EnemyMissiles MissileFrequency = 50 EMissileSpeed = 150 CurrentEnemyMissile = 0 OldScore = -1 Score = 0 Level = 1 True = 1: False = 0 Dim Explosions(10,2) Dim MissileLeftPos(21,1) rem Dim EMissiles(40) Dim EMissilesSlot(40) Dim XStep#(20) Dim X#(20) Dim MLeft(20) Dim MX#(20) Dim MY#(20) Dim MBulletPosX#(20) Dim MBulletPosY#(20) For N=1 To 20 X#(N)=MSpeed# Next N Create Bitmap 1,640,480 Rem Image For City Sprites Ink RGB(45,50,184),0 For N=0 To 7 Width = 4 Top = Rnd(6)*2 Box N*4,Top,N*4+3,18 Next N Get Image City,0,0,32,18 Rem Image For Base Sprite CLS 0 Ink RGB(135,183,84),0 Box 0,SH-24,SW-1,SH-1 Box 0,SH-42,31,SH-1 Box SW-32,SH-42,SW-1,SH-1 Box 320-50,SH-30,320+50,SH-1 Box 320-34,SH-36,320+34,SH-1 Box 320-18,SH-42,320+16,SH-1 Get Image Base,0,SH-42,SW-1,SH-1 CLS 0 Get Image 500,0,0,639,31 Sprite 500,0,0,500 Rem Image For Gun Sprite CLS 0 Ink RGB(162,64,180),0 Box 0,0,8,1 Ink RGB(45,50,184),0 Box 0,2,8,3 Get Image Gun,0,0,9,4 Rem Image For Sight Sprite CLS 0 Ink RGB(155,0,0),0: Circle 16,15,15: Circle 16,16,15 Ink RGB(155,0,0),0 Circle 16,15,14: Circle 16,16,14 Ink RGB(170,0,0),0: Line 2,15,39,15: Line 2,17,39,17 Line 15,1,15,30: Line 17,1,17,30 Ink 0,0: Box 15,15,17,17 Get Image Sight,0,0,32,32 Rem Image For Bullet Sprite CLS 0 Ink RGB(255,255,255),0 Box 0,0,2,2 Get Image Missile,0,0,3,3 Rem Image For Enemy Missiles Sprites CLS 0 Ink RGB(255,0,255),0 Dot 0,0: Dot 3,0: Dot 0,3: Dot 3,3 Box 1,1,2,2 Get Image EMissile,0,0,4,4 Rem Image For Explosion Sprite CLS 0 R=255: G=255: B=0 For N=1 To 14 Ink RGB(R,G,B),0 Circle 16,16,N Circle 16,17,N Dec G,16 Next N Blur Bitmap 1,1 Get Image Explosion,0,0,32,32 Rem Image For Base Explosion Sprite CLS 0 R=255: G=31: B=100 For N=1 To 14 Ink RGB(R,G,B),0 Circle 16,16,N Circle 16,17,N Inc G,16 Next N Blur Bitmap 1,1 Get Image BaseExplosion,0,0,32,16 Rem Image For Lives Indicator 16 x 8 CLS 0 Ink RGB(255,0,0),0: Box 0,0,15,7 Ink RGB(12,12,12),0: Box 1,1,14,6 Get Image Lives,0,0,16,8 CLS RGB(135,183,84) Get Image LivesBlank,0,0,16,8 Rem Image For Missiles Left Indicator 7 x 3 CLS 0 Ink RGB(12,12,12),0: Box 0,0,6,2 Ink RGB(255,255,255),0: Box 1,1,5,1 Get Image NumMissiles,0,0,7,3 CLS RGB(135,183,84) Get Image MissileBlank,0,0,7,3 Set Current Bitmap 0 Rem Now Build Scene On Main Screen... Gosub BuildScreen Ink RGB(255,255,255),0 Return