commit ecccc1828858be4c580e1c5960acc1cc71fbe33c
parent a3faaa89b8185478bfdecefee09460f8070121f6
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 24 Dec 2022 13:50:42 +0900
modify collision handler
Diffstat:
M | ex4/ex4.c | | | 86 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 48 insertions(+), 38 deletions(-)
diff --git a/ex4/ex4.c b/ex4/ex4.c
@@ -11,11 +11,12 @@
#define INIT_WIDTH (800)
#define INIT_HEIGHT (600)
#define FPS (60)
-#define NUM_SQUARE (3)
+#define SUB_TICK (4)
+#define NUM_SQUARE (40)
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
-/*
-#define COUNT_FPS
-*/
+//#define COUNT_FPS
enum keys {
KEY_D,
@@ -299,19 +300,26 @@ 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;
+ float lapx = min(s1->px + s1->w, s2->px + s2->w) - max(s1->px, s2->px);
+ float lapy = min(s1->py + s1->h, s2->py + s2->h) - max(s1->py, s2->py);
- 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;
+ if (lapx < lapy) {
+ if (s1->px + s1->w < s2->px + s2->w / 2) {
+ s1->px -= lapx / 2;
+ s2->px += lapx / 2;
+ } else {
+ s1->px += lapx / 2;
+ s2->px -= lapx / 2;
+ }
+ } else {
+ if (s1->py + s1->h < s2->py + s2->h / 2) {
+ s1->py -= lapy / 2;
+ s2->py += lapy / 2;
+ } else {
+ s1->py += lapy / 2;
+ s2->py -= lapy / 2;
+ }
+ }
}
void
@@ -325,10 +333,10 @@ game_play(void)
struct timespec ts;
for(int i = 0; i < NUM_SQUARE; i++){
- square[i].ppx = square[i].px = 100 * (i + 1);
+ square[i].ppx = square[i].px = 10 * (i + 1);
square[i].ppy = square[i].py = 100;
square[i].vx = square[i].vy = 0;
- square[i].w = square[i].h = 20;
+ square[i].w = square[i].h = 10;
}
while (next_menu == GAME_PLAY){
@@ -337,6 +345,28 @@ game_play(void)
receive_events(key_state);
handle_inputs(key_state);
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ t0 = ts.tv_nsec;
+
+ int collision[NUM_SQUARE] = {0};
+ for (int j = 0; j < SUB_TICK; j++) {
+ for (int i = 0; i < NUM_SQUARE; i++)
+ next_tick(&square[i], 1000 * 1000 * 1000 / FPS / SUB_TICK);
+
+ 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], 0xFFFF00);
+ else
+ XSetForeground(display, sgc[i], 0xFF << i % 3 * 8);
+
// fix fps
// TODO: This method create some strange stripe when
// rendered in 60fps on a 60fps monitor.
@@ -355,26 +385,6 @@ game_play(void)
}
#endif
- clock_gettime(CLOCK_MONOTONIC, &ts);
- t0 = ts.tv_nsec;
-
- for (int i = 0; i < NUM_SQUARE; i++)
- next_tick(&square[i], 1000 * 1000 * 1000 / FPS);
-
- 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
win_width, win_height, // width and height