source code migrating from gitlab
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
cmake_minimum_required(VERSION 4.0)
|
||||
project(SnakeClone C)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
# Adding Raylib
|
||||
# include(FetchContent)
|
||||
# set(FETCHCONTENT_QUIET FALSE)
|
||||
# set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) # don't build the supplied examples
|
||||
# set(BUILD_GAMES OFF CACHE BOOL "" FORCE) # don't build the supplied example games
|
||||
#
|
||||
# FetchContent_Declare(
|
||||
# raylib
|
||||
# GIT_REPOSITORY "https://github.com/raysan5/raylib.git"
|
||||
# GIT_TAG "master"
|
||||
# GIT_PROGRESS TRUE
|
||||
# )
|
||||
#
|
||||
# FetchContent_MakeAvailable(raylib)
|
||||
|
||||
# Adding our source files
|
||||
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/src/*.c") # Define PROJECT_SOURCES as a list of all source files
|
||||
set(PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/src/") # Define PROJECT_INCLUDE to be the path to the include directory of the project
|
||||
|
||||
find_package(raylib REQUIRED)
|
||||
|
||||
# Declaring our executable
|
||||
add_executable(${PROJECT_NAME})
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCES})
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE raylib)
|
||||
|
||||
# Setting ASSETS_PATH
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC ASSETS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/assets/") # Set the asset path macro to the absolute path on the dev machine
|
||||
#target_compile_definitions(${PROJECT_NAME} PUBLIC ASSETS_PATH="./assets") # Set the asset path macro in release mode to a relative path that assumes the assets folder is in the same directory as the game executable
|
||||
@@ -0,0 +1,11 @@
|
||||
# SNAKE CLONE
|
||||
|
||||
The first game we write should be relatively easy. There is always a lot of things to do with game development, such as writing the code, designing the levels, making the artwork and/or models for the game. So it's a really good idea to start small and build into making your Science Based Dragon MMO
|
||||
|
||||
## Watch Here
|
||||
[YouTube](https://youtu.be/lEFoKvBfqHk)
|
||||
|
||||
|
||||
## What Next?
|
||||
|
||||
I'd look at trying to clone another easy game, maybe easier than snake. Asteroids? Pong? Brick Breaker? Pacman? etc.. there's a ton of old school games that were made with far less resources than we have today.
|
||||
@@ -0,0 +1,266 @@
|
||||
#include <raylib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define GRID_SIZE 25
|
||||
#define SCREEN_WIDTH 800
|
||||
#define SCREEN_HEIGHT 600
|
||||
#define MAX_SCORE 256
|
||||
|
||||
int widthByGrid = SCREEN_WIDTH / GRID_SIZE;
|
||||
int heightByGrid = SCREEN_HEIGHT / GRID_SIZE;
|
||||
|
||||
Vector2 head;
|
||||
Vector2 dir;
|
||||
Vector2 food;
|
||||
Vector2 segments[MAX_SCORE - 1];
|
||||
|
||||
int score = 0;
|
||||
char scoreStr[32];
|
||||
bool isRunning = true;
|
||||
bool gameStart = false;
|
||||
|
||||
const Color bg = {236, 239, 244, 255};
|
||||
const Color snakeRed = {191, 97, 106, 255};
|
||||
const Color snakeBlack = {46, 52, 64, 255};
|
||||
const Color foodColor = {163, 190, 140, 255};
|
||||
const Color textDark = {76, 85, 106, 255};
|
||||
const Color textOrange = {208, 135, 112, 255};
|
||||
const Color textGreen = {143, 188, 187, 255};
|
||||
const Color textBlue = {90, 129, 172, 255};
|
||||
|
||||
void initGame();
|
||||
void quitGame();
|
||||
void draw();
|
||||
Vector2 spawnFood();
|
||||
bool collide(Vector2 a, Vector2 b);
|
||||
bool collideSelf(Vector2 self);
|
||||
void processInput();
|
||||
void update();
|
||||
void gameOver();
|
||||
void restartGame();
|
||||
void startScreen();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
initGame();
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
|
||||
processInput();
|
||||
if (!gameStart) {
|
||||
startScreen();
|
||||
} else if (isRunning) {
|
||||
update();
|
||||
}
|
||||
if (gameStart) {
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
quitGame();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initGame() {
|
||||
time_t t;
|
||||
srand(time(&t));
|
||||
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Snake Clone");
|
||||
|
||||
SetTargetFPS(10);
|
||||
|
||||
sprintf(scoreStr, "SCORE: %d", score);
|
||||
|
||||
head.x = 0;
|
||||
head.y = 0;
|
||||
dir.x = 1;
|
||||
dir.y = 0;
|
||||
|
||||
food = spawnFood();
|
||||
}
|
||||
|
||||
Vector2 spawnFood() {
|
||||
|
||||
Vector2 snack = {1 + rand() % (GRID_SIZE - 2), 1 + rand() % (GRID_SIZE - 2)};
|
||||
|
||||
while (collide(head, snack) || collideSelf(snack)) {
|
||||
snack.x = 1 + rand() % (GRID_SIZE - 2);
|
||||
snack.y = 1 + rand() % (GRID_SIZE - 2);
|
||||
}
|
||||
|
||||
return snack;
|
||||
}
|
||||
|
||||
bool collide(Vector2 a, Vector2 b) { return (a.x == b.x && a.y == b.y); }
|
||||
|
||||
bool collideSelf(Vector2 self) {
|
||||
for (int i = 0; i < score; i++) {
|
||||
if (collide(self, segments[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void processInput() {
|
||||
|
||||
if (IsKeyPressed(KEY_W) || IsKeyPressed(KEY_UP)) {
|
||||
if (dir.y == 1)
|
||||
return;
|
||||
dir.x = 0;
|
||||
dir.y = -1;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_A) || IsKeyPressed(KEY_LEFT)) {
|
||||
if (dir.x == 1)
|
||||
return;
|
||||
dir.y = 0;
|
||||
dir.x = -1;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_D) || IsKeyPressed(KEY_RIGHT)) {
|
||||
if (dir.x == -1)
|
||||
return;
|
||||
dir.y = 0;
|
||||
dir.x = 1;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_S) || IsKeyPressed(KEY_DOWN)) {
|
||||
if (dir.y == -1)
|
||||
return;
|
||||
dir.y = 1;
|
||||
dir.x = 0;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE) && !isRunning) {
|
||||
restartGame();
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ESCAPE)) {
|
||||
isRunning = false;
|
||||
quitGame();
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER)) {
|
||||
gameStart = true;
|
||||
}
|
||||
}
|
||||
|
||||
void update() {
|
||||
|
||||
for (int i = score; i > 0; i--) {
|
||||
segments[i] = segments[i - 1];
|
||||
}
|
||||
|
||||
segments[0] = head;
|
||||
|
||||
head.x += dir.x;
|
||||
head.y += dir.y;
|
||||
|
||||
if (collideSelf(head) || head.x < 0 || head.y < 0 || head.x >= GRID_SIZE ||
|
||||
head.y >= GRID_SIZE) {
|
||||
isRunning = false;
|
||||
}
|
||||
|
||||
if (collide(head, food)) {
|
||||
if (score < MAX_SCORE) {
|
||||
score += 1;
|
||||
sprintf(scoreStr, "SCORE: %d", score);
|
||||
} else {
|
||||
sprintf(scoreStr, "YOU WIN");
|
||||
}
|
||||
food = spawnFood();
|
||||
}
|
||||
}
|
||||
|
||||
void quitGame() {
|
||||
printf("quitGame called\n");
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(bg);
|
||||
|
||||
DrawRectangle(food.x * widthByGrid, food.y * heightByGrid, widthByGrid,
|
||||
heightByGrid, foodColor);
|
||||
|
||||
DrawRectangle(head.x * widthByGrid, head.y * heightByGrid, widthByGrid,
|
||||
heightByGrid, snakeRed);
|
||||
|
||||
for (int i = 0; i < score; i++) {
|
||||
if (i % 2 == 0) {
|
||||
DrawRectangle(segments[i].x * widthByGrid, segments[i].y * heightByGrid,
|
||||
widthByGrid, heightByGrid, snakeBlack);
|
||||
} else {
|
||||
DrawRectangle(segments[i].x * widthByGrid, segments[i].y * heightByGrid,
|
||||
widthByGrid, heightByGrid, snakeRed);
|
||||
}
|
||||
}
|
||||
|
||||
DrawText(scoreStr, 10, 10, 30, textBlue);
|
||||
|
||||
if (!isRunning) {
|
||||
gameOver();
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
void gameOver() {
|
||||
DrawText("GAME OVER", 30, 120, 120, textOrange);
|
||||
|
||||
char *restartText = "Try Again? Press Space";
|
||||
int resWidth = MeasureText(restartText, 28);
|
||||
int resMid = (SCREEN_WIDTH - resWidth) / 2;
|
||||
DrawText(restartText, resMid, SCREEN_HEIGHT / 2, 28, textGreen);
|
||||
|
||||
char *quitText = "Press Escape to Quit.";
|
||||
int quitWidth = MeasureText(quitText, 28);
|
||||
int quitMid = (SCREEN_WIDTH - quitWidth) / 2;
|
||||
DrawText(quitText, quitMid, SCREEN_HEIGHT / 2 + 40, 28, textDark);
|
||||
}
|
||||
|
||||
void restartGame() {
|
||||
|
||||
head.x = 0;
|
||||
head.y = 0;
|
||||
|
||||
dir.x = 1;
|
||||
dir.y = 0;
|
||||
|
||||
score = 0;
|
||||
sprintf(scoreStr, "SCORE %d", score);
|
||||
isRunning = true;
|
||||
food = spawnFood();
|
||||
}
|
||||
|
||||
void startScreen() {
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(bg);
|
||||
|
||||
DrawText("Snake Clone", 30, 120, 120, textGreen);
|
||||
|
||||
char *startText = "Press Enter to Start";
|
||||
int restart = MeasureText(startText, 28);
|
||||
int resX = (SCREEN_WIDTH - restart) / 2;
|
||||
int resY = (SCREEN_HEIGHT / 2);
|
||||
DrawText(startText, resX, restart, 28, textOrange);
|
||||
|
||||
char *quitText = "Press Escape to Quit";
|
||||
int quit = MeasureText(quitText, 28);
|
||||
int quitX = (SCREEN_WIDTH - quit) / 2;
|
||||
int quitY = (SCREEN_HEIGHT / 2) + 40;
|
||||
DrawText(quitText, quitX, quitY, 28, textDark);
|
||||
|
||||
char *helpText = "Use WASD or arrows to move";
|
||||
int help = MeasureText(helpText, 24);
|
||||
int helpX = (SCREEN_WIDTH - help) / 2;
|
||||
int helpY = (SCREEN_HEIGHT / 2) + 80;
|
||||
DrawText(helpText, helpX + 40, helpY, 24, textBlue);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
Reference in New Issue
Block a user