Blitz3D RockOut

Blitz3D Forums/Blitz3D Programming/Blitz3D RockOut

Maybe I got to much free time?

Run this from the blitzMax RockOut folder in Blitz3D

The .png's need to be changed to black



; -----------------------------------------------------------------------------
; RockOut -- Rocket BlockOut
; -----------------------------------------------------------------------------
; Public domain source code by James L Boyd (support @ blitzbasic . com)
; -----------------------------------------------------------------------------
; Rocket image © 2004 James L Boyd, with permission granted For freeware/PD use,
; Not that anyone;d really want it anyway...!
; -----------------------------------------------------------------------------


; -----------------------------------------------------------------------------
; Constants...
; -----------------------------------------------------------------------------

; Sizes used For blocks...

Const BLOCKWIDTH = 32
Const BLOCKHEIGHT = 16



; ------------------------------------------------------------------------
; Type-specific globals...
; ------------------------------------------------------------------------

Global GCount				 ; Count of all GravityItems (For debugging)
;Global GravityItemList.TList	 ; List used For all GravityItem objects
Global Gravity# = 0.05		  ; Gravity applied To all GravityItems

Type GravityItem
	Field x#					 ; x position of Object
	Field y#					 ; y position of Object
	Field xs#					; x speed of Object
	Field ys#					; y speed of Object
	
	Field width				   ; Width of Object
	Field height				  ; Height of Object
	
	Field damage				  ; Damage caused by this item If it hits player
	Field fixed			; Is Object fixed in place? Blocks are, at First...
	
	Field r, g, b
End Type

