xlib_playground

Xlib playground for experiments.
Log | Files | Refs

commit 5f3484485073c11a1f5b91d44af27e07d803874a
parent 04b70906ce60ebe8823ead7f3eff1da2d2359f09
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Mon, 26 Dec 2022 14:03:59 +0900

add blocks and player

Diffstat:
Mex6/ex6.c | 207++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 174 insertions(+), 33 deletions(-)

diff --git a/ex6/ex6.c b/ex6/ex6.c @@ -12,10 +12,13 @@ #define INIT_HEIGHT (600) #define FPS (60) #define SUB_TICK (4) -#define NUM_RECT (20) +#define NUM_RECT (200) #define GRAVITY (1000) #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) +#define WORLD_WIDTH (80) +#define WORLD_HEIGHT (60) +#define BLOCK_SIZE (10) // #define COUNT_FPS @@ -57,6 +60,68 @@ struct circle { int m; }; +char world_map[WORLD_WIDTH * WORLD_HEIGHT + 1] = +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +".......................b........................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"..................b............................................................." +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"....................................bbbbbbbbbb.................................." +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"..............................................bbbbbbbbbb........................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"....................................bbbbbbbbbb.................................." +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"..........................bbbbbbbbbb............................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................................................................................" +"................bbbbbbbbbb......................................................" +"................................................................................" +"................................................................................" +"...p............................................................................" +"bbbbbbbbbbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb" +"........................b.......b......................b...b...................." +"........................b.......b......................b...b...................." +"........................b.......b......................b...b...................." +"........................b.......b......................b...b...................."; + /* variables */ Display *display; Window window; @@ -65,6 +130,7 @@ GC gc, sgc[NUM_RECT]; Atom wm_delete_window; struct rect block[NUM_RECT]; struct rect player; +int player_is_falling; int next_menu = START_MENU; @@ -82,6 +148,7 @@ void rect_handle_collision(struct rect *, struct rect *); void rect_handle_collision_elastic(struct rect *, struct rect *); void circle_next_tick(struct circle *, long); int circle_test_collision(struct circle *, struct circle *); +void update_falling_status(struct rect *, long); void game_over(void); @@ -253,19 +320,35 @@ handle_inputs(int key_state[]) next_menu = GAME_OVER; return; } - player.vx = 0; - if (key_state[KEY_D] == KEY_DOWN) - player.vx += 300; - if (key_state[KEY_A] == KEY_DOWN) - player.vx += -300; + if (key_state[KEY_D] == KEY_DOWN) { + if (player.vx > 0) { + player.ax = 500; + } else { + player.ax = 1000; + } + } else if (key_state[KEY_A] == KEY_DOWN) { + if (player.vx > 0) { + player.ax = -1000; + } else { + player.ax = -500; + } + } else { + if (player_is_falling) + player.ax = -player.vx; + else + player.ax = -3 * player.vx; + } + + if (player.vx < -200) player.vx = -200; + if (player.vx > 200) player.vx = 200; /* if (key_state[KEY_S] == KEY_DOWN) player.vy += 300; if (key_state[KEY_W] == KEY_DOWN) player.vy += -300; */ - if (key_state[KEY_SPACE] == KEY_DOWN) - player.vy = -300; + if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN) + player.vy = -450; } void @@ -281,12 +364,13 @@ rect_next_tick(struct rect *s, long ndt) // nano second // bind within the window if (s->px < 0) { s->px = 0; - s->vx *= -1; + //s->vx *= -1; } if (win_width < s->px + s->w) { s->px = win_width - s->w; - s->vx *= -1; + //s->vx *= -1; } + /* if (s->py < 0) { s->py = 0; s->vy *= -1; @@ -295,6 +379,10 @@ rect_next_tick(struct rect *s, long ndt) // nano second s->py = win_height - s->h; s->vy *= -1; } + */ + // game over when fall out of the screen + if (s->py > win_height) + next_menu = GAME_OVER; } void @@ -349,19 +437,28 @@ rect_handle_collision_mf(struct rect *sm, struct rect *sf) { if (!rect_test_collision(sm, sf)) return; - if (sm->ppx + sm->w <= sf->ppx && sf->px < sm->px + sm->w) + 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) + sm->vx = 0; + } + if (sf->ppx + sf->w <= sm->ppx && sm->px < sf->px + sf->w) { // collision from right to left sm->px = sf->px + sf->w; + sm->vx = 0; + } - if (sm->ppy + sm->h <= sf->ppy && sf->py < sm->py + sm->h) + 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) + sm->vy = 0; + } + if (sf->ppy + sf->h <= sm->ppy && sm->py < sf->py + sf->h) { // collision from dohn to up sm->py = sf->py + sf->h; + sm->vy = 0; + } + } /* @@ -478,6 +575,35 @@ circle_handle_collision_elastic(struct circle *c1, struct circle *c2) c2->vx = col_2vxn + nor_2vx; c2->vy = col_2vyn + nor_2vy; } + +void +update_falling_status(struct rect *player, long ndt) +{ + int collision = 0; + struct rect r = {0}; + r.ppx = player->ppx; + r.ppy = player->ppy; + r.px = player->px; + r.py = player->py; + r.vx = 0; + r.vy = 0; + r.ax = 0; + r.ay = GRAVITY; + r.w = player->w; + r.h = player->h; + r.m = player->m; + + rect_next_tick(&r, ndt); + for (int i = 0; i < NUM_RECT; i++) + if (rect_test_collision(&r, &block[i])) + collision = 1; + + if (collision == 1) + player_is_falling = 0; + else + player_is_falling = 1; +} + void game_play(void) { @@ -488,24 +614,29 @@ game_play(void) #endif struct timespec ts; - for(int i = 0; i < NUM_RECT; i++){ - block[i].ppx = block[i].px = 40 * (i + 1) % win_width; - block[i].ppy = block[i].py = 400 ; - block[i].ax = 0; - block[i].ay = 0; - block[i].vx = 0; - block[i].vy = 0; - block[i].w = block[i].h = 40; - block[i].m = block[i].w * block[i].h; + int bi = 0; + for (int i = 0; i < WORLD_WIDTH * WORLD_HEIGHT; i++) { + if (world_map[i] == 'b') { + block[bi].ppx = block[bi].px = i % WORLD_WIDTH * BLOCK_SIZE; + block[bi].ppy = block[bi].py = i / WORLD_WIDTH * BLOCK_SIZE; + block[bi].ax = 0; + block[bi].ay = 0; + block[bi].vx = 0; + block[bi].vy = 0; + block[bi].w = block[bi].h = BLOCK_SIZE; + block[bi].m = block[bi].w * block[bi].h; + bi++; + } else if (world_map[i] == 'p') { + player.ppx = player.px = i % WORLD_WIDTH * BLOCK_SIZE; + player.ppy = player.py = i / WORLD_WIDTH * BLOCK_SIZE; + player.vx = 0; + player.vy = 0; + player.ax = 0; + player.ay = GRAVITY; + player.w = player.h = BLOCK_SIZE; + player.m = player.w * player.h; + } } - player.ppx = player.px = 100; - player.ppy = player.py = 300 ; - player.vx = 0; - player.vy = 0; - player.ax = 0; - player.ay = GRAVITY; - player.w = player.h = 20; - player.m = player.w * player.h; while (next_menu == GAME_PLAY){ clock_gettime(CLOCK_MONOTONIC, &ts); @@ -519,6 +650,11 @@ game_play(void) int collision[NUM_RECT] = {0}; for (int k = 0; k < SUB_TICK; k++) { + update_falling_status(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK); + if (player_is_falling) + player.ay = GRAVITY; + else + player.ay = 0; rect_next_tick(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK); for (int i = 0; i < NUM_RECT; i++) rect_next_tick(&block[i], 1000 * 1000 * 1000 / FPS / SUB_TICK); @@ -533,7 +669,7 @@ game_play(void) if (collision[i] == 1) XSetForeground(display, sgc[i], 0xFFFF00); else - XSetForeground(display, sgc[i], 0xFF << i % 3 * 8); + XSetForeground(display, sgc[i], 0x90FF90); // fix fps // TODO: This method create some strange stripe when @@ -567,8 +703,13 @@ game_play(void) player.px, player.py, // position player.w, player.h); + char status_string[128]; + snprintf(status_string, 128, "falling: %d", player_is_falling); + XDrawString(display, window, gc, + 0, 20, + status_string, + strlen(status_string)); } - XSetForeground(display, gc, 0x00FFFF); } void