Building Pong in Zig with Raylib – Part 2: Ball Movement & Paddle Collisions
In Part 1 we set up the basics: a window, paddles, and a ball. In this episode, we go one step further and get the ball moving 😉, add paddle collisions, and make everything frame-rate independent.
Ball Movement
The first step was to give the ball some velocity and update its position every frame.
|
|
We also fixed a small oversight: the ball and paddles were being recreated every frame inside the game loop. Moving their initialization outside meant we could actually observe state changes between frames.
Frame-Rate Independence
Raylib provides GetFrameTime()
which returns the time in seconds since the
last frame. Multiplying the velocity by this dt
value ensures that the ball
movement stays consistent across different frame rates:
|
|
With that, the ball now moves at a steady speed, no matter the frame rate.
Paddle Collision (X-Axis)
Next up: detecting collisions between the ball and paddles. I considered writing
a standalone collision checker, but ended up keeping the logic within the
Paddle
struct itself.
To simplify which edge to check (left or right), I added a which
field to
paddles - an enum with values left
and right
. That made the conditional
logic much cleaner.
To debug collisions, I added color switching: when a paddle detects a collision on the x-axis, it flashes red.
|
|
Paddle Collision (Y-Axis)
After confirming horizontal collision detection, I added vertical bounds checking. This just involved verifying the ball’s y-position is within the paddle’s vertical range.
|
|
Bounce Logic
With detection in place, we added bounce logic to the ball. If a collision with a paddle is detected, we flip the x-component of the velocity vector:
|
|
What’s Next
That wraps up part 2. In the next episode, we’ll handle edge collisions (top and bottom), scoring, and input management.
Thanks for following along!