diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..0a4f13f --- /dev/null +++ b/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + CompilationDatabase: build/ \ No newline at end of file diff --git a/assets/sounds/bgMusic.wav b/assets/sounds/bgMusic.wav new file mode 100644 index 0000000..b21be06 Binary files /dev/null and b/assets/sounds/bgMusic.wav differ diff --git a/assets/sounds/eat.wav b/assets/sounds/eat.wav new file mode 100644 index 0000000..c7debc6 Binary files /dev/null and b/assets/sounds/eat.wav differ diff --git a/assets/sounds/lose.ogg b/assets/sounds/lose.ogg new file mode 100644 index 0000000..0791ebc Binary files /dev/null and b/assets/sounds/lose.ogg differ diff --git a/assets/sounds/move.wav b/assets/sounds/move.wav new file mode 100644 index 0000000..4110d3e Binary files /dev/null and b/assets/sounds/move.wav differ diff --git a/assets/sounds/win.ogg b/assets/sounds/win.ogg new file mode 100644 index 0000000..2c1b22e Binary files /dev/null and b/assets/sounds/win.ogg differ diff --git a/include/Fruit.h b/include/Fruit.h index 71a7bee..b0a32d1 100644 --- a/include/Fruit.h +++ b/include/Fruit.h @@ -11,6 +11,6 @@ struct Fruit sf::Vector2u gridPos{}; Color color{}; - sf::Vector2f windowPos(float gridSize_in); + sf::Vector2f windowPos(float gridSize_in) const; void respawn(const std::vector& body_in, sf::Vector2u gridCount_in); }; \ No newline at end of file diff --git a/include/Game.h b/include/Game.h index 96a66e5..58f7715 100644 --- a/include/Game.h +++ b/include/Game.h @@ -1,14 +1,21 @@ #pragma once -#include -#include -#include -#include +#include "Util.h" +#include "Player.h" +#include "Fruit.h" +#include "GameConfig.h" + #include #include #include #include +enum class GameState +{ + playing, + lose, + win +}; class Game { @@ -51,6 +58,16 @@ private: sf::Text score; sf::SoundBuffer failSoundBuffer; + sf::SoundBuffer winSoundBuffer; + sf::SoundBuffer bgMusicBuffer; + sf::SoundBuffer eatSoundBuffer; + sf::SoundBuffer moveSoundBuffer; + + sf::Sound failSound; + sf::Sound winSound; + sf::Sound bgMusic; + sf::Sound eatSound; + sf::Sound moveSound; sf::RectangleShape tempRect; @@ -62,6 +79,8 @@ private: sf::Vector2u gridCount; size_t frameCount{}; + size_t fruitEaten{}; + GameState state{GameState::playing}; bool useImgui; bool fail{}; bool win{}; diff --git a/include/GameConfig.h b/include/GameConfig.h index 0fac628..0f4be31 100644 --- a/include/GameConfig.h +++ b/include/GameConfig.h @@ -11,5 +11,5 @@ struct GameConfig Color playerHeadColor; Color playerBodyColor; sf::Vector2u headGridStartPos; - unsigned int gridSize; + float gridSize; }; diff --git a/include/Util.h b/include/Util.h index 53ba3ae..4e8db27 100644 --- a/include/Util.h +++ b/include/Util.h @@ -1,5 +1,5 @@ #pragma once -#include -#include -#include \ No newline at end of file +#include "Random.h" +#include "Color.h" +#include "Math-util.h" \ No newline at end of file diff --git a/scripts/ecc.sh b/scripts/ecc.sh index fc4a4bc..081dbfe 100755 --- a/scripts/ecc.sh +++ b/scripts/ecc.sh @@ -5,7 +5,7 @@ cd "$SCRIPT_DIR" if [ -z "$1" ] || [ $# -eq 0 ] then - ./third-party/premake5/premake5 --config=Debug ecc + ../third-party/premake5/premake5 --config=Debug ecc else - ./third-party/premake5/premake5 --config=$1 ecc + ../third-party/premake5/premake5 --config=$1 ecc fi diff --git a/src/Fruit.cpp b/src/Fruit.cpp index 001f2ba..50ee136 100644 --- a/src/Fruit.cpp +++ b/src/Fruit.cpp @@ -7,7 +7,7 @@ Fruit::Fruit(sf::Vector2i gridPos_in, const sf::Color& color_in) , color(color_in) { } -sf::Vector2f Fruit::windowPos(float gridSize_in) +sf::Vector2f Fruit::windowPos(float gridSize_in) const { return {gridPos.x * gridSize_in, gridPos.y * gridSize_in}; } @@ -16,16 +16,17 @@ void Fruit::respawn(const std::vector& body_in, sf::Vector2u gridCoun { unsigned int tempX; unsigned int tempY; - bool valid = false; + bool valid; do { + valid = true; tempX = Random::get(0, gridCount_in.x - 1); tempY = Random::get(0, gridCount_in.y - 1); for (const auto& node : body_in) { - if (node.gridPos.x != tempX and node.gridPos.y != tempY) + if (node.gridPos.x == tempX and node.gridPos.y == tempY) { - valid = true; + valid = false; } } } while (!valid); diff --git a/src/Game.cpp b/src/Game.cpp index fc50d1d..e190d5b 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -10,36 +10,84 @@ #include #include - Game::Game(bool useImgui_in) : config() - , window({sf::VideoMode({ 1920u, 1080u }), "project-snake"}) - , font("assets/fonts/ChakraPetch-Regular.ttf") + , window({sf::VideoMode({1920u, 1080u}), "project-snake"}) , score(font) + , failSound(failSoundBuffer) + , winSound(winSoundBuffer) + , bgMusic(bgMusicBuffer) + , eatSound(eatSoundBuffer) + , moveSound(moveSoundBuffer) , useImgui(useImgui_in) -{ - if (!ImGui::SFML::Init(window)) +{ + if (!ImGui::SFML::Init(window)) { std::cout << "ERROR: Could not open window\n"; return; } - if (!parseConfigFile()) + if (!parseConfigFile()) { std::cout << "ERROR: Could not parse config file\n"; window.close(); return; } - gridCount.x = window.getSize().x / config.gridSize; - gridCount.y = window.getSize().y / config.gridSize; + gridCount.x = window.getSize().x / static_cast(config.gridSize); + gridCount.y = window.getSize().y / static_cast(config.gridSize); player.body.reserve(100); player.body.emplace_back(config.headGridStartPos); - fruit.gridPos = {5,5}; + fruit.gridPos = {5, 5}; fruit.color = sf::Color::Red; - + + if (!font.openFromFile("assets/fonts/ChakraPetch-Regular.ttf")) + { + std::cerr << "ERROR: Failed to load font!\n"; + return; + } + + if (!failSoundBuffer.loadFromFile("assets/sounds/lose.ogg")) + { + std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n"; + return; + } + + if (!winSoundBuffer.loadFromFile("assets/sounds/win.ogg")) + { + std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n"; + return; + } + + if (!bgMusicBuffer.loadFromFile("assets/sounds/bgMusic.wav")) + { + std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n"; + return; + } + + if (!eatSoundBuffer.loadFromFile("assets/sounds/eat.wav")) + { + std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n"; + return; + } + + if (!moveSoundBuffer.loadFromFile("assets/sounds/move.wav")) + { + std::cerr << "ERROR: Failed to load lose.ogg! Check file path.\n"; + return; + } + + failSound.setVolume(10.f); + winSound.setVolume(10.f); + bgMusic.setVolume(10.f); + eatSound.setVolume(10.f); + moveSound.setVolume(10.f); + + bgMusic.setLooping(true); + bgMusic.play(); + //uncomment to quickly test player movement /* player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 1, config.headGridStartPos.y}); @@ -47,15 +95,14 @@ Game::Game(bool useImgui_in) player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 3, config.headGridStartPos.y}); player.body.emplace_back(sf::Vector2i{config.headGridStartPos.x - 4, config.headGridStartPos.y}); */ - - tempRect.setSize(sf::Vector2f{(float)config.gridSize, (float)config.gridSize}); + + tempRect.setSize(sf::Vector2f{(config.gridSize), config.gridSize}); tempRect.setOutlineThickness(-5); tempRect.setOutlineColor(sf::Color::Black); score.setPosition({10, static_cast(window.getSize().y - 40)}); window.setFramerateLimit(config.framerate); - } bool Game::parseConfigFile() @@ -74,31 +121,37 @@ bool Game::parseConfigFile() if (inputBuff == "framerate") { configFile >> config.framerate; + continue; } if (inputBuff == "tickRate") { configFile >> config.tickRate; + continue; } if (inputBuff == "playerHeadColor") { configFile >> config.playerHeadColor.r >> config.playerHeadColor.g >> config.playerHeadColor.b; + continue; } if (inputBuff == "playerBodyColor") { configFile >> config.playerBodyColor.r >> config.playerBodyColor.g >> config.playerBodyColor.b; + continue; } if (inputBuff == "headGridStartPos") { configFile >> config.headGridStartPos.x >> config.headGridStartPos.y; + continue; } if (inputBuff == "gridSize") { configFile >> config.gridSize; + continue; } } @@ -191,7 +244,8 @@ void Game::collision() { if (player.head().gridPos == player.body.at(i).gridPos) { - fail = true; + state = GameState::lose; + failSound.play(); return; } } @@ -201,13 +255,14 @@ void Game::collision() player.body.emplace_back(player.body.back().previousGridPos); if (player.body.size() != (gridCount.x * gridCount.y)) { - //play sound + eatSound.play(); + player.score += 100; fruit.respawn(player.body, gridCount); } else { - //play win sound - + state = GameState::win; + winSound.play(); } } @@ -237,13 +292,16 @@ void Game::movement() if (frameCount % config.tickRate != 0) return; + moveSound.play(); + SnakeNode& head = player.head(); switch (player.inputBuffer) { case Direction::up: if (head.gridPos.y == 0) { - fail = true; + state = GameState::lose; + failSound.play(); return; } @@ -256,7 +314,8 @@ void Game::movement() case Direction::down: if (head.gridPos.y == gridCount.y - 1) { - fail = true; + state = GameState::lose; + failSound.play(); return; } @@ -269,7 +328,8 @@ void Game::movement() case Direction::left: if (head.gridPos.x == 0) { - fail = true; + state = GameState::lose; + failSound.play(); return; } @@ -282,7 +342,8 @@ void Game::movement() case Direction::right: if (head.gridPos.x == gridCount.x -1) { - fail = true; + state = GameState::lose; + failSound.play(); return; } @@ -334,12 +395,12 @@ void Game::render() for (auto& node : player.body) { tempRect.setFillColor(node.color.sfml()); - tempRect.setPosition(node.windowPos((float)config.gridSize)); + tempRect.setPosition(node.windowPos(config.gridSize)); window.draw(tempRect); } tempRect.setFillColor(fruit.color.sfml()); - tempRect.setPosition(fruit.windowPos((float)config.gridSize)); + tempRect.setPosition(fruit.windowPos(config.gridSize)); window.draw(tempRect); score.setString("Score: " + std::to_string(player.score)); @@ -353,11 +414,12 @@ void Game::render() void Game::soundSystem() { - -} - -void Game::scoreSystem() -{ + if (state != GameState::playing) + { + bgMusic.stop(); + eatSound.stop(); + moveSound.stop(); + } } @@ -365,22 +427,30 @@ void Game::resetGame() { player.body.clear(); player.body.emplace_back(config.headGridStartPos); - fail = false; player.facing = Direction::up; + + fruit.respawn(player.body, gridCount); + + state = GameState::playing; + bgMusic.play(); } void Game::failState() { - // if (failSound.getStatus() == sf::Sound::Status::Stopped) - // { - // resetGame(); - // return; - // } + if (failSound.getStatus() == sf::Sound::Status::Stopped) + { + resetGame(); + return; + } } void Game::winState() { - + if (winSound.getStatus() == sf::Sound::Status::Stopped) + { + resetGame(); + return; + } } void Game::run() @@ -393,21 +463,19 @@ void Game::run() input(); - if (!fail and !win) + if (state == GameState::playing) { movement(); collision(); soundSystem(); - - scoreSystem(); } - else if (fail) + else if (state == GameState::lose) { failState(); } - else if (win) + else if (state == GameState::win) { winState(); } @@ -419,4 +487,8 @@ void Game::run() } ImGui::SFML::Shutdown(); -} \ No newline at end of file +} + +/* + * + */ \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2bbb27e..5a7480b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,7 @@ int main(int argc, char* argv[]) { // parse command-line arguments bool useImgui{true}; - for (int i = 0; i < argc; i++) + for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--noImgui")) {