| /******************************************************************************************* | |
| * | |
| *   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() | |
| { | |
|     // Initialization | |
|     //-------------------------------------------------------------------------------------- | |
|     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 | |
|         //---------------------------------------------------------------------------------- | |
|         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) | |
| { | |
|     // 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; | |
| } |