From 790bcddfa9db17769b8d42ebd5dce4ac44e3a3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Fri, 14 Jan 2022 15:32:00 +0000 Subject: [PATCH] Implement player - tile collision. --- platformer.c | 60 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/platformer.c b/platformer.c index 7166f81..2db6628 100644 --- a/platformer.c +++ b/platformer.c @@ -84,11 +84,10 @@ static double timespec2double(struct timespec ts) { return ts.tv_sec + ts.tv_nsec / 1000.0 / 1000.0 / 1000.0; } -char sample_tilemap(double x, double y) { +static char sample_tilemap(size_t x, size_t y) { size_t tx = x / TILE_SIDE; size_t ty = y / TILE_SIDE; - assert(tx < TILES); - assert(ty < TILES); + if (tx >= TILES || ty >= TILES) return ' '; return tilemap[ty * TILES + tx]; } @@ -105,6 +104,9 @@ static void update(struct timespec now, struct timespec dt_timespec) { else if (right_held) player_dx = 30; else player_dx = 0; + if (jump_held) player_dy = -30; + else player_dy = 30; + // Collision against walls of the map if (player_x < 0) { player_x = 0; @@ -122,22 +124,50 @@ static void update(struct timespec now, struct timespec dt_timespec) { } // Collision against tiles - char topleft = sample_tilemap(player_x, player_y); - char topright = sample_tilemap(player_x + TILE_SIDE, player_y); - char bottomleft = sample_tilemap(player_x, player_y + TILE_SIDE); - char bottomright = sample_tilemap(player_x + TILE_SIDE, player_y + TILE_SIDE); + size_t px = player_x; + size_t py = player_y; + size_t left_cx = px - 1; + size_t right_cx = px + TILE_SIDE; + size_t leftright_top_cy = py; + size_t leftright_bottom_cy = py + TILE_SIDE - 1; + if ((sample_tilemap(left_cx, leftright_top_cy) != ' ' || + sample_tilemap(left_cx, leftright_bottom_cy) != ' ') && + player_dx < 0) { + size_t snapped_px = (px + TILE_SIDE - 1) / TILE_SIDE * TILE_SIDE; + player_x = snapped_px; + player_dx = 0; + } + if ((sample_tilemap(right_cx, leftright_top_cy) != ' ' || + sample_tilemap(right_cx, leftright_bottom_cy) != ' ') && + player_dx > 0) { + size_t snapped_px = px / TILE_SIDE * TILE_SIDE; + player_x = snapped_px; + player_dx = 0; + } + + px = player_x; + py = player_y; + size_t topbottom_left_cx = px; + size_t topbottom_right_cx = px + TILE_SIDE - 1; + size_t top_cy = py - 1; + size_t bottom_cy = py + TILE_SIDE; bool on_ground = false; - if (bottomleft != ' ' || bottomright != ' ') + if ((sample_tilemap(topbottom_left_cx, bottom_cy) != ' ' || + sample_tilemap(topbottom_right_cx, bottom_cy) != ' ') && + player_dy > 0) { on_ground = true; - if (topleft != ' ' || topright != ' ' || bottomleft != ' ' || bottomright != ' ') - player_dx = 0; - - if (on_ground) + size_t snapped_py = py / TILE_SIDE * TILE_SIDE; + player_y = snapped_py; player_dy = 0; - else - player_dy = 30; - + } + if ((sample_tilemap(topbottom_left_cx, top_cy) != ' ' || + sample_tilemap(topbottom_right_cx, top_cy) != ' ') && + player_dy < 0) { + size_t snapped_py = (py + TILE_SIDE - 1) / TILE_SIDE * TILE_SIDE; + player_y = snapped_py; + player_dy = 0; + } } static void draw_grass_tile(size_t x, size_t y) {