xlib_playground

Xlib playground for experiments.
Log | Files | Refs

commit 5b57a73784bc434851d1f4a3a3aed7436fd12567
parent e77c5bff1c4acdd2957016efe7a84856c83294c5
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Thu,  5 Jan 2023 15:12:38 +0900

add experimental collision handler

Diffstat:
Mex9/main.c | 102++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mex9/main.h | 33++++++++++++++-------------------
Mex9/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;