;x,y,width,height,damage
Function PlayerCollide (x,y,width,height,damage,multiplier# = 1, posyonly = 0)

		  ; Offset x/y position of shots (all images; handles are centered)...

		  ox = x - width / 2
		  oy = y - height / 2

		  ; Offset x/y position of player...

		  opx = PlayerOne\x - PlayerOne\width / 2
		  opy = PlayerOne\y - PlayerOne\height / 2

		  ; Hack To Stop Shot objects damaging player While going up...

		  check = 1

		  If posyonly
			If ys < 0
			   check = 0
			EndIf
		  EndIf

		  ; Test For collision, apply damage And make explosion...
			
		  If check
			If OverLap (ox, oy, ox + width, oy + height, opx, opy, opx + PlayerOne\width, opy + PlayerOne\height)
			   PlayerOne\shields = PlayerOne\shields - damage * multiplier
			   ExplosionParticle_Explode x, y, damage * 5 * multiplier
			   PlayerOne\damaged = MilliSecs ()
			   Return True
			EndIf
		  EndIf
End Function




; Particles created in an explosion. This Type extends GravityItem, meaning all
; properties of GravityItem apply, except where methods are over-ridden
; (ie. re-defined) here...

Type ExplosionParticle
	Field Obj
	
	Field alph#
	Field x#					 ; x position of Object
	Field y#					 ; y position of Object
	Field xs#					; x speed of Object
	Field ys#					; y speed of Object
	
	Field width				   ; Width of Object
	Field height				  ; Height of Object
	
	Field damage				  ; Damage caused by this item If it hits player
	Field fixed					; Is Object fixed in place? Blocks are, at First...
	
	Field r, g, b
End Type
; ------------------------------------------------------------------------
; Type functions...
; ------------------------------------------------------------------------

Function ExplosionParticle_Explode(x#, y#, particles)
	If Sounds_On
		pan# = x / GW2 - 1.0
		play = PlaySound (hit)
		ChannelPan play, pan
	EndIf
	For loop = 1 To particles
		ExplosionParticle_Create(x, y)
	Next
End Function

Function ExplosionParticle_Create.ExplosionParticle(x, y)
	e.ExplosionParticle = New ExplosionParticle
	e\Obj=MakeObj()
	e\alph#=1.0
	e\x = x
	e\y = y
	e\xs = Rnd (-8, 8)
	e\ys = Rnd (-8, 8)
	; Random colour...
	Select Rand (0, 3)
	Case 0
		e\r = 255
		e\g = 255
		e\b = 255
	Case 1
		e\r = 255
		e\g = 127
		e\b = 0
	Case 2
		e\r = 255
		e\g = 255
		e\b = 0
	Case 3
		e\r = 255
		e\g = 0
		e\b = 0
	End Select
	; Random size...
	size = Rand (1, 8)
	e\width = size
	e\height = size
	Return e
End Function

	; ------------------------------------------------------------------------
	; Type methods...
	; ------------------------------------------------------------------------

	; Update () over-rides the GravityItem Update () method...

Function ExplosionParticle_Update()
	For e.ExplosionParticle = Each ExplosionParticle
	   ; Reduce alpha level of particle...

	   e\alph = e\alph - 0.01

	   ; Apply Gravity Global (see GravityItem) To y speed...

	   e\ys = e\ys + Gravity

	   ; Move particle by current speed...

	   e\x = e\x + e\xs
	   e\y = e\y + e\ys
	   
	   ; If off-screen Or reduced To invisible, remove from list by
	   ; calling the Destroy method (inherited from GravityItem)...
		
	   If e\y > GraphicsHeight () Or e\alph = 0 Then FreeObj e\Obj:Delete e
	Next
End Function

	; Draw particle...

Function ExplosionParticle_Draw()
	For e.ExplosionParticle = Each ExplosionParticle
		  SetScale 1, 1
		  SetBlend ALPHABLEND
		  SetAlpha e\alph
		  SetColor e\r, e\g, e\b
		  SetObj e\obj, e\x, e\y, e\width, e\height

	Next
End Function



; Block definition. Again, Block is a kind of GravityItem...

Global BCount		  ; Number of blocks

Type Block
	Field Obj
	Field Obj2
	Field x#					 ; x position of Object
	Field y#					 ; y position of Object
	Field xs#					; x speed of Object
	Field ys#					; y speed of Object
	
	Field width				   ; Width of Object
	Field height				  ; Height of Object
	
	Field damage				  ; Damage caused by this item If it hits player
	Field fixed			; Is Object fixed in place? Blocks are, at First...
	
	Field r, g, b
	
; ------------------------------------------------------------------------
; Type-specific fields...
; ------------------------------------------------------------------------
	Field alph#	    ; Alpha level of block
	Field ang#			; Rotation of block
	Field angspeed#		; Rotation speed of block
	Field desty#


End Type


	; ------------------------------------------------------------------------
	; Type-specific Function...
	; ------------------------------------------------------------------------

	; Create a Block Object (added To GravityItem list automatically)...


	Function Block_Create.Block(x, y)
		blk.Block = New Block
		blk\Obj=MakeObj(BlockImage)
		blk\Obj2=MakeObj(BlockImage)
		blk\x = x
		blk\y = y
		blk\desty = y
		blk\width = BLOCKWIDTH
		blk\height = BLOCKHEIGHT
		blk\fixed = True
		blk\damage = 20
		blk\alph#=1.0
		BCount = BCount + 1
		Return blk
	End Function

	; ------------------------------------------------------------------------
	; Type-specific methods...
	; ------------------------------------------------------------------------

	; Update () method For Block objects...

Function Block_Update ()
	For blk.Block = Each Block
		  ; Check For collision (passing alpha level of block To apply
		  ; appropriate damage), And remove from GravityItem list If hit...

		  If PlayerCollide (blk\x,blk\y,blk\width,blk\height,blk\damage,blk\alph) Then BCount = BCount - 1:FreeObj blk\Obj2:FreeObj blk\Obj: Delete blk: Return

		  ; If the block has been freed (by being hit), make it fall...

		  If Not blk\fixed

			blk\alph = blk\alph - 0.0075: If blk\alph < 0 Then blk\alph = 0
			blk\ang = blk\ang + blk\angspeed: If blk\ang > 359 Then blk\ang = 0
			blk\ys = blk\ys + Gravity
			blk\x = blk\x + blk\xs
			blk\y = blk\y + blk\ys

			If blk\y > GraphicsHeight () Or blk\alph = 0 FreeObj blk\Obj2:FreeObj blk\Obj:Delete blk: BCount = BCount - 1

		  Else

			 ; When blocks are lowered in main loop, they are just set To ;desty;,
			 ; their New y-position destination. This moves them towards that...

			 ydist# = blk\desty - blk\y
			 blk\ys = ydist / 12.0
			 blk\y = blk\y + blk\ys

		  EndIf
	Next
End Function

	; Block-specific Draw () method...

Function Block_Draw()
	For blk.Block = Each Block
	
	SetBlend ALPHABLEND
	SetRotation blk\ang
	
	SetColor blk\r, blk\g, blk\b
	SetAlpha blk\alph
	
	SetObj blk\Obj, blk\x, blk\y
	SetRotation 0
	
	Next
End Function

Function Block_DrawShadows ()
	SetBlend ALPHABLEND
	For blk.Block = Each Block
		SetRotation blk\ang
		SetColor 0, 0, 0
		SetAlpha blk\alph * 0.25
		SetObj blk\Obj2, blk\x + 8, blk\y + 8
	Next
End Function










; Player Object. Only one player possible Right now, but this keeps everything
; together For easy reference...

Type Player
	Field Obj

	Field damaged    ; Set To MilliSecs () when hit (used For flashing effect)

	; ------------------------------------------------------------------------
	; Type-specific fields...
	; ------------------------------------------------------------------------

	; The shields Field is a Float so I can reduce by small amounts, but I use
	; Int (PlayerOne.shields) To display/evaluate it...

	Field shields#
	
	Field x#
	Field y#
	Field xs#
	Field ys#

	Field image	 ; Player image...
	
	Field width
	Field height
	
End Type

	; ------------------------------------------------------------------------
	; Type-specific functions...
	; ------------------------------------------------------------------------

	; Create () is a Function that creates & returns a :Player Type Object...

Function Player_Create.Player (x, y, image, image2)
	PlayerOne.Player = New Player
	PlayerOne\image = image
	PlayerOne\x = x
	PlayerOne\y = y
	PlayerOne\shields# = 100
	PlayerOne\width = ImageWidth (image2) * 0.2	; Image is scaled in Draw ()
	PlayerOne\height = ImageHeight (image2) * 0.2
	Return PlayerOne
End Function

	; ------------------------------------------------------------------------
	; Type-specific methods...
	; ------------------------------------------------------------------------

	; This is passed the MouseX () And MouseY () positions in the main game
	; loop, And hence moves the player toward the mouse cursor...

	Function Player_Move (destx#, desty#, div#)
		  xdist# = destx - PlayerOne\x
		  ydist# = desty - PlayerOne\y
		  PlayerOne\xs = xdist / div
		  PlayerOne\ys = ydist / div
		  PlayerOne\x = PlayerOne\x + PlayerOne\xs
		  PlayerOne\y = PlayerOne\y + PlayerOne\ys
	End Function

Function Player_Draw (alpha# = 1, r = 255, g = 255, b = 255)
	If PlayerOne<>Null Then
		  SetBlend ALPHABLEND
		  SetScale 0.2, 0.2

		  If Shadows_On
			SetColor 0, 0, 0
			SetAlpha alpha * 0.4
			DrawImage PlayerOne\image, PlayerOne\x + 8, PlayerOne\y + 8
		  EndIf

		  SetAlpha alpha

		; If player is damaged, rgb will be RED...
		
		  SetColor r, g, b
		  DrawImage PlayerOne\image, PlayerOne\x, PlayerOne\y
		  SetScale 1, 1
	End If
End Function




Type Shot
	Field Obj
	
	Field x#					 ; x position of Object
	Field y#					 ; y position of Object
	Field xs#					; x speed of Object
	Field ys#					; y speed of Object

	Field width				   ; Width of Object
	Field height				  ; Height of Object

	Field damage				  ; Damage caused by this item If it hits player
	Field fixed			; Is Object fixed in place? Blocks are, at First...

	Field r, g, b
End Type


Function Shot_Create.Shot(x#, y#, ys#, xs#, SoundPan#)
	If Sounds_On
		play = PlaySound (shoot)
		ChannelPan play, SoundPan#
	EndIf
	s.Shot = New Shot
	s\obj=MakeObj(ShotImage)
	s\x = x
	s\y = y
	s\xs = xs
	s\ys = ys
	s\width = 6
	s\height = 6
	s\damage = 2
	Return s
End Function


Function Shot_Update()
	For s.Shot = Each Shot

	   ; Hit the player (note ;posyonly;, 2nd parameter, of PlayerCollide)...
		
	   If PlayerCollide (s\x,s\y,s\width,s\height,s\damage,1, 1) Then FreeObj s\Obj:Delete s:Return 1

	   s\ys = s\ys + Gravity
	   s\x = s\x + s\xs
	   s\y = s\y + s\ys
	
	   ; Remove If below bottom of screen...

	   If s\y > GraphicsHeight ()

		 FreeObj s\Obj:Delete s

	   Else

		  ; Check current Shot against all Blocks...

		  ; (Notice that this only checks Block objects in the list!)

		  For blk.Block = Each Block

			 ; Get x offset (rectangles are Mid-handled)...

			 ox = s\x - s\width / 2
			 oy = s\y - s\height / 2

			 ogx = blk\x - blk\width / 2
			 ogy = blk\y - blk\width / 2

			 ; Check collision...

			 If OverLap (ox, oy, ox + s\width, oy + s\height, ogx, ogy, ogx + blk\width, ogy + blk\height)

			    ; If Block is already dead (ie. falling), reflect Shot, otherwise
			    ; un-fix block And create explosion...

			    ; Note: ys is current Shot Object;s y speed...

			    If blk\fixed = False
				  s\ys = -s\ys
			    Else
				  blk\fixed = False
				  blk\ys = s\ys / Rnd (1, 4)
				  blk\angspeed = Rnd (-4, 4)
				  ExplosionParticle_Explode ogx, ogy, 4
			    EndIf

			 EndIf

			 ;FlushMem ; FlushMem Crash!

		  Next

	   EndIf
	
	Next
End Function

Function Shot_Draw()
	For s.Shot = Each Shot
		SetBlend MASKBLEND
		 SetAlpha 1
		 SetColor 255, 255, 255
		 SetObj s\obj, s\x, s\y
	Next
End Function


;--------------------------------------------------
;				debris
;--------------------------------------------------

Type DebrisItem
	Field Obj
	Field x#
	Field y#
	Field ys#
	Field size
End Type

Function Create_DebrisItem.DebrisItem()
	Debris.DebrisItem=New DebrisItem
	Debris\x#	=Rand (0, GraphicsWidth () - 1)
	Debris\y#	=Rand (0, GraphicsHeight () - 1)
	Debris\ys#	=Rnd (0.01, 8)
	Debris\size	=Rand (1, 2)
	Return Debris
End Function

Function DebrisItem_Update()
	For Debris.DebrisItem=Each DebrisItem
		If Debris\y > GraphicsHeight () Debris\y = 0
		Debris\y = Debris\y + Debris\ys
		SetColor Rnd (127, 255), Rnd (127, 255), 255
		SetBlend SOLIDBLEND
		SetObj debris\Obj,Debris\x, Debris\y, Debris\size, Debris\size
	Next
End Function




Function UpdateAll()

If Shadows_On Then Block_DrawShadows() ; Shadows_On is a Global...
;ExplosionParticle
;Block
;Player
;Shot
;DebrisItem

ExplosionParticle_Update()
Block_Update()
;Player_Update()
Shot_Update()


ExplosionParticle_Draw()
Block_Draw()
Shot_Draw()


End Function





; -----------------------------------------------------------------------------
; Functions...
; -----------------------------------------------------------------------------

; Draw simple Text with shadow...

Function DrawShadowText (t$, x, y)
	 SetColor 0, 0, 0
	 DrawText t$, x + 1, y + 1
	 SetColor 255, 255, 255
	 DrawText t$, x, y
End Function

; Draw stuff in WireFrame mode...

;Function WireFrame (enable = True)
;	    If enable
;		  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE)
;	    Else
;		  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL)
;	    EndIf
;End Function

; Draw stuff in point mode...

Function Point (enable = True)
	    If enable
;		  glPolygonMode (GL_FRONT_AND_BACK, GL_POINT)
	    Else
;		  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL)
	    EndIf
End Function

; Returns "Off" If ;status; is 0, otherwise "On"...

Function OnOff$ (status)
	    If status Then Return "On" Else Return "Off"
End Function

; Phew! Thanks, Birdie! Rectangular overlap Function. Should have been so easy...

Function OverLap (x0, y0, x1, y1, x2, y2, x3, y3)
	If x0 > x3 Or x1 < x2 Then Return False
 	If y0 > y3 Or y1 < y2 Then Return False
 	Return True
End Function

; Distance between two points...

Function Dist# (x0#, y0#, x1#, y1#)
	Return Sqr( ((x1 - x0) * (x1 - x0)) + ((y1 - y0) * (y1 - y0)) )
End Function

; -----------------------------------------------------------------------------
; Main game. This is where it all goes pear-shaped!
; -----------------------------------------------------------------------------

; Open display...

Graphics 640, 480,32;,2

; Pre-calc half of Graphics width...

Global GW2 = GraphicsWidth () / 2
Global GH2 = GraphicsHeight () / 2

; Set Cls colour (used when background turned off)...

ClsColor 64, 96, 128

; All images; And rectangles; handles should be set To the centre...

AutoMidHandle True
;SetHandle 0.5, 0.5

; All images unfiltered...

;AutoImageFlags MASKEDIMAGE

; Mask colour For loaded images (will be transparent)...

;SetMaskColor 255, 0, 255

; Mouse position -- used in some Type methods And functions, hence Global...

Global mx, my

; Player Object...

Global PlayerOne.Player

; Draw shadows?

Global Shadows_On = True

; Turn off sound?

Global Sounds_On = True

; Load media -- sounds, from included binaries (see start of code)...

Global shoot = LoadSound ("sounds/shot.ogg")
Global hit   = LoadSound ("sounds/hit.ogg")
Global beep  = LoadSound ("sounds/beep.ogg")
Global over  = LoadSound ("sounds/gameover.ogg")

; Load media -- images, from included binaries...

; Shots...

Global ShotImage = Load3DImage ("gfx/shot.png")

; Blocks...

; Note there is only one image For all blocks -- they are altered by SetColorRGB Before
; drawing (WHITE gives normal image)...

Global BlockImage = Load3DImage ("gfx/block.png")

; Player...

pimage = Load3DImage ("gfx\boing.png")
pimage2 = LoadImage ("gfx\boing.png")

; Background...

; Note that bgscale stores the length of the screen diagonal, And this value is used
; For the image height, so it doesn;t get chopped when it rotates...

bg = Load3DImage ("gfx/land.png")

Tmpbg = LoadImage ("gfx/land.png")
bgscale# = Dist (0, 0, GraphicsWidth () - 1, GraphicsHeight () - 1) / ImageHeight (Tmpbg)
FreeImage Tmpbg


; Background angle/speed of rotation...

bgang# = 0
bgangspeed# = 0

; Create an array of 100 debris particles...

;Local debris.DebrisItem [100]
For loop = 0 To 100
    ;debris [loop] = New DebrisItem
	debris.DebrisItem = Create_DebrisItem.DebrisItem()
	debris\Obj=MakeObj()
Next

; This should probably Read ;rows; -- the number of rows of blocks at startup...

layers = 5

; Toggle variables For drawing background, debris And WireFrame mode...

bgtoggle = 1
debristoggle = 1
wftoggle = 0

; Delay Before adding another row of blocks (this is decreased as the game progresses)...

rowdelay = 10000 ; 10 seconds (10000 milliseconds)...

; Background colour And First target colour...

backr# = 64
backg# = 96
backb# = 180

backtr# = 128
backtg# = 32
backtb# = 48

; Delay between colour increments...

backstep# = 5000

; Colour increments...

backstepr# = (backtr - backr) / backstep
backstepg# = (backtg - backg) / backstep
backstepb# = (backtb - backb) / backstep

; Direction of increment To target colour...

backsgn = Sgn (backtr - backr)

; This is the point where the game is re-started from, whenever a level is completed Or game ended...

.ResetLevel ; $name signifies a label now...

; Increase level number (level is 0 on startup, so becomes 1 For First level)...

level = level + 1

; Reset the ;New row; Delay timer To the current time...

rowtimer = MilliSecs ()

; Set fire rate limiter To current time...

firetimer = MilliSecs ()

; Create rows of blocks...

For y = 0 To layers - 1
    For x = 0 To GraphicsWidth () Step BLOCKWIDTH
	   b.Block = Block_Create(x + BLOCKWIDTH / 2, (y * BLOCKHEIGHT) + BLOCKHEIGHT / 2)
	   b\r = Rnd (127, 255)
	   b\g = Rnd (127, 255)
	   b\b = Rnd (127, 255)
    Next
Next

; Minimum number of blocks Left Before we *Stop* dropping them down (equivalent of 2 rows)...

lowblocks = 2 * (GraphicsWidth () / BLOCKWIDTH)

; When a level is completed, we Delete the player Object For simplicity of resetting
; all its values. This creates it (same For game startup)...


;If PlayerOne = Null Then PlayerOne = Player_Create.Player (MouseX (), MouseY (), pimage,pimage2)
If PlayerOne = Null Then PlayerOne = Player_Create.Player (320, 480, pimage,pimage2)


; Don't show the mouse pointer; gonna draw our own...

HidePointer()

; Game Text And precalculated x offsets...

go$ = "G A M E   O V E R   --   H I T   S P A C E   O R   R M B"
wd$ = "W E L L   D O N E   --   H I T   S P A C E   O R   R M B"

gox = (GraphicsWidth () / 2) - (StringWidth (go$) / 2)
wdx = (GraphicsWidth () / 2) - (StringWidth (wd$) / 2)

Repeat

	 ; Clear the screen...

	 Cls

	 ; Store mouse position in these Global variables...

	 mx = MouseX ()
	 my = MouseY ()

	 ; -----------------------------------------------------------------------
	 ; Toggles...
	 ; -----------------------------------------------------------------------

	 If KeyHit (59) Then bgtoggle = 1 - bgtoggle					   ; Background
	 If KeyHit (60) Then debristoggle = 1 - debristoggle				; Debris
	 If KeyHit (61) Then wftoggle = 1 - wftoggle; WireFrame wftoggle	   ; Wireframe *
	 If KeyHit (62) Then Sounds_On = 1 - Sounds_On					 ; Sound
	 If KeyHit (63) Then Shadows_On = 1 - Shadows_On				    ; Shadows

	 ; * WireFrame worked when the game used rectangles instead of images For blocks!
	 
	 ; -----------------------------------------------------------------------
	 ; Background...
	 ; -----------------------------------------------------------------------

	 ; Update background rotation...

	 bgang = bgang + bgangspeed: If bgang > 359 - bgangspeed Then bgang = 0
	 bgangspeed = bgangspeed + 0.0001

	 ; The bgtoggle variable controls whether the background should be drawn Or Not...

	 If bgtoggle

		    ; Turn off WireFrame mode (If it;s on)...

		    If wftoggle Then WireFrame False

		    ; Change colour by pre-calculated increment...

		    backr = backr + backstepr
		    backg = backg + backstepg
		    backb = backb + backstepb

		    ; Reached target colour? Set a New target/increments/increment-direction...

		    If backr => backtr * backsgn
			   backtr = Rnd (255)
			   backtg = Rnd (255)
			   backtb = Rnd (255)
			   backstepr# = (backtr - backr) / backstep
			   backstepg# = (backtg - backg) / backstep
			   backstepb# = (backtb - backb) / backstep
			   backsgn = Sgn (backtr - backr)
		    EndIf

		    ; Set colour of background image (applied To the greyscale Default)...

		    SetColor backr, backg, backb

		    ; Set the background;s pre-calculated scale...

		    SetScale bgscale, bgscale
		    SetRotation bgang
		    SetAlpha 1

		    DrawImage bg, GW2, GH2

		    ; Reset this stuff so Next drawn items don;t have To...

		    SetRotation 0
		    SetScale 1, 1

		    ; Put back To WireFrame/non-WireFrame mode, depending on value of ;wftoggle;...

		    WireFrame wftoggle

	 EndIf

	 ; -----------------------------------------------------------------------
	 ; Debris...
	 ; -----------------------------------------------------------------------

	 ; Draw debris particles If ;debristoggle; is True...

	 If debristoggle
	    ;For loop = 0 To 100
	 	   ;debris [loop].Update
			DebrisItem_Update()
	    ;Next
	 EndIf

	 ; -----------------------------------------------------------------------
	 ; Cursor...
	 ; -----------------------------------------------------------------------

	 SetColor 255, 255, 255
	 DrawLine mx - 8, my, mx + 8, my
	 DrawLine mx, my - 8, mx, my + 8
	
	 ; -----------------------------------------------------------------------
	 ; Move And draw player...
	 ; -----------------------------------------------------------------------

	 ; Move the player Object based on mouse position (the ;20; controls the
	 ; speed at which the player moves toward the mouse -- play with it;
	 ; Lower is faster)...

	 Player_Move(mx, my, 12)
	
	; Turn WireFrame off If still on, Before drawing player...

	 If wftoggle Then WireFrame False

	 ; When the player is hit, the ;damaged; Field is set To the current time.
	 ; This code checks If a second has passed since ;damaged;. If so, it draws
	; the player normally; if not, the player is drawn in red, with varying
	; transparency...

	 If MilliSecs () > PlayerOne\damaged + 1000 ; Damage timeout has passed...

	    ; Draw normally...
		
	    PlayerOne\damaged = 0 ; Resetting damage time...
	    alpha# = 1
	    rcol = 255: gcol = 255: bcol = 255

	 Else

		; Flash player For 1 second If hit...

		alpha# = Sin (MilliSecs ())
		rcol = 255: gcol = 0: bcol = 0

	 EndIf

	 ; Draw the player using the above values...

	 Player_Draw (alpha, rcol, gcol, bcol)
		
	 ; Reset the WireFrame mode according To ;w;...

	 WireFrame wftoggle

	 ; -----------------------------------------------------------------------
	 ; If player is alive, do stuff...
	 ; -----------------------------------------------------------------------

	 If Int (PlayerOne\shields) > 0 ; Shields is a Float, so gotta round it...

	    ; Player is alive...

	    ; If more than ;lowblocks; Left on screen, add a row And Lower all
	    ; blocks. Reset drop-down timer And reduce Delay For Next drop-down...

	    If BCount > lowblocks And MilliSecs () > rowtimer + rowdelay

		  ; Add a row of blocks, above top of screen...

		  For x = 0 To GraphicsWidth () Step BLOCKWIDTH
			 b.Block = Block_Create (x + BLOCKWIDTH / 2, -BLOCKHEIGHT / 2)
			 b\r = Rnd (127, 255)
			 b\g = Rnd (127, 255)
			 b\b = Rnd (127, 255)
		  Next

		  ; Set all blocks; target y position down by block height. When blocks
		  ; are updated, they get moved towards this New position...

		  For b.Block = Each Block
			 b\desty = b\desty + BLOCKHEIGHT
		  Next

		  ; Reset timeout Until a New row is added...

		  rowtimer = MilliSecs ()

		  ; Reduce row-down timeout a bit...

		  If rowdelay => 1100 Then rowdelay = rowdelay - 100 ; Minimum 1 sec interval!

	    EndIf

	    ; --------------------------------------------------------------------
	    ; Fire shot (maximum fire rate 75 milliseconds)...
	    ; --------------------------------------------------------------------

	    If MouseDown (1)
		  If MilliSecs () > firetimer + 75
			pan# = PlayerOne\x / GW2 - 1.0
			s.Shot = Shot_Create.Shot (PlayerOne\x, PlayerOne\y - (PlayerOne\height / 2 + 5), -5, PlayerOne\xs / 5.0, pan)
			firetimer = MilliSecs ()
		  EndIf
	    EndIf

	    ; --------------------------------------------------------------------
	    ; No blocks Left?
	    ; --------------------------------------------------------------------

	    ; Set ;welldone; flag (Text shows "Well done" below If True);

	    ; If there are no blocks And Space is hit, Delete all GravityItems,
	    ; reduce block count, increase number of block rows And reset level...

	    If BCount = 0

		  ; Will display ;well done; message further down...

		  welldone = True

		  ; Remove all items (And reduce block count)...
			
			;--Fix!--
			
		  ;For g.GravityItem = Each GravityItem.GravityItemList
		  ;    If Block (g) Then Block\BCount = Block\BCount - 1
		  ;    Destroy_g g
		  ;Next
			
			
			For e.ExplosionParticle =Each ExplosionParticle
			FreeObj e\Obj:Delete e:Next
			For b.Block =Each Block
			FreeObj b\Obj2:FreeObj b\Obj:Delete b:Next
			For s.Shot =Each Shot
			FreeObj s\Obj:Delete s:Next
			
			
			
		  ; If space is hit, add some layers And reset everything (New level)...

		  If KeyHit (57) Or MouseHit (2)
			If Sounds_On Then PlaySound beep
			layers = layers + 3
			Goto ResetLevel
		  EndIf

	    EndIf

	 Else

		If gameoverplayed = 0
		   If Sounds_On Then PlaySound over
		   gameoverplayed = 1
		EndIf

		; Player is dead...

		PlayerOne\shields = 0 ; Force To zero as can be reduced After game is over...
			
		gameover = True

		; Remove all blocks...

		For b.Block = Each Block
		    FreeObj b\Obj2:FreeObj b\Obj:Delete b
		    BCount = BCount - 1
		Next
			
		; -------------------------------------------------------------------
		; If player is dead And Space hit...
		; -------------------------------------------------------------------

		; Space hit... remove everything Else And reset To inital settings...

		If KeyHit (57) Or MouseHit (2)

		   If Sounds_On Then PlaySound beep
			
			For e.ExplosionParticle =Each ExplosionParticle
			FreeObj e\Obj:Delete e:Next
			For b.Block =Each Block
			FreeObj b\Obj:Delete b:Next
			For s.Shot =Each Shot
			FreeObj s\Obj:Delete s:Next
			
			
		   ; Delete player (recreated when level is reset)...
			
		   Delete PlayerOne
		   layers = 5
		   bgang = 0
		   bgangspeed = 0
		   level = 0
		   rowdelay = 10000

		   gameoverplayed = 0

		   Goto ResetLevel

		Else

		    ; Quit If ESC hit...

		    If KeyHit (KEY_ESCAPE) Then End

		EndIf

	 EndIf

	 ; -----------------------------------------------------------------------
	 ; Update everything...
	 ; -----------------------------------------------------------------------

	UpdateAll

	 ; -----------------------------------------------------------------------
	 ; Draw Text on top of everything...
	 ; -----------------------------------------------------------------------

	SetAlpha 1
		
	DrawShadowText "Level: " + level + " | Shields: " + Int (PlayerOne\shields) + "%", 20, GraphicsHeight () - 80

	DrawShadowText "F1: Toggle background | F3: Wireframe mode | F5: Toggle shadows", 20, GraphicsHeight () - 40
	DrawShadowText "F2: Toggle debris	| F4: Toggle audio (" + OnOff (Sounds_On) + ")", 20, GraphicsHeight () - 20

	 ; Draw extra Text If appropriate...

	If gameover
	   DrawShadowText go$, gox, GraphicsHeight () / 2
	   gameover = False
	Else
	   If welldone
		 DrawShadowText wd$, wdx, GraphicsHeight () / 2
		 welldone = False
	   EndIf
	EndIf

	 ; Flush memory (Blitz will Delete any objects set To Null And free their memory)...

	 ;FlushMem

	 ; Display everything that;s been drawn To the hidden back buffer...

	 Flip3D

Until KeyHit (KEY_ESCAPE)

End











;------------------3D Image Include---------------------
;				   By Luke Hoschke
;
;
; To Use:
; 		-Add: Include "Draw3DImage.bb"
; 		-Change: 'Flip' To "Flip3D'
; 
; Note: Uses BlitzMax commands (Not all)
;
;
;-------------------------------------------------------

;-----------------------
;		KeyCodes
;-----------------------

Const KEY_ESCAPE = 1


Const KEY_RIGHT=203

Const KEY_LEFT=205


;-----------------------
;		Const
;-----------------------

Const SolidBlend	=2
Const Maskblend		=1 ;(Why One, I don't know)
Const Alphablend	=3
Const Lightblend	=4
Const ShadeBlend	=5


Const Image3D_LoadText=0 ;Not Working ;Set to 0 for less overhead, Faster Load

;-----------------------
;		Globals
;-----------------------

Global Image3D_Camera=0
Global Image3D_CameraPivot=0

Global Image3D_Rect
Global Image3D_TextChar



Global Image3D_OrderCount	=-2

Global Image3D_BlendMode	=MaskblEnd
Global Image3D_Alpha#		=1
Global Image3D_ColorR		=255
Global Image3D_ColorG		=255
Global Image3D_ColorB		=255
Global Image3D_Rotation#	=0
Global Image3D_ScaleX#		=1
Global Image3D_ScaleY#		=1

Function SetAlpha(alpha#)
	Image3D_Alpha#=alpha#
End Function
Function GetAlpha#()
	Return Image3D_Alpha#
End Function
Function SetTransform( rotation# , scale_x#, scale_y# )
	Image3D_Rotation#=rotation#:Image3D_ScaleX#=scale_x#:Image3D_ScaleY#=scale_y#
End Function
Function SetColor(red, green, blue)
	Color red, green, blue;Temp
	Image3D_ColorR=red:Image3D_ColorG=green:Image3D_ColorB=blue
End Function
Function GetColorR()
	Return Image3D_ColorR
End Function
Function GetColorG()
	Return Image3D_ColorG
End Function
Function GetColorB()
	Return Image3D_ColorB
End Function
Function SetRotation( rotation# )
	Image3D_Rotation#=rotation#
End Function
Function GetRotation#()
	Return Image3D_Rotation#
End Function
Function SetScale#( scale_x#, scale_y# )
	Image3D_ScaleX#=scale_x#:Image3D_ScaleY#=scale_y#
End Function
Function GetScalex#()
	Return Image3D_ScaleX#
End Function
Function GetScaley#()
	Return Image3D_ScaleY#
End Function
Function SetBlend( blend )
	Image3D_BlendMode=blend
End Function
Function GetBlend()
	Return Image3D_BlendMode
End Function

AutoMidHandle( enable )




Function Load3DImage(Filename$,Flags=1+4)
	
	TmpTex=LoadTexture(Filename$,Flags)
	If TmpTex=0 Then Return 0
	
	TmpImage=LoadImage(Filename$)
	If TmpImage=0 Then FreeTexture(TmpTex):Return 0
	
	Mesh=CreateMesh(Image3D_CameraPivot)
	Surface=CreateSurface(Mesh)
	
	v0=AddVertex(Surface,0-ImageXHandle(TmpImage)						,0-ImageYHandle(TmpImage)						,0	,0,0)
	v1=AddVertex(Surface,ImageWidth(TmpImage)-ImageXHandle(TmpImage)	,0-ImageYHandle(TmpImage)						,0	,1,0)
	v2=AddVertex(Surface,0-ImageXHandle(TmpImage)						,ImageHeight(TmpImage)-ImageYHandle(TmpImage)	,0	,0,1)
	v3=AddVertex(Surface,ImageWidth(TmpImage)-ImageXHandle(TmpImage)	,ImageHeight(TmpImage)-ImageYHandle(TmpImage)	,0	,1,1)
	
	AddTriangle(Surface,V0,V1,V2)
	AddTriangle(Surface,V1,V3,V2)
	EntityFX mesh,1+4+8
	
	EntityTexture mesh,TmpTex
	FreeTexture TmpTex
	FreeImage TmpImage
	
	HideEntity mesh
	
	cube= CreateCube()
	PositionEntity cube,0,0,8
	EntityColor cube,255,0,0
	Return mesh
	
End Function

Function Free3DImage(Image)
	FreeEntity Image
End Function





Type Image3D_ListImages
	Field Obj
End Type











Function DrawImage(Image,x#,y#,frame=0)
	ListImage.Image3D_ListImages=New Image3D_ListImages
	ListImage\Obj=CopyEntity(Image,Image3D_CameraPivot)
	
	ShowEntity ListImage\Obj
	;CameraProjMode Image3D_Camera,1
	
	EntityColor ListImage\Obj,Image3D_ColorR,Image3D_ColorG,Image3D_ColorB
	
	If Image3D_BlendMode=SolidBlend Or Image3D_BlendMode=Maskblend Then
	EntityBlend ListImage\Obj,1
	EntityAlpha ListImage\Obj,1
	ElseIf Image3D_BlendMode=Alphablend Then
	EntityBlend ListImage\Obj,1
	EntityAlpha ListImage\Obj,Image3D_Alpha#
	ElseIf Image3D_BlendMode=Lightblend Then
	EntityBlend ListImage\Obj,3
	EntityAlpha ListImage\Obj,Image3D_Alpha#
	ElseIf Image3D_BlendMode=ShadeBlend Then
	EntityBlend ListImage\Obj,2
	EntityAlpha ListImage\Obj,Image3D_Alpha#
	End If
	
	RotateEntity ListImage\Obj,0,0,Image3D_Rotation#
	ScaleEntity ListImage\Obj,Image3D_ScaleX#,Image3D_ScaleY#,1;,1
	
	PositionEntity ListImage\Obj,x,y,0
	
	EntityOrder ListImage\Obj,Image3D_OrderCount
	Image3D_OrderCount=Image3D_OrderCount-1
	
	;RenderWorld()
	;CameraProjMode Image3D_Camera,0
	;HideEntity Image
End Function

Function DrawRect(x#,y#,width#,height#)
	ListImage.Image3D_ListImages=New Image3D_ListImages
	ListImage\Obj=CopyEntity(Image3D_Rect,Image3D_CameraPivot)
	
	ShowEntity ListImage\Obj
	;CameraProjMode Image3D_Camera,1
	
	EntityColor ListImage\Obj,Image3D_ColorR,Image3D_ColorG,Image3D_ColorB
	
	If Image3D_BlendMode=SolidBlend Or Image3D_BlendMode=Maskblend Then
	EntityBlend ListImage\Obj,1
	EntityAlpha ListImage\Obj,1
	ElseIf Image3D_BlendMode=Alphablend Then
	EntityBlend ListImage\Obj,1
	EntityAlpha ListImage\Obj,Image3D_Alpha#
	ElseIf Image3D_BlendMode=Lightblend Then
	EntityBlend ListImage\Obj,3
	EntityAlpha ListImage\Obj,Image3D_Alpha#
	ElseIf Image3D_BlendMode=ShadeBlend Then
	EntityBlend ListImage\Obj,2
	EntityAlpha ListImage\Obj,Image3D_Alpha#
	End If
	
	RotateEntity ListImage\Obj,0,0,Image3D_Rotation#
	ScaleEntity ListImage\Obj,width#*Image3D_ScaleX#,height#*Image3D_ScaleY#,1;,1
	
	PositionEntity ListImage\Obj,x,y,0
	
	EntityOrder ListImage\Obj,Image3D_OrderCount
	Image3D_OrderCount=Image3D_OrderCount-1
	
	;RenderWorld()
	;CameraProjMode Image3D_Camera,0
	;HideEntity Image
End Function

Function FreeObj(Obj)
FreeEntity Obj
End Function

Function MakeObj(Image=0)
If Image=0 Then
Return CopyEntity(Image3D_Rect,Image3D_CameraPivot)
Else
Return CopyEntity(Image,Image3D_CameraPivot)
End If
End Function

Function SetObj(Obj,x#,y#,width#=1,height#=1)
	ShowEntity Obj
	;CameraProjMode Image3D_Camera,1
	EntityColor Obj,Image3D_ColorR,Image3D_ColorG,Image3D_ColorB
	If Image3D_BlendMode=SolidBlend Or Image3D_BlendMode=Maskblend Then
	EntityBlend Obj,1
	EntityAlpha Obj,1
	ElseIf Image3D_BlendMode=Alphablend Then
	EntityBlend Obj,1
	EntityAlpha Obj,Image3D_Alpha#
	ElseIf Image3D_BlendMode=Lightblend Then
	EntityBlend Obj,3
	EntityAlpha Obj,Image3D_Alpha#
	ElseIf Image3D_BlendMode=ShadeBlend Then
	EntityBlend Obj,2
	EntityAlpha Obj,Image3D_Alpha#
	End If
	RotateEntity Obj,0,0,Image3D_Rotation#
	ScaleEntity Obj,width#*Image3D_ScaleX#,height#*Image3D_ScaleY#,1;,1
	PositionEntity Obj,x,y,0
	EntityOrder Obj,Image3D_OrderCount
	Image3D_OrderCount=Image3D_OrderCount-1
End Function


Function Flip3D(TmpVWait=1)
CameraProjMode Image3D_Camera,1
RenderWorld()
CameraProjMode Image3D_Camera,0
For ListImage.Image3D_ListImages=Each Image3D_ListImages
FreeEntity ListImage\Obj
Delete ListImage
Next
Flip TmpVWait

Image3D_OrderCount=-1
End Function

Function DrawText(StringText$,x#,y#)
If Image3D_LoadText=0 Then;2D
;RuntimeError "Please set 'Image3D_LoadText' to 1"
Text x#,y#,StringText$
Return 1
End If

For n=1 To Len(StringText$)
ListImage.Image3D_ListImages=New Image3D_ListImages
ListImage\Obj=CopyEntity(Image3D_Rect,Image3D_CameraPivot)
ShowEntity ListImage\Obj
EntityColor ListImage\Obj,Image3D_ColorR,Image3D_ColorG,Image3D_ColorB
If Image3D_BlendMode=SolidBlend Or Image3D_BlendMode=Maskblend Then
EntityBlend ListImage\Obj,1
EntityAlpha ListImage\Obj,1
ElseIf Image3D_BlendMode=Alphablend Then
EntityBlend ListImage\Obj,1
EntityAlpha ListImage\Obj,Image3D_Alpha#
ElseIf Image3D_BlendMode=Lightblend Then
EntityBlend ListImage\Obj,3
EntityAlpha ListImage\Obj,Image3D_Alpha#
ElseIf Image3D_BlendMode=ShadeBlend Then
EntityBlend ListImage\Obj,2
EntityAlpha ListImage\Obj,Image3D_Alpha#
End If
RotateEntity ListImage\Obj,0,0,Image3D_Rotation#
;ScaleEntity ListImage\Obj,width#*Image3D_ScaleX#,height#*Image3D_ScaleY#,1;,1
PositionEntity ListImage\Obj,x+StringWidth(Mid(StringText$,1,n)),y,0
EntityTexture ListImage\Obj,Image3D_TextChar,Asc(Mid(StringText$,n,1))+1

Next

End Function

Function DrawLine(x#,y#,x2#,y2#,draw_last_pixel=True)





End Function


Function Graphics(x,y,depth=0,mode=0)
Graphics3D x,y,depth,mode

	If Image3D_Camera=0 Then;-Needs Graphics Set in Do
		Image3D_Camera=CreateCamera()
		CameraRange Image3D_Camera,1,1.001
		CameraClsMode Image3D_Camera,0,0;0,0
		CameraProjMode Image3D_Camera,0
		CameraZoom Image3D_Camera,1
		
		Image3D_CameraPivot=CreatePivot();Image3D_Camera
		PositionEntity Image3D_CameraPivot,-1,Float(GraphicsHeight())/GraphicsWidth(),1,1
		;PositionEntity Image3D_CameraPivot,0,0,5,1
		scale#=2.0/Float(GraphicsWidth())
		ScaleEntity Image3D_CameraPivot,scale#,-scale#,1
	End If
	
	Image3D_Rect=CreateMesh(Image3D_CameraPivot)
	Surface=CreateSurface(Image3D_Rect)
	
	v0=AddVertex(Surface,0	,0	,0	,0,0)
	v1=AddVertex(Surface,1	,0	,0	,1,0)
	v2=AddVertex(Surface,0	,1	,0	,0,1)
	v3=AddVertex(Surface,1	,1	,0	,1,1)
	
	AddTriangle(Surface,V0,V1,V2)
	AddTriangle(Surface,V1,V3,V2)
	EntityFX Image3D_Rect,1+4+8
	
	HideEntity Image3D_Rect
	
	If Image3D_LoadText=1 Then
	Image3D_TextChar=CreateTexture(FontWidth(),FontHeight(),1,257)
	Color 255,255,255
	For n=0 To 255
	
	SetBuffer TextureBuffer(Image3D_TextChar,n+1)
	Text 0,0,Chr(n)
	
	
	
	Next
	End If
	
	SetBuffer BackBuffer()
	
End Function