Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
Mini Projet
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jiaqi GAO
Mini Projet
Commits
08a5af10
Commit
08a5af10
authored
Nov 02, 2020
by
Jiaqi GAO
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new file
parent
eec1b366
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
594 additions
and
0 deletions
+594
-0
gorilas
gorilas
+594
-0
No files found.
gorilas
0 → 100644
View file @
08a5af10
/*******************************************************************************************
*
* 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 const int screenWidth = 800;
static const int screenHeight = 450;
static bool gameOver = false;
static bool pause = false;
static Player player[MAX_PLAYERS] = { 0 };
static Building building[MAX_BUILDINGS] = { 0 };
static Explosion explosion[MAX_EXPLOSIONS] = { 0 };
static Ball ball = { 0 };
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++;
// playerTurn==0;
if (playerTurn == MAX_PLAYERS) playerTurn = 0;
}
else
{
UnloadGame();
}
}
}
}
}
}
// Draw game (one frame)
void DrawGame(void)
{
BeginDrawing();
ClearBackground(RAYWHITE);//910
if (!gameOver)
{
// Draw buildings
for (int i = 0; i < MAX_BUILDINGS; i++) DrawRectangleRec(building[i].rectangle, building[i].color);//1076
// 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);//1064
}
// 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,//1074
player[i].size.x, player[i].size.y, GREEN);
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, SKYBLUE);
// Draw the angle and the power of the aim, and the previous ones
if (!ballOnAir)
{
// Draw shot information
/*
if (player[playerTurn].isLeftTeam)
{
DrawText(TextFormat("Previous Point %i, %i", (int)player[playerTurn].previousPoint.x, (int)player[playerTurn].previousPoint.y), 20, 20, 20, DARKBLUE);
DrawText(TextFormat("Previous Angle %i", player[playerTurn].previousAngle), 20, 50, 20, DARKBLUE);
DrawText(TextFormat("Previous Power %i", player[playerTurn].previousPower), 20, 80, 20, DARKBLUE);
DrawText(TextFormat("Aiming Point %i, %i", (int)player[playerTurn].aimingPoint.x, (int)player[playerTurn].aimingPoint.y), 20, 110, 20, DARKBLUE);
DrawText(TextFormat("Aiming Angle %i", player[playerTurn].aimingAngle), 20, 140, 20, DARKBLUE);
DrawText(TextFormat("Aiming Power %i", player[playerTurn].aimingPower), 20, 170, 20, DARKBLUE);
}
else
{
DrawText(TextFormat("Previous Point %i, %i", (int)player[playerTurn].previousPoint.x, (int)player[playerTurn].previousPoint.y), screenWidth*3/4, 20, 20, DARKBLUE);
DrawText(TextFormat("Previous Angle %i", player[playerTurn].previousAngle), screenWidth*3/4, 50, 20, DARKBLUE);
DrawText(TextFormat("Previous Power %i", player[playerTurn].previousPower), screenWidth*3/4, 80, 20, DARKBLUE);
DrawText(TextFormat("Aiming Point %i, %i", (int)player[playerTurn].aimingPoint.x, (int)player[playerTurn].aimingPoint.y), screenWidth*3/4, 110, 20, DARKBLUE);
DrawText(TextFormat("Aiming Angle %i", player[playerTurn].aimingAngle), screenWidth*3/4, 140, 20, DARKBLUE);
DrawText(TextFormat("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);//1085
// 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, DARKGREEN);
}
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);//1218,1226
}
EndDrawing();//912
}
// Unload game variables
void UnloadGame(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)");
InitAudioDevice(); // Initialize audio device 1398
Music music = LoadMusicStream("123.mp3");
PlayMusicStream(music);//1432
float timePlayed = 0.0f;
bool pause = false;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateMusicStream(music); // Update music buffer with new stream data 1433
// Get timePlayed scaled to bar dimensions (400 pixels)
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*400;
if (timePlayed > 399) StopMusicStream(music);
BeginDrawing();
ClearBackground(RAYWHITE);
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
DrawRectangle(200, 200, (int)timePlayed, 12, PINK);
DrawRectangleLines(200, 200, 400, 12, GRAY);
DrawText(" YOU WIN BRAVO GOOD GAME ! !", 215, 250, 20, VIOLET);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadMusicStream(music); // Unload music stream buffers from RAM
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
}
// 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;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment