diff options
| author | Ray <raysan5@gmail.com> | 2016-01-29 07:26:06 -0800 |
|---|---|---|
| committer | Ray <raysan5@gmail.com> | 2016-01-29 07:26:06 -0800 |
| commit | 708e8c558cb843b5e4b071bc2b99102533bafaea (patch) | |
| tree | 83561a8bf0b640c565a684c7a2b1ec80f490c044 /games/samples/space_invaders.c | |
| parent | 4ec0ac89cda482031c393425381a2627a9468f09 (diff) | |
| download | raylib-708e8c558cb843b5e4b071bc2b99102533bafaea.tar.gz raylib-708e8c558cb843b5e4b071bc2b99102533bafaea.zip | |
Added a bunch of sample games
Those games have been developed by students and ported to a common base
template. Some of them still require some review to be consistent with
each other (formatting, variables naming, code structure...)
Diffstat (limited to 'games/samples/space_invaders.c')
| -rw-r--r-- | games/samples/space_invaders.c | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/games/samples/space_invaders.c b/games/samples/space_invaders.c new file mode 100644 index 00000000..9f380628 --- /dev/null +++ b/games/samples/space_invaders.c @@ -0,0 +1,407 @@ +/******************************************************************************************* +* +* raylib - sample game: space invaders +* +* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria +* +* This game has been created using raylib v1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#if defined(PLATFORM_WEB) + #include <emscripten/emscripten.h> +#endif + +//---------------------------------------------------------------------------------- +// Some Defines +//---------------------------------------------------------------------------------- +#define NUM_SHOOTS 50 +#define NUM_MAX_ENEMIES 50 +#define FIRST_WAVE 10 +#define SECOND_WAVE 20 +#define THIRD_WAVE 50 + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum { FIRST = 0, SECOND, THIRD } enemyWave; + +typedef struct Player{ + Rectangle rec; + Vector2 speed; + Color color; +} Player; + +typedef struct Enemy{ + Rectangle rec; + Vector2 speed; + bool active; + Color color; +} Enemy; + +typedef struct Shoot{ + Rectangle rec; + Vector2 speed; + bool active; + Color color; +} Shoot; + +//------------------------------------------------------------------------------------ +// Global Variables Declaration +//------------------------------------------------------------------------------------ +static int screenWidth = 800; +static int screenHeight = 450; + +static int framesCounter; +static bool gameOver; +static bool pause; +static int score; +static bool victory; + +static Player player; +static Enemy enemy[NUM_MAX_ENEMIES]; +static Shoot shoot[NUM_SHOOTS]; +static enemyWave wave; + +static int shootRate; +static float alpha; + +static int activeEnemies; +static int enemiesKill; +static bool smooth; + +//------------------------------------------------------------------------------------ +// Module Functions Declaration (local) +//------------------------------------------------------------------------------------ +static void InitGame(void); // Initialize game +static void UpdateGame(void); // Update game (one frame) +static void DrawGame(void); // Draw game (one frame) +static void UnloadGame(void); // Unload game +static void UpdateDrawFrame(void); // Update and Draw (one frame) + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + InitWindow(screenWidth, screenHeight, "sample game: space invaders"); + + InitGame(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateGame(); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + DrawGame(); + //---------------------------------------------------------------------------------- + } +#endif + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadGame(); // Unload loaded data (textures, sounds, models...) + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definitions (local) +//------------------------------------------------------------------------------------ + +// Initialize game variables +void InitGame(void) +{ + // Initialize game variables + shootRate = 0; + pause = false; + gameOver = false; + victory = false; + smooth = false; + wave = FIRST; + activeEnemies = FIRST_WAVE; + enemiesKill = 0; + score = 0; + alpha = 0; + + // Initialize player + player.rec.x = 20; + player.rec.y = 50; + player.rec.width = 10; + player.rec.height = 10; + player.speed.x = 5; + player.speed.y = 5; + player.color = BLACK; + + // Initialize enemies + for (int i = 0; i < NUM_MAX_ENEMIES; i++) + { + 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 = DARKGRAY; + } + + // Initialize shoots + for (int i = 0; i < NUM_SHOOTS; i++) + { + 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 = WHITE; + } +} + +// Update game (one frame) +void UpdateGame(void) +{ + if (!gameOver) + { + if (IsKeyPressed('P')) pause = !pause; + + if (!pause) + { + switch (wave) + { + case FIRST: + { + if (!smooth) + { + alpha += 0.02f; + + if (alpha >= 1.0f) smooth = true; + } + + if (smooth) alpha -= 0.02f; + + if (enemiesKill == activeEnemies) + { + enemiesKill = 0; + + for (int i = 0; i < activeEnemies; i++) + { + if (!enemy[i].active) enemy[i].active = true; + } + + activeEnemies = SECOND_WAVE; + wave = SECOND; + smooth = false; + alpha = 0.0f; + } + } break; + case SECOND: + { + if (!smooth) + { + alpha += 0.02f; + + if (alpha >= 1.0f) smooth = true; + } + + if (smooth) alpha -= 0.02f; + + if (enemiesKill == activeEnemies) + { + enemiesKill = 0; + + for (int i = 0; i < activeEnemies; i++) + { + if (!enemy[i].active) enemy[i].active = true; + } + + activeEnemies = THIRD_WAVE; + wave = THIRD; + smooth = false; + alpha = 0.0f; + } + } break; + case THIRD: + { + if (!smooth) + { + alpha += 0.02f; + + if (alpha >= 1.0f) smooth = true; + } + + if (smooth) alpha -= 0.02f; + + if (enemiesKill == activeEnemies) victory = true; + + } break; + default: break; + } + + // Player movement + if (IsKeyDown(KEY_RIGHT)) player.rec.x += player.speed.x; + if (IsKeyDown(KEY_LEFT)) player.rec.x -= player.speed.x; + if (IsKeyDown(KEY_UP)) player.rec.y -= player.speed.y; + if (IsKeyDown(KEY_DOWN)) player.rec.y += player.speed.y; + + // Player collision with enemy + for (int i = 0; i < activeEnemies; i++) + { + if (CheckCollisionRecs(player.rec, enemy[i].rec)) gameOver = true; + } + + // Enemy behaviour + for (int i = 0; i < activeEnemies; i++) + { + if (enemy[i].active) + { + enemy[i].rec.x -= enemy[i].speed.x; + + if (enemy[i].rec.x < 0) + { + enemy[i].rec.x = GetRandomValue(screenWidth, screenWidth + 1000); + enemy[i].rec.y = GetRandomValue(0, screenHeight - enemy[i].rec.height); + } + } + } + + // Wall behaviour + if (player.rec.x <= 0) player.rec.x = 0; + if (player.rec.x + player.rec.width >= screenWidth) player.rec.x = screenWidth - player.rec.width; + if (player.rec.y <= 0) player.rec.y = 0; + if (player.rec.y + player.rec.height >= screenHeight) player.rec.y = screenHeight - player.rec.height; + + //Shoot initialization + if (IsKeyDown(KEY_SPACE)) + { + shootRate += 5; + + for (int i = 0; i < NUM_SHOOTS; i++) + { + if (!shoot[i].active && shootRate%20 == 0) + { + shoot[i].rec.x = player.rec.x; + shoot[i].rec.y = player.rec.y + player.rec.height/4; + shoot[i].active = true; + break; + } + } + } + + // Shoot logic + for (int i = 0; i < NUM_SHOOTS; i++) + { + if (shoot[i].active) + { + // Movement + shoot[i].rec.x += shoot[i].speed.x; + + // Collision with enemy + for (int j = 0; j < activeEnemies; j++) + { + if (enemy[j].active) + { + if (CheckCollisionRecs(shoot[i].rec, enemy[j].rec)) + { + shoot[i].active = false; + enemy[j].active = false; + enemy[j].rec.x = GetRandomValue(screenWidth, screenWidth + 1000); + enemy[j].rec.y = GetRandomValue(0, screenHeight - enemy[j].rec.height); + shootRate = 0; + enemiesKill++; + score += 100; + } + + if (shoot[i].rec.x + shoot[i].rec.width >= screenWidth) + { + shoot[i].active = false; + shootRate = 0; + } + } + } + } + } + } + } + else + { + if (IsKeyPressed(KEY_ENTER)) + { + InitGame(); + gameOver = false; + } + } +} + +// Draw game (one frame) +void DrawGame(void) +{ + BeginDrawing(); + + ClearBackground(LIGHTGRAY); + + if (!gameOver) + { + DrawRectangleRec(player.rec, player.color); + + if (wave == FIRST) DrawText("FIRST WAVE", screenWidth/2 - MeasureText("FIRST WAVE", 40)/2, screenHeight/2 - 40, 40, Fade(BLACK, alpha)); + else if (wave == SECOND) DrawText("SECOND WAVE", screenWidth/2 - MeasureText("SECOND WAVE", 40)/2, screenHeight/2 - 40, 40, Fade(BLACK, alpha)); + else if (wave == THIRD) DrawText("THIRD WAVE", screenWidth/2 - MeasureText("THIRD WAVE", 40)/2, screenHeight/2 - 40, 40, Fade(BLACK, alpha)); + + for (int i = 0; i < activeEnemies; i++) + { + if (enemy[i].active) DrawRectangleRec(enemy[i].rec, enemy[i].color); + } + + for (int i = 0; i < NUM_SHOOTS; i++) + { + if (shoot[i].active) DrawRectangleRec(shoot[i].rec, shoot[i].color); + } + + DrawText(FormatText("%04i", score), 20, 20, 40, DARKGRAY); + + if (victory) DrawText("YOU WIN", screenWidth/2 - MeasureText("YOU WIN", 40)/2, screenHeight/2 - 40, 40, BLACK); + + if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY); + } + else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY); + + EndDrawing(); +} + +// Unload game variables +void UnloadGame(void) +{ + // TODO: Unload all dynamic loaded data (textures, sounds, models...) +} + +// Update and Draw (one frame) +void UpdateDrawFrame(void) +{ + UpdateGame(); + DrawGame(); +}
\ No newline at end of file |
