Small Steps II — Making Things
Adding a score to a game
Add a score to a game.
What you will learn
Game rules determine how state changes when an event occurs. Increase the score only when the ball is caught.
Try it
void small_main()
{
Window window;
window.set_title("Catch the Ball");
window.open(640, 480);
double player_x = 320;
double ball_x = 100;
double ball_y = 80;
double ball_vx = 180;
double ball_vy = 140;
int score = 0;
StopWatch watch;
while (window.is_open())
{
double dt = watch.elapsed();
watch.reset();
if (window.key_down(Key::Left)) player_x = player_x - 250 * dt;
if (window.key_down(Key::Right)) player_x = player_x + 250 * dt;
ball_x = ball_x + ball_vx * dt;
ball_y = ball_y + ball_vy * dt;
if (ball_x < 15)
{
ball_x = 15;
ball_vx = -ball_vx;
}
if (ball_x > 625)
{
ball_x = 625;
ball_vx = -ball_vx;
}
if (ball_y < 15)
{
ball_y = 15;
ball_vy = -ball_vy;
}
if (ball_y > 430 && ball_y < 460 &&
ball_x > player_x - 60 && ball_x < player_x + 60)
{
ball_y = 430;
ball_vy = -ball_vy;
score = score + 1;
play_sound(Sound::Coin);
}
if (ball_y > 500)
{
ball_x = 100;
ball_y = 80;
}
window.set_title("Score: ", score);
window.clear(Black);
window.fill_rectangle(player_x - 60, 450, 120, 12, White);
window.fill_circle(ball_x, ball_y, 15, Cyan);
window.show();
}
}
Move the paddle with the left and right arrow keys. When the ball touches the paddle's range, it bounces and score increases by 1. set_title displays the current score in the window title.
After a miss, only the ball returns to its starting position. Test both hits and misses. Diagnose problems by separating position updates, conditions, and score changes.
Exercise
Move the starter's paddle with the left and right arrow keys. Increase score by 1 only when the ball hits it, and show it with window.set_title("Score: ", score). Moving the paddle aside and missing must not increase the score. Collision detection is provided in the starter.
void small_main()
{
Window window;
window.open(640, 480);
int score = 0;
double paddle_x = 320;
double ball_x = 320;
double ball_y = 100;
double ball_vy = 180;
StopWatch watch;
while (window.is_open())
{
double dt = watch.elapsed();
watch.reset();
if (window.key_down(Key::Left)) { paddle_x = paddle_x - 250 * dt; }
if (window.key_down(Key::Right)) { paddle_x = paddle_x + 250 * dt; }
if (paddle_x < 70) { paddle_x = 70; }
if (paddle_x > 570) { paddle_x = 570; }
double previous_y = ball_y;
ball_y = ball_y + ball_vy * dt;
if (ball_vy > 0 && previous_y <= 430 && ball_y >= 430 &&
ball_x >= paddle_x - 70 && ball_x <= paddle_x + 70)
{
ball_y = 430;
ball_vy = -ball_vy;
// Increase score only on a paddle hit.
play_sound(Sound::Hit);
}
if (ball_y < 20) { ball_y = 20; ball_vy = -ball_vy; }
if (ball_y > 500) { ball_y = 100; ball_vy = 180; }
// show score in the window title.
window.clear(Black);
window.fill_rectangle(paddle_x - 70, 450, 140, 10, White);
window.fill_circle(ball_x, ball_y, 20, Yellow);
window.show();
}
}
Hint
Create score with value 0 outside the loop, and increase it inside the collision if.
show solution
void small_main()
{
Window window;
window.open(640, 480);
int score = 0;
double paddle_x = 320;
double ball_x = 320;
double ball_y = 100;
double ball_vy = 180;
StopWatch watch;
while (window.is_open())
{
double dt = watch.elapsed();
watch.reset();
if (window.key_down(Key::Left)) { paddle_x = paddle_x - 250 * dt; }
if (window.key_down(Key::Right)) { paddle_x = paddle_x + 250 * dt; }
if (paddle_x < 70) { paddle_x = 70; }
if (paddle_x > 570) { paddle_x = 570; }
double previous_y = ball_y;
ball_y = ball_y + ball_vy * dt;
if (ball_vy > 0 && previous_y <= 430 && ball_y >= 430 &&
ball_x >= paddle_x - 70 && ball_x <= paddle_x + 70)
{
ball_y = 430;
ball_vy = -ball_vy;
score = score + 1;
play_sound(Sound::Hit);
}
if (ball_y < 20) { ball_y = 20; ball_vy = -ball_vy; }
if (ball_y > 500) { ball_y = 100; ball_vy = 180; }
window.set_title("Score: ", score);
window.clear(Black);
window.fill_rectangle(paddle_x - 70, 450, 140, 10, White);
window.fill_circle(ball_x, ball_y, 20, Yellow);
window.show();
}
}