xlib_playground

Xlib playground for experiments.
Log | Files | Refs

commit baca3d925f22efd7fec0a6f2107ad2a78a4b041a
parent dca94e2f1913c38d316fa9048b43d2ac31045574
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Fri, 30 Dec 2022 08:22:41 +0900

move a function

Diffstat:
Mex7/ex7.c | 246++++++++++++++++++++++++++++++++++---------------------------------------------
Mex7/physics.c | 28++++++++++++++++++++++++----
Mex7/physics.h | 2++
3 files changed, 132 insertions(+), 144 deletions(-)

diff --git a/ex7/ex7.c b/ex7/ex7.c @@ -46,7 +46,6 @@ enum next_menu next_menu = START_MENU; /* function prototypes */ -void cleanup(void); /* menus */ void start_menu(void); void game_play(void); @@ -54,9 +53,6 @@ void game_over(void); /* events */ void receive_events(enum key_state[]); void handle_inputs(enum key_state[]); -void update_falling_status(struct Object *, long); -/* physics */ -void rect_next_tick(struct rect *, long); void start_menu(void) @@ -112,137 +108,6 @@ start_menu(void) } void -receive_events(enum key_state key_state[]) -{ - while (x_pending() > 0) { - char c; - int event = x_next_event(&c); - - switch (event) { - case XWINDEL: - next_menu = QUIT; - break; - case XKEYPRESS: - switch (c) { - case 'q': - key_state[KEY_Q] = KEY_DOWN; - break; - case 'd': - key_state[KEY_D] = KEY_DOWN; - break; - case 'a': - key_state[KEY_A] = KEY_DOWN; - break; - case 'w': - key_state[KEY_W] = KEY_DOWN; - break; - case 's': - key_state[KEY_S] = KEY_DOWN; - break; - case ' ': - key_state[KEY_SPACE] = KEY_DOWN; - break; - default: - break; - } - break; - case XKEYRELEASE: - switch (c) { - case 'q': - key_state[KEY_Q] = KEY_UP; - break; - case 'd': - key_state[KEY_D] = KEY_UP; - break; - case 'a': - key_state[KEY_A] = KEY_UP; - break; - case 'w': - key_state[KEY_W] = KEY_UP; - break; - case 's': - key_state[KEY_S] = KEY_UP; - break; - case ' ': - key_state[KEY_SPACE] = KEY_UP; - break; - default: - break; - } - break; - } - } -} - -void -handle_inputs(enum key_state key_state[]) -{ - if (key_state[KEY_Q] == KEY_DOWN){ - next_menu = GAME_OVER; - return; - } - if (key_state[KEY_D] == KEY_DOWN) { - if (player.v.x > 0) { - player.a.x = 500; - } else { - player.a.x = 1000; - } - } else if (key_state[KEY_A] == KEY_DOWN) { - if (player.v.x > 0) { - player.a.x = -1000; - } else { - player.a.x = -500; - } - } else { - if (player_is_falling) - player.a.x = -player.v.x; - else - player.a.x = -3 * player.v.x; - } - - if (player.v.x < -200) player.v.x = -200; - if (player.v.x > 200) player.v.x = 200; - /* - if (key_state[KEY_S] == KEY_DOWN) - player.v.y += 300; - if (key_state[KEY_W] == KEY_DOWN) - player.v.y += -300; - */ - if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN) - player.v.y = -450; -} - - -void -update_falling_status(struct Object *player, long ndt) -{ - int collision = 0; - struct Object o = {0}; - o.shape = player->shape; - o.pp.x = player->pp.x; - o.pp.y = player->pp.y; - o.p.x = player->p.x; - o.p.y = player->p.y; - o.v.x = 0; - o.v.y = 0; - o.a.x = 0; - o.a.y = GRAVITY; - o.body.rectangle.w = player->body.rectangle.w; - o.body.rectangle.h = player->body.rectangle.h; - o.m = player->m; - - next_tick(&o, ndt); - for (int i = 0; i < NUM_RECT; i++) - if (test_collision(&o, &block[i])) - collision = 1; - - if (collision == 1) - player_is_falling = 0; - else - player_is_falling = 1; -} - -void game_play(void) { enum key_state key_state[NUM_KEY]; @@ -289,12 +154,12 @@ game_play(void) t0 = ts.tv_nsec; for (int k = 0; k < SUB_TICK; k++) { - update_falling_status(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK); + player_is_falling = object_is_falling(&player, block, NUM_RECT); if (player_is_falling) player.a.y = GRAVITY; else player.a.y = 0; - next_tick(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK); + next_tick(&player, 1e9 / FPS / SUB_TICK); // game over when fall out of the screen if (player.p.y > WORLD_HEIGHT * BLOCK_SIZE) { @@ -313,7 +178,7 @@ game_play(void) for (int i = 0; i < NUM_RECT; i++) - next_tick(&block[i], 1000 * 1000 * 1000 / FPS / SUB_TICK); + next_tick(&block[i], 1e9 / FPS / SUB_TICK); for (int i = 0; i < NUM_RECT; i++) handle_collision_mf(&player, &block[i]); @@ -323,10 +188,10 @@ game_play(void) // TODO: This method create some strange stripe when // rendered in 60fps on a 60fps monitor. dt = 0; - while (dt < 1.0 * 1000 * 1000 * 1000 / FPS){ + while (dt < 1.0 * 1e9 / FPS){ clock_gettime(CLOCK_MONOTONIC, &ts); t1 = ts.tv_nsec; - dt = t1 > t0 ? t1 - t0 : t1 - t0 + 1000 * 1000 * 1000; + dt = t1 > t0 ? t1 - t0 : t1 - t0 + 1e9; } #ifdef COUNT_FPS // count fps. @@ -372,6 +237,107 @@ game_over(void) next_menu = START_MENU; } +void +receive_events(enum key_state key_state[]) +{ + while (x_pending() > 0) { + char c; + int event = x_next_event(&c); + + switch (event) { + case XWINDEL: + next_menu = QUIT; + break; + case XKEYPRESS: + switch (c) { + case 'q': + key_state[KEY_Q] = KEY_DOWN; + break; + case 'd': + key_state[KEY_D] = KEY_DOWN; + break; + case 'a': + key_state[KEY_A] = KEY_DOWN; + break; + case 'w': + key_state[KEY_W] = KEY_DOWN; + break; + case 's': + key_state[KEY_S] = KEY_DOWN; + break; + case ' ': + key_state[KEY_SPACE] = KEY_DOWN; + break; + default: + break; + } + break; + case XKEYRELEASE: + switch (c) { + case 'q': + key_state[KEY_Q] = KEY_UP; + break; + case 'd': + key_state[KEY_D] = KEY_UP; + break; + case 'a': + key_state[KEY_A] = KEY_UP; + break; + case 'w': + key_state[KEY_W] = KEY_UP; + break; + case 's': + key_state[KEY_S] = KEY_UP; + break; + case ' ': + key_state[KEY_SPACE] = KEY_UP; + break; + default: + break; + } + break; + } + } +} + +void +handle_inputs(enum key_state key_state[]) +{ + if (key_state[KEY_Q] == KEY_DOWN){ + next_menu = GAME_OVER; + return; + } + if (key_state[KEY_D] == KEY_DOWN) { + if (player.v.x > 0) { + player.a.x = 500; + } else { + player.a.x = 1000; + } + } else if (key_state[KEY_A] == KEY_DOWN) { + if (player.v.x > 0) { + player.a.x = -1000; + } else { + player.a.x = -500; + } + } else { + if (player_is_falling) + player.a.x = -player.v.x; + else + player.a.x = -3 * player.v.x; + } + + if (player.v.x < -200) player.v.x = -200; + if (player.v.x > 200) player.v.x = 200; + /* + if (key_state[KEY_S] == KEY_DOWN) + player.v.y += 300; + if (key_state[KEY_W] == KEY_DOWN) + player.v.y += -300; + */ + if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN) + player.v.y = -450; +} + int main(void) { diff --git a/ex7/physics.c b/ex7/physics.c @@ -53,10 +53,10 @@ rect_next_tick(struct Object *o, long ndt) } o->pp.x = o->p.x; o->pp.y = o->p.y; - o->v.x += o->a.x * ndt / 1000 / 1000 / 1000; - o->v.y += o->a.y * ndt / 1000 / 1000 / 1000; - o->p.x += o->v.x * ndt / 1000 / 1000 / 1000; - o->p.y += o->v.y * ndt / 1000 / 1000 / 1000; + o->v.x += o->a.x * ndt / 1e9; + o->v.y += o->a.y * ndt / 1e9; + o->p.x += o->v.x * ndt / 1e9; + o->p.y += o->v.y * ndt / 1e9; } void @@ -109,3 +109,23 @@ rect_handle_collision_mf(struct Object *om, struct Object *of) } } + +/* + * Test if object o is not on top of one of fb (floor blocks). + * o: object to be tested, fb: floor blocks, num_f: count of fb. + */ +int +object_is_falling(struct Object *o, struct Object *fb, int num_f) +{ + struct Object p = *o; + + p.v.x = 0; p.v.y = 1; + p.a.x = 0; p.a.y = 0; + + next_tick(&p, 1e9); + + for (int i = 0; i < num_f; i++) + if (test_collision(&p, &fb[i])) + return 0; + return 1; +} diff --git a/ex7/physics.h b/ex7/physics.h @@ -59,3 +59,5 @@ struct circle { int test_collision(struct Object *, struct Object *); // 1 if collide, 0 if not void next_tick(struct Object *o, long); void handle_collision_mf(struct Object *, struct Object *); +int object_is_falling(struct Object *o, struct Object *fb, int num_f); +