Nostalgia: Missile Attack

Again, some nostalgia. I remember, that it was late 80s, when I had a game called “Missile Attack” for Amiga. It was shareware game priced at $5.

Many years ago I made just for fun my own implementation of this classic game in Blitz3D. For curiosity, if my memory serves me right, in Terminator II young John Connor is playing this kind of game in one part of the movie.

In this blog post is shortened version of my Missile Attack game. The code is quite messy. I hope there are not any horrible bugs in this old game. This is the first time the game sees the daylight.

Copy paste the code to Blitz3D and start playing, it’s really quite fun, though quite pointless. 🙂 No external files are needed.

ma_ingame

AppTitle "Missile Attack"
HidePointer

Graphics 640,480,32,2

SeedRnd MilliSecs()


fntArial20 = LoadFont("Arial",20)
fntCourier20 = LoadFont("courier",20,True)


SeedRnd MilliSecs()

Type missile
	Field x#,y#
	Field dx#,dy#
	Field origX#, origY#
	Field r,g,b
	Field ovalM
End Type

Type ammoCircle
	Field frame
	Field x,y
	Field hit
End Type


Type energyBar
	Field r#
	Field dr#
	Field g#
	Field dg#
	Field b#
	Field hit	
End Type

Type yellowFlash
	Field hit
End Type

gfxAim = CreateImage(25,25)
SetBuffer ImageBuffer(gfxAim)
Line 0,13,25,13
Line 13,0,13,25


gfxAmmo = CreateImage(72,72,72)


For q = 0 To 71							
	SetBuffer ImageBuffer (gfxAmmo,q)

	Origin ox#,oy#
	Color 0,0,255
	Oval 72/2,72/2,r#,r#,0

	ox# = ox# - 0.5
	oy# = oy# - 0.5
	r# = r# + 1


Next

gfxOval = CreateImage(15,15)
SetBuffer ImageBuffer(gfxOval)
Origin 0,0
Oval 0,0,15,15,0

SetBuffer BackBuffer()

.start
FlushKeys


For mssl.missile = Each missile
	Delete mssl
Next
		
For ammo.ammoCircle = Each ammoCircle
	Delete ammo
Next

For yc.yellowFlash = Each yellowFlash
	Delete yc
Next
		
For eb.energyBar = Each energyBar
	Delete eb
Next

eb.energyBar = New energyBar

divisor = 48

yellowFlashes = 0	; nr of yellow flashes

energyBarLen = 72
yellow = 0

maxMissiles = 0

r# = 1

orig# = 50
ox# = 0
oy# = 0


nr_of_missiles = 0
gameover = False
printInstr = False
printStr = False

extraEarned = False
print_fullDestr = True
big = False

SetBuffer BackBuffer()

Repeat
	Cls

	If KeyHit(1) Then	
		End
	EndIf	

			
	Color 255,0,0
	SetFont fntCourier20
	Text (640 - StringWidth("Missile Attack")) / 2,40,"Missile Attack"
			
	SetFont fntArial20
	Color 200,80,180
	Text (640 - StringWidth("Use mouse to shoot the missiles")) / 2, 100, "Use mouse to shoot the missiles"
	Text (640 - StringWidth("Space for full destruction")) / 2, 140, "Space for full destruction"
	
	Color 0,255,0
	Text (640 - StringWidth("Press Return to begin"))/2,380,"Press Return To begin"
	
	Color 255,0,255
	Text (640 - StringWidth("Public Domain"))/2,420,"Public Domain"

	Flip
		
Until KeyHit(28)	; Return starts the game



FlushKeys
Cls
destr = 0	; full destructions


SetBuffer BackBuffer()

blueFrame = False
bigBangs = 3
amountMissiles = Rand(5,8)
nr_of_missiles = 0

print_bigShot = False

divisor = 48

yellowFlashes = 0
energyBarLen = 72
yellow = 0

maxMissiles = 0

r# = 1

orig# = 50
ox# = 0
oy# = 0

gameover = False
extraEarned = False
print_fullDestr = True
big = False

firstBigShot = True
yellowFlashesInfo = False

