diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..690ae25 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.29.2) +project(StarRay) +#Dependencies?? +include(FetchContent) + +# 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 + URL https://github.com/raysan5/raylib/releases/download/5.0/raylib-5.0_win64_mingw-w64.zip + FIND_PACKAGE_ARGS ${RAYLIB_VERSION} EXACT + ) + +FetchContent_MakeAvailable(raylib) + +# Adding our source files +file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_LIST_DIR}/sources/*.c") # Define PROJECT_SOURCES as a list of all source files +set(PROJECT_INCLUDE "${CMAKE_CURRENT_LIST_DIR}/sources/") # Define PROJECT_INCLUDE to be the path to the include directory of the project + +# Declaring our executable +add_executable(${PROJECT_NAME} main.cpp) +target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE}) +target_link_libraries(${PROJECT_NAME} PUBLIC raylib) + +# Setting ASSETS_PATH +target_compile_definitions(${PROJECT_NAME} PUBLIC ASSETS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/assets/") +#set(RAYLIB_VERSION 5.0) +#FetchContent_Declare( +# raylib +# URL https://github.com/raysan5/raylib/releases/download/5.0/raylib-5.0_win64_mingw-w64.zip +# FIND_PACKAGE_ARGS ${RAYLIB_VERSION} EXACT +# ) + +#set(BUILD_EXAMPLES OFF CACHE INTERNAL "") +#FetchContent_MakeAvailable(raylib) + +#add_executable(StarRay main.cpp) +#target_link_libraries(StarRay PUBLIC raylib) diff --git a/ConsoleGame/ConsoleGame.cpp b/ConsoleGame/ConsoleGame.cpp new file mode 100644 index 0000000..278a261 --- /dev/null +++ b/ConsoleGame/ConsoleGame.cpp @@ -0,0 +1,17 @@ +#include +#include "GameMap.h" + +void generateMap(World1.MaxX, World1.MaxY) { + for (int i = 0; i < MaxX; i++) + for (int j = 0; j < MaxY; j++) + +} + +int main() +{ + World World1; + +} + + + diff --git a/ConsoleGame/GameMap.h b/ConsoleGame/GameMap.h new file mode 100644 index 0000000..2aa3d2e --- /dev/null +++ b/ConsoleGame/GameMap.h @@ -0,0 +1,39 @@ +#pragma once +#include +using namespace std; + +class Terrain +{ +public: + Terrain(int moveCost, bool isWater, string texture) : + moveCost_(moveCost), + isWater_(isWater), + texture_(texture) + {} + + int getMoveCost() const { return moveCost_; } + bool getIsWater() const { return isWater_; } + string getTexture() const { return texture_; } + +private: + int moveCost_; + bool isWater_; + string texture_; +}; + +class World +{ +public: + int width, height, MaxX = 100, MaxY = 100; + World() : + grassTerrain_(1, false, '#'), + hillTerrain_(3, false, '/'), + riverTerrain_(3, true, '=') + {} + +private: + //Terrain* tiles_[width][height]; + Terrain grassTerrain_; + Terrain hillTerrain_; + Terrain riverTerrain_; +}; diff --git a/Snake/input.cpp b/Snake/input.cpp new file mode 100644 index 0000000..fde97f8 --- /dev/null +++ b/Snake/input.cpp @@ -0,0 +1,24 @@ +#include +#include + +struct termios terminalSettings; + +void input_on() +{ + struct termios newTerminalSettings; + + tcgetattr( STDIN_FILENO, &terminalSettings ); + + newTerminalSettings = terminalSettings; + + newTerminalSettings.c_lflag &= ~( ICANON | ECHO ); + newTerminalSettings.c_cc[VTIME] = 0; + newTerminalSettings.c_cc[VMIN] = 1; + + tcsetattr( STDIN_FILENO, TCSANOW, &newTerminalSettings ); +} + +void input_off() +{ + tcsetattr(STDIN_FILENO, TCSANOW, &terminalSettings); +} \ No newline at end of file diff --git a/Snake/main.cpp b/Snake/main.cpp new file mode 100644 index 0000000..f6673b1 --- /dev/null +++ b/Snake/main.cpp @@ -0,0 +1,257 @@ +#include +#include +#include "input.cpp" + +using namespace std; + +const int DIRECTION_LEFT = 1; +const int DIRECTION_RIGHT = 2; +const int DIRECTION_UP = 3; +const int DIRECTION_DOWN = 4; + +int SCORE = 0; + +// current direction of the snake +int DIRECTION = DIRECTION_DOWN; + +// size of the map +const int MAP_WIDTH = 40; +const int MAP_HEIGHT = 15; + +// character of the snake body +const char SNAKE_BODY = '*'; + +// array of the available characters for food +const char FOOD_SYMBOLS[] = {'%', '$', '&', '@', '+'}; +// current coordinates of food +int FOOD_X = 0; +int FOOD_Y = 0; + +// current food's index +int FOOD_SYMBOL_NUM = 0; + +// cell of the snake's body +struct snake_body { + int x; + int y; +}; + +// array of cells of the snake's body +vector snake; + +// creates the primary snake +void init_snake() { + for (int i(0); i < 5; i++) { + snake_body body; + body.x = -10; + body.y = -10; + + snake.push_back(body); + } + + snake[0].x = 5; + snake[0].y = 3; +} + +// checks if the snake has eaten itself +bool snake_eats_itself() { + int head_x = snake[0].x; + int head_y = snake[0].y; + + for (int i(1); i < snake.size(); i++) { + if (snake[i].x == head_x && snake[i].y == head_y) { + return true; + } + } + + return false; +} + +// checks if the snake's body overlaps with coordinates +bool is_snake_body(int x, int y) { + for (int k(0); k < snake.size(); k++) { + if (snake[k].y == y && snake[k].x == x) { + return true; + } + } + + return false; +} + +// checks if the coordinates are border of the map +bool is_map_border(int x, int y) { + return y == 0 || x == 0 || x == MAP_WIDTH || y == MAP_HEIGHT; +} + +// checks if the coordinates match the coordinates of food +bool is_food(int x, int y) { + return FOOD_X == x && FOOD_Y == y; +} + +// checks if the snake's body overlaps with food +bool snake_ate_food() { + for (int i(0); i < snake.size(); i++) { + if (snake[i].x == FOOD_X && snake[i].y == FOOD_Y) { + return true; + } + } + + return false; +} + +// checks if the snake is out of map +bool is_out_of_borders() { + return snake[0].x == 0 || snake[0].y == 0 || snake[0].x == MAP_WIDTH || snake[0].y == MAP_HEIGHT; +} + +// generates new coordinates for food +void generate_food_coord() { + srand( time( 0 ) ); + + FOOD_X = 3 + rand() % (MAP_WIDTH - 3); + FOOD_Y = 3 + rand() % (MAP_HEIGHT - 3); +} + +// generates a new food character +void generate_food_symbol() { + FOOD_SYMBOL_NUM = rand() % sizeof(FOOD_SYMBOLS); +} + +// prints score +void print_score() { + printf("\n###### SCORE: %d ######\n\n", SCORE); +} + +// draws a map and snake +void draw() { + system("clear"); + + // draws the map + for (int i(0); i <= MAP_HEIGHT; i++) { + for (int j(0); j <= MAP_WIDTH; j++) { + + if (is_map_border(j, i)) { + cout << '#' << flush; + + } else if (is_snake_body(j, i)) { + cout << SNAKE_BODY << flush; + + } else if (is_food(j, i)) { + cout << FOOD_SYMBOLS[FOOD_SYMBOL_NUM] << flush; + + } else { + cout << ' ' << flush; + } + } + + cout << "\n"; + } + + print_score(); +} + +// moves the snake and its body +void move_snake() { + int _x = snake[0].x; + int _y = snake[0].y; + int last_x, last_y; + + // changing the head coordinates + switch (DIRECTION) { + case DIRECTION_DOWN: snake[0].y++; break; + case DIRECTION_LEFT: snake[0].x--; break; + case DIRECTION_UP: snake[0].y--; break; + case DIRECTION_RIGHT:snake[0].x++; break; + default:break; + } + + // each next cell gets coordinates of the previous cell + for (int i(1); i < snake.size(); i++) { + last_x = snake[i].x; + last_y = snake[i].y; + + snake[i].x = _x; + snake[i].y = _y; + + _x = last_x; + _y = last_y; + } +} + +// will be called on 'Esc' +void exit() { + input_off(); + + printf("\n\n###### THANK YOU FOR GAME ######\n\n"); +} + +int main () { + fd_set rfds; + timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + input_on(); + + generate_food_coord(); + generate_food_symbol(); + init_snake(); + + while (true) { + + FD_ZERO(&rfds); + FD_SET(STDIN_FILENO, &rfds); + + // there is some data in the thread + if (select(1, &rfds, NULL, NULL, &timeout) > 0 && FD_ISSET(STDIN_FILENO, &rfds)) { + switch (getchar()) { + + case 100: + case 68: if (DIRECTION != DIRECTION_LEFT) DIRECTION = DIRECTION_RIGHT; break; + + case 83: + case 115: if (DIRECTION != DIRECTION_UP) DIRECTION = DIRECTION_DOWN; break; + + case 65: + case 97: if (DIRECTION != DIRECTION_RIGHT) DIRECTION = DIRECTION_LEFT; break; + + case 119: + case 87: if (DIRECTION != DIRECTION_DOWN) DIRECTION = DIRECTION_UP; break; + + case 27: exit(); return 0; + default:break; + } + } + + move_snake(); + + // if the snake's head is overlapping with food's coordinates then add + // a cell to the end of the snake and generate food + if (snake_ate_food()) { + generate_food_coord(); + generate_food_symbol(); + + snake_body snake_peace; + snake_peace.y = snake[snake.size()-1].y; + snake_peace.x = snake[snake.size()-1].x; + + snake.push_back(snake_peace); + + SCORE += 7; + } + + // the snake has eaten itself or is out of map + if (is_out_of_borders() || snake_eats_itself()) { + exit(); + break; + } + + draw(); + + usleep(100000); + } + + input_off(); + return 0; +} diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..0d3c47a --- /dev/null +++ b/main.cpp @@ -0,0 +1,34 @@ +#include "raylib.h" + +int main(int argc, const char **argv) { + // Initialization + const int screenWidth = 1280; + const int screenHeight = 768; + const char *windowTitle = "Hello world!"; + const char *message = "Hello world! It's great to be here."; + const int fontSize = 40; + const float msgSpacing = 1.0f; + + InitWindow(screenWidth, screenHeight, windowTitle); + + // NOTE: The following only works after calling InitWindow() (i.e,. RayLib is initialized) + const Font font = GetFontDefault(); + const Vector2 msgSize = MeasureTextEx(font, message, fontSize, msgSpacing); + const Vector2 msgPos = Vector2{(screenWidth - msgSize.x) / 2, (screenHeight - msgSize.y) / 2}; + + SetTargetFPS(60); + + // Main loop + while(!WindowShouldClose()) { + + // Update the display + BeginDrawing(); + ClearBackground(RAYWHITE); + DrawTextEx(font, message, msgPos, fontSize, msgSpacing, RED); + EndDrawing(); + } + + // Cleanup + CloseWindow(); + return 0; +} \ No newline at end of file