xlib_playground

Xlib playground for experiments.
Log | Files | Refs

commit a3faaa89b8185478bfdecefee09460f8070121f6
parent c30d1d25cd402a1fda5dc4fe5a44db49b3fbce45
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 24 Dec 2022 12:13:49 +0900

add collision handler

Diffstat:
Mex4/ex4.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 69 insertions(+), 8 deletions(-)

diff --git a/ex4/ex4.c b/ex4/ex4.c @@ -11,7 +11,7 @@ #define INIT_WIDTH (800) #define INIT_HEIGHT (600) #define FPS (60) -#define NUM_SQUARE (2) +#define NUM_SQUARE (3) /* #define COUNT_FPS @@ -38,6 +38,7 @@ enum next_menu { }; struct square { + float ppx, ppy; // previous position float px, py; float vx, vy; int w, h; @@ -61,7 +62,9 @@ void game_play(void); void receive_events(int[]); void handle_inputs(int[]); void next_tick(struct square *, long); -int test_collision(struct square *, struct square*); +int test_collision(struct square *, struct square *); +void handle_collision_mf(struct square *, struct square *); +void handle_collision(struct square *, struct square *); void game_over(void); @@ -241,6 +244,8 @@ handle_inputs(int key_state[]) void next_tick(struct square *s, long ndt) // nano second { + s->ppx = s->px; + s->ppy = s->py; s->px = s->px + s->vx * ndt / 1000 / 1000 / 1000; s->py = s->py + s->vy * ndt / 1000 / 1000 / 1000; @@ -262,6 +267,53 @@ test_collision(struct square *s1, struct square* s2) s2->py < s1->py + s1->h && s1->py < s2->py + s2->h; } +/* + * Handle collision of a moving square against fixed square + */ +void +handle_collision_mf(struct square *sm, struct square *sf) +{ + if (!test_collision(sm, sf)) + return; + if (sm->ppx + sm->w <= sf->ppx && sf->px < sm->px + sm->w) + // collisioin from left to right + sm->px = sf->px - sm->w; + if (sf->ppx + sf->w <= sm->ppx && sm->px < sf->px + sf->w) + // collision from right to left + sm->px = sf->px + sf->w; + + if (sm->ppy + sm->h <= sf->ppy && sf->py < sm->py + sm->h) + // collision from up to down + sm->py = sf->py - sm->h; + if (sf->ppy + sf->h <= sm->ppy && sm->py < sf->py + sf->h) + // collision from dohn to up + sm->py = sf->py + sf->h; +} + +/* + * Handle collision of a moving square against another moving square + */ +void +handle_collision_mm(struct square *s1, struct square* s2) +{ + if (!test_collision(s1, s2)) + return; + + if (s1->ppx + s1->w <= s2->ppx && s2->px < s1->px + s1->w) + // collisioin from left to right + s2->px = s1->px + s1->w; + if (s2->ppx + s2->w <= s1->ppx && s1->px < s2->px + s2->w) + // collision from right to left + s2->px = s1->px - s2->w; + + if (s1->ppy + s1->h <= s2->ppy && s2->py < s1->py + s1->h) + // collision from up to down + s2->py = s1->py + s1->h; + if (s2->ppy + s2->h <= s1->ppy && s1->py < s2->py + s2->h) + // collision from dohn to up + s2->py = s1->py - s2->h; +} + void game_play(void) { @@ -273,8 +325,8 @@ game_play(void) struct timespec ts; for(int i = 0; i < NUM_SQUARE; i++){ - square[i].px = 100 * (i + 1); - square[i].py = 100; + square[i].ppx = square[i].px = 100 * (i + 1); + square[i].ppy = square[i].py = 100; square[i].vx = square[i].vy = 0; square[i].w = square[i].h = 20; } @@ -309,10 +361,19 @@ game_play(void) for (int i = 0; i < NUM_SQUARE; i++) next_tick(&square[i], 1000 * 1000 * 1000 / FPS); - if (test_collision(&square[0], &square[1])) - XSetForeground(display, sgc[1], 0xFF0000); - else - XSetForeground(display, sgc[1], 0x00FF00); + int collision[NUM_SQUARE] = {0}; + for (int i = 0; i < NUM_SQUARE; i++) + for (int j = i + 1; j < NUM_SQUARE; j++) { + handle_collision_mm(&square[i], &square[j]); + if (test_collision(&square[i], &square[j])) + collision[i] = collision[j] = 1; + } + for (int i = 0; i < NUM_SQUARE; i++) + if (collision[i] == 1) + XSetForeground(display, sgc[i], 0xFF0000); + else + XSetForeground(display, sgc[i], 0x00FF00); + XClearArea(display, window, 0, 0, // position