Initial commit
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
|||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
*.exe
|
||||||
Vendored
+60
@@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Debug",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/KleiaxSnake",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"miDebuggerPath": "C:/raylib/w64devkit/bin/gdb.exe",
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"MIMode": "lldb"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"miDebuggerPath": "/usr/bin/gdb",
|
||||||
|
},
|
||||||
|
"preLaunchTask": "build debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Run",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"program": "${workspaceFolder}/${fileBasenameNoExtension}",
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"windows": {
|
||||||
|
"program": "${workspaceFolder}/${fileBasenameNoExtension}.exe",
|
||||||
|
"miDebuggerPath": "C:/raylib/w64devkit/bin/gdb.exe"
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"MIMode": "lldb"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"miDebuggerPath": "/usr/bin/gdb"
|
||||||
|
},
|
||||||
|
"preLaunchTask": "build release",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files.exclude": {
|
||||||
|
"**/.git": true,
|
||||||
|
"**/.svn": true,
|
||||||
|
"**/.hg": true,
|
||||||
|
"**/CVS": true,
|
||||||
|
"**/.DS_Store": true,
|
||||||
|
"**/*.o": true,
|
||||||
|
"**/*.exe": true,
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+58
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build debug",
|
||||||
|
"type": "process",
|
||||||
|
"command": "make",
|
||||||
|
"args": [
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"command": "mingw32-make.exe",
|
||||||
|
"args": [
|
||||||
|
"RAYLIB_PATH=C:/raylib/raylib",
|
||||||
|
// "OBJS=${fileBasenameNoExtension}.cpp",
|
||||||
|
"BUILD_MODE=DEBUG"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$g++"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build release",
|
||||||
|
"type": "process",
|
||||||
|
"command": "make",
|
||||||
|
"args": [
|
||||||
|
"PLATFORM=PLATFORM_DESKTOP",
|
||||||
|
// "PROJECT_NAME=${fileBasenameNoExtension}",
|
||||||
|
"OBJS=${fileBasenameNoExtension}.cpp"
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"command": "mingw32-make.exe",
|
||||||
|
"args": [
|
||||||
|
"RAYLIB_PATH=C:/raylib/raylib",
|
||||||
|
"PROJECT_NAME=${fileBasenameNoExtension}",
|
||||||
|
"OBJS=${fileBasenameNoExtension}.cpp"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"osx": {
|
||||||
|
"args": [
|
||||||
|
"RAYLIB_PATH=<path_to_raylib>/raylib",
|
||||||
|
"PROJECT_NAME=${fileBasenameNoExtension}",
|
||||||
|
"OBJS=${fileBasenameNoExtension}.c++"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$g++"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
# Define required raylib variables
|
||||||
|
PROJECT_NAME ?= KleiaxSnake
|
||||||
|
RAYLIB_VERSION ?= 4.2.0
|
||||||
|
RAYLIB_PATH ?= ..\..
|
||||||
|
|
||||||
|
# Define compiler path on Windows
|
||||||
|
COMPILER_PATH ?= C:/raylib/w64devkit/bin
|
||||||
|
|
||||||
|
PLATFORM ?= PLATFORM_DESKTOP
|
||||||
|
|
||||||
|
DESTDIR ?= /usr/local
|
||||||
|
RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib
|
||||||
|
RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include
|
||||||
|
|
||||||
|
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
|
||||||
|
RAYLIB_LIBTYPE ?= STATIC
|
||||||
|
|
||||||
|
# Build mode for project: DEBUG or RELEASE
|
||||||
|
BUILD_MODE ?= DEBUG
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
PLATFORM_OS=WINDOWS
|
||||||
|
export PATH := $(COMPILER_PATH):$(PATH)
|
||||||
|
endif
|
||||||
|
|
||||||
|
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
|
||||||
|
EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH)
|
||||||
|
|
||||||
|
# Define default C compiler: gcc
|
||||||
|
# NOTE: define g++ compiler if using C++
|
||||||
|
CC = g++
|
||||||
|
|
||||||
|
# Define default make program: Mingw32-make
|
||||||
|
MAKE = mingw32-make
|
||||||
|
|
||||||
|
# Define compiler flags:
|
||||||
|
# -O0 defines optimization level (no optimization, better for debugging)
|
||||||
|
# -O1 defines optimization level
|
||||||
|
# -g include debug information on compilation
|
||||||
|
# -s strip unnecessary data from build -> do not use in debug builds
|
||||||
|
# -Wall turns on most, but not all, compiler warnings
|
||||||
|
# -std=c99 defines C language mode (standard C from 1999 revision)
|
||||||
|
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
|
||||||
|
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
|
||||||
|
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
|
||||||
|
CFLAGS += -Wall -Wno-missing-braces
|
||||||
|
|
||||||
|
ifeq ($(BUILD_MODE),DEBUG)
|
||||||
|
CFLAGS += -g -O0
|
||||||
|
else
|
||||||
|
CFLAGS += -s -O1
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
# Define include paths for required headers
|
||||||
|
# NOTE: Several external required libraries (stb and others)
|
||||||
|
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
|
||||||
|
INCLUDE_PATHS += -I./include
|
||||||
|
# INCLUDE_PATHS += -I./src
|
||||||
|
|
||||||
|
# Define library paths containing required libs.
|
||||||
|
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
|
||||||
|
|
||||||
|
# Define any libraries required on linking
|
||||||
|
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||||
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
|
# Libraries for Windows desktop compilation
|
||||||
|
# NOTE: WinMM library required to set high-res timer resolution
|
||||||
|
LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Define a recursive wildcard function
|
||||||
|
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||||
|
|
||||||
|
# Define all source files required
|
||||||
|
SRC_DIR = src
|
||||||
|
OBJ_DIR = obj
|
||||||
|
|
||||||
|
# Define all object files from source files
|
||||||
|
# SRC = $(call rwildcard, *.c, *.h)
|
||||||
|
SRC = $(call rwildcard, *.cpp, *.h)
|
||||||
|
# OBJS = $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
|
||||||
|
OBJS ?= main.cpp
|
||||||
|
OBJS += src/Game.cpp
|
||||||
|
OBJS += src/Board.cpp
|
||||||
|
OBJS += src/raylibCpp.cpp
|
||||||
|
OBJS += src/Snake.cpp
|
||||||
|
|
||||||
|
MAKEFILE_PARAMS = $(PROJECT_NAME)
|
||||||
|
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(MAKE) $(MAKEFILE_PARAMS)
|
||||||
|
|
||||||
|
# Project target defined by PROJECT_NAME
|
||||||
|
$(PROJECT_NAME): $(OBJS)
|
||||||
|
$(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
# Compile source files
|
||||||
|
# NOTE: This pattern will compile every module defined on $(OBJS)
|
||||||
|
#%.o: %.c
|
||||||
|
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
|
||||||
|
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
# Clean everything
|
||||||
|
clean:
|
||||||
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
|
del *.o *.exe /s
|
||||||
|
endif
|
||||||
|
@echo Cleaning done
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "raylibCpp.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "Vec2.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
class Board {
|
||||||
|
public:
|
||||||
|
Board(Vec2<int> screenPos, Vec2<int> widthHeight, int padding);
|
||||||
|
void DrawBorder() const;
|
||||||
|
void Draw() const;
|
||||||
|
int GetWidth() const;
|
||||||
|
int GetHeight() const;
|
||||||
|
private:
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
const int padding;
|
||||||
|
Vec2<int> size;
|
||||||
|
Vec2<int> screenPos;
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Board.h"
|
||||||
|
#include "Snake.h"
|
||||||
|
|
||||||
|
class Game {
|
||||||
|
public:
|
||||||
|
Game(int width, int height, int fps, std::string title);
|
||||||
|
Game(const Game& other) = delete;
|
||||||
|
Game& operator=(const Game& other) = delete;
|
||||||
|
~Game() noexcept;
|
||||||
|
bool GameShouldClose() const;
|
||||||
|
void Tick();
|
||||||
|
private:
|
||||||
|
void Update();
|
||||||
|
void Draw();
|
||||||
|
|
||||||
|
Board board;
|
||||||
|
Snake snake;
|
||||||
|
};
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Vec2.h"
|
||||||
|
namespace settings
|
||||||
|
{
|
||||||
|
//Board settings
|
||||||
|
inline constexpr Vec2<int> gridSize{30, 15};
|
||||||
|
inline constexpr Vec2<int> gridPos{50, 50};
|
||||||
|
inline constexpr int gridCellSize = 30;
|
||||||
|
inline constexpr int gridInnerPadding = 2;
|
||||||
|
inline constexpr int gridBorderWidth = 15;
|
||||||
|
|
||||||
|
//Window settings
|
||||||
|
inline constexpr int fps = 60;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "raylibCpp.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include "Vec2.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
class Snake {
|
||||||
|
public:
|
||||||
|
enum Direction {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Body {
|
||||||
|
public:
|
||||||
|
Body(Vec2<int> pos);
|
||||||
|
|
||||||
|
void draw(Color color = WHITE) const;
|
||||||
|
void move(Vec2<int> pos) { this->pos = pos; };
|
||||||
|
Vec2<int> getPos() const { return this->pos; }
|
||||||
|
static void setSize(Vec2<int> size) { Body::size = size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vec2<int> pos;
|
||||||
|
static Vec2<int> size;
|
||||||
|
Snake::Direction nextPart;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Food {
|
||||||
|
public:
|
||||||
|
Food();
|
||||||
|
|
||||||
|
void draw() const;
|
||||||
|
void newPosition();
|
||||||
|
Vec2<int> getPosition() { return this->pos; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vec2<int> pos;
|
||||||
|
Vec2<int> size;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Snake();
|
||||||
|
|
||||||
|
void update();
|
||||||
|
void draw() const;
|
||||||
|
|
||||||
|
void setDirection(Direction dir);
|
||||||
|
private:
|
||||||
|
void move();
|
||||||
|
void eat();
|
||||||
|
|
||||||
|
Direction dir = Direction::None;
|
||||||
|
Food food;
|
||||||
|
|
||||||
|
bool hasEaten = false;
|
||||||
|
bool hasBitten = false;
|
||||||
|
|
||||||
|
int score = 0;
|
||||||
|
|
||||||
|
double lastMoveTime = 0;
|
||||||
|
double moveDelay = 0.15;
|
||||||
|
|
||||||
|
std::list<Snake::Body> bodyList;
|
||||||
|
};
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Vec2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vec2() = default;
|
||||||
|
constexpr Vec2(T x, T y)
|
||||||
|
:
|
||||||
|
x(x),
|
||||||
|
y(y)
|
||||||
|
{}
|
||||||
|
constexpr T GetX() const {return x;};
|
||||||
|
constexpr T GetY() const {return y;};
|
||||||
|
constexpr void SetX(T x_in) { x = x_in;};
|
||||||
|
constexpr void SetY(T y_in) { y = y_in;};
|
||||||
|
public:
|
||||||
|
constexpr bool operator==(const Vec2& rhs) const
|
||||||
|
{
|
||||||
|
return (x == rhs.x && y == rhs.y);
|
||||||
|
}
|
||||||
|
constexpr bool operator!=(const Vec2& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
constexpr Vec2 operator+(const Vec2& rhs) const
|
||||||
|
{
|
||||||
|
return {x + rhs.x, y + rhs.y};
|
||||||
|
}
|
||||||
|
constexpr Vec2 operator+(const int rhs) const
|
||||||
|
{
|
||||||
|
return {x + rhs, y + rhs};
|
||||||
|
}
|
||||||
|
constexpr Vec2& operator+=(const Vec2& rhs)
|
||||||
|
{
|
||||||
|
return *this = *this + rhs;
|
||||||
|
}
|
||||||
|
constexpr Vec2 operator-(const Vec2& rhs) const
|
||||||
|
{
|
||||||
|
return {x - rhs.x, y - rhs.y};
|
||||||
|
}
|
||||||
|
constexpr Vec2 operator-(const int rhs) const
|
||||||
|
{
|
||||||
|
return { x - rhs, y - rhs};
|
||||||
|
}
|
||||||
|
constexpr Vec2& operator-=(const Vec2& rhs)
|
||||||
|
{
|
||||||
|
return *this = *this - rhs;
|
||||||
|
}
|
||||||
|
constexpr Vec2 operator*(const Vec2& rhs) const
|
||||||
|
{
|
||||||
|
return {x * rhs.x, y * rhs.y};
|
||||||
|
}
|
||||||
|
constexpr Vec2 operator*(const int rhs) const
|
||||||
|
{
|
||||||
|
return { x * rhs, y * rhs };
|
||||||
|
}
|
||||||
|
constexpr Vec2& operator*=(const Vec2& rhs)
|
||||||
|
{
|
||||||
|
return *this = *this * rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T x;
|
||||||
|
T y;
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <raylib.h>
|
||||||
|
#include "Vec2.h"
|
||||||
|
namespace raycpp
|
||||||
|
{
|
||||||
|
void DrawRectangle(Vec2<int> pos, Vec2<int> widthHeight, Color color);
|
||||||
|
void DrawRectangleLinesEx(Vec2<int> pos, Vec2<int> widthHeight, int lineThick, Color color);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"files.associations": {
|
||||||
|
"raylib.h": "c",
|
||||||
|
"math.h": "c",
|
||||||
|
"blocks.h": "c",
|
||||||
|
"stdio.h": "c",
|
||||||
|
"*.m": "c"
|
||||||
|
},
|
||||||
|
"cSpell.words": [
|
||||||
|
"DARKGRAY",
|
||||||
|
"fovy",
|
||||||
|
"Kleiax",
|
||||||
|
"raycpp",
|
||||||
|
"raylib",
|
||||||
|
"RAYWHITE"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#include "Game.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int width = 2 * settings::gridPos.GetX()
|
||||||
|
+ 2 * settings::gridBorderWidth
|
||||||
|
+ settings::gridSize.GetX() * settings::gridCellSize
|
||||||
|
+ (settings::gridSize.GetX() + 1) * settings::gridInnerPadding;
|
||||||
|
|
||||||
|
int height = 2 * settings::gridPos.GetY()
|
||||||
|
+ 2 * settings::gridBorderWidth
|
||||||
|
+ settings::gridSize.GetY() * settings::gridCellSize
|
||||||
|
+ (settings::gridSize.GetY() + 1) * settings::gridInnerPadding;
|
||||||
|
|
||||||
|
Game game{width,
|
||||||
|
height,
|
||||||
|
settings::fps,
|
||||||
|
"Snake Kleiax Raylib"};
|
||||||
|
|
||||||
|
while (!game.GameShouldClose())
|
||||||
|
{
|
||||||
|
game.Tick();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Assets license.
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "Board.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
Board::Board(Vec2<int> screenPos, Vec2<int> widthHeight, int padding) :
|
||||||
|
screenPos(screenPos),
|
||||||
|
size(widthHeight),
|
||||||
|
padding(padding) {
|
||||||
|
this->width = 2 * settings::gridBorderWidth
|
||||||
|
+ settings::gridSize.GetX() * settings::gridCellSize
|
||||||
|
+ (settings::gridSize.GetX() + 1) * settings::gridInnerPadding;
|
||||||
|
|
||||||
|
this->height = 2 * settings::gridBorderWidth
|
||||||
|
+ settings::gridSize.GetY() * settings::gridCellSize
|
||||||
|
+ (settings::gridSize.GetY() + 1) * settings::gridInnerPadding;
|
||||||
|
|
||||||
|
assert(width > 0 && height > 0); //If assertion triggers : The width or height is smaller than 1
|
||||||
|
}
|
||||||
|
|
||||||
|
void Board::DrawBorder() const
|
||||||
|
{
|
||||||
|
raycpp::DrawRectangleLinesEx(screenPos,
|
||||||
|
Vec2<int>{width,height},
|
||||||
|
settings::gridBorderWidth,
|
||||||
|
WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Board::Draw() const
|
||||||
|
{
|
||||||
|
DrawBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Board::GetWidth() const
|
||||||
|
{
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Board::GetHeight() const
|
||||||
|
{
|
||||||
|
return height;
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include "Game.h"
|
||||||
|
#include "raylibCpp.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
Game::Game(int width, int height, int fps, std::string title) :
|
||||||
|
board(settings::gridPos,
|
||||||
|
settings::gridSize,
|
||||||
|
settings::gridInnerPadding)
|
||||||
|
{
|
||||||
|
assert(!GetWindowHandle()); //If assertion triggers : Window is already opened
|
||||||
|
SetTargetFPS(fps);
|
||||||
|
InitWindow(width, height, title.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Game::~Game() noexcept
|
||||||
|
{
|
||||||
|
assert(GetWindowHandle()); //If assertion triggers : Window is already closed
|
||||||
|
CloseWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::GameShouldClose() const
|
||||||
|
{
|
||||||
|
return WindowShouldClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::Tick()
|
||||||
|
{
|
||||||
|
BeginDrawing();
|
||||||
|
Update();
|
||||||
|
Draw();
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::Update()
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_UP))
|
||||||
|
snake.setDirection(Snake::Direction::Up);
|
||||||
|
else if (IsKeyPressed(KEY_DOWN))
|
||||||
|
snake.setDirection(Snake::Direction::Down);
|
||||||
|
else if (IsKeyPressed(KEY_LEFT))
|
||||||
|
snake.setDirection(Snake::Direction::Left);
|
||||||
|
else if (IsKeyPressed(KEY_RIGHT))
|
||||||
|
snake.setDirection(Snake::Direction::Right);
|
||||||
|
else if (IsKeyPressed(KEY_SPACE))
|
||||||
|
snake.setDirection(Snake::Direction::None);
|
||||||
|
|
||||||
|
snake.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::Draw()
|
||||||
|
{
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
board.Draw();
|
||||||
|
snake.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+166
@@ -0,0 +1,166 @@
|
|||||||
|
#include "Snake.h"
|
||||||
|
|
||||||
|
Vec2<int> Snake::Body::size;
|
||||||
|
|
||||||
|
Snake::Body::Body(Vec2<int> pos) {
|
||||||
|
this->pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::Body::draw(Color color) const{
|
||||||
|
int offsetX = settings::gridPos.GetX() + settings::gridBorderWidth + settings::gridInnerPadding;
|
||||||
|
int offsetY = settings::gridPos.GetY() + settings::gridBorderWidth + settings::gridInnerPadding;
|
||||||
|
|
||||||
|
Vec2<int> pixelPos;
|
||||||
|
pixelPos.SetX(offsetX + this->pos.GetX() * (settings::gridCellSize + settings::gridInnerPadding));
|
||||||
|
pixelPos.SetY(offsetY + this->pos.GetY() * (settings::gridCellSize + settings::gridInnerPadding));
|
||||||
|
raycpp::DrawRectangle(pixelPos, this->size, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
Snake::Food::Food() {
|
||||||
|
this->newPosition();
|
||||||
|
this->size.SetX(settings::gridCellSize);
|
||||||
|
this->size.SetY(settings::gridCellSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::Food::newPosition() {
|
||||||
|
int x = GetRandomValue(0, settings::gridSize.GetX() - 1);
|
||||||
|
int y = GetRandomValue(0, settings::gridSize.GetY() - 1);
|
||||||
|
|
||||||
|
this->pos.SetX(x);
|
||||||
|
this->pos.SetY(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::Food::draw() const {
|
||||||
|
int offsetX = settings::gridPos.GetX() + settings::gridBorderWidth + settings::gridInnerPadding;
|
||||||
|
int offsetY = settings::gridPos.GetY() + settings::gridBorderWidth + settings::gridInnerPadding;
|
||||||
|
|
||||||
|
Vec2<int> pixelPos;
|
||||||
|
pixelPos.SetX(offsetX + this->pos.GetX() * (settings::gridCellSize + settings::gridInnerPadding));
|
||||||
|
pixelPos.SetY(offsetY + this->pos.GetY() * (settings::gridCellSize + settings::gridInnerPadding));
|
||||||
|
raycpp::DrawRectangle(pixelPos, this->size, RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
Snake::Snake() {
|
||||||
|
Body::setSize(Vec2<int>{settings::gridCellSize, settings::gridCellSize});
|
||||||
|
|
||||||
|
this->bodyList.push_back(Body{Vec2<int>{5, 5}});
|
||||||
|
this->bodyList.push_back(Body{Vec2<int>{5, 6}});
|
||||||
|
this->bodyList.push_back(Body{Vec2<int>{5, 7}});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::update() {
|
||||||
|
if (GetTime() - this->lastMoveTime < this->moveDelay || this->hasBitten)
|
||||||
|
return;
|
||||||
|
this->lastMoveTime = GetTime();
|
||||||
|
|
||||||
|
this->move();
|
||||||
|
|
||||||
|
Vec2<int> head = (*this->bodyList.cbegin()).getPos();
|
||||||
|
if (head == this->food.getPosition())
|
||||||
|
this->eat();
|
||||||
|
|
||||||
|
bool firstSkip = true;
|
||||||
|
for (const Body & body : this->bodyList) {
|
||||||
|
if (firstSkip) {
|
||||||
|
firstSkip = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (head == body.getPos())
|
||||||
|
this->hasBitten = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::draw() const {
|
||||||
|
for (const Body & body : this->bodyList)
|
||||||
|
body.draw();
|
||||||
|
(*this->bodyList.cbegin()).draw(GREEN);
|
||||||
|
this->food.draw();
|
||||||
|
|
||||||
|
std::string scoreString;
|
||||||
|
scoreString += "Score: ";
|
||||||
|
scoreString += std::to_string(this->score);
|
||||||
|
DrawText(scoreString.c_str(), 10, 10, 30, WHITE);
|
||||||
|
|
||||||
|
if (this->hasBitten)
|
||||||
|
DrawText("Game over!", 10, 70, 50, BLUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::setDirection(Direction dir) {
|
||||||
|
if (this->dir == Direction::Up && dir == Direction::Down)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this->dir == Direction::Down && dir == Direction::Up)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this->dir == Direction::Left && dir == Direction::Right)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this->dir == Direction::Right && dir == Direction::Left)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->dir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::move() {
|
||||||
|
if (this->dir == Direction::None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vec2<int> head = (*this->bodyList.cbegin()).getPos();
|
||||||
|
|
||||||
|
if (this->hasEaten)
|
||||||
|
this->hasEaten = false;
|
||||||
|
else
|
||||||
|
this->bodyList.pop_back();
|
||||||
|
|
||||||
|
switch (this->dir)
|
||||||
|
{
|
||||||
|
case Direction::Up:
|
||||||
|
head.SetY(head.GetY() - 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Direction::Down:
|
||||||
|
head.SetY(head.GetY() + 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Direction::Left:
|
||||||
|
head.SetX(head.GetX() - 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Direction::Right:
|
||||||
|
head.SetX(head.GetX() + 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head.GetX() >= settings::gridSize.GetX())
|
||||||
|
head.SetX(0);
|
||||||
|
else if (head.GetX() < 0)
|
||||||
|
head.SetX(settings::gridSize.GetX() - 1);
|
||||||
|
|
||||||
|
if (head.GetY() >= settings::gridSize.GetY())
|
||||||
|
head.SetY(0);
|
||||||
|
else if (head.GetY() < 0)
|
||||||
|
head.SetY(settings::gridSize.GetY() - 1);
|
||||||
|
|
||||||
|
this->bodyList.push_front(Snake::Body(head));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snake::eat() {
|
||||||
|
this->hasEaten = true;
|
||||||
|
this->food.newPosition();
|
||||||
|
this->score++;
|
||||||
|
|
||||||
|
bool newFoodPlaceFound = false;
|
||||||
|
while (!newFoodPlaceFound) {
|
||||||
|
this->food.newPosition();
|
||||||
|
newFoodPlaceFound = true;
|
||||||
|
for (const Body & body : this->bodyList)
|
||||||
|
if (this->food.getPosition() == body.getPos()) {
|
||||||
|
newFoodPlaceFound = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#include "raylibCpp.h"
|
||||||
|
#include <assert.h>
|
||||||
|
void raycpp::DrawRectangle(Vec2<int> pos, Vec2<int> widthHeight, Color color)
|
||||||
|
{
|
||||||
|
assert(pos.GetX() >= 0 && pos.GetY() >= 0 &&
|
||||||
|
pos.GetX() < GetScreenWidth() && pos.GetY() < GetScreenHeight()); //If assertion triggers : Trying to draw outisde of the screen
|
||||||
|
DrawRectangle(pos.GetX(),pos.GetY(),widthHeight.GetX(),widthHeight.GetY(),color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void raycpp::DrawRectangleLinesEx(Vec2<int> pos, Vec2<int> widthHeight, int lineThick, Color color)
|
||||||
|
{
|
||||||
|
assert(pos.GetX() >= 0 && pos.GetY() >= 0 &&
|
||||||
|
pos.GetX() < GetScreenWidth() && pos.GetY() < GetScreenHeight()); //If assertion triggers : Trying to draw outisde of the screen
|
||||||
|
assert(lineThick > 0); //If assertion triggers : line thickness is less than 1
|
||||||
|
DrawRectangleLinesEx({(float)pos.GetX(),(float)pos.GetY(), (float)widthHeight.GetX(), (float)widthHeight.GetY()}, (float)lineThick, color);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user