diff --git a/Config/game-config.txt b/Config/game-config.txt index 1351ef4..7fedaff 100644 --- a/Config/game-config.txt +++ b/Config/game-config.txt @@ -1,8 +1,8 @@ framerate 60 -playerStartPos 700 700 +playerStartPos 900 900 -playerSize 500 10 +playerSize 250 10 playerSpeed 10 @@ -10,7 +10,7 @@ playerColor 1 1 1 ballRadius 5 -ballSpeed 2.5 +ballSpeed 5 ballColor 1 0 0 @@ -18,10 +18,8 @@ brickSize 50 10 brickColor 1 1 1 +brickCount 1000 + specialBrickColor 0 1 0 -bricksPerRow 8 - -bricksPerColumn 5 - -specialBrickCount 3 +specialBrickCount 10 diff --git a/include/Game.h b/include/Game.h index 91b8571..2f6e784 100644 --- a/include/Game.h +++ b/include/Game.h @@ -69,10 +69,14 @@ private: bool parseConfigFile(); + void setupLevel(); + private: sf::Clock clock; sf::RenderWindow window; + sf::Font font; + sf::Text lives; Player player; std::vector balls; @@ -88,10 +92,8 @@ private: sf::Vector2f playerStartPos{}; sf::Vector2f brickHalfSize{}; sf::Vector2f playerHalfSize{}; - int rowSize{}; - int columnSize{}; - int totalSpecialBricks{}; - int totalBricks{rowSize * columnSize}; + unsigned int totalSpecialBricks{}; + unsigned int totalBricks{}; unsigned int framerate{}; float playerSpeed{}; float ballRadius{}; @@ -102,4 +104,5 @@ private: Color specialBrickColor{}; bool windowCollasped{false}; static constexpr unsigned int numPhysicsUpdates{4}; + }; \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index 9ad33c0..cdcb162 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -26,13 +26,16 @@ Player::Player(sf::Vector2f position_in) Game::Game() - : window({sf::VideoMode({ 1920u, 1080u }), "breakout"}) + : window({sf::VideoMode({ 1920u, 1080u }), "project-breakout"}) + , font("assets/fonts/ChakraPetch-Regular.ttf") + , lives(font) { if (!ImGui::SFML::Init(window)) return; if (!parseConfigFile()) return; + lives.setPosition({10, static_cast(window.getSize().y - 40)}); window.setFramerateLimit(framerate); player.pos = playerStartPos; @@ -43,12 +46,49 @@ Game::Game() ballMaxSpeed /= numPhysicsUpdates; bricks.reserve(totalBricks); - bricks.emplace_back(sf::Vector2f{200, 100}); specialBricks.reserve(totalSpecialBricks); balls.reserve(10); ballsToAdd.reserve(10); - ballsToAdd.emplace_back(playerStartPos.x, playerStartPos.y - 300); + setupLevel(); + + ballsToAdd.emplace_back(playerStartPos.x, playerStartPos.y - 50); +} + +void Game::setupLevel() +{ + const unsigned int specialBrickInterval = totalBricks / totalSpecialBricks; + + constexpr float xSpacing = 20.f; + constexpr float ySpacing = 20.f; + const float xOffset = brickSize.x + xSpacing; + const float yOffset = brickSize.y + ySpacing; + const unsigned int numRows = window.getSize().x / xOffset; + const unsigned int numColumns = (window.getSize().y - 300)/ yOffset; + unsigned int row{}; + unsigned int column{}; + + for (size_t i = 0; i < totalBricks; i++) + { + if (row >= numRows) + { + row = 0; + column++; + } + + if (column >= numColumns) + break; + + if (i % specialBrickInterval == 0) + { + specialBricks.emplace_back(sf::Vector2f{(row * xOffset) + xSpacing + brickHalfSize.x, (column * yOffset) + ySpacing + brickHalfSize.y}); + } + else + { + bricks.emplace_back(sf::Vector2f{(row * xOffset) + xSpacing + brickHalfSize.x, (column * yOffset) + ySpacing + brickHalfSize.y}); + } + row++; + } } bool Game::parseConfigFile() @@ -67,17 +107,14 @@ bool Game::parseConfigFile() if (inputBuff == "framerate") configFile >> framerate; - if (inputBuff == "bricksPerRow") - configFile >> rowSize; - if (inputBuff == "ballRadius") configFile >> ballRadius; if (inputBuff == "playerSpeed") configFile >> playerSpeed; - if (inputBuff == "bricksPerColumn") - configFile >> columnSize; + if (inputBuff == "brickCount") + configFile >> totalBricks; if (inputBuff == "specialBrickCount") configFile >> totalSpecialBricks; @@ -107,6 +144,9 @@ bool Game::parseConfigFile() configFile >> ballMaxSpeed; } + if (totalSpecialBricks > totalBricks) + totalSpecialBricks = totalBricks; + return true; } @@ -176,7 +216,7 @@ void Game::input() switch (MouseButtonPressed->button) { case sf::Mouse::Button::Left: - specialBricks.emplace_back((sf::Vector2f)MouseButtonPressed->position); + //specialBricks.emplace_back((sf::Vector2f)MouseButtonPressed->position); break; default: @@ -218,16 +258,17 @@ void Game::checkBallCollision() const auto intersect = getOverlap(ballBounds, brickBounds); const auto previousIntersect = getOverlap(previousBallBounds, brickBounds); + // coming from x directon if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0) { brick.alive = false; ball.velocity.x *= -1; if (ball.pos.x < brick.pos.x) - { + {// from the left ball.pos.x -= intersect.x; } else - { + {// from the right ball.pos.x += intersect.x; } } @@ -238,11 +279,11 @@ void Game::checkBallCollision() brick.alive = false; ball.velocity.y *= -1; if (ball.pos.y < brick.pos.y) - { + {// from the top ball.pos.y -= intersect.y; } else - { + {// from the bottom ball.pos.y += intersect.y; } } @@ -262,11 +303,11 @@ void Game::checkBallCollision() spawnExtraBall = true; ball.velocity.x *= -1; if (ball.pos.x < brick.pos.x) - { + {// from the left ball.pos.x -= intersect.x; } else - { + {// from the right ball.pos.x += intersect.x; } } @@ -278,11 +319,11 @@ void Game::checkBallCollision() spawnExtraBall = true; ball.velocity.y *= -1; if (ball.pos.y < brick.pos.y) - { + {// from the top ball.pos.y -= intersect.y; } else - { + {// from the bottom ball.pos.y += intersect.y; } } @@ -293,7 +334,6 @@ void Game::checkBallCollision() } } - //wall collide if (ballBounds.position.y + ballBounds.size.y > window.getSize().y) { @@ -378,13 +418,15 @@ void Game::checkEndGame() if (balls.empty()) { player.lives--; - ballsToAdd.emplace_back(sf::Vector2f{player.pos.x, player.pos.y - 500}); + ballsToAdd.emplace_back(sf::Vector2f{player.pos.x, player.pos.y - 50}); } if (player.lives <= 0) { - + player.lives = 3; + resetGame(); + ballsToAdd.emplace_back(sf::Vector2f{player.pos.x, player.pos.y - 50}); } } @@ -406,7 +448,7 @@ void Game::imgui() { ImGui::Begin("menu"); - ImGui::SetWindowCollapsed(windowCollasped); + ImGui::SetWindowCollapsed(true); ImGui::Text("Controls:"); ImGui::Indent(); ImGui::Text("A/D or arrow keys: move left and right"); @@ -434,6 +476,8 @@ void Game::render() { window.clear(); + lives.setString("Lives: " + std::to_string(player.lives)); + window.draw(lives); tempRect.setOrigin(brickHalfSize); tempRect.setSize(brickSize); for (auto& brick : bricks) @@ -476,6 +520,7 @@ void Game::resetGame() balls.clear(); ballsToAdd.clear(); + setupLevel(); } void Game::run() @@ -510,6 +555,7 @@ void Game::runNoImgui() while(window.isOpen()) { ImGui::SFML::Update(window, clock.restart()); + input(); for (size_t i = 0; i <= numPhysicsUpdates; i++)