Created
December 28, 2018 17:32
-
-
Save monsterbrain/030c7feeed2cb220e896a3b730e359a3 to your computer and use it in GitHub Desktop.
Raylib Space Invader Game Tutorial Full source Code. Made for this blogpost. https://monsterbraininc.com/2018/12/raylib-game-tutorial-space-invaders-using-vscode/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************************* | |
* | |
* raylib - sample game: space invaders | |
* | |
* Based on Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria | |
* Modifed by Monster Brain (monsterbraininc.com) - 2018 | |
* | |
* 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 <math.h> | |
#include "raylib.h" | |
//---------------------------------------------------------------------------------- | |
// Types and Structures Definition | |
//---------------------------------------------------------------------------------- | |
typedef struct Player | |
{ | |
Rectangle rect; | |
Vector2 speed; | |
Color color; | |
} Player; | |
typedef struct Enemy | |
{ | |
Rectangle rect; | |
Vector2 speed; | |
bool active; | |
Color color; | |
} Enemy; | |
typedef struct Shoot | |
{ | |
Rectangle rect; | |
Vector2 speed; | |
bool active; | |
Color color; | |
} Shoot; | |
//---------------------------------------------------------------------------------- | |
// Some Defines | |
//---------------------------------------------------------------------------------- | |
#define NUM_SHOOTS 50 | |
#define NUM_MAX_ENEMIES 50 | |
#define FIRST_WAVE 10 | |
#define SECOND_WAVE 20 | |
#define THIRD_WAVE 50 | |
//------------------------------------------------------------------------------------ | |
// Global Variables Declaration | |
//------------------------------------------------------------------------------------ | |
static int screenWidth = 800; | |
static int screenHeight = 450; | |
static Player player; | |
static Enemy enemy[NUM_MAX_ENEMIES]; | |
static Shoot shoot[NUM_SHOOTS]; | |
static int shootRate; | |
static int activeEnemies; | |
static Sound sfxShoot; | |
static Sound sfxExplode; | |
//------------------------------------------------------------------------------------ | |
// 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) | |
int main() | |
{ | |
InitWindow(screenWidth, screenHeight, "Space Invader - Sample"); | |
// Initialize audio device | |
InitAudioDevice(); | |
InitGame(); | |
SetTargetFPS(60); | |
// Main game loop | |
while (!WindowShouldClose()) // Detect window close button or ESC key | |
{ | |
// Update and Draw | |
UpdateDrawFrame(); | |
} | |
UnloadGame(); | |
CloseWindow(); | |
return 0; | |
} | |
// Module Functions Definitions (local) | |
// Initialize game variables | |
void InitGame(void) | |
{ | |
activeEnemies = 10; | |
shootRate = 0; | |
sfxShoot = LoadSound("shoot.ogg"); | |
sfxExplode = LoadSound("explode.ogg"); | |
// Initialize player | |
player.rect.x = screenWidth / 2.0f; | |
player.rect.y = screenHeight - 20; | |
player.rect.width = 20; | |
player.rect.height = 20; | |
player.speed.x = 5; | |
player.speed.y = 5; | |
player.color = BLACK; | |
// Initialize enemies | |
for (int i = 0; i < NUM_MAX_ENEMIES; i++) | |
{ | |
enemy[i].rect.width = 20; | |
enemy[i].rect.height = 20; | |
enemy[i].rect.x = GetRandomValue(0, screenWidth); | |
enemy[i].rect.y = GetRandomValue(-screenHeight, -20); | |
enemy[i].speed.x = 5; | |
enemy[i].speed.y = 5; | |
enemy[i].active = true; | |
enemy[i].color = BLUE; | |
} | |
// Initialize shoots | |
for (int i = 0; i < NUM_SHOOTS; i++) | |
{ | |
shoot[i].rect.x = player.rect.x; | |
shoot[i].rect.y = player.rect.y + player.rect.height / 4; | |
shoot[i].rect.width = 5; | |
shoot[i].rect.height = 10; | |
shoot[i].speed.x = 0; | |
shoot[i].speed.y = -10; | |
shoot[i].active = false; | |
shoot[i].color = MAROON; | |
} | |
} | |
// Update game (one frame) | |
void UpdateGame(void) | |
{ | |
// Player movement | |
if (IsKeyDown(KEY_RIGHT)) | |
player.rect.x += player.speed.x; | |
if (IsKeyDown(KEY_LEFT)) | |
player.rect.x -= player.speed.x; | |
// Enemy behaviour | |
for (int i = 0; i < activeEnemies; i++) | |
{ | |
if (enemy[i].active) | |
{ | |
enemy[i].rect.y += enemy[i].speed.y; | |
if (enemy[i].rect.y > screenHeight) | |
{ | |
enemy[i].rect.x = GetRandomValue(0, screenWidth); | |
enemy[i].rect.y = GetRandomValue(-screenHeight, -20); | |
} | |
} | |
} | |
// Wall behaviour | |
if (player.rect.x <= 0) | |
player.rect.x = 0; | |
if (player.rect.x + player.rect.width >= screenWidth) | |
player.rect.x = screenWidth - player.rect.width; | |
//Shoot initialization | |
if (IsKeyDown(KEY_SPACE)) | |
{ | |
shootRate += 5; | |
for (int i = 0; i < NUM_SHOOTS; i++) | |
{ | |
if (!shoot[i].active && shootRate % 40 == 0) | |
{ | |
PlaySound(sfxShoot); | |
shoot[i].rect.x = player.rect.x; | |
shoot[i].rect.y = player.rect.y + player.rect.height / 4; | |
shoot[i].active = true; | |
break; | |
} | |
} | |
} | |
// Shoot logic | |
for (int i = 0; i < NUM_SHOOTS; i++) | |
{ | |
if (shoot[i].active) | |
{ | |
// Movement | |
shoot[i].rect.y += shoot[i].speed.y; | |
// Collision with enemy | |
for (int j = 0; j < activeEnemies; j++) | |
{ | |
if (enemy[j].active) | |
{ | |
if (CheckCollisionRecs(shoot[i].rect, enemy[j].rect)) | |
{ | |
shoot[i].active = false; | |
enemy[j].rect.x = GetRandomValue(screenWidth, screenWidth + 1000); | |
enemy[j].rect.y = GetRandomValue(0, screenHeight - enemy[j].rect.height); | |
shootRate = 0; | |
PlaySound(sfxExplode); | |
// enemiesKill++; | |
// score += 100; | |
} | |
if (shoot[i].rect.y <= 0) //goes above the screen | |
{ | |
shoot[i].active = false; | |
shootRate = 0; | |
} | |
} | |
} | |
} | |
} | |
} | |
// Draw game (one frame) | |
void DrawGame(void) | |
{ | |
BeginDrawing(); | |
ClearBackground(RAYWHITE); | |
DrawRectangleRec(player.rect, player.color); | |
for (int i = 0; i < activeEnemies; i++) | |
{ | |
if (enemy[i].active) | |
DrawRectangleRec(enemy[i].rect, enemy[i].color); | |
} | |
for (int i = 0; i < NUM_SHOOTS; i++) | |
{ | |
if (shoot[i].active) | |
DrawRectangleRec(shoot[i].rect, shoot[i].color); | |
} | |
EndDrawing(); | |
} | |
// Update and Draw (one frame) | |
void UpdateDrawFrame(void) | |
{ | |
UpdateGame(); | |
DrawGame(); | |
} | |
void UnloadGame(void){ | |
UnloadSound(sfxShoot); | |
UnloadSound(sfxExplode); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment