From 5a9b07a597b35aa7b98b750cf6e6260f4b891422 Mon Sep 17 00:00:00 2001 From: Rommmmaha Date: Wed, 5 Jun 2024 22:40:47 +0300 Subject: [PATCH] . --- .github/workflows/msbuild.yml | 4 +- client/client.vcxproj | 7 +- client/client.vcxproj.filters | 4 +- client/{_game.cpp => game.cpp} | 199 +++++++++++++++++++++++---------- client/{_game.hpp => game.hpp} | 48 +++++--- client/main.cpp | 21 ++-- client/myfunc.hpp | 30 +++-- client/object.hpp | 7 +- 8 files changed, 214 insertions(+), 106 deletions(-) rename client/{_game.cpp => game.cpp} (70%) rename client/{_game.hpp => game.hpp} (61%) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 30584b0..609283a 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -45,6 +45,6 @@ jobs: - uses: actions/upload-artifact@v4 with: name: build - path: bin/client.exe - retention-days: 7 + path: bin/ + retention-days: 3 compression-level: 0 \ No newline at end of file diff --git a/client/client.vcxproj b/client/client.vcxproj index cc174bb..59b0966 100644 --- a/client/client.vcxproj +++ b/client/client.vcxproj @@ -42,6 +42,7 @@ SFML_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(SolutionDir)SFML\include + stdcpp20 Console @@ -49,17 +50,17 @@ true true $(SolutionDir)SFML\lib - winmm.lib;sfml-system-s.lib;opengl32.lib;gdi32.lib;sfml-window-s.lib;freetype.lib;sfml-graphics-s.lib;%(AdditionalDependencies) + sfml-graphics-s.lib;sfml-window-s.lib;sfml-system-s.lib;sfml-audio-s.lib;opengl32.lib;freetype.lib;winmm.lib;gdi32.lib;openal32.lib;flac.lib;vorbisenc.lib;vorbisfile.lib;vorbis.lib;ogg.lib;%(AdditionalDependencies) - + - + diff --git a/client/client.vcxproj.filters b/client/client.vcxproj.filters index 9f4821b..38df41d 100644 --- a/client/client.vcxproj.filters +++ b/client/client.vcxproj.filters @@ -18,12 +18,12 @@ Source Files - + Source Files - + Header Files diff --git a/client/_game.cpp b/client/game.cpp similarity index 70% rename from client/_game.cpp rename to client/game.cpp index 6e42cef..e6ed3f9 100644 --- a/client/_game.cpp +++ b/client/game.cpp @@ -1,35 +1,64 @@ -#include "_game.hpp" +#include "game.hpp" #include "iostream" #include "myfunc.hpp" -_game::_game() +game::game() { + srand(unsigned int(time(NULL))); + + fps = 10; + scale = 20; running = true; needInitialization = true; - number_of_enemies = 3; + number_of_enemies = 2; + + sb_intro.loadFromFile("resources/intro.wav"); + sb_damaged.loadFromFile("resources/damaged.wav"); + sb_captured.loadFromFile("resources/captured.wav"); + sb_dead.loadFromFile("resources/dead.wav"); + + intro.setBuffer(sb_intro); + damaged.setBuffer(sb_damaged); + captured.setBuffer(sb_captured); + dead.setBuffer(sb_dead); + + intro.setVolume(10.f); + + font.loadFromFile("resources/04B_30__.TTF"); + + _RenderWindow = new sf::RenderWindow(sf::VideoMode(800, 600), "xonix-x", sf::Style::Titlebar | sf::Style::Close); + _RenderWindow->setFramerateLimit(fps); + + firstStart = true; } -void _game::init() +void game::clear() { - this->destruct(); - srand(0); - srand(unsigned int(time(NULL))); + if (map != nullptr) + delete map; + if (tmp_map != nullptr) + delete tmp_map; + leftNeighbours.clear(); + rightNeighbours.clear(); +} + +void game::init() +{ + // Preparing + clear(); needInitialization = false; - // Initialization - _Clock.restart(); + // Window - _RenderWindow = new sf::RenderWindow(sf::VideoMode(800, 600), "xonix-x", sf::Style::Titlebar | sf::Style::Close); - _RenderWindow->setFramerateLimit(15); + scale_vector = {scale, scale}; + // Map - map_size.x = _RenderWindow->getSize().x / 10; - map_size.y = _RenderWindow->getSize().y / 10; + map_size.x = size_t(_RenderWindow->getSize().x / scale); + map_size.y = size_t(_RenderWindow->getSize().y / scale); map_size.z = map_size.x * map_size.y; map = new int[map_size.z]; tmp_map = new int[map_size.z]; for (int i = 0; i < map_size.z; ++i) - { map[i] = 0; - tmp_map[i] = 0; - } + // Map borders for (int i = 0; i < map_size.x; ++i) { @@ -45,42 +74,32 @@ void _game::init() map[pos2index(map_size.x - 2, i, map_size.x)] = 1; map[pos2index(map_size.x - 1, i, map_size.x)] = 1; } + // Player player = object(1, int(map_size.x) / 2, 1); + player.shape = sf::RectangleShape(scale_vector); player.direction = -1; + // Enemies enemies.clear(); for (; enemies.size() < number_of_enemies;) { enemies.push_back(object(2, 3 + rand() % (map_size.x - 6), 3 + rand() % (map_size.y - 6))); + enemies.back().shape = sf::RectangleShape(scale_vector); } - // Colors - player_color = sf::Color::Green; - enemy_color = sf::Color::Magenta; - wall_color = sf::Color::White; - path_color = sf::Color::White; - background_color = sf::Color::Black; -} -void _game::destruct() -{ - if (_RenderWindow != nullptr) - { - delete _RenderWindow; - } - if (map != nullptr) - { - delete map; - } - if (tmp_map != nullptr) + // Restarting clock + _Clock.restart(); + _GlobalClock.restart(); + // First start + if (firstStart) { - delete tmp_map; + intro.play(); + firstStart = false; } - leftNeighbours.clear(); - rightNeighbours.clear(); } -void _game::update() +void game::update() { // Updating title { @@ -98,11 +117,13 @@ void _game::update() title += std::to_string(number_of_enemies - 2); title += " | "; title += std::to_string(int(percentage)); - title += "% < 90%"; + title += "% < 90% | FPS: "; + title += std::to_string(fps); _RenderWindow->setTitle(title); } // Events + bool moved = false; sf::Event event; while (_RenderWindow->pollEvent(event)) { @@ -113,7 +134,6 @@ void _game::update() } if (event.type == sf::Event::KeyPressed) { - bool moved = false; switch (event.key.code) { case sf::Keyboard::Up: @@ -134,12 +154,35 @@ void _game::update() case sf::Keyboard::D: debug = !debug; break; + case sf::Keyboard::PageUp: + ++scale; + needInitialization = true; + return; + case sf::Keyboard::PageDown: + --scale; + scale = scale < 1 ? 1 : scale; + needInitialization = true; + return; + case sf::Keyboard::Equal: + ++fps; + _RenderWindow->setFramerateLimit(fps); + break; + case sf::Keyboard::Dash: + --fps; + _RenderWindow->setFramerateLimit(fps); + break; + case sf::Keyboard::Space: + return; case sf::Keyboard::Escape: running = false; return; } } } + if (fps < 0) + fps = 0; + if (scale < 1) + scale = 10; // Color gradients float speed = 30; float hue = _Clock.getElapsedTime().asSeconds() * speed; @@ -158,13 +201,13 @@ void _game::update() if (player.x < 0 || player.x > map_size.x - 1 || player.y < 0 || player.y > map_size.y - 1) { player.direction = -1; - for (; player.x < 0; player.x++) + for (; player.x < 0; ++player.x) ; - for (; player.x > map_size.x - 1; player.x--) + for (; player.x > map_size.x - 1; --player.x) ; - for (; player.y < 0; player.y++) + for (; player.y < 0; ++player.y) ; - for (; player.y > map_size.y - 1; player.y--) + for (; player.y > map_size.y - 1; --player.y) ; } @@ -240,9 +283,10 @@ void _game::update() leftNeighbours.clear(); rightNeighbours.clear(); player.direction = -1; + captured.play(); } } - player.updateShape(); + player.updateShape(scale_vector); // Enemies movement for (auto &enemy : enemies) @@ -291,14 +335,15 @@ void _game::update() // Check if enemy is on path if (map[pos2index(enemy.x, enemy.y, map_size.x)] == 2) { + damaged.play(); needInitialization = true; return; } - enemy.updateShape(); + enemy.updateShape(scale_vector); } } -void _game::draw() +void game::draw() { // - Render Start @@ -306,27 +351,28 @@ void _game::draw() _RenderWindow->clear(background_color); // Init abojects and colors - sf::RectangleShape wall(sf::Vector2f(10, 10)); - sf::RectangleShape path(sf::Vector2f(10, 10)); - sf::RectangleShape scanR(sf::Vector2f(10, 10)); - sf::RectangleShape scanL(sf::Vector2f(10, 10)); + sf::Vector2i i = sf::Vector2i(0, 0); + + sf::RectangleShape wall(scale_vector); + sf::RectangleShape path(scale_vector); + sf::RectangleShape scanR(scale_vector); + sf::RectangleShape scanL(scale_vector); wall.setFillColor(wall_color); path.setFillColor(path_color); scanL.setFillColor(sf::Color(0, 0, 255, 100)); scanR.setFillColor(sf::Color(255, 0, 0, 100)); - sf::Vector2i i = sf::Vector2i(0, 0); // [d] Drawing sides if (debug) { for (auto &i : leftNeighbours) { - scanL.setPosition(sf::Vector2f(i.x * 10.0f, i.y * 10.0f)); + scanL.setPosition(sf::Vector2f(i.x * scale, i.y * scale)); _RenderWindow->draw(scanL); } for (auto &i : rightNeighbours) { - scanR.setPosition(sf::Vector2f(i.x * 10.0f, i.y * 10.0f)); + scanR.setPosition(sf::Vector2f(i.x * scale, i.y * scale)); _RenderWindow->draw(scanR); } } @@ -337,13 +383,13 @@ void _game::draw() // Drawing walls if (map[pos2index(i.x, i.y, map_size.x)] == 1) { - wall.setPosition(sf::Vector2f(i.x * 10.0f, i.y * 10.0f)); + wall.setPosition(sf::Vector2f(i.x * scale, i.y * scale)); _RenderWindow->draw(wall); } // Drawing player path if (map[pos2index(i.x, i.y, map_size.x)] == 2) { - path.setPosition(sf::Vector2f(i.x * 10.0f, i.y * 10.0f)); + path.setPosition(sf::Vector2f(i.x * scale, i.y * scale)); _RenderWindow->draw(path); } // [d] Drawing sides @@ -351,12 +397,12 @@ void _game::draw() { if (tmp_map[pos2index(i.x, i.y, map_size.x)] == 'l') { - scanL.setPosition(sf::Vector2f(i.x * 10.0f, i.y * 10.0f)); + scanL.setPosition(sf::Vector2f(i.x * scale, i.y * scale)); _RenderWindow->draw(scanL); } if (tmp_map[pos2index(i.x, i.y, map_size.x)] == 'r') { - scanR.setPosition(sf::Vector2f(i.x * 10.0f, i.y * 10.0f)); + scanR.setPosition(sf::Vector2f(i.x * scale, i.y * scale)); _RenderWindow->draw(scanR); } } @@ -374,21 +420,52 @@ void _game::draw() player.shape.setFillColor(player_color); _RenderWindow->draw(player.shape); + // Drawing intro overlay + if (_GlobalClock.getElapsedTime().asSeconds() < 5) + { + float seconds = _GlobalClock.getElapsedTime().asSeconds(); + int alpha = 0, alpha2 = 255; + _RenderWindow->setFramerateLimit(0); + if (0.16 < seconds && seconds < 1.18) + alpha = int((seconds - 0.16) / 0.025) % 2 ? (100 * (seconds - 0.16f)) : 0; + if (1.16 < seconds && seconds < 3) + alpha = 255; + if (3 < seconds) + { + _RenderWindow->setFramerateLimit(fps); + alpha = (5 - _GlobalClock.getElapsedTime().asSeconds()) / 2 * 255; + alpha2 = (5 - _GlobalClock.getElapsedTime().asSeconds()) / 2 * 255; + } + + sf::Text _Text; + _Text.setString("xonix-X"); + _Text.setFont(font); + _Text.setCharacterSize(100); + _Text.setPosition(sf::Vector2f(_RenderWindow->getSize().x / 2 - _Text.getGlobalBounds().width / 2, + _RenderWindow->getSize().y / 2 - _Text.getGlobalBounds().height / 2 - + _Text.getCharacterSize())); + _Text.setFillColor(sf::Color(255, 255, 255, alpha)); + sf::RectangleShape bg(sf::Vector2f(_RenderWindow->getSize().x, _RenderWindow->getSize().y)); + bg.setFillColor(sf::Color(0, 0, 0, alpha2)); + + _RenderWindow->draw(bg); + _RenderWindow->draw(_Text); + } // - Display _RenderWindow->display(); } -int _game::count_walls() const +int game::count_walls() const { int count = 0; for (int i = 0; i < map_size.x; ++i) for (int j = 0; j < map_size.y; ++j) if (map[pos2index(i, j, map_size.x)] == 1) - count++; + ++count; return count; } -void _game::update_tmp_map() +void game::update_tmp_map() { for (size_t i = 0; i < map_size.z; ++i) tmp_map[i] = map[i]; diff --git a/client/_game.hpp b/client/game.hpp similarity index 61% rename from client/_game.hpp rename to client/game.hpp index 33713bf..371ce38 100644 --- a/client/_game.hpp +++ b/client/game.hpp @@ -1,38 +1,60 @@ #pragma once +#include "SFML/Audio.hpp" #include "SFML/Graphics.hpp" #include "object.hpp" #include -class _game +class game { public: - _game(); - bool running; + game(); + void clear(); + void draw_intro(); + void init(); - void destruct(); void update(); void draw(); + + bool running; bool needInitialization; private: - sf::Color player_color; - sf::Color enemy_color; - sf::Color wall_color; - sf::Color path_color; - sf::Color background_color; - - bool debug; + bool firstStart; + int fps; int number_of_enemies; + bool debug; + float scale; + int *map; int *tmp_map; sf::Vector3 map_size; + sf::Vector2f scale_vector; + sf::RenderWindow *_RenderWindow; + object player; std::vector enemies; - std::vector leftNeighbours, rightNeighbours; sf::Clock _Clock; - sf::RenderWindow *_RenderWindow; + sf::Clock _GlobalClock; + std::vector leftNeighbours, rightNeighbours; + + sf::Color player_color; + sf::Color enemy_color; + sf::Color wall_color; + sf::Color path_color; + sf::Color background_color; + + sf::SoundBuffer sb_intro; + sf::SoundBuffer sb_damaged; + sf::SoundBuffer sb_captured; + sf::SoundBuffer sb_dead; + + sf::Sound intro; + sf::Sound damaged; + sf::Sound captured; + sf::Sound dead; + sf::Font font; int count_walls() const; void update_tmp_map(); }; diff --git a/client/main.cpp b/client/main.cpp index f2bad06..43db77e 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -1,16 +1,17 @@ -#include "_game.hpp" -#pragma warning(disable : 4244 4267 4305) - +#include "game.hpp" int main() { - _game game; - while (game.running) + game _game; + while (_game.running) { - if (game.needInitialization) - game.init(); - game.update(); - game.draw(); + if (_game.needInitialization) + _game.init(); + _game.update(); + _game.draw(); } - game.destruct(); return 0; } +int WinMain() +{ + return main(); +} diff --git a/client/myfunc.hpp b/client/myfunc.hpp index 64a6759..db71971 100644 --- a/client/myfunc.hpp +++ b/client/myfunc.hpp @@ -85,17 +85,25 @@ sf::Color HSV2RGB(float fH, float fV, float fS) void getNeighbours(int *map, sf::Vector2i pos, sf::Vector3 map_size, int type) { - if (pos.x < 0 || pos.y < 0 || pos.x >= map_size.x || pos.y >= map_size.y) - { - return; - } - if (map[pos2index(pos.x, pos.y, map_size.x)] != 0) + std::vector queue; + queue.push_back(pos); + + while (!queue.empty()) { - return; + sf::Vector2i current = queue.front(); + queue.erase(queue.begin()); + + if (current.x < 0 || current.y < 0 || current.x >= map_size.x || current.y >= map_size.y) + continue; + + size_t index = pos2index(current.x, current.y, map_size.x); + if (map[index] != 0) + continue; + + map[index] = type; + queue.push_back(sf::Vector2i(current.x - 1, current.y)); + queue.push_back(sf::Vector2i(current.x + 1, current.y)); + queue.push_back(sf::Vector2i(current.x, current.y - 1)); + queue.push_back(sf::Vector2i(current.x, current.y + 1)); } - map[pos2index(pos.x, pos.y, map_size.x)] = type; // scanned - getNeighbours(map, sf::Vector2i(pos.x - 1, pos.y), map_size, type); - getNeighbours(map, sf::Vector2i(pos.x + 1, pos.y), map_size, type); - getNeighbours(map, sf::Vector2i(pos.x, pos.y - 1), map_size, type); - getNeighbours(map, sf::Vector2i(pos.x, pos.y + 1), map_size, type); } diff --git a/client/object.hpp b/client/object.hpp index 2ee06bb..dd5302e 100644 --- a/client/object.hpp +++ b/client/object.hpp @@ -6,7 +6,7 @@ class object : public sf::Vector2i sf::Vector2i previous = sf::Vector2i(0, 0); int direction; int type; // 1 - player, 2 - enemy - sf::RectangleShape shape = sf::RectangleShape(sf::Vector2f(10, 10)); + sf::RectangleShape shape; object() { this->x = 0; @@ -24,7 +24,6 @@ class object : public sf::Vector2i } void move() { - float step = 10; if (type == 1) // player movement { switch (direction) @@ -70,9 +69,9 @@ class object : public sf::Vector2i } } } - void updateShape() + void updateShape(sf::Vector2f scale) { this->previous = sf::Vector2i(this->x, this->y); - this->shape.setPosition(sf::Vector2f(x * 10.0f, y * 10.0f)); + this->shape.setPosition(sf::Vector2f(x * scale.x, y * scale.y)); } };