/*******************************************************************************************
							 | 
						|
								*
							 | 
						|
								*   raylib - sample game: floppy
							 | 
						|
								*
							 | 
						|
								*   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 MAX_TUBES 100
							 | 
						|
								#define FLOPPY_RADIUS 24
							 | 
						|
								#define TUBES_WIDTH 80
							 | 
						|
								
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								// Types and Structures Definition
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								typedef struct Floppy {
							 | 
						|
								    Vector2 position;
							 | 
						|
								    int radius;
							 | 
						|
								    Color color;
							 | 
						|
								} Floppy;
							 | 
						|
								
							 | 
						|
								typedef struct Tubes {
							 | 
						|
								    Rectangle rec;
							 | 
						|
								    Color color;
							 | 
						|
								    bool active;
							 | 
						|
								} Tubes;
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// Global Variables Declaration
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								static int screenWidth = 800;
							 | 
						|
								static int screenHeight = 450;
							 | 
						|
								
							 | 
						|
								static int framesCounter;
							 | 
						|
								static bool gameOver;
							 | 
						|
								static bool pause;
							 | 
						|
								static int score;
							 | 
						|
								static int hiScore = 0;
							 | 
						|
								
							 | 
						|
								static Floppy floppy;
							 | 
						|
								static Tubes tubes[MAX_TUBES*2];
							 | 
						|
								static Vector2 tubesPos[MAX_TUBES];
							 | 
						|
								static int tubesSpeedX;
							 | 
						|
								static bool superfx;
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// 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: floppy");
							 | 
						|
								
							 | 
						|
								    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)
							 | 
						|
								{
							 | 
						|
								    floppy.radius = FLOPPY_RADIUS;
							 | 
						|
								    floppy.position = (Vector2){80, screenHeight/2 - floppy.radius};
							 | 
						|
								    tubesSpeedX = 2;
							 | 
						|
								
							 | 
						|
								    for (int i = 0; i < MAX_TUBES; i++)
							 | 
						|
								    {
							 | 
						|
								        tubesPos[i].x = 400 + 280*i;
							 | 
						|
								        tubesPos[i].y = -GetRandomValue(0, 120);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    for (int i = 0; i < MAX_TUBES*2; i += 2)
							 | 
						|
								    {
							 | 
						|
								        tubes[i].rec.x = tubesPos[i/2].x;
							 | 
						|
								        tubes[i].rec.y = tubesPos[i/2].y;
							 | 
						|
								        tubes[i].rec.width = TUBES_WIDTH;
							 | 
						|
								        tubes[i].rec.height = 255;
							 | 
						|
								
							 | 
						|
								        tubes[i+1].rec.x = tubesPos[i/2].x;
							 | 
						|
								        tubes[i+1].rec.y = 600 + tubesPos[i/2].y - 255;
							 | 
						|
								        tubes[i+1].rec.width = TUBES_WIDTH;
							 | 
						|
								        tubes[i+1].rec.height = 255;
							 | 
						|
								
							 | 
						|
								        tubes[i/2].active = true;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    score = 0;
							 | 
						|
								
							 | 
						|
								    gameOver = false;
							 | 
						|
								    superfx = false;
							 | 
						|
								    pause = false;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Update game (one frame)
							 | 
						|
								void UpdateGame(void)
							 | 
						|
								{
							 | 
						|
								    if (!gameOver)
							 | 
						|
								    {
							 | 
						|
								        if (IsKeyPressed('P')) pause = !pause;
							 | 
						|
								
							 | 
						|
								        if (!pause)
							 | 
						|
								        {
							 | 
						|
								            for (int i = 0; i < MAX_TUBES; i++) tubesPos[i].x -= tubesSpeedX;
							 | 
						|
								
							 | 
						|
								            for (int i = 0; i < MAX_TUBES*2; i += 2)
							 | 
						|
								            {
							 | 
						|
								                tubes[i].rec.x = tubesPos[i/2].x;
							 | 
						|
								                tubes[i+1].rec.x = tubesPos[i/2].x;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            if (IsKeyDown(KEY_SPACE) && !gameOver) floppy.position.y -= 3;
							 | 
						|
								            else floppy.position.y += 1;
							 | 
						|
								
							 | 
						|
								            // Check Collisions
							 | 
						|
								            for (int i = 0; i < MAX_TUBES*2; i++)
							 | 
						|
								            {
							 | 
						|
								                if (CheckCollisionCircleRec(floppy.position, floppy.radius, tubes[i].rec))
							 | 
						|
								                {
							 | 
						|
								                    gameOver = true;
							 | 
						|
								                    pause = false;
							 | 
						|
								                }
							 | 
						|
								                else if ((tubesPos[i/2].x < floppy.position.x) && tubes[i/2].active && !gameOver)
							 | 
						|
								                {
							 | 
						|
								                    score += 100;
							 | 
						|
								                    tubes[i/2].active = false;
							 | 
						|
								
							 | 
						|
								                    superfx = true;
							 | 
						|
								
							 | 
						|
								                    if (score > hiScore) hiScore = score;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        if (IsKeyPressed(KEY_ENTER))
							 | 
						|
								        {
							 | 
						|
								            InitGame();
							 | 
						|
								            gameOver = false;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Draw game (one frame)
							 | 
						|
								void DrawGame(void)
							 | 
						|
								{
							 | 
						|
								    BeginDrawing();
							 | 
						|
								
							 | 
						|
								        ClearBackground(RAYWHITE);
							 | 
						|
								
							 | 
						|
								        if (!gameOver) 
							 | 
						|
								        {
							 | 
						|
								            DrawCircle(floppy.position.x, floppy.position.y, floppy.radius, DARKGRAY);
							 | 
						|
								
							 | 
						|
								            // Draw tubes
							 | 
						|
								            for (int i = 0; i < MAX_TUBES; i++)
							 | 
						|
								            {
							 | 
						|
								                DrawRectangle(tubes[i*2].rec.x, tubes[i*2].rec.y, tubes[i*2].rec.width, tubes[i*2].rec.height, GRAY);
							 | 
						|
								                DrawRectangle(tubes[i*2 + 1].rec.x, tubes[i*2 + 1].rec.y, tubes[i*2 + 1].rec.width, tubes[i*2 + 1].rec.height, GRAY);
							 | 
						|
								            }
							 | 
						|
								            
							 | 
						|
								            // Draw flashing fx (one frame only)
							 | 
						|
								            if (superfx)
							 | 
						|
								            {
							 | 
						|
								                DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
							 | 
						|
								                superfx = false;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            DrawText(FormatText("%04i", score), 20, 20, 40, GRAY);
							 | 
						|
								            DrawText(FormatText("HI-SCORE: %04i", hiScore), 20, 70, 20, LIGHTGRAY);
							 | 
						|
								
							 | 
						|
								            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();
							 | 
						|
								}
							 |