From 69175cf1894481b34c9a5a583556572d24ed3539 Mon Sep 17 00:00:00 2001 From: Joseph Aquino Date: Fri, 9 Jan 2026 13:21:35 -0500 Subject: [PATCH] added more imgui widgets to change colors and game config --- config/game-config.txt | 6 +++- include/Fruit.h | 2 +- include/GameConfig.h | 5 +++ include/Player.h | 2 +- src/Fruit.cpp | 2 +- src/Game.cpp | 71 ++++++++++++++++++++++++++++++++++++------ src/Player.cpp | 2 +- 7 files changed, 75 insertions(+), 15 deletions(-) diff --git a/config/game-config.txt b/config/game-config.txt index 02f8fdf..3c72ccc 100644 --- a/config/game-config.txt +++ b/config/game-config.txt @@ -1,6 +1,6 @@ framerate 60 -tickRate 30 +tickRate 2 resolution 1920 1080 @@ -8,6 +8,10 @@ playerHeadColor 1 1 1 playerBodyColor 1 1 1 +boundaryColor 1 1 1 + +fruitColor 1 0 0 + headGridStartPos 3 5 gridCount 8 \ No newline at end of file diff --git a/include/Fruit.h b/include/Fruit.h index 4986e0f..5a584ba 100644 --- a/include/Fruit.h +++ b/include/Fruit.h @@ -7,7 +7,7 @@ struct Fruit { Fruit() = default; - Fruit(sf::Vector2i gridPos_in, const sf::Color& color_in = sf::Color::White); + Fruit(sf::Vector2i gridPos_in, const Color& color_in = sf::Color::White); sf::Vector2u gridPos{}; Color color{}; diff --git a/include/GameConfig.h b/include/GameConfig.h index 5a84487..4da2069 100644 --- a/include/GameConfig.h +++ b/include/GameConfig.h @@ -7,11 +7,16 @@ struct GameConfig { float volume{10}; int tickRate{}; + int tickRateBuffer{}; int framerate{}; Color playerHeadColor; Color playerBodyColor; + Color boundaryColor; + Color fruitColor; sf::Vector2u headGridStartPos; + sf::Vector2u headGridStartPosBuffer; sf::Vector2u resolution; unsigned int gridCount; + int gridCountBuffer; float nodeSize; }; diff --git a/include/Player.h b/include/Player.h index 8102527..7884250 100644 --- a/include/Player.h +++ b/include/Player.h @@ -13,7 +13,7 @@ enum class Direction struct SnakeNode { - SnakeNode(sf::Vector2u gridPos_in, const sf::Color& color_in = sf::Color::White); + SnakeNode(sf::Vector2u gridPos_in, const Color& color_in); sf::Vector2u gridPos{}; sf::Vector2u previousGridPos{}; Color color{}; diff --git a/src/Fruit.cpp b/src/Fruit.cpp index ad46994..56f043c 100644 --- a/src/Fruit.cpp +++ b/src/Fruit.cpp @@ -2,7 +2,7 @@ #include #include -Fruit::Fruit(sf::Vector2i gridPos_in, const sf::Color& color_in) +Fruit::Fruit(sf::Vector2i gridPos_in, const Color& color_in) : gridPos(gridPos_in) , color(color_in) { } diff --git a/src/Game.cpp b/src/Game.cpp index 6dc6e09..759c300 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -38,14 +38,14 @@ Game::Game(bool useImgui_in) config.headGridStartPos.y = config.headGridStartPos.y % config.gridCount; gameBoundary.setFillColor(sf::Color::Transparent); - gameBoundary.setOutlineColor(sf::Color::White); + gameBoundary.setOutlineColor(config.boundaryColor.sfml()); setNewBounds(); player.body.reserve(config.gridCount * config.gridCount); - player.body.emplace_back(config.headGridStartPos); + player.body.emplace_back(config.headGridStartPos, config.playerHeadColor); fruit.respawn(player.body, config.gridCount); - fruit.color = sf::Color::Red; + fruit.color = config.fruitColor; if (!font.openFromFile("assets/fonts/ChakraPetch-Regular.ttf")) { @@ -133,6 +133,7 @@ bool Game::parseConfigFile() if (inputBuff == "tickRate") { configFile >> config.tickRate; + config.tickRateBuffer = config.tickRate; continue; } @@ -157,6 +158,7 @@ bool Game::parseConfigFile() if (inputBuff == "gridCount") { configFile >> config.gridCount; + config.gridCountBuffer = config.gridCount; continue; } @@ -165,6 +167,16 @@ bool Game::parseConfigFile() configFile >> config.resolution.x >> config.resolution.y; continue; } + + if (inputBuff == "boundaryColor") + { + configFile >> config.boundaryColor.r >> config.boundaryColor.g >> config.boundaryColor.b; + } + + if (inputBuff == "fruitColor") + { + configFile >> config.fruitColor.r >> config.fruitColor.g >> config.fruitColor.b; + } } return true; @@ -269,7 +281,7 @@ void Game::collision() if (player.head().gridPos == fruit.gridPos) { - player.body.emplace_back(player.body.back().previousGridPos); + player.body.emplace_back(player.body.back().previousGridPos, config.playerBodyColor); if (player.body.size() != (config.gridCount * config.gridCount)) { eatSound.play(); @@ -307,7 +319,7 @@ void Game::movement() player.inputBuffer = Direction::down; } - if (frameCount % config.tickRate != 0) return; + if (frameCount % (config.framerate / config.tickRate) != 0) return; moveSound.play(); @@ -394,6 +406,7 @@ void Game::imgui() ImGui::Indent(); ImGui::Text("W/A/S/D or arrow keys: move"); ImGui::Text("R: reset game"); + ImGui::Text("Esc: close game"); ImGui::Unindent(); if (ImGui::SliderFloat("Game Volume", &config.volume, 0, 100, "%.1f")) @@ -405,6 +418,38 @@ void Game::imgui() moveSound.setVolume(config.volume); } + if (ImGui::ColorEdit3("Snake head color", config.playerHeadColor.imgui())) + { + player.head().color = config.playerHeadColor; + } + + if (ImGui::ColorEdit3("Snake body color", config.playerBodyColor.imgui())) + { + for (size_t i = 1; i < player.body.size(); i++) + { + player.body[i].color = config.playerBodyColor; + } + } + + if (ImGui::ColorEdit3("Boundary color", config.boundaryColor.imgui())) + { + gameBoundary.setOutlineColor(config.boundaryColor.sfml()); + } + + if (ImGui::ColorEdit3("Fruit color", config.fruitColor.imgui())) + { + fruit.color = config.fruitColor; + } + + ImGui::Text("Game configuration: (press 'reload game' to apply)"); + ImGui::SliderInt("Moves per second", &config.tickRateBuffer, 1, 10); + ImGui::SliderInt("Grid size", &config.gridCountBuffer, 2, 20); + if (ImGui::Button("reload game")) + { + config.tickRate = config.tickRateBuffer; + config.gridCount = config.gridCountBuffer; + resetGame(); + } ImGui::End(); } @@ -448,14 +493,20 @@ void Game::soundSystem() void Game::resetGame() { + failSound.stop(); + winSound.stop(); + setNewBounds(); player.body.clear(); - player.body.emplace_back(config.headGridStartPos); + player.body.emplace_back(config.headGridStartPos, config.playerHeadColor); player.facing = Direction::up; player.inputBuffer = {}; player.score = 0; + config.headGridStartPos.x = config.headGridStartPos.x % config.gridCount; + config.headGridStartPos.y = config.headGridStartPos.y % config.gridCount; + fruit.respawn(player.body, config.gridCount); frameCount = 0; @@ -492,13 +543,13 @@ void Game::setNewBounds() // how big each node is // use integer division to cut off remainder - config.nodeSize = minDimension / config.gridCount; - const float boundryThickness = config.nodeSize * 0.05f * -1; + config.nodeSize = minDimension / (float)config.gridCount; + const float boundaryThickness = config.nodeSize * 0.05f * -1; tempRect.setSize(sf::Vector2f{config.nodeSize, config.nodeSize}); tempRect.setOutlineThickness((config.nodeSize / 10.f) * -1); - const float boundarySize = config.gridCount * config.nodeSize; + const float boundarySize = (float)config.gridCount * config.nodeSize; // Center the grid in the window const float boundaryPosX = (newSize.x - boundarySize) / 2.f; @@ -506,7 +557,7 @@ void Game::setNewBounds() gameBoundary.setSize({boundarySize, boundarySize}); gameBoundary.setPosition({boundaryPosX, boundaryPosY}); - gameBoundary.setOutlineThickness(boundryThickness); + gameBoundary.setOutlineThickness(boundaryThickness); score.setPosition({10, newSize.y - 40}); } diff --git a/src/Player.cpp b/src/Player.cpp index 5777146..4aaece5 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1,6 +1,6 @@ #include -SnakeNode::SnakeNode(sf::Vector2u gridPos_in, const sf::Color& color_in) +SnakeNode::SnakeNode(sf::Vector2u gridPos_in, const Color& color_in) : gridPos(gridPos_in) , color(color_in) { }