I looked over this PR, and also tried building/running the code on my machine for the first time. If you haven’t tested it on Windows yet, I can confirm that it runs great!
My feedback:
std.heap.GeneralPurposeAllocatoris deprecated, usestd.heap.DebugAllocator(it’s basically the same thing under a different name).- You are initializing the allocator correctly, nothing to change there.
- The proper way to deinit your allocator is to just do
defer _ = gpa.deinit().deinitwill already print memory leak info if any leaks occur, so there is no need to@panicif leaks occur. - The
showScorelogic could be part ofPaddlesince the paddles own the scores, but that feels kinds unintuitive. I think that if you want a super ‘correct’ structure/hierarchy, you should either move the scores into theGamestruct and keepshowScoreinGame, or make a newPlayerstruct that contains a score, a paddle, andshowScore. Either way, moving the score out ofPaddleseems like the right call. - Your score rendering is fine, but just in case you want to make the font larger, I wrote an example of how you could do that in your code. I wanted to point this out because setting font sizes in
dvuiis a little unintuitive, and I wasn’t sure if you were happy with the font size, or if you just settled for the largest default option:
const font_size: f32 = 64;
var label_options: dvui.Options = .{
.color_text = .white,
.font_style = .title,
};
label_options.font = label_options.fontGet().resize(font_size);
dvui.label(@src(), "{d}", .{score}, label_options);
- A ball may still be colliding with a paddle after bouncing off it, triggering an additional bounce. This can lead to a glitchy state where the ball is permanently colliding, constantly switching direction while embedded in the paddle. You can resolve this by making your
crossing_xlogic check if the ball is moving towards the paddle:
const crossing_x = switch (self.which) {
.right => ball.vel.x > 0 and
ball.pos.x + ball.r >= self.pos.x,
.left => ball.vel.x < 0 and
ball.pos.x - ball.r <= self.pos.x + size.x,
};