While Not gameover = True

	Cls
	
	If KeyHit(1) Then Goto start
	
	mx = MouseX()
	my = MouseY()
	
	DrawImage gfxAim,mx,my

	While nr_of_missiles < amountMissiles
	
		mssl.missile = New missile
		mssl\origX# = Rand(100,580)
		mssl\x# = Rand(50,100)
		mssl\origY# = 31
		mssl\x# = mssl\origX# + Rand(-5,5)
		mssl\y# = 32
		mssl\dx# = Rnd(-2,2)
		mssl\dy# = Rnd(0,2)
	
		mssl\r = Rand(50,255)
		mssl\g = Rand(50,255)
		mssl\b = Rand(50,255)

		mssl\ovalM = Rand(5,15)

		nr_of_missiles = nr_of_missiles + 1
		
	Wend

	If MouseHit(1) Then
		ammo.ammoCircle = New ammoCircle
		ammo\x = mx - 24
		ammo\y = my - 24
		ammo\frame = 1
		ammo\hit = 0 
	EndIf

	Origin 0,0

	Color 0,0,255
	If bigBangs > 0 And bigBangs < 4 Then
		For i = 1 To bigBangs
			Oval 565 + i * 15,460,10,10,1
		Next
	EndIf

	For ammo.ammoCircle = Each ammoCircle
		ammo\frame = ammo\frame + 2
		
		If ammo\frame >= divisor Then
			Delete ammo
		Else
			If nr_of_missiles > 0 Then
			
				DrawImage gfxAmmo,ammo\x,ammo\y,ammo\frame

				For mssl.missile = Each missile
					If ImageRectCollide (gfxAmmo,ammo\x,ammo\y,ammo\frame, mssl\x ,mssl\y ,5,5)					
						Delete mssl
						ammo\hit = ammo\hit + 1
						nr_of_missiles = nr_of_missiles - 1
					EndIf
				Next
			EndIf	
		EndIf
	Next


	If print_bigShot = True Then

		Color 0,0,255

		If MilliSecs() - 2500 < timer_bigShot Then
			Text 270,200,"Big shot earned!"
		Else
			print_bigShot = False
		EndIf
				
		
	EndIf
		

	
	For ammo.ammoCircle = Each ammoCircle 
		maxMissiles = ammo\hit

		If ammo\hit >= 2 Then
			divisor = 72
			
			If firstBigShot = True Then
			
				firstBigShot = False
				print_bigShot = True
				timer_bigShot = MilliSecs()
				
				yellowFlashes = 0 
			EndIf
						
			big = True
		EndIf
			
		
		; If nr of missiles = 0, player get all 3 full destruction balls
		If nr_of_missiles = 0 Then

			timer_all = MilliSecs()
			print_fullDestr = True
	
			first_bigShot = True
			timer_bigShot = MilliSecs()
			
			blueTimer = MilliSecs()
			blueFrame = True
			
			bigBangs = 3
			
			destr = destr + 1
			
			For mssl.missile = Each missile
				Delete mssl
			Next
			
			For ammo.ammoCircle = Each ammoCircle
				Delete ammo
			Next


			For yc.yellowFlash = Each yellowFlash
				Delete yc
			Next
		
			For eb.energyBar = Each energyBar
				Delete eb
			Next
			nr_of_missiles = 0

			divisor = 72
			big = True
			Exit
			
		EndIf
						
	Next
	

	If print_fullDestr = True Then
		If MilliSecs() - timer_all < 2500 Then
			Text 270,220,"Full destruction!"
		EndIf
		If MilliSecs() - timer_all > 2500 Then print_fullDestr = False
	EndIf
	
	
	If gameover = True Then
			
		For mssl.missile = Each missile
			Delete mssl
		Next
		
		For ammo.ammoCircle = Each ammoCircle
			Delete ammo
		Next

		For yc.yellowFlash = Each yellowFlash
			Delete yc
		Next
		
		For eb.energyBar = Each energyBar
			Delete eb
		Next

		Goto gameEnd
	EndIf

	; BigBang
	If KeyHit(57) Then
		
		If bigBangs > 0 Then
			blueTimer = MilliSecs()
			blueFrame = True
			bigBangs = bigBangs - 1
			amountMissiles = 1
			nr_of_missiles = 0
			
		Else
			bigBangs = 0
			blueFrame = False
		EndIf
	EndIf

	Color 0,255,0
	Line 0,450,639,450
	Line 0,30,639,30
	

	For mssl.missile = Each missile
		If mssl\x# <= 0 Or mssl\x# >= 639 Then
			Delete mssl
			nr_of_missiles = nr_of_missiles - 1
			
			ec.yellowFlash = New yellowFlash
			ec\hit = True
			
			yellowFrame = True
			yellowTimer = MilliSecs()
						
			yellowFlashes = yellowFlashes + 1
						
		EndIf
	Next


	; If 20 missiles have gone to side of the screen.
	; return the normal size shot
	If yellowFlashesInfo = False And yellowFlashes > 20 And big = True Then	
		divisor = 48
		yellowFlashesDelay = MilliSecs()
		yellowFlashesInfo = True
		yellowFlashes = 0
	EndIf
	
	If yellowFlashesInfo = True Then
		If big = True Then print_bigShot = True	;
		If MilliSecs() - 2500 < yellowFlashesDelay Then
			firstBigShot = True
			Color 255,0,0
			Text 270,185,"Big shot lost!"
		Else
			yellowFlashesInfo = False
			big = False
			firstBigShot = True
		EndIf
	EndIf


	For mssl.missile = Each missile
		mssl\x# = mssl\x# + mssl\dx#
		mssl\y# = mssl\y# + mssl\dy#

		Color 255,255,255
		Line mssl\origX#, 31, mssl\x#, mssl\y#

		Color mssl\r,mssl\g,mssl\b	
		Oval mssl\x#-mssl\ovalM/2,mssl\y#-mssl\ovalM/2,mssl\OvalM,mssl\ovalM,1		
				
		If mssl\y# >=450 Then
			gameover = True
		EndIf
	Next
			
	
	If gameover = False Then
	
		eb.energyBar = New energyBar
		eb\r# = 255
		eb\dr# = 255 / 72
		eb\g# = 0
		eb\dg# = 255 / 72
		eb\b# = 0
		eb\hit = 0
		
		yellow = 0
		For ec.yellowFlash = Each yellowFlash
			If ec\hit = True Then
				yellow = yellow + 1
				Delete ec
			EndIf
		Next
		
		energyBarLen = energyBarLen - yellow
		
		If energyBarLen <= 0 Then
			gameOver = True
			Goto gameEnd
		EndIf
		
		For i = 1 To energyBarLen
		
			eb\r# = eb\r# - eb\dr#
			eb\g# = eb\g# + eb\dg#

			Color eb\r#,eb\g#,eb\b#
	
			Line i + 263 ,460,i + 263,470

		Next
		yellow = 0
	EndIf
	
	If gameover = True Then
	
		For mssl.missile = Each missile
			Delete mssl
		Next
		
		For ammo.ammoCircle = Each ammoCircle
			Delete ammo
		Next

		For yc.yellowFlash = Each yellowFlash
			Delete yc
		Next
		
		For eb.energyBar = Each energyBar
			Delete eb
		Next

	EndIf		

	If yellowFrame = True Then
		Color 255,255,0
		Rect 0,31,640,419,1
		If MilliSecs() < yellowTimer + 2000 Then yellowFrame = False		
	EndIf

	If blueFrame = True Then
		Color 0,0,255
		Rect 0,31,640,420,1
		
		For mssl.missile = Each missile
			nr_of_missiles = nr_of_missiles - 1
			
			Delete mssl
		Next

		For ammo.ammoCircle = Each ammoCircle
			Delete ammo
		Next

		nr_of_missiles = 0
		amountMissiles = Rand(5,8)
				
		If MilliSecs() < blueTimer + 2000 Then
			blueFrame = False
			nr_of_missiles = 0
		EndIf
	
	EndIf

	Flip	

Wend

.gameEnd
endTimer = MilliSecs()

Repeat
	If MilliSecs() > endTimer + 10000 Then Exit
	Color 200,100,100
	Text (640 - StringWidth("Game Over")) / 2, 200, "Game Over"
	Flip
Until KeyHit(1) Or KeyHit(28) Or KeyHit(57)

Goto start
End

Instructions for playing:

  • Use mouse to shoot the missiles
  • Space bar for full destruction
  • When at least 2 missiles are shot with one shot. the player is rewarded by bigger shot
  • If a missile goes to the side of the screen, player’s energy decreases
  • If missile touches the line at the bottom of the window, the game ends
  • If the player clears the screen by firing, the player is rewarded by giving 3 full destruction balls

The code isn’t really commented, sorry!