Bläddra i källkod

Added new game.

Brucey 5 år sedan
förälder
incheckning
399b6de4a6
1 ändrade filer med 378 tillägg och 0 borttagningar
  1. 378 0
      games/space_invaders.bmx

+ 378 - 0
games/space_invaders.bmx

@@ -0,0 +1,378 @@
+SuperStrict
+
+Framework Ray.Lib
+Import Text.Format
+
+
+New TSpaceInvadersGame.Run()
+
+
+Type TSpaceInvadersGame
+
+	Const NUM_SHOOTS:Int = 50
+	Const NUM_MAX_ENEMIES:Int = 50
+	Const FIRST_WAVE:Int = 10
+	Const SECOND_WAVE:Int = 20
+	Const THIRD_WAVE:Int = 50
+
+	Const screenWidth:Int = 800
+	Const screenHeight:Int = 450
+
+	Field gameOver:Int = False
+	Field pause:Int =  False
+	Field score:Int = 0
+	Field victory:Int = False
+
+	Field player:SPlayer
+	Field enemy:SEnemy[NUM_MAX_ENEMIES]
+	Field shoot:SShoot[NUM_SHOOTS]
+	Field wave:EEnemyWave
+
+	Field shootRate:Int = 0
+	Field alpha:Float = 0.0
+
+	Field activeEnemies:Int = 0
+	Field enemiesKill:Int = 0
+	Field smooth:Int = False
+
+	Field scoreFormat:TFormatter = TFormatter.Create("%04i")
+
+	Method Run()
+		' Initialization (Note windowTitle is unused on Android)
+		'---------------------------------------------------------
+		InitWindow(screenWidth, screenHeight, "sample game: space invaders")
+
+		InitGame()
+
+		SetTargetFPS(60)
+		'--------------------------------------------------------------------------------------
+
+		' Main game loop
+		While Not WindowShouldClose()    ' Detect window close button or ESC key
+			' Update and Draw
+			'----------------------------------------------------------------------------------
+			UpdateDrawFrame()
+			'----------------------------------------------------------------------------------
+		Wend
+
+		' De-Initialization
+		'--------------------------------------------------------------------------------------
+		UnloadGame()         ' Unload loaded data (textures, sounds, models...)
+
+		CloseWindow()        ' Close window and OpenGL context
+		'--------------------------------------------------------------------------------------
+	End Method
+	
+	' Initialize game variables
+	Method InitGame()
+		' Initialize game variables
+		shootRate = 0
+		pause = False
+		gameOver = False
+		victory = False
+		smooth = False
+		wave = EEnemyWave.First
+		activeEnemies = FIRST_WAVE
+		enemiesKill = 0
+		score = 0
+		alpha = 0
+
+		' Initialize player
+		player.rec.x =  20
+		player.rec.y = 50
+		player.rec.width = 20
+		player.rec.height = 20
+		player.speed.x = 5
+		player.speed.y = 5
+		player.color = BLACK
+
+		' Initialize enemies
+		For Local i:Int = 0 Until NUM_MAX_ENEMIES
+			enemy[i].rec.width = 10
+			enemy[i].rec.height = 10
+			enemy[i].rec.x = GetRandomValue(screenWidth, screenWidth + 1000)
+			enemy[i].rec.y = GetRandomValue(0, screenHeight - enemy[i].rec.height)
+			enemy[i].speed.x = 5
+			enemy[i].speed.y = 5
+			enemy[i].active = True
+			enemy[i].color = GRAY
+		Next
+
+		' Initialize shoots
+		For Local i:Int = 0 Until NUM_SHOOTS
+			shoot[i].rec.x = player.rec.x
+			shoot[i].rec.y = player.rec.y + player.rec.height/4
+			shoot[i].rec.width = 10
+			shoot[i].rec.height = 5
+			shoot[i].speed.x = 7
+			shoot[i].speed.y = 0
+			shoot[i].active = False
+			shoot[i].color = MAROON
+		Next
+
+	End Method
+	
+	' Update game (one frame)
+	Method UpdateGame()
+		If Not gameOver Then
+
+			If IsKeyPressed(KEY_P) Then
+				pause = Not pause
+			End If
+
+			If Not pause Then
+				Select wave
+
+					Case EEnemyWave.First
+
+						If Not smooth Then
+							alpha :+ 0.02
+							
+							If alpha >= 1.0 Then
+								smooth = True
+							End If
+						End If
+						
+						If smooth Then
+							alpha :- 0.02
+						End If
+						
+						If enemiesKill = activeEnemies Then
+
+							enemiesKill = 0
+
+							For Local i:Int = 0 Until activeEnemies
+								If Not enemy[i].active Then
+									enemy[i].active = True
+								End If
+							Next
+							
+							activeEnemies = SECOND_WAVE
+							wave = EEnemyWave.Second
+							smooth = False
+							alpha = 0.0
+						End If
+					Case EEnemyWave.Second
+						If Not smooth Then
+							alpha :+ 0.02
+							
+							If alpha >= 1.0 Then
+								smooth = True
+							End If
+						End If
+						
+						If smooth Then
+							alpha :- 0.02
+						End If
+						
+						If enemiesKill = activeEnemies Then
+							enemiesKill = 0
+
+							For Local i:Int = 0 Until activeEnemies
+								If Not enemy[i].active Then
+									enemy[i].active = True
+								End If
+							Next
+							
+							activeEnemies = THIRD_WAVE
+							wave = EEnemyWave.Third
+							smooth = False
+							alpha = 0.0
+						End If
+					Case EEnemyWave.Third
+						If Not smooth Then
+							alpha :+ 0.02
+							
+							If alpha >= 1.0 Then
+								smooth = True
+							End If
+						End If
+						
+						If smooth Then
+							alpha :- 0.02
+						End If
+						
+						If enemiesKill = activeEnemies Then
+							victory = True
+						End If
+							
+				End Select
+
+				' Player movement
+				If IsKeyDown(KEY_RIGHT) Then
+					player.rec.x :+ player.speed.x
+				End If
+				If IsKeyDown(KEY_LEFT) Then
+					player.rec.x :- player.speed.x
+				End If
+				If IsKeyDown(KEY_UP) Then
+					player.rec.y :- player.speed.y
+				End If
+				If IsKeyDown(KEY_DOWN) Then
+					player.rec.y :+ player.speed.y
+				End If
+
+				' Player collision with enemy
+				For Local i:Int = 0 Until activeEnemies
+					If CheckCollisionRecs(player.rec, enemy[i].rec) Then
+						gameOver = True
+					End If
+				Next
+
+				 ' Enemy behaviour
+				For Local i:Int = 0 Until activeEnemies
+					If enemy[i].active Then
+						enemy[i].rec.x :- enemy[i].speed.x
+
+						If enemy[i].rec.x < 0 Then
+							enemy[i].rec.x = GetRandomValue(screenWidth, screenWidth + 1000)
+							enemy[i].rec.y = GetRandomValue(0, screenHeight - enemy[i].rec.height)
+						End If
+					End If
+				Next
+
+				' Wall behaviour
+				If player.rec.x <= 0 Then
+					player.rec.x = 0
+				End If
+				If player.rec.x + player.rec.width >= screenWidth Then
+					player.rec.x = screenWidth - player.rec.width
+				End If
+				If player.rec.y <= 0 Then
+					player.rec.y = 0
+				End If
+				If player.rec.y + player.rec.height >= screenHeight Then
+					player.rec.y = screenHeight - player.rec.height
+				End If
+
+				' Shoot initialization
+				If IsKeyDown(KEY_SPACE) Then
+					shootRate :+ 5
+
+					For Local i:Int = 0 Until NUM_SHOOTS
+						If Not shoot[i].active And shootRate Mod 20 = 0 Then
+							shoot[i].rec.x = player.rec.x
+							shoot[i].rec.y = player.rec.y + player.rec.height/4
+							shoot[i].active = True
+							Exit
+						End If
+					Next
+				End If
+
+				' Shoot logic
+				For Local i:Int = 0 Until NUM_SHOOTS
+					If shoot[i].active Then
+						' Movement
+						shoot[i].rec.x :+ shoot[i].speed.x
+
+						' Collision with enemy
+						For Local j:Int = 0 Until activeEnemies
+
+							If enemy[j].active Then
+								If CheckCollisionRecs(shoot[i].rec, enemy[j].rec) Then
+									shoot[i].active = False
+									enemy[j].rec.x = GetRandomValue(screenWidth, screenWidth + 1000)
+									enemy[j].rec.y = GetRandomValue(0, screenHeight - enemy[j].rec.height)
+									shootRate = 0
+									enemiesKill :+ 1
+									score :+ 100
+								End If
+								
+								If shoot[i].rec.x + shoot[i].rec.width >= screenWidth Then
+									shoot[i].active = False
+									shootRate = 0
+								End If
+							End If
+						Next
+					End If
+				Next
+			End If
+		Else
+			If IsKeyPressed(KEY_ENTER) Then
+				InitGame()
+				gameOver = False
+			End If
+		End If
+	End Method
+
+	' Draw game (one frame)
+	Method DrawGame()
+		BeginDrawing()
+
+			ClearBackground(RAYWHITE)
+			
+			If Not gameOver Then
+				DrawRectangleRec(player.rec, player.color)
+
+				If wave = EEnemyWave.First Then
+					DrawText("FIRST WAVE", screenWidth/2 - MeasureText("FIRST WAVE", 40)/2, screenHeight/2 - 40, 40, Fade(BLACK, alpha))
+				Else If wave = EEnemyWave.Second Then
+					DrawText("SECOND WAVE", screenWidth/2 - MeasureText("SECOND WAVE", 40)/2, screenHeight/2 - 40, 40, Fade(BLACK, alpha))
+				Else If wave = EEnemyWave.Third Then
+					DrawText("THIRD WAVE", screenWidth/2 - MeasureText("THIRD WAVE", 40)/2, screenHeight/2 - 40, 40, Fade(BLACK, alpha))
+				End If
+				
+				For Local i:Int = 0 Until activeEnemies
+					If enemy[i].active Then
+						DrawRectangleRec(enemy[i].rec, enemy[i].color)
+					End If
+				Next
+
+				For Local i:Int = 0 Until NUM_SHOOTS
+					If shoot[i].active Then
+						DrawRectangleRec(shoot[i].rec, shoot[i].color)
+					End If
+				Next
+				
+				DrawText(scoreFormat.Clear().Arg(score).Format(), 20, 20, 40, GRAY)
+			
+				If victory Then
+					DrawText("YOU WIN", screenWidth/2 - MeasureText("YOU WIN", 40)/2, screenHeight/2 - 40, 40, BLACK)
+				End If
+			
+				If pause Then
+					DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY)
+				End If
+			Else
+				DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY)
+			End If
+
+		EndDrawing()
+	End Method
+	
+	Method UnloadGame()
+		' TODO: Unload all dynamic loaded data (textures, sounds, models...)
+	End Method
+
+	' Update and Draw (one frame)
+	Method UpdateDrawFrame()
+		UpdateGame()
+		DrawGame()
+	End Method
+End Type
+
+Enum EEnemyWave
+	First = 0
+	Second
+	Third
+End Enum
+
+Struct SPlayer
+    Field rec:RRectangle
+    Field speed:RVector2
+    Field color:RColor
+End Struct
+
+Struct SEnemy
+    Field rec:RRectangle
+    Field speed:RVector2
+    Field active:Int
+    Field color:RColor
+End Struct
+
+Struct SShoot
+    Field rec:RRectangle
+    Field speed:RVector2
+    Field active:Int
+    Field color:RColor
+End Struct