Little collision changes to allow 360 degree movement

This commit is contained in:
Lucas S. Vieira 2024-11-30 11:39:49 -03:00 committed by Lucas Vieira
parent cb6c935e1c
commit 048d03fd23
5 changed files with 19 additions and 16 deletions

View file

@ -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 */

View file

@ -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,

View file

@ -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;

View file

@ -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:

View file

@ -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)) {