commit a3faaa89b8185478bfdecefee09460f8070121f6
parent c30d1d25cd402a1fda5dc4fe5a44db49b3fbce45
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 24 Dec 2022 12:13:49 +0900
add collision handler
Diffstat:
M | ex4/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