Verticle shooter (NO download required)

BlitzMax Forums/BlitzMax Tutorials/Verticle shooter (NO download required)

Matt McFarland(Posted 2006) [#1]
There is no media in this shooter, it uses bmax drawing commands and bmax OOP.


Strict
SeedRnd MilliSecs()
Global kills
Global Player = 1     
Global Enemy  = 2    
Global Lives
Global Score
Global PlayerList:TList			= CreateList()
Global PlayerBulletList:TList	= CreateList()  
Global EnemyList:TList			= CreateList()
Global EnemyBulletList:TList	= CreateList()
Global explosionlist:TList		= CreateList() 
Global BulletTimer
Graphics 800,600,0
Type TGameObject
	Field x,y,xv,yv
End Type

Type TPlayer Extends TGameObject
	Field InvincibleTimer ' we want him to be invincible when he starts so we need a timer
	Function Spawn()
		Local Player:TPlayer = New TPlayer  'Create a new TPlayer Object
		Player.InvincibleTimer=MilliSecs()+3000 '3 Seconds
		Player.x = 400 'center
		Player.y = 590 'bottom
		'Add the player with info above into the player list
        'The list is there so we can grab the player at any time.		
		PlayerList.AddLast(Player)  
	End Function
	Function Update()
		'This grabs the last object in the list, which happens to the the player object
		'that was created.  That's you!
		Local Player:TPlayer = TPlayer(PlayerList.Last()) 
		'Now we need to draw the object, but first lets find out if he's invincible.
		SetColor 255,255,255 'naturally the player will be white in color,
							 'if the player is invincible he'll flash different colors.
		
		If MilliSecs() < Player.InvincibleTimer ' then he's still invincible
			SetColor Rand(0,255),Rand(0,255),Rand(0,255)  'pick a random color 
		End If
		
		If KeyDown(KEY_LEFT) Then Player.x:-5
		If KeyDown(KEY_RIGHT) Then Player.x:+5
		If KeyDown(KEY_SPACE) and MilliSecs() > BulletTimer 
			TBullet.PlayerShoot(Player.x,Player.y-8)
			TBullet.PlayerShoot(Player.x-8,Player.y)
			TBullet.PlayerShoot(Player.x+8,Player.y)
		EndIf
		'Now lets draw the player, a triangle
		DrawLine Player.x+16,Player.y,Player.x-16,Player.y
		DrawLine Player.x,Player.y-32,Player.x+16,Player.y
		DrawLine Player.x,Player.y-32,Player.x-16,Player.y	
		
	End Function
End Type

Type TEnemy Extends TGameObject
	Field hitpoints
	Field wave
	Field startx
	Function Spawn()
		Local Enemy:TEnemy = New TEnemy
		Enemy.startx=Rand(20,780)
		Enemy.y= - 20
		Enemy.hitpoints = 255
		EnemyList.AddLast(Enemy)
	End Function
	Function Update()
		For Local Enemy:TEnemy = EachIn EnemyList
			Enemy.wave:+2
			Enemy.y:+1
			Enemy.x=Enemy.startx + Sin(Enemy.wave) * 20
			If Rand(1,100) = 99 Then TBullet.EnemyShoot(Enemy.x,Enemy.y)
			SetColor 255,Enemy.hitpoints,Enemy.hitpoints
			DrawOval Enemy.x-32,Enemy.y-16,64,32
			If Enemy.x < -70 Then Enemy.x = 864
			If Enemy.x > 864 Then Enemy.x = -70
			If Enemy.y > 660 Then Enemy.y = -60			
			If Enemy.hitpoints < 1 Then Enemy.explode
		Next
	End Function
	Method explode()
			kills:+1

		For Local explosions = 1 To 10
			TExplosion.Make(Self.x+Rand(-32,32),Self.y+Rand(-16,16),Rand(10,50))
			EnemyList.Remove(Self)
		Next
			If CountList(EnemyList) < 6 
				TEnemy.Spawn()			'make two
				TEnemy.Spawn()						
			EndIf
	End Method
End Type

Type TExplosion Extends TGameObject
	Field Radius
	Field MaxRadius
	Function Make (x,y,MaxRadius)
		Local Explosion:TExplosion = New TExplosion
		explosion.x = x
		explosion.y = y
		explosion.MaxRadius = MaxRadius
		explosionlist.AddLast (explosion)		
	End Function                         
	Function Update()
		For Local explosion:TExplosion = EachIn explosionlist
			explosion.Radius:+1
			If explosion.Radius = explosion.MaxRadius Then explosionlist.Remove(explosion)
			SetColor 255,255,0
			DrawOval explosion.x-explosion.Radius/2,explosion.y-explosion.Radius/2,explosion.Radius,explosion.Radius
		Next
	End Function
End Type

Type TBullet Extends TGameObject
	Field Owner ' specify who shot the bullet
	Function PlayerShoot(x,y)	
		Local Bullet:TBullet = New TBullet
		Bullet.x = x  'That's carried over from the function call, was player.x
		Bullet.y = y - 34 ' Also carried over, but adjusted to be above the player
		Bullet.Owner = Player 'The bullet collision detection will know whose is whose
		PlayerBulletList.AddLast(Bullet)
		BulletTimer = MilliSecs()+100
	End Function
	Function EnemyShoot(x,y)
		Local Bullet:TBullet = New TBullet
		Bullet.x = x  'Carried over from the function call, which was enemy.x
		bullet.y = y  'Also carried over, but adjusted to be below the firing enemy
		Bullet.Owner = Enemy 'The bullet collision detection will know whose is whose
		EnemyBulletList.AddLast(Bullet)
	End Function
	
		
	
	Function Update()
		For Local Bullet:TBullet = EachIn PlayerBulletList			
			SetColor 255,255,0
			bullet.y:-14
			DrawOval bullet.x,bullet.y,3,9
			If bullet.y < -10 Then PlayerBulletList.Remove(Bullet)
		
		' --------- CHECK COLLISIONS -----------
			For Local Enemy:TEnemy = EachIn EnemyList
				If bullet.x > Enemy.x-32 and bullet.x < Enemy.x+32 and bullet.y > Enemy.y-16 and bullet.y < Enemy.y+16
					Enemy.hitpoints:-20
				PlayerBulletList.Remove(bullet)
				TExplosion.Make(bullet.x,bullet.y,10)
				EndIf
			Next
		
		
		Next

		For Local Bullet:TBullet = EachIn EnemyBulletList			
			SetColor 255,0,0
			bullet.y:+4
			DrawOval bullet.x,bullet.y,9,9
			If bullet.y > 610 Then EnemyBulletList.Remove(Bullet)
			Local Player:TPlayer = TPlayer(PlayerList.Last()) 
         	If MilliSecs() > Player.InvincibleTimer ' then he's not invincible
				If bullet.x > Player.x-16 and bullet.x < Player.x+16 and bullet.y > Player.y-16 and bullet.y < Player.y+16
					EnemyBulletList.Remove(bullet)
					TExplosion.Make(Player.x,Player.y,100)
					PlayerList.Remove(Player)
					Lives:-1
					TPlayer.Spawn()					
				EndIf
			EndIf
		Next
	End Function
End Type
'These two lines start the game..
TPlayer.Spawn()
TEnemy.Spawn()
Repeat ' This is the main loop!!!!
	Cls
	If Lives > 0
		SetBlend LIGHTBLEND
		SetColor 0,255,255
		DrawText "Lives:",1,1
		DrawText Lives,50,1
		DrawText "Kills:",1,20
		DrawText kills,50,20
		SetBlend ALPHABLEND
		TEnemy.Update()
		TBullet.Update() 
		TPlayer.Update()	
		TExplosion.Update()
	EndIf
	If Lives = 0 
		SetColor 255,Rand(0,255),255
		DrawText "Highest kills:",10,10
		DrawText kills,130,10
		DrawText "Press 1 to play or ESC to quit",10,60
		If KeyHit(key_1) Then Lives = 5; kills = 0
	End If
	
	Flip

Until KeyHit(KEY_ESCAPE)


Copy paste and enjoy, the source should help you understand bmax a little better. If I have time I'll try to create a step by step creation. As of now I'm concerned on the best way to walk some one through making this. Would it be better to go line by line, concept by concept, type by type.. Not sure exactly.. But if you study the code you'll understand whats going on.


assari(Posted 2006) [#2]
Very nice retro looking game. Type by Type explaination would be good IMHO.
Thanks for sharing


Wellmt(Posted 2006) [#3]
Thats nice and simple, but still really useful. Thanks.


WendellM(Posted 2006) [#4]
Cool, thanks - a Galaxian/Galaga-Type Starter Kit: just add your own art, AI, and gameplay chrome! :)


Why0Why(Posted 2006) [#5]
This is really nice. Thanks for sharing.


Xerra(Posted 2006) [#6]
Very clever. Something cool to play with for a beginner. Thanks a lot :)