Commit df36b02e authored by Fan FEI's avatar Fan FEI

version "final"

parent b1554786
......@@ -18,9 +18,7 @@
#include <raylib.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
......@@ -32,15 +30,14 @@
//----------------------------------------------------------------------------------
// Some Defines
//----------------------------------------------------------------------------------
#define SNAKE_LENGTH 256
#define SQUARE_SIZE 39
Music soundtrack;
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct Snake { //
typedef struct Snake {
Vector2 position;
Vector2 size;
Vector2 speed;
......@@ -57,20 +54,26 @@ typedef struct Food {
//------------------------------------------------------------------------------------
// Global Variables Declaration
//------------------------------------------------------------------------------------
static const int screenWidth = 1500; //Set the width of the game interface
static const int screenHeight = 1500; //Set the Height of the game interface
static const int screenWidth = 1200; //Set the width of the game interface
static const int screenHeight = 1200; //Set the Height of the game interface
static int framesCounter = 0;
static bool gameOver = false;
static bool pause = false;
static Food fruit = { 0 };
static Food star = { 0 }; // Generate a reward
static Snake snake[SNAKE_LENGTH] = { 0 }; //Maximum length of snake
static Vector2 snakePosition[SNAKE_LENGTH] = { 0 }; //The coordinates of the snake body
static bool allowMove = false;
static Vector2 offset = { 0 };
static int counterTail = 0;
static int numWalls = 7; // Number of walls
static Rectangle walls[ 7 ];
Music soundtrack; // Add soundtrack
//------------------------------------------------------------------------------------
// Module Functions Declaration (local)
//------------------------------------------------------------------------------------
......@@ -79,6 +82,9 @@ 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)
static void InitWalls(void);
static void DrawWalls(void);
static bool IsCoCollision(Vector2 coor);
//------------------------------------------------------------------------------------
// Program main entry point
......@@ -87,14 +93,16 @@ int main(void)
{
// 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();
char *music = "Music_snake_FanFEI.mp3";
soundtrack = LoadMusicStream(music);
PlayMusicStream(soundtrack);
InitGame(); //Initialize the game
InitGame(); //Initialize the game
InitWalls(); //Initialize the walls
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 60, 1); // The number of frames can adjust the game speed
......@@ -156,9 +164,13 @@ void InitGame(void)
snakePosition[i] = (Vector2){ 0.0f, 0.0f };
}
fruit.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE }; // The color, coordinates and status of the props
fruit.color = RED;
fruit.size = (Vector2){ SQUARE_SIZE, SQUARE_SIZE }; // The color, coordinates and status of the fruit
fruit.color = RED; // An apple maybe :)
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)
......@@ -166,7 +178,10 @@ void UpdateGame(void)
{
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)
{
......@@ -211,12 +226,7 @@ void UpdateGame(void)
}
// 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))
snake[0].position.x = offset.x/2;
if ((snake[0].position.y) > (screenHeight - offset.y))
......@@ -226,6 +236,12 @@ void UpdateGame(void)
if ((snake[0].position.y < 0))
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
for (int i = 1; i < counterTail; i++)
{
......@@ -239,14 +255,28 @@ void UpdateGame(void)
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 };
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 };
}
}
}
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
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)
counterTail += 1;
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++;
}
}
......@@ -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)
void DrawGame(void)
{
......@@ -294,18 +383,29 @@ void DrawGame(void)
// Draw snake
for (int i = 0; i < counterTail; i++) DrawRectangleV(snake[i].position, snake[i].size, snake[i].color);
// Draw walls
DrawWalls();
// Draw fruit to pick
DrawRectangleV(fruit.position, fruit.size, fruit.color);
DrawRectangleV(star.position, star.size, star.color);
// Show time and score
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
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();
}
......@@ -322,4 +422,4 @@ void UpdateDrawFrame(void)
{
UpdateGame();
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