Score, Lives, and Game Over
A playable game needs feedback: a visible score, a limited number of lives, and a clear end condition.
Drawing text
sf::Font font;
if (!font.loadFromFile("arial.ttf")) {
// handle missing font file
}
sf::Text scoreText;
scoreText.setFont(font);
scoreText.setCharacterSize(20);
scoreText.setFillColor(sf::Color::White);
scoreText.setPosition(10.f, 10.f);
// Each frame:
scoreText.setString("Score: " + std::to_string(score) + " Lives: " + std::to_string(lives));
window.draw(scoreText);
Losing a life
When the ball's position goes past the bottom edge, it's a miss, not a wall bounce:
if (ball.shape.getPosition().y > windowHeight) {
lives--;
if (lives <= 0) {
gameOver = true;
} else {
// Reset the ball above the paddle to keep playing
ball.shape.setPosition(windowWidth / 2.f, windowHeight / 2.f);
ball.velocity = sf::Vector2f(200.f, -200.f);
}
}
Winning
if (bricks.empty()) {
won = true;
}
The pieces
sf::Fontandsf::Textneed a real.ttffile, on Linux/usr/share/fonts/truetype/dejavu/DejaVuSans.ttfusually exists, on other platforms bundle a font file with your project.std::to_string(score)converts a number to astd::stringso it can be concatenated with+onto other strings.- Losing a life resets the ball instead of ending the game immediately, the game should only end once
livesreaches0. - Checking
bricks.empty()is a clean win condition, once every brick is destroyed, the vector naturally has no elements left.
TIP
Once gameOver or won is true, stop calling ball.update() and paddle.update() (but keep the event loop and window.display() running), otherwise the ball keeps bouncing behind your "GAME OVER" text.