Commit df36b02e authored by Fan FEI's avatar Fan FEI

version "final"

parent b1554786
...@@ -18,9 +18,7 @@ ...@@ -18,9 +18,7 @@
#include <raylib.h> #include <raylib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <math.h> #include <math.h>
#include <errno.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
...@@ -32,15 +30,14 @@ ...@@ -32,15 +30,14 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Some Defines // Some Defines
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define SNAKE_LENGTH 256 #define SNAKE_LENGTH 256
#define SQUARE_SIZE 39 #define SQUARE_SIZE 39
Music soundtrack;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef struct Snake { // typedef struct Snake {
Vector2 position; Vector2 position;
Vector2 size; Vector2 size;
Vector2 speed; Vector2 speed;
...@@ -57,20 +54,26 @@ typedef struct Food { ...@@ -57,20 +54,26 @@ typedef struct Food {
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Global Variables Declaration // Global Variables Declaration
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
static const int screenWidth = 1500; //Set the width of the game interface static const int screenWidth = 1200; //Set the width of the game interface
static const int screenHeight = 1500; //Set the Height of the game interface static const int screenHeight = 1200; //Set the Height of the game interface
static int framesCounter = 0; static int framesCounter = 0;
static bool gameOver = false; static bool gameOver = false;
static bool pause = false; static bool pause = false;
static Food fruit = { 0 }; static Food fruit = { 0 };
static Food star = { 0 }; // Generate a reward
static Snake snake[SNAKE_LENGTH] = { 0 }; //Maximum length of snake static Snake snake[SNAKE_LENGTH] = { 0 }; //Maximum length of snake
static Vector2 snakePosition[SNAKE_LENGTH] = { 0 }; //The coordinates of the snake body static Vector2 snakePosition[SNAKE_LENGTH] = { 0 }; //The coordinates of the snake body
static bool allowMove = false; static bool allowMove = false;
static Vector2 offset = { 0 }; static Vector2 offset = { 0 };
static int counterTail = 0; static int counterTail = 0;
static int numWalls = 7; // Number of walls
static Rectangle walls[ 7 ];
Music soundtrack; // Add soundtrack
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module Functions Declaration (local) // Module Functions Declaration (local)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
...@@ -79,6 +82,9 @@ static void UpdateGame(void); // Update game (one frame) ...@@ -79,6 +82,9 @@ static void UpdateGame(void); // Update game (one frame)
static void DrawGame(void); // Draw game (one frame) static void DrawGame(void); // Draw game (one frame)
static void UnloadGame(void); // Unload game static void UnloadGame(void); // Unload game
static void UpdateDrawFrame(void); // Update and Draw (one frame) static void UpdateDrawFrame(void); // Update and Draw (one frame)
static void InitWalls(void);
static void DrawWalls(void);
static bool IsCoCollision(Vector2 coor);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
...@@ -87,14 +93,16 @@ int main(void) ...@@ -87,14 +93,16 @@ int main(void)
{ {
// Initialization (Note windowTitle is unused on Android) // Initialization (Note windowTitle is unused on Android)
//--------------------------------------------------------- //---------------------------------------------------------
InitWindow(screenWidth, screenHeight, "sample game: snake By FanFEI"); // Initialize the interface and title InitWindow(screenWidth, screenHeight , "Raylib : snake By Fan FEI"); // Initialize the interface and title
// Add soundtrack
InitAudioDevice(); InitAudioDevice();
char *music = "Music_snake_FanFEI.mp3"; char *music = "Music_snake_FanFEI.mp3";
soundtrack = LoadMusicStream(music); soundtrack = LoadMusicStream(music);
PlayMusicStream(soundtrack); PlayMusicStream(soundtrack);
InitGame(); //Initialize the game InitGame(); //Initialize the game
InitWalls(); //Initialize the walls
#if defined(PLATFORM_WEB) #if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 60, 1); // The number of frames can adjust the game speed emscripten_set_main_loop(UpdateDrawFrame, 60, 1); // The number of frames can adjust the game speed
...@@ -156,9 +164,13 @@ void InitGame(void) ...@@ -156,9 +164,13 @@ void InitGame(void)
snakePosition[i] = (Vector2){ 0.0f, 0.0f }; snakePosition[i] = (Vector2){ 0.0f, 0.0f };
} }
fruit.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE }; // The color, coordinates and status of the props fruit.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE }; // The color, coordinates and status of the fruit
fruit.color = RED; fruit.color = RED; // An apple maybe :)
fruit.active = false; fruit.active = false;
star.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE }; // The color, coordinates and status of the star
star.color = GOLD;
star.active = false;
} }
// Update game (one frame) // Update game (one frame)
...@@ -166,7 +178,10 @@ void UpdateGame(void) ...@@ -166,7 +178,10 @@ void UpdateGame(void)
{ {
if (!gameOver) if (!gameOver)
{ {
if (IsKeyPressed('P')) pause = !pause; // Keyboard input p pause if (IsKeyPressed('P')){
pause = !pause; // Keyboard input p pause
SetMusicVolume(soundtrack, 1);
}
if (!pause) if (!pause)
{ {
...@@ -211,12 +226,7 @@ void UpdateGame(void) ...@@ -211,12 +226,7 @@ void UpdateGame(void)
} }
// Wall behaviour // Wall behaviour
/*
if (((snake[0].position.y) > (screenHeight - offset.y)) || (snake[0].position.y < 0))
{
gameOver = true;
}
*/
if ((snake[0].position.x) > (screenWidth - offset.x)) if ((snake[0].position.x) > (screenWidth - offset.x))
snake[0].position.x = offset.x/2; snake[0].position.x = offset.x/2;
if ((snake[0].position.y) > (screenHeight - offset.y)) if ((snake[0].position.y) > (screenHeight - offset.y))
...@@ -226,6 +236,12 @@ void UpdateGame(void) ...@@ -226,6 +236,12 @@ void UpdateGame(void)
if ((snake[0].position.y < 0)) if ((snake[0].position.y < 0))
snake[0].position.y += (screenHeight - offset.y); snake[0].position.y += (screenHeight - offset.y);
for(int i = 0;i < numWalls;i++){
if(CheckCollisionPointRec(snake[0].position, walls[i])){
gameOver = true;
}
}
// Collision with yourself // Collision with yourself
for (int i = 1; i < counterTail; i++) for (int i = 1; i < counterTail; i++)
{ {
...@@ -239,14 +255,28 @@ void UpdateGame(void) ...@@ -239,14 +255,28 @@ void UpdateGame(void)
fruit.active = true; //Randomly generate a fruit on the map fruit.active = true; //Randomly generate a fruit on the map
fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 }; fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
for (int i = 0; i < counterTail; i++) //The position of the fruit will not overlap with the snake for (int i = 0; i < counterTail; i++) //The position of the fruit will not overlap with the snake and walls
{ {
while ((fruit.position.x == snake[i].position.x) && (fruit.position.y == snake[i].position.y)) while (((fruit.position.x == snake[i].position.x) && (fruit.position.y == snake[i].position.y)) || (IsCoCollision(fruit.position)))
{ {
fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 }; fruit.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
} }
} }
} }
if (!star.active || (framesCounter%300 == 0))
{
star.active = true; //Randomly generate a star on the map
star.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
for (int i = 0; i < counterTail; i++) //The position of the star will not overlap with the snake and walls
{
while (((star.position.x == snake[i].position.x) && (star.position.y == snake[i].position.y)) || (IsCoCollision(star.position)))
{
star.position = (Vector2){ GetRandomValue(0, (screenWidth/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2, GetRandomValue(0, (screenHeight/SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2 };
}
}
}
// Collision // Collision
if ((snake[0].position.x < (fruit.position.x + fruit.size.x) && (snake[0].position.x + snake[0].size.x) > fruit.position.x) && if ((snake[0].position.x < (fruit.position.x + fruit.size.x) && (snake[0].position.x + snake[0].size.x) > fruit.position.x) &&
...@@ -256,7 +286,15 @@ void UpdateGame(void) ...@@ -256,7 +286,15 @@ void UpdateGame(void)
counterTail += 1; counterTail += 1;
fruit.active = false; fruit.active = false;
} }
if ((snake[0].position.x < (star.position.x + star.size.x) && (snake[0].position.x + snake[0].size.x) > star.position.x) &&
(snake[0].position.y < (star.position.y + star.size.y) && (snake[0].position.y + snake[0].size.y) > star.position.y))
{
snake[counterTail].position = snakePosition[counterTail - 1];
counterTail += 2;
star.active = false;
}
framesCounter++; framesCounter++;
} }
} }
...@@ -272,6 +310,57 @@ void UpdateGame(void) ...@@ -272,6 +310,57 @@ void UpdateGame(void)
} }
} }
// Draw walls
void InitWalls(void){
int randNum;
int randDirection;
int randX;
int randY;
int maxWalls = (screenWidth/SQUARE_SIZE)/4;
int minWalls = 3;
for(int i = 0;i < numWalls;i++){
randNum = rand() % (maxWalls - minWalls) + minWalls;
randX = rand() % (screenWidth/SQUARE_SIZE); // ((maxWalls ) - minWalls) + minWalls;
randY = rand() % (screenWidth/SQUARE_SIZE); // ((maxWalls ) - minWalls) + minWalls;
walls[i].x = randX*SQUARE_SIZE + offset.x/2;
walls[i].y = randY*SQUARE_SIZE + offset.y/2;
if(i%2 == 0){
walls[i].width = (SQUARE_SIZE - 1);
walls[i].height = (SQUARE_SIZE*randNum - 1);
}else{
walls[i].width = (SQUARE_SIZE*randNum - 1);
walls[i].height = (SQUARE_SIZE - 1);
}
/*
If i do not subtract 1 from the height and the width,
then after the judgment of function bool CheckCollisionPointRec(Vector2 point, Rectangle rec),
a game bug will occur.
*/
}
}
void DrawWalls(void){
for(int i = 0;i < numWalls;i++){
DrawRectangleRec(walls[i],GRAY);
}
}
bool IsCoCollision(Vector2 coor){
for(int i = 0;i < numWalls;i++){
if(CheckCollisionPointRec(coor, walls[i])){
return true;
}
}
return false;
}
// Draw game (one frame) // Draw game (one frame)
void DrawGame(void) void DrawGame(void)
{ {
...@@ -294,18 +383,29 @@ void DrawGame(void) ...@@ -294,18 +383,29 @@ void DrawGame(void)
// Draw snake // Draw snake
for (int i = 0; i < counterTail; i++) DrawRectangleV(snake[i].position, snake[i].size, snake[i].color); for (int i = 0; i < counterTail; i++) DrawRectangleV(snake[i].position, snake[i].size, snake[i].color);
// Draw walls
DrawWalls();
// Draw fruit to pick // Draw fruit to pick
DrawRectangleV(fruit.position, fruit.size, fruit.color); DrawRectangleV(fruit.position, fruit.size, fruit.color);
DrawRectangleV(star.position, star.size, star.color);
// Show time and score // Show time and score
DrawText(TextFormat("TIME : %.1f s", (float)framesCounter/60), screenWidth-SQUARE_SIZE*8, SQUARE_SIZE, SQUARE_SIZE, DARKGRAY); DrawText(TextFormat("TIME : %.1f s", (float)framesCounter/60), screenWidth-SQUARE_SIZE*8, SQUARE_SIZE, SQUARE_SIZE, DARKGRAY);
DrawText(TextFormat("SCORE: %03d", counterTail), screenWidth-SQUARE_SIZE*8, SQUARE_SIZE*2, SQUARE_SIZE, DARKGRAY); DrawText(TextFormat("SCORE: %03d", counterTail-2), screenWidth-SQUARE_SIZE*8, SQUARE_SIZE*2, SQUARE_SIZE, DARKGRAY);
// Show pause // Show pause
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY); if (pause){
DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 50, 50, BLACK);
DrawText(TextFormat("SCORE: %03d", counterTail-2), screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 100, 50, BLACK);
SetMusicVolume(soundtrack, 0); // Set volume for music (1.0 is max level)
}
}
else{
DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 40)/2, GetScreenHeight()/2 - 50, 40, GRAY);
DrawText(TextFormat("SCORE: %03d", counterTail-2), screenWidth/2 - MeasureText("SCORE: %03d", 40)/2, screenHeight/2 - 100, 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(); EndDrawing();
} }
...@@ -322,4 +422,4 @@ void UpdateDrawFrame(void) ...@@ -322,4 +422,4 @@ void UpdateDrawFrame(void)
{ {
UpdateGame(); UpdateGame();
DrawGame(); DrawGame();
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment