commit 5b57a73784bc434851d1f4a3a3aed7436fd12567
parent e77c5bff1c4acdd2957016efe7a84856c83294c5
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 5 Jan 2023 15:12:38 +0900
add experimental collision handler
Diffstat:
M | ex9/main.c | | | 102 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
M | ex9/main.h | | | 33 | ++++++++++++++------------------- |
M | ex9/util.c | | | 6 | ++++-- |
3 files changed, 80 insertions(+), 61 deletions(-)
diff --git a/ex9/main.c b/ex9/main.c
@@ -7,18 +7,20 @@
#include "main.h"
#include "world_map.h"
-/* macros */
-#define FPS 60
-#define SUB_TICK 4
-#define NUM_BLOCK 200
-#define GRAVITY 1000
-#define WIN_WIDTH 800
-#define WIN_HEIGHT 600
-
/*
#define COUNT_FPS
*/
+/* constants */
+enum {
+ FPS = 60,
+ SUB_TICK = 4,
+ NUM_BLOCK = 200,
+ GRAVITY = 1000,
+ WIN_WIDTH = 800,
+ WIN_HEIGHT = 600,
+};
+
enum keys {
KEY_D,
KEY_S,
@@ -36,6 +38,7 @@ enum next_menu {
START_MENU,
GAME_PLAY,
GAME_OVER,
+ GAME_CLEAR,
QUIT,
};
@@ -50,12 +53,14 @@ enum next_menu next_menu = START_MENU;
void start_menu(void);
void game_play(void);
void game_over(void);
+void game_clear(void);
/* events */
void receive_events(enum key_state[]);
void handle_inputs(enum key_state[]);
/* sort */
void sort_ll(struct OL *ol, struct Object *player);
+
void
start_menu(void)
{
@@ -109,6 +114,14 @@ start_menu(void)
}
}
+/*
+ * this function should be moved to other file
+ */
+void handle_collision_pf(struct Object *o0, struct Object *o1) {
+ handle_collision_mf(o0, o1);
+ next_menu = GAME_CLEAR;
+}
+
void
game_play(void)
{
@@ -122,30 +135,37 @@ game_play(void)
struct OL *blc;
struct OH *flh; // flag
struct OL *flc;
-
int scroll_dst = 0;
+ void (* col_func[NUM_OBJ_TYPE][NUM_OBJ_TYPE])(struct Object *,
+ struct Object *);
+
for (int xi = 0; xi < WORLD_WIDTH; xi++)
blh[xi] = create_ol();
flh = create_ol();
+ for (int i = 0; i < NUM_OBJ_TYPE; i++)
+ for (int j = 0; j < NUM_OBJ_TYPE; j++)
+ col_func[i][j] = &handle_collision_mf;
+ col_func[TPLAYER][TFLAG] = col_func[TFLAG][TPLAYER] = &handle_collision_pf;
+
for (int i = 0; i < WORLD_WIDTH * WORLD_HEIGHT; i++) {
if (world_map[i] == 'b') {
int xi = i % WORLD_WIDTH;
// TODO: don't forget to free these things.
- append_ol(blh[xi], create_object(i % WORLD_WIDTH * BLOCK_SIZE,
+ append_ol(blh[xi], create_object(TBLOCK, i % WORLD_WIDTH * BLOCK_SIZE,
i / WORLD_WIDTH * BLOCK_SIZE,
0, 0, 0, 0,
BLOCK_SIZE, BLOCK_SIZE,
BLOCK_SIZE * BLOCK_SIZE));
} else if (world_map[i] == 'p') {
- player = create_object(i % WORLD_WIDTH * BLOCK_SIZE,
+ player = create_object(TPLAYER, i % WORLD_WIDTH * BLOCK_SIZE,
i / WORLD_WIDTH * BLOCK_SIZE,
0, 0, 0, GRAVITY,
BLOCK_SIZE, BLOCK_SIZE,
BLOCK_SIZE * BLOCK_SIZE);
} else if (world_map[i] == 'f') {
- append_ol(flh, create_object(i % WORLD_WIDTH * BLOCK_SIZE,
+ append_ol(flh, create_object(TFLAG, i % WORLD_WIDTH * BLOCK_SIZE,
i / WORLD_WIDTH * BLOCK_SIZE,
0, 0, 0, 0,
BLOCK_SIZE, BLOCK_SIZE,
@@ -214,6 +234,15 @@ game_play(void)
}
}
free_ol(collidings);
+
+ // collision aganst the goal flag
+ for (flc = flh->first; flc != NULL; flc = flc->next){
+ if (test_collision(player, flc->o)) {
+ next_menu = GAME_CLEAR;
+ break;
+ }
+ }
+
}
// fix fps
@@ -262,12 +291,6 @@ game_play(void)
}
}
- char status_string[128];
- snprintf(status_string, 128, "falling: %d", player_is_falling);
- x_draw_string(0x00FFFF,
- 0, 20,
- status_string,
- strlen(status_string));
}
for (int xi = 0; xi < WORLD_WIDTH; xi++)
free_obj_and_ol(blh[xi]);
@@ -294,6 +317,24 @@ game_over(void)
}
void
+game_clear(void)
+{
+ char *menu_char = "GAME CLEAR";
+
+ x_draw_string(0x00FFFF,
+ WIN_WIDTH / 2 - 10 * strlen(menu_char)/2,
+ WIN_HEIGHT / 2,
+ menu_char, strlen(menu_char));
+ x_flush();
+
+ sleep(1);
+ while(x_pending() > 0) {
+ x_next_event(NULL);
+ }
+ next_menu = START_MENU;
+}
+
+void
receive_events(enum key_state key_state[])
{
while (x_pending() > 0) {
@@ -395,28 +436,6 @@ handle_inputs(enum key_state key_state[])
}
}
-void
-swap_ll(struct OL *oi, struct OL *oj)
-{
- struct Object *tmp;
- tmp = oi->o;
- oi->o = oj->o;
- oj->o = tmp;
-}
-
-void
-sort_ll(struct OL *ol, struct Object *player)
-{
- if (ol == NULL)
- return;
- struct OL *oi, *oj;
- for (oi = ol; oi->next != NULL; oi = oi->next) {
- for (oj = oi->next; oj != NULL; oj = oj->next) {
- if (object_dist(oj->o, player) < object_dist(oi->o, player))
- swap_ll(oi, oj);
- }
- }
-}
int
main(void)
@@ -435,6 +454,9 @@ main(void)
case GAME_OVER:
game_over();
break;
+ case GAME_CLEAR:
+ game_clear();
+ break;
default:
break;
}
diff --git a/ex9/main.h b/ex9/main.h
@@ -7,6 +7,14 @@ enum object_shape {
SCIRCLE,
};
+enum object_type {
+ TPLAYER,
+ TBLOCK,
+ TENEMY,
+ TFLAG,
+ NUM_OBJ_TYPE,
+};
+
struct Point {
float x;
float y;
@@ -32,6 +40,7 @@ union Body {
};
struct Object {
+ enum object_type type;
enum object_shape shape;
struct Point pp;
struct Point p;
@@ -53,6 +62,7 @@ struct OL {
struct Object *o;
struct OL *next;
};
+
struct OH *create_ol(void);
void free_ol(struct OH *);
void free_obj_and_ol(struct OH *);
@@ -61,31 +71,16 @@ void swap_ol(struct OL *, struct OL *);
void sort_ol(struct OH *, struct Object *);
int object_dist(struct Object *, struct Object *);
-struct rect {
- struct Point pp;
- struct Point p;
- struct Point v;
- struct Point a;
- int w, h;
- int m;
-};
-
-struct circle {
- struct Point pp;
- struct Point p;
- struct Point v;
- struct Point a;
- int r;
- int m;
-};
-
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);
-struct Object *create_object(float, float, float, float, float, float,
+struct Object *create_object(enum object_type,
+ float, float, float, float, float, float,
int, int, int);
int is_on_floor_before(struct Object *, struct Object *);
+
+
/*
* x.c
*/
diff --git a/ex9/util.c b/ex9/util.c
@@ -8,18 +8,20 @@ static void rect_next_tick(struct Object *, long);
static void rect_handle_collision_mf(struct Object *, struct Object *);
struct Object *
-create_object(float px, float py, float vx, float vy, float ax, float ay,
+create_object(enum object_type t,
+ float px, float py, float vx, float vy, float ax, float ay,
int w, int h, int m)
{
struct Object *o;
o = (struct Object *)malloc(sizeof(struct Object));
+ o->type = t;
+ o->shape = SRECTANGLE;
o->pp.x = o->p.x = px;
o->pp.y = o->p.y = py;
o->v.x = vx;
o->v.y = vy;
o->a.x = ax;
o->a.y = ay;
- o->shape = SRECTANGLE;
o->body.rectangle.w = w;
o->body.rectangle.h = h;
o->m = m;