From 048d03fd23edfa16366a6fff34f22950b4832665 Mon Sep 17 00:00:00 2001 From: "Lucas S. Vieira" Date: Sat, 30 Nov 2024 11:39:49 -0300 Subject: [PATCH] Little collision changes to allow 360 degree movement --- include/collision.h | 2 +- src/collision.c | 10 ++++++---- src/object_state_update.c | 6 +++--- src/player.c | 16 ++++++++-------- src/screen_level.c | 1 + 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/include/collision.h b/include/collision.h index 2abd471..75e58d7 100644 --- a/include/collision.h +++ b/include/collision.h @@ -26,7 +26,7 @@ typedef enum { CollisionEvent linecast(LevelData *lvl, TileMap128 *map128, TileMap16 *map16, int32_t vx, int32_t vy, LinecastDirection direction, - uint8_t magnitude); + uint8_t magnitude, LinecastDirection floor_direction); /* Simpler collision detection algorithms */ diff --git a/src/collision.c b/src/collision.c index b215e3d..8b842f4 100644 --- a/src/collision.c +++ b/src/collision.c @@ -80,11 +80,11 @@ _get_height_and_angle_from_mask( mask = collision->rwall; break; case CDIR_CEILING: - *out_angle = collision->ceiling_angle; + *out_angle = 0x1000 + collision->ceiling_angle; mask = collision->ceiling; break; case CDIR_LWALL: - *out_angle = collision->lwall_angle; + *out_angle = 0x1000 + collision->lwall_angle; mask = collision->lwall; break; default: goto abort_retrieve; @@ -133,7 +133,8 @@ _get_tip_height(LinecastDirection direction, CollisionEvent linecast(LevelData *lvl, TileMap128 *map128, TileMap16 *map16, - int32_t vx, int32_t vy, LinecastDirection direction, uint8_t magnitude) + int32_t vx, int32_t vy, LinecastDirection direction, + uint8_t magnitude, LinecastDirection floor_direction) { // No level data? No collision. if(lvl->num_layers < 1) return (CollisionEvent){ 0 }; @@ -194,7 +195,8 @@ linecast(LevelData *lvl, TileMap128 *map128, TileMap16 *map16, if(h > 0) { int32_t tip_height = _get_tip_height(direction, lx, ly); - if(direction == CDIR_FLOOR || (h >= tip_height)) { + + if(direction == floor_direction || (h >= tip_height)) { int32_t coord = _get_new_position(direction, cx, cy, px, py, h); ev = (CollisionEvent) { .collided = 1, diff --git a/src/object_state_update.c b/src/object_state_update.c index 500fad5..af4e5e3 100644 --- a/src/object_state_update.c +++ b/src/object_state_update.c @@ -178,7 +178,7 @@ _ring_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos) // variables as well. Check the file header. if(linecast(&leveldata, &map128, &map16, pos->vx + 8, pos->vy + 8, - CDIR_FLOOR, 10).collided) + CDIR_FLOOR, 10, CDIR_FLOOR).collided) // Multiply Y speed by -0.75 state->freepos->spdy = (state->freepos->spdy * -0x00000c00) >> 12; } @@ -186,10 +186,10 @@ _ring_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos) if(/*!(state->timer % 4) &&*/ ((state->freepos->spdx < 0) && linecast(&leveldata, &map128, &map16, pos->vx + 8, pos->vy + 8, - CDIR_LWALL, 10).collided) + CDIR_LWALL, 10, CDIR_FLOOR).collided) || ((state->freepos->spdx > 0) && linecast(&leveldata, &map128, &map16, pos->vx + 8, pos->vy + 8, - CDIR_RWALL, 10).collided)) + CDIR_RWALL, 10, CDIR_FLOOR).collided)) // Multiply X speed by -0.75 state->freepos->spdx = (state->freepos->spdx * -0x00000c00) >> 12; diff --git a/src/player.c b/src/player.c index 3e7f828..8056272 100644 --- a/src/player.c +++ b/src/player.c @@ -268,7 +268,7 @@ _player_update_collision_lr(Player *player) if(player->vel.vx < 0) { player->ev_left = linecast(&leveldata, &map128, &map16, anchorx, push_anchory, - ldir, left_mag); + ldir, left_mag, player->gsmode); } } @@ -277,7 +277,7 @@ _player_update_collision_lr(Player *player) if(player->vel.vx > 0) { player->ev_right = linecast(&leveldata, &map128, &map16, anchorx, push_anchory, - rdir, right_mag); + rdir, right_mag, player->gsmode); } } } @@ -416,12 +416,12 @@ _player_update_collision_tb(Player *player) if(!player->ev_grnd1.collided) { player->ev_grnd1 = linecast(&leveldata, &map128, &map16, anchorx_left, anchory_left, - grndir, grn_mag); + grndir, grn_mag, player->gsmode); } if(!player->ev_grnd2.collided) { player->ev_grnd2 = linecast(&leveldata, &map128, &map16, anchorx_right, anchory_right, - grndir, grn_mag); + grndir, grn_mag, player->gsmode); } if(!player->grnd) { @@ -429,12 +429,12 @@ _player_update_collision_tb(Player *player) if(!player->ev_ceil1.collided) { player->ev_ceil1 = linecast(&leveldata, &map128, &map16, anchorx_left, anchory_left, - ceildir, ceil_mag); + ceildir, ceil_mag, player->gsmode); } if(!player->ev_ceil2.collided) { player->ev_ceil2 = linecast(&leveldata, &map128, &map16, anchorx_right, anchory_right, - ceildir, ceil_mag); + ceildir, ceil_mag, player->gsmode); } } @@ -576,14 +576,14 @@ _player_update_collision_tb(Player *player) if((player->ev_grnd2.collided && (player->ev_grnd2.coord > new_coord)) || (new_coord == 0)) new_coord = player->ev_grnd2.coord; - player->pos.vx = (new_coord + 32) << 12; + player->pos.vx = (new_coord) << 12; break; case CDIR_CEILING: if(player->ev_grnd1.collided) new_coord = player->ev_grnd1.coord; if((player->ev_grnd2.collided && (player->ev_grnd2.coord > new_coord)) || (new_coord == 0)) new_coord = player->ev_grnd2.coord; - player->pos.vy = (new_coord + 32) << 12; + player->pos.vy = (new_coord) << 12; break; case CDIR_FLOOR: default: diff --git a/src/screen_level.c b/src/screen_level.c index bdc57f8..da6bece 100644 --- a/src/screen_level.c +++ b/src/screen_level.c @@ -251,6 +251,7 @@ screen_level_update(void *d) player.grnd = 0; player.anim_dir = 1; player.vel.vx = player.vel.vy = player.vel.vz = 0; + player.psmode = player.gsmode = CDIR_FLOOR; } if(pad_pressed(PAD_CIRCLE)) {