/*******************************************************************************************
							 | 
						|
								*
							 | 
						|
								*   raylib - sample game: gorilas
							 | 
						|
								*
							 | 
						|
								*   Sample game Marc Palau 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"
							 | 
						|
								
							 | 
						|
								#include <stdio.h>
							 | 
						|
								#include <stdlib.h>
							 | 
						|
								#include <time.h>
							 | 
						|
								#include <math.h>
							 | 
						|
								
							 | 
						|
								#if defined(PLATFORM_WEB)
							 | 
						|
								    #include <emscripten/emscripten.h>
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								// Some Defines
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								#define MAX_BUILDINGS                    15
							 | 
						|
								#define MAX_EXPLOSIONS                  200
							 | 
						|
								#define MAX_PLAYERS                       2
							 | 
						|
								
							 | 
						|
								#define BUILDING_RELATIVE_ERROR          30        // Building size random range %
							 | 
						|
								#define BUILDING_MIN_RELATIVE_HEIGHT     20        // Minimum height in % of the screenHeight
							 | 
						|
								#define BUILDING_MAX_RELATIVE_HEIGHT     60        // Maximum height in % of the screenHeight
							 | 
						|
								#define BUILDING_MIN_GRAYSCALE_COLOR    120        // Minimum gray color for the buildings
							 | 
						|
								#define BUILDING_MAX_GRAYSCALE_COLOR    200        // Maximum gray color for the buildings
							 | 
						|
								
							 | 
						|
								#define MIN_PLAYER_POSITION               5        // Minimum x position %
							 | 
						|
								#define MAX_PLAYER_POSITION              20        // Maximum x position %
							 | 
						|
								
							 | 
						|
								#define GRAVITY                       9.81f
							 | 
						|
								#define DELTA_FPS                        60
							 | 
						|
								
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								// Types and Structures Definition
							 | 
						|
								//----------------------------------------------------------------------------------
							 | 
						|
								typedef struct Player {
							 | 
						|
								    Vector2 position;
							 | 
						|
								    Vector2 size;
							 | 
						|
								
							 | 
						|
								    Vector2 aimingPoint;
							 | 
						|
								    int aimingAngle;
							 | 
						|
								    int aimingPower;
							 | 
						|
								
							 | 
						|
								    Vector2 previousPoint;
							 | 
						|
								    int previousAngle;
							 | 
						|
								    int previousPower;
							 | 
						|
								
							 | 
						|
								    Vector2 impactPoint;
							 | 
						|
								
							 | 
						|
								    bool isLeftTeam;                // This player belongs to the left or to the right team
							 | 
						|
								    bool isPlayer;                  // If is a player or an AI
							 | 
						|
								    bool isAlive;
							 | 
						|
								} Player;
							 | 
						|
								
							 | 
						|
								typedef struct Building {
							 | 
						|
								    Rectangle rectangle;
							 | 
						|
								    Color color;
							 | 
						|
								} Building;
							 | 
						|
								
							 | 
						|
								typedef struct Explosion {
							 | 
						|
								    Vector2 position;
							 | 
						|
								    int radius;
							 | 
						|
								    bool active;
							 | 
						|
								} Explosion;
							 | 
						|
								
							 | 
						|
								typedef struct Ball {
							 | 
						|
								    Vector2 position;
							 | 
						|
								    Vector2 speed;
							 | 
						|
								    int radius;
							 | 
						|
								    bool active;
							 | 
						|
								} Ball;
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// Global Variables Declaration
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								static int screenWidth = 800;
							 | 
						|
								static int screenHeight = 450;
							 | 
						|
								
							 | 
						|
								static bool gameOver = false;
							 | 
						|
								static bool pause = false;
							 | 
						|
								
							 | 
						|
								static Player player[MAX_PLAYERS];
							 | 
						|
								static Building building[MAX_BUILDINGS];
							 | 
						|
								static Explosion explosion[MAX_EXPLOSIONS];
							 | 
						|
								static Ball ball;
							 | 
						|
								
							 | 
						|
								static int playerTurn = 0;
							 | 
						|
								static bool ballOnAir = false;
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// 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)
							 | 
						|
								
							 | 
						|
								// Additional module functions
							 | 
						|
								static void InitBuildings(void);
							 | 
						|
								static void InitPlayers(void);
							 | 
						|
								static bool UpdatePlayer(int playerTurn);
							 | 
						|
								static bool UpdateBall(int playerTurn);
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								// Program main entry point
							 | 
						|
								//------------------------------------------------------------------------------------
							 | 
						|
								int main(void)
							 | 
						|
								{
							 | 
						|
								    // Initialization (Note windowTitle is unused on Android)
							 | 
						|
								    //---------------------------------------------------------
							 | 
						|
								    InitWindow(screenWidth, screenHeight, "sample game: gorilas");
							 | 
						|
								
							 | 
						|
								    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 and Draw
							 | 
						|
								        //----------------------------------------------------------------------------------
							 | 
						|
								        UpdateDrawFrame();
							 | 
						|
								        //----------------------------------------------------------------------------------
							 | 
						|
								    }
							 | 
						|
								#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)
							 | 
						|
								{
							 | 
						|
								    // Init shoot
							 | 
						|
								    ball.radius = 10;
							 | 
						|
								    ballOnAir = false;
							 | 
						|
								    ball.active = false;
							 | 
						|
								
							 | 
						|
								    InitBuildings();
							 | 
						|
								    InitPlayers();
							 | 
						|
								    
							 | 
						|
								    // Init explosions
							 | 
						|
								    for (int i = 0; i < MAX_EXPLOSIONS; i++)
							 | 
						|
								    {
							 | 
						|
								        explosion[i].position = (Vector2){ 0.0f, 0.0f };
							 | 
						|
								        explosion[i].radius = 30;
							 | 
						|
								        explosion[i].active = false;
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Update game (one frame)
							 | 
						|
								void UpdateGame(void)
							 | 
						|
								{
							 | 
						|
								    if (!gameOver)
							 | 
						|
								    {
							 | 
						|
								        if (IsKeyPressed('P')) pause = !pause;
							 | 
						|
								
							 | 
						|
								        if (!pause)
							 | 
						|
								        {
							 | 
						|
								            if (!ballOnAir) ballOnAir = UpdatePlayer(playerTurn); // If we are aiming
							 | 
						|
								            else
							 | 
						|
								            {
							 | 
						|
								                if (UpdateBall(playerTurn))                       // If collision
							 | 
						|
								                {
							 | 
						|
								                    // Game over logic
							 | 
						|
								                    bool leftTeamAlive = false;
							 | 
						|
								                    bool rightTeamAlive = false;
							 | 
						|
								
							 | 
						|
								                    for (int i = 0; i < MAX_PLAYERS; i++)
							 | 
						|
								                    {
							 | 
						|
								                        if (player[i].isAlive)
							 | 
						|
								                        {
							 | 
						|
								                            if (player[i].isLeftTeam) leftTeamAlive = true;
							 | 
						|
								                            if (!player[i].isLeftTeam) rightTeamAlive = true;
							 | 
						|
								                        }
							 | 
						|
								                    }
							 | 
						|
								                    
							 | 
						|
								                    if (leftTeamAlive && rightTeamAlive)
							 | 
						|
								                    {
							 | 
						|
								                        ballOnAir = false;
							 | 
						|
								                        ball.active = false;
							 | 
						|
								
							 | 
						|
								                        playerTurn++;
							 | 
						|
								
							 | 
						|
								                        if (playerTurn == MAX_PLAYERS) playerTurn = 0;
							 | 
						|
								                    }
							 | 
						|
								                    else
							 | 
						|
								                    {
							 | 
						|
								                        gameOver = true;
							 | 
						|
								                        
							 | 
						|
								                        // if (leftTeamAlive) left team wins
							 | 
						|
								                        // if (rightTeamAlive) right team wins
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        if (IsKeyPressed(KEY_ENTER))
							 | 
						|
								        {
							 | 
						|
								            InitGame();
							 | 
						|
								            gameOver = false;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Draw game (one frame)
							 | 
						|
								void DrawGame(void)
							 | 
						|
								{
							 | 
						|
								    BeginDrawing();
							 | 
						|
								
							 | 
						|
								        ClearBackground(RAYWHITE);
							 | 
						|
								
							 | 
						|
								        if (!gameOver)
							 | 
						|
								        {
							 | 
						|
								            // Draw buildings
							 | 
						|
								            for (int i = 0; i < MAX_BUILDINGS; i++) DrawRectangleRec(building[i].rectangle, building[i].color);
							 | 
						|
								
							 | 
						|
								            // Draw explosions
							 | 
						|
								            for (int i = 0; i < MAX_EXPLOSIONS; i++)
							 | 
						|
								            {
							 | 
						|
								                if (explosion[i].active) DrawCircle(explosion[i].position.x, explosion[i].position.y, explosion[i].radius, RAYWHITE);
							 | 
						|
								            }
							 | 
						|
								            
							 | 
						|
								            // Draw players
							 | 
						|
								            for (int i = 0; i < MAX_PLAYERS; i++)
							 | 
						|
								            {
							 | 
						|
								                if (player[i].isAlive)
							 | 
						|
								                {
							 | 
						|
								                    if (player[i].isLeftTeam) DrawRectangle(player[i].position.x - player[i].size.x/2, player[i].position.y - player[i].size.y/2,
							 | 
						|
								                                                             player[i].size.x, player[i].size.y, BLUE);
							 | 
						|
								                    else DrawRectangle(player[i].position.x - player[i].size.x/2, player[i].position.y - player[i].size.y/2,
							 | 
						|
								                                                             player[i].size.x, player[i].size.y, RED);
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            // Draw ball
							 | 
						|
								            if (ball.active) DrawCircle(ball.position.x, ball.position.y, ball.radius, MAROON);
							 | 
						|
								
							 | 
						|
								            // Draw the angle and the power of the aim, and the previous ones
							 | 
						|
								            if (!ballOnAir)
							 | 
						|
								            {
							 | 
						|
								                // Draw shot information
							 | 
						|
								                /*
							 | 
						|
								                if (player[playerTurn].isLeftTeam)
							 | 
						|
								                {
							 | 
						|
								                    DrawText(FormatText("Previous Point %i, %i", (int)player[playerTurn].previousPoint.x, (int)player[playerTurn].previousPoint.y), 20, 20, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Previous Angle %i", player[playerTurn].previousAngle), 20, 50, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Previous Power %i", player[playerTurn].previousPower), 20, 80, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Aiming Point %i, %i", (int)player[playerTurn].aimingPoint.x, (int)player[playerTurn].aimingPoint.y), 20, 110, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Aiming Angle %i", player[playerTurn].aimingAngle), 20, 140, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Aiming Power %i", player[playerTurn].aimingPower), 20, 170, 20, DARKBLUE);
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								                {
							 | 
						|
								                    DrawText(FormatText("Previous Point %i, %i", (int)player[playerTurn].previousPoint.x, (int)player[playerTurn].previousPoint.y), screenWidth*3/4, 20, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Previous Angle %i", player[playerTurn].previousAngle), screenWidth*3/4, 50, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Previous Power %i", player[playerTurn].previousPower), screenWidth*3/4, 80, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Aiming Point %i, %i", (int)player[playerTurn].aimingPoint.x, (int)player[playerTurn].aimingPoint.y), screenWidth*3/4, 110, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Aiming Angle %i", player[playerTurn].aimingAngle), screenWidth*3/4, 140, 20, DARKBLUE);
							 | 
						|
								                    DrawText(FormatText("Aiming Power %i", player[playerTurn].aimingPower), screenWidth*3/4, 170, 20, DARKBLUE);
							 | 
						|
								                }
							 | 
						|
								                */
							 | 
						|
								                
							 | 
						|
								                // Draw aim
							 | 
						|
								                if (player[playerTurn].isLeftTeam)
							 | 
						|
								                {
							 | 
						|
								                    // Previous aiming
							 | 
						|
								                    DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
							 | 
						|
								                                 (Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
							 | 
						|
								                                 player[playerTurn].previousPoint, GRAY);
							 | 
						|
								
							 | 
						|
								                    // Actual aiming
							 | 
						|
								                    DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
							 | 
						|
								                                 (Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
							 | 
						|
								                                 player[playerTurn].aimingPoint, DARKBLUE);
							 | 
						|
								                }
							 | 
						|
								                else
							 | 
						|
								                {
							 | 
						|
								                    // Previous aiming
							 | 
						|
								                    DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
							 | 
						|
								                                 (Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
							 | 
						|
								                                 player[playerTurn].previousPoint, GRAY);
							 | 
						|
								
							 | 
						|
								                    // Actual aiming
							 | 
						|
								                    DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
							 | 
						|
								                                 (Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
							 | 
						|
								                                 player[playerTurn].aimingPoint, MAROON);
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            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();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								//--------------------------------------------------------------------------------------
							 | 
						|
								// Additional module functions
							 | 
						|
								//--------------------------------------------------------------------------------------
							 | 
						|
								static void InitBuildings(void)
							 | 
						|
								{
							 | 
						|
								    // Horizontal generation
							 | 
						|
								    int currentWidth = 0;
							 | 
						|
								
							 | 
						|
								    // We make sure the absolute error randomly generated for each building, has as a minimum value the screenWidth.
							 | 
						|
								    // This way all the screen will be filled with buildings. Each building will have a different, random width.
							 | 
						|
								
							 | 
						|
								    float relativeWidth = 100/(100 - BUILDING_RELATIVE_ERROR);
							 | 
						|
								    float buildingWidthMean = (screenWidth*relativeWidth/MAX_BUILDINGS) + 1;        // We add one to make sure we will cover the whole screen.
							 | 
						|
								
							 | 
						|
								    // Vertical generation
							 | 
						|
								    int currentHeighth = 0;
							 | 
						|
								    int grayLevel;
							 | 
						|
								
							 | 
						|
								    // Creation
							 | 
						|
								    for (int i = 0; i < MAX_BUILDINGS; i++)
							 | 
						|
								    {
							 | 
						|
								        // Horizontal
							 | 
						|
								        building[i].rectangle.x = currentWidth;
							 | 
						|
								        building[i].rectangle.width = GetRandomValue(buildingWidthMean*(100 - BUILDING_RELATIVE_ERROR/2)/100 + 1, buildingWidthMean*(100 + BUILDING_RELATIVE_ERROR)/100);
							 | 
						|
								
							 | 
						|
								        currentWidth += building[i].rectangle.width;
							 | 
						|
								
							 | 
						|
								        // Vertical
							 | 
						|
								        currentHeighth = GetRandomValue(BUILDING_MIN_RELATIVE_HEIGHT, BUILDING_MAX_RELATIVE_HEIGHT);
							 | 
						|
								        building[i].rectangle.y = screenHeight - (screenHeight*currentHeighth/100);
							 | 
						|
								        building[i].rectangle.height = screenHeight*currentHeighth/100 + 1;
							 | 
						|
								
							 | 
						|
								        // Color
							 | 
						|
								        grayLevel = GetRandomValue(BUILDING_MIN_GRAYSCALE_COLOR, BUILDING_MAX_GRAYSCALE_COLOR);
							 | 
						|
								        building[i].color = (Color){ grayLevel, grayLevel, grayLevel, 255 };
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static void InitPlayers(void)
							 | 
						|
								{
							 | 
						|
								    for (int i = 0; i < MAX_PLAYERS; i++)
							 | 
						|
								    {
							 | 
						|
								        player[i].isAlive = true;
							 | 
						|
								
							 | 
						|
								        // Decide the team of this player
							 | 
						|
								        if (i % 2 == 0) player[i].isLeftTeam = true;
							 | 
						|
								        else player[i].isLeftTeam = false;
							 | 
						|
								
							 | 
						|
								        // Now there is no AI
							 | 
						|
								        player[i].isPlayer = true;
							 | 
						|
								
							 | 
						|
								        // Set size, by default by now
							 | 
						|
								        player[i].size = (Vector2){ 40, 40 };
							 | 
						|
								
							 | 
						|
								        // Set position
							 | 
						|
								        if (player[i].isLeftTeam) player[i].position.x = GetRandomValue(screenWidth*MIN_PLAYER_POSITION/100, screenWidth*MAX_PLAYER_POSITION/100);
							 | 
						|
								        else player[i].position.x = screenWidth - GetRandomValue(screenWidth*MIN_PLAYER_POSITION/100, screenWidth*MAX_PLAYER_POSITION/100);
							 | 
						|
								
							 | 
						|
								        for (int j = 0; j < MAX_BUILDINGS; j++)
							 | 
						|
								        {
							 | 
						|
								            if (building[j].rectangle.x > player[i].position.x)
							 | 
						|
								            {
							 | 
						|
								                // Set the player in the center of the building
							 | 
						|
								                player[i].position.x = building[j-1].rectangle.x + building[j-1].rectangle.width/2;
							 | 
						|
								                // Set the player at the top of the building
							 | 
						|
								                player[i].position.y = building[j-1].rectangle.y - player[i].size.y/2;
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // Set statistics to 0
							 | 
						|
								        player[i].aimingPoint = player[i].position;
							 | 
						|
								        player[i].previousAngle = 0;
							 | 
						|
								        player[i].previousPower = 0;
							 | 
						|
								        player[i].previousPoint = player[i].position;
							 | 
						|
								        player[i].aimingAngle = 0;
							 | 
						|
								        player[i].aimingPower = 0;
							 | 
						|
								
							 | 
						|
								        player[i].impactPoint = (Vector2){ -100, -100 };
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static bool UpdatePlayer(int playerTurn)
							 | 
						|
								{
							 | 
						|
								    // If we are aiming at the firing quadrant, we calculate the angle
							 | 
						|
								    if (GetMousePosition().y <= player[playerTurn].position.y)
							 | 
						|
								    {
							 | 
						|
								        // Left team
							 | 
						|
								        if (player[playerTurn].isLeftTeam && GetMousePosition().x >= player[playerTurn].position.x)
							 | 
						|
								        {
							 | 
						|
								            // Distance (calculating the fire power)
							 | 
						|
								            player[playerTurn].aimingPower = sqrt(pow(player[playerTurn].position.x - GetMousePosition().x, 2) + pow(player[playerTurn].position.y - GetMousePosition().y, 2));
							 | 
						|
								            // Calculates the angle via arcsin
							 | 
						|
								            player[playerTurn].aimingAngle = asin((player[playerTurn].position.y - GetMousePosition().y)/player[playerTurn].aimingPower)*RAD2DEG;
							 | 
						|
								            // Point of the screen we are aiming at
							 | 
						|
								            player[playerTurn].aimingPoint = GetMousePosition();
							 | 
						|
								
							 | 
						|
								            // Ball fired
							 | 
						|
								            if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
							 | 
						|
								            {
							 | 
						|
								                player[playerTurn].previousPoint = player[playerTurn].aimingPoint;
							 | 
						|
								                player[playerTurn].previousPower = player[playerTurn].aimingPower;
							 | 
						|
								                player[playerTurn].previousAngle = player[playerTurn].aimingAngle;
							 | 
						|
								                ball.position = player[playerTurn].position;
							 | 
						|
								
							 | 
						|
								                return true;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        // Right team
							 | 
						|
								        else if (!player[playerTurn].isLeftTeam && GetMousePosition().x <= player[playerTurn].position.x)
							 | 
						|
								        {
							 | 
						|
								            // Distance (calculating the fire power)
							 | 
						|
								            player[playerTurn].aimingPower = sqrt(pow(player[playerTurn].position.x - GetMousePosition().x, 2) + pow(player[playerTurn].position.y - GetMousePosition().y, 2));
							 | 
						|
								            // Calculates the angle via arcsin
							 | 
						|
								            player[playerTurn].aimingAngle = asin((player[playerTurn].position.y - GetMousePosition().y)/player[playerTurn].aimingPower)*RAD2DEG;
							 | 
						|
								            // Point of the screen we are aiming at
							 | 
						|
								            player[playerTurn].aimingPoint = GetMousePosition();
							 | 
						|
								
							 | 
						|
								            // Ball fired
							 | 
						|
								            if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
							 | 
						|
								            {
							 | 
						|
								                player[playerTurn].previousPoint = player[playerTurn].aimingPoint;
							 | 
						|
								                player[playerTurn].previousPower = player[playerTurn].aimingPower;
							 | 
						|
								                player[playerTurn].previousAngle = player[playerTurn].aimingAngle;
							 | 
						|
								                ball.position = player[playerTurn].position;
							 | 
						|
								
							 | 
						|
								                return true;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            player[playerTurn].aimingPoint = player[playerTurn].position;
							 | 
						|
								            player[playerTurn].aimingPower = 0;
							 | 
						|
								            player[playerTurn].aimingAngle = 0;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        player[playerTurn].aimingPoint = player[playerTurn].position;
							 | 
						|
								        player[playerTurn].aimingPower = 0;
							 | 
						|
								        player[playerTurn].aimingAngle = 0;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return false;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								static bool UpdateBall(int playerTurn)
							 | 
						|
								{
							 | 
						|
								    static int explosionNumber = 0;
							 | 
						|
								
							 | 
						|
								    // Activate ball
							 | 
						|
								    if (!ball.active)
							 | 
						|
								    {
							 | 
						|
								        if (player[playerTurn].isLeftTeam)
							 | 
						|
								        {
							 | 
						|
								            ball.speed.x = cos(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
							 | 
						|
								            ball.speed.y = -sin(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
							 | 
						|
								            ball.active = true;
							 | 
						|
								        }
							 | 
						|
								        else
							 | 
						|
								        {
							 | 
						|
								            ball.speed.x = -cos(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
							 | 
						|
								            ball.speed.y = -sin(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
							 | 
						|
								            ball.active = true;
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    ball.position.x += ball.speed.x;
							 | 
						|
								    ball.position.y += ball.speed.y;
							 | 
						|
								    ball.speed.y += GRAVITY/DELTA_FPS;
							 | 
						|
								
							 | 
						|
								    // Collision
							 | 
						|
								    if (ball.position.x + ball.radius < 0) return true;
							 | 
						|
								    else if (ball.position.x - ball.radius > screenWidth) return true;
							 | 
						|
								    else
							 | 
						|
								    {
							 | 
						|
								        // Player collision
							 | 
						|
								        for (int i = 0; i < MAX_PLAYERS; i++)
							 | 
						|
								        {
							 | 
						|
								            if (CheckCollisionCircleRec(ball.position, ball.radius,  (Rectangle){ player[i].position.x - player[i].size.x/2, player[i].position.y - player[i].size.y/2,
							 | 
						|
								                                                                                  player[i].size.x, player[i].size.y }))
							 | 
						|
								            {
							 | 
						|
								                // We can't hit ourselves
							 | 
						|
								                if (i == playerTurn) return false;
							 | 
						|
								                else
							 | 
						|
								                {
							 | 
						|
								                    // We set the impact point
							 | 
						|
								                    player[playerTurn].impactPoint.x = ball.position.x;
							 | 
						|
								                    player[playerTurn].impactPoint.y = ball.position.y + ball.radius;
							 | 
						|
								
							 | 
						|
								                    // We destroy the player
							 | 
						|
								                    player[i].isAlive = false;
							 | 
						|
								                    return true;
							 | 
						|
								                }
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // Building collision
							 | 
						|
								        // NOTE: We only check building collision if we are not inside an explosion
							 | 
						|
								        for (int i = 0; i < MAX_BUILDINGS; i++)
							 | 
						|
								        {
							 | 
						|
								            if (CheckCollisionCircles(ball.position, ball.radius, explosion[i].position, explosion[i].radius - ball.radius))
							 | 
						|
								            {
							 | 
						|
								                return false;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        for (int i = 0; i < MAX_BUILDINGS; i++)
							 | 
						|
								        {
							 | 
						|
								            if (CheckCollisionCircleRec(ball.position, ball.radius, building[i].rectangle))
							 | 
						|
								            {
							 | 
						|
								                // We set the impact point
							 | 
						|
								                player[playerTurn].impactPoint.x = ball.position.x;
							 | 
						|
								                player[playerTurn].impactPoint.y = ball.position.y + ball.radius;
							 | 
						|
								
							 | 
						|
								                // We create an explosion
							 | 
						|
								                explosion[explosionNumber].position = player[playerTurn].impactPoint;
							 | 
						|
								                explosion[explosionNumber].active = true;
							 | 
						|
								                explosionNumber++;
							 | 
						|
								
							 | 
						|
								                return true;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return false;
							 | 
						|
								}
							 |