Skip to content

Commit adf0e01

Browse files
mpong/breakout: physics time independent
1 parent 4d5d556 commit adf0e01

1 file changed

Lines changed: 40 additions & 31 deletions

File tree

c_mpos/mpong/mpong.c

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ size_t g_framebuffer_height;
1919
int g_paddle_x;
2020
int g_paddle_width;
2121
int g_paddle_height;
22-
int g_ball_x;
23-
int g_ball_y;
24-
int g_ball_vx;
25-
int g_ball_vy;
22+
float g_ball_x;
23+
float g_ball_y;
24+
float g_ball_vx;
25+
float g_ball_vy;
26+
uint32_t g_last_tick_ms;
2627

2728
uint32_t g_fps_last_ms;
2829
uint32_t g_fps_frames;
@@ -99,10 +100,10 @@ static void draw_rect(int x, int y, int w, int h, uint16_t color) {
99100
}
100101

101102
static void reset_ball(void) {
102-
g_ball_x = (int)g_framebuffer_width / 2;
103-
g_ball_y = (int)g_framebuffer_height / 2;
104-
g_ball_vx = 1;
105-
g_ball_vy = -1;
103+
g_ball_x = (float)((int)g_framebuffer_width / 2);
104+
g_ball_y = (float)((int)g_framebuffer_height / 2);
105+
g_ball_vx = 120.0f;
106+
g_ball_vy = -120.0f;
106107
}
107108

108109
static void reset_bricks(void) {
@@ -132,6 +133,7 @@ static mp_obj_t init(mp_obj_t framebuffer_obj, mp_obj_t width_obj, mp_obj_t heig
132133

133134
g_fps_last_ms = ticks_ms();
134135
g_fps_frames = 0;
136+
g_last_tick_ms = g_fps_last_ms;
135137

136138
return mp_const_none;
137139
}
@@ -160,22 +162,29 @@ static mp_obj_t render(void) {
160162
g_fps_frames = 0;
161163
}
162164

165+
uint32_t tick_delta_ms = now_ms - g_last_tick_ms;
166+
g_last_tick_ms = now_ms;
167+
if (tick_delta_ms > 50) {
168+
tick_delta_ms = 50;
169+
}
170+
const float dt = (float)tick_delta_ms / 1000.0f;
171+
163172
// Update ball position.
164-
g_ball_x += g_ball_vx;
165-
g_ball_y += g_ball_vy;
173+
g_ball_x += g_ball_vx * dt;
174+
g_ball_y += g_ball_vy * dt;
166175

167176
// Wall collisions.
168-
if (g_ball_x <= 0) {
169-
g_ball_x = 0;
170-
g_ball_vx = 1;
171-
} else if (g_ball_x >= (int)width - 1) {
172-
g_ball_x = (int)width - 1;
173-
g_ball_vx = -1;
177+
if (g_ball_x <= 0.0f) {
178+
g_ball_x = 0.0f;
179+
g_ball_vx = 120.0f;
180+
} else if (g_ball_x >= (float)width - 1.0f) {
181+
g_ball_x = (float)width - 1.0f;
182+
g_ball_vx = -120.0f;
174183
}
175184

176-
if (g_ball_y <= 0) {
177-
g_ball_y = 0;
178-
g_ball_vy = 1;
185+
if (g_ball_y <= 0.0f) {
186+
g_ball_y = 0.0f;
187+
g_ball_vy = 120.0f;
179188
}
180189

181190
// Brick layout.
@@ -188,15 +197,15 @@ static mp_obj_t render(void) {
188197
const int brick_offset_y = 8;
189198

190199
// Brick collision.
191-
if (brick_width > 0 && g_ball_y <= brick_offset_y + brick_rows * (brick_height + brick_gap)) {
200+
if (brick_width > 0 && g_ball_y <= (float)(brick_offset_y + brick_rows * (brick_height + brick_gap))) {
192201
for (int row = 0; row < brick_rows; row++) {
193202
for (int col = 0; col < brick_cols; col++) {
194203
if (!g_bricks[row][col]) {
195204
continue;
196205
}
197206
const int bx = brick_gap + col * (brick_width + brick_gap);
198207
const int by = brick_offset_y + row * (brick_height + brick_gap);
199-
if (g_ball_x >= bx && g_ball_x < bx + brick_width && g_ball_y >= by && g_ball_y < by + brick_height) {
208+
if (g_ball_x >= (float)bx && g_ball_x < (float)(bx + brick_width) && g_ball_y >= (float)by && g_ball_y < (float)(by + brick_height)) {
200209
g_bricks[row][col] = 0;
201210
g_ball_vy = -g_ball_vy;
202211
row = brick_rows;
@@ -208,21 +217,21 @@ static mp_obj_t render(void) {
208217

209218
// Paddle collision.
210219
const int paddle_y = (int)height - g_paddle_height - 4;
211-
if (g_ball_y >= paddle_y - 1 && g_ball_y <= paddle_y + g_paddle_height) {
212-
if (g_ball_x >= g_paddle_x && g_ball_x <= g_paddle_x + g_paddle_width) {
213-
g_ball_y = paddle_y - 1;
214-
g_ball_vy = -1;
220+
if (g_ball_y >= (float)(paddle_y - 1) && g_ball_y <= (float)(paddle_y + g_paddle_height)) {
221+
if (g_ball_x >= (float)g_paddle_x && g_ball_x <= (float)(g_paddle_x + g_paddle_width)) {
222+
g_ball_y = (float)(paddle_y - 1);
223+
g_ball_vy = -120.0f;
215224
const int paddle_center = g_paddle_x + g_paddle_width / 2;
216-
if (g_ball_x < paddle_center) {
217-
g_ball_vx = -1;
218-
} else if (g_ball_x > paddle_center) {
219-
g_ball_vx = 1;
225+
if (g_ball_x < (float)paddle_center) {
226+
g_ball_vx = -120.0f;
227+
} else if (g_ball_x > (float)paddle_center) {
228+
g_ball_vx = 120.0f;
220229
}
221230
}
222231
}
223232

224233
// Ball fell below paddle: reset.
225-
if (g_ball_y >= (int)height - 1) {
234+
if (g_ball_y >= (float)((int)height - 1)) {
226235
reset_ball();
227236
}
228237

@@ -242,7 +251,7 @@ static mp_obj_t render(void) {
242251

243252
// Draw paddle and ball.
244253
draw_rect(g_paddle_x, paddle_y, g_paddle_width, g_paddle_height, 0xFFFF); // RGB565 white
245-
draw_pixel(g_ball_x, g_ball_y, 0xFFFF);
254+
draw_pixel((int)g_ball_x, (int)g_ball_y, 0xFFFF);
246255

247256
return mp_const_none;
248257
}

0 commit comments

Comments
 (0)