added basic level loading and proper player life system
This commit is contained in:
parent
110af2c12a
commit
0fc6c50009
|
|
@ -1,8 +1,8 @@
|
||||||
framerate 60
|
framerate 60
|
||||||
|
|
||||||
playerStartPos 700 700
|
playerStartPos 900 900
|
||||||
|
|
||||||
playerSize 500 10
|
playerSize 250 10
|
||||||
|
|
||||||
playerSpeed 10
|
playerSpeed 10
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@ playerColor 1 1 1
|
||||||
|
|
||||||
ballRadius 5
|
ballRadius 5
|
||||||
|
|
||||||
ballSpeed 2.5
|
ballSpeed 5
|
||||||
|
|
||||||
ballColor 1 0 0
|
ballColor 1 0 0
|
||||||
|
|
||||||
|
|
@ -18,10 +18,8 @@ brickSize 50 10
|
||||||
|
|
||||||
brickColor 1 1 1
|
brickColor 1 1 1
|
||||||
|
|
||||||
|
brickCount 1000
|
||||||
|
|
||||||
specialBrickColor 0 1 0
|
specialBrickColor 0 1 0
|
||||||
|
|
||||||
bricksPerRow 8
|
specialBrickCount 10
|
||||||
|
|
||||||
bricksPerColumn 5
|
|
||||||
|
|
||||||
specialBrickCount 3
|
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,14 @@ private:
|
||||||
|
|
||||||
bool parseConfigFile();
|
bool parseConfigFile();
|
||||||
|
|
||||||
|
void setupLevel();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
|
sf::Font font;
|
||||||
|
sf::Text lives;
|
||||||
|
|
||||||
Player player;
|
Player player;
|
||||||
std::vector<Ball> balls;
|
std::vector<Ball> balls;
|
||||||
|
|
@ -88,10 +92,8 @@ private:
|
||||||
sf::Vector2f playerStartPos{};
|
sf::Vector2f playerStartPos{};
|
||||||
sf::Vector2f brickHalfSize{};
|
sf::Vector2f brickHalfSize{};
|
||||||
sf::Vector2f playerHalfSize{};
|
sf::Vector2f playerHalfSize{};
|
||||||
int rowSize{};
|
unsigned int totalSpecialBricks{};
|
||||||
int columnSize{};
|
unsigned int totalBricks{};
|
||||||
int totalSpecialBricks{};
|
|
||||||
int totalBricks{rowSize * columnSize};
|
|
||||||
unsigned int framerate{};
|
unsigned int framerate{};
|
||||||
float playerSpeed{};
|
float playerSpeed{};
|
||||||
float ballRadius{};
|
float ballRadius{};
|
||||||
|
|
@ -102,4 +104,5 @@ private:
|
||||||
Color specialBrickColor{};
|
Color specialBrickColor{};
|
||||||
bool windowCollasped{false};
|
bool windowCollasped{false};
|
||||||
static constexpr unsigned int numPhysicsUpdates{4};
|
static constexpr unsigned int numPhysicsUpdates{4};
|
||||||
|
|
||||||
};
|
};
|
||||||
88
src/Game.cpp
88
src/Game.cpp
|
|
@ -26,13 +26,16 @@ Player::Player(sf::Vector2f position_in)
|
||||||
|
|
||||||
|
|
||||||
Game::Game()
|
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 (!ImGui::SFML::Init(window)) return;
|
||||||
|
|
||||||
if (!parseConfigFile()) return;
|
if (!parseConfigFile()) return;
|
||||||
|
|
||||||
|
lives.setPosition({10, static_cast<float>(window.getSize().y - 40)});
|
||||||
window.setFramerateLimit(framerate);
|
window.setFramerateLimit(framerate);
|
||||||
|
|
||||||
player.pos = playerStartPos;
|
player.pos = playerStartPos;
|
||||||
|
|
@ -43,12 +46,49 @@ Game::Game()
|
||||||
ballMaxSpeed /= numPhysicsUpdates;
|
ballMaxSpeed /= numPhysicsUpdates;
|
||||||
|
|
||||||
bricks.reserve(totalBricks);
|
bricks.reserve(totalBricks);
|
||||||
bricks.emplace_back(sf::Vector2f{200, 100});
|
|
||||||
specialBricks.reserve(totalSpecialBricks);
|
specialBricks.reserve(totalSpecialBricks);
|
||||||
balls.reserve(10);
|
balls.reserve(10);
|
||||||
ballsToAdd.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()
|
bool Game::parseConfigFile()
|
||||||
|
|
@ -67,17 +107,14 @@ bool Game::parseConfigFile()
|
||||||
if (inputBuff == "framerate")
|
if (inputBuff == "framerate")
|
||||||
configFile >> framerate;
|
configFile >> framerate;
|
||||||
|
|
||||||
if (inputBuff == "bricksPerRow")
|
|
||||||
configFile >> rowSize;
|
|
||||||
|
|
||||||
if (inputBuff == "ballRadius")
|
if (inputBuff == "ballRadius")
|
||||||
configFile >> ballRadius;
|
configFile >> ballRadius;
|
||||||
|
|
||||||
if (inputBuff == "playerSpeed")
|
if (inputBuff == "playerSpeed")
|
||||||
configFile >> playerSpeed;
|
configFile >> playerSpeed;
|
||||||
|
|
||||||
if (inputBuff == "bricksPerColumn")
|
if (inputBuff == "brickCount")
|
||||||
configFile >> columnSize;
|
configFile >> totalBricks;
|
||||||
|
|
||||||
if (inputBuff == "specialBrickCount")
|
if (inputBuff == "specialBrickCount")
|
||||||
configFile >> totalSpecialBricks;
|
configFile >> totalSpecialBricks;
|
||||||
|
|
@ -107,6 +144,9 @@ bool Game::parseConfigFile()
|
||||||
configFile >> ballMaxSpeed;
|
configFile >> ballMaxSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (totalSpecialBricks > totalBricks)
|
||||||
|
totalSpecialBricks = totalBricks;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,7 +216,7 @@ void Game::input()
|
||||||
switch (MouseButtonPressed->button)
|
switch (MouseButtonPressed->button)
|
||||||
{
|
{
|
||||||
case sf::Mouse::Button::Left:
|
case sf::Mouse::Button::Left:
|
||||||
specialBricks.emplace_back((sf::Vector2f)MouseButtonPressed->position);
|
//specialBricks.emplace_back((sf::Vector2f)MouseButtonPressed->position);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -218,16 +258,17 @@ void Game::checkBallCollision()
|
||||||
const auto intersect = getOverlap(ballBounds, brickBounds);
|
const auto intersect = getOverlap(ballBounds, brickBounds);
|
||||||
const auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
const auto previousIntersect = getOverlap(previousBallBounds, brickBounds);
|
||||||
|
|
||||||
|
// coming from x directon
|
||||||
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
if (intersect.x > 0 && previousIntersect.x <= 0 && intersect.y > 0)
|
||||||
{
|
{
|
||||||
brick.alive = false;
|
brick.alive = false;
|
||||||
ball.velocity.x *= -1;
|
ball.velocity.x *= -1;
|
||||||
if (ball.pos.x < brick.pos.x)
|
if (ball.pos.x < brick.pos.x)
|
||||||
{
|
{// from the left
|
||||||
ball.pos.x -= intersect.x;
|
ball.pos.x -= intersect.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{// from the right
|
||||||
ball.pos.x += intersect.x;
|
ball.pos.x += intersect.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -238,11 +279,11 @@ void Game::checkBallCollision()
|
||||||
brick.alive = false;
|
brick.alive = false;
|
||||||
ball.velocity.y *= -1;
|
ball.velocity.y *= -1;
|
||||||
if (ball.pos.y < brick.pos.y)
|
if (ball.pos.y < brick.pos.y)
|
||||||
{
|
{// from the top
|
||||||
ball.pos.y -= intersect.y;
|
ball.pos.y -= intersect.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{// from the bottom
|
||||||
ball.pos.y += intersect.y;
|
ball.pos.y += intersect.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,11 +303,11 @@ void Game::checkBallCollision()
|
||||||
spawnExtraBall = true;
|
spawnExtraBall = true;
|
||||||
ball.velocity.x *= -1;
|
ball.velocity.x *= -1;
|
||||||
if (ball.pos.x < brick.pos.x)
|
if (ball.pos.x < brick.pos.x)
|
||||||
{
|
{// from the left
|
||||||
ball.pos.x -= intersect.x;
|
ball.pos.x -= intersect.x;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{// from the right
|
||||||
ball.pos.x += intersect.x;
|
ball.pos.x += intersect.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,11 +319,11 @@ void Game::checkBallCollision()
|
||||||
spawnExtraBall = true;
|
spawnExtraBall = true;
|
||||||
ball.velocity.y *= -1;
|
ball.velocity.y *= -1;
|
||||||
if (ball.pos.y < brick.pos.y)
|
if (ball.pos.y < brick.pos.y)
|
||||||
{
|
{// from the top
|
||||||
ball.pos.y -= intersect.y;
|
ball.pos.y -= intersect.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{// from the bottom
|
||||||
ball.pos.y += intersect.y;
|
ball.pos.y += intersect.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -293,7 +334,6 @@ void Game::checkBallCollision()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//wall collide
|
//wall collide
|
||||||
if (ballBounds.position.y + ballBounds.size.y > window.getSize().y)
|
if (ballBounds.position.y + ballBounds.size.y > window.getSize().y)
|
||||||
{
|
{
|
||||||
|
|
@ -378,13 +418,15 @@ void Game::checkEndGame()
|
||||||
if (balls.empty())
|
if (balls.empty())
|
||||||
{
|
{
|
||||||
player.lives--;
|
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)
|
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::Begin("menu");
|
||||||
ImGui::SetWindowCollapsed(windowCollasped);
|
ImGui::SetWindowCollapsed(true);
|
||||||
ImGui::Text("Controls:");
|
ImGui::Text("Controls:");
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
ImGui::Text("A/D or arrow keys: move left and right");
|
ImGui::Text("A/D or arrow keys: move left and right");
|
||||||
|
|
@ -434,6 +476,8 @@ void Game::render()
|
||||||
{
|
{
|
||||||
window.clear();
|
window.clear();
|
||||||
|
|
||||||
|
lives.setString("Lives: " + std::to_string(player.lives));
|
||||||
|
window.draw(lives);
|
||||||
tempRect.setOrigin(brickHalfSize);
|
tempRect.setOrigin(brickHalfSize);
|
||||||
tempRect.setSize(brickSize);
|
tempRect.setSize(brickSize);
|
||||||
for (auto& brick : bricks)
|
for (auto& brick : bricks)
|
||||||
|
|
@ -476,6 +520,7 @@ void Game::resetGame()
|
||||||
balls.clear();
|
balls.clear();
|
||||||
ballsToAdd.clear();
|
ballsToAdd.clear();
|
||||||
|
|
||||||
|
setupLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::run()
|
void Game::run()
|
||||||
|
|
@ -510,6 +555,7 @@ void Game::runNoImgui()
|
||||||
while(window.isOpen())
|
while(window.isOpen())
|
||||||
{
|
{
|
||||||
ImGui::SFML::Update(window, clock.restart());
|
ImGui::SFML::Update(window, clock.restart());
|
||||||
|
|
||||||
input();
|
input();
|
||||||
|
|
||||||
for (size_t i = 0; i <= numPhysicsUpdates; i++)
|
for (size_t i = 0; i <= numPhysicsUpdates; i++)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue