Adjust ladder player interaction

Changelog:
- Use box check to allow player to climb ladder
    - This make it more lenient
- Use interp to smoothly 'snap' the player to ladder's center
    - only when climbing straight up/down
- Increase speed when climbing horizontally
- Decrease jump penalty when jumping off ladder
main
En Yi 2025-08-27 22:43:09 +08:00
parent dacb235fad
commit b8b475bfc4
1 changed files with 41 additions and 53 deletions

View File

@ -326,77 +326,65 @@ void player_movement_input_system(Scene_t* scene)
CMovementState_t* p_mstate = get_component(p_player, CMOVEMENTSTATE_T);
// Ladder handling
// Entering ladder bbox check is a quarter smaller, while exitting the ladder is a full bbox check
if (!p_pstate->ladder_state)
{
// Transit into ladder state if possible
if (!p_pstate->locked)
{
if (p_pstate->player_dir.y < 0)
if (p_pstate->player_dir.y < 0 && p_ctransform->velocity.y >= 0)
{
unsigned int tile_idx = get_tile_idx(
p_player->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->half_size.y,
data->tilemap
);
if (tilemap.tiles[tile_idx].tile_type == LADDER && p_ctransform->velocity.y >= 0)
unsigned int tile_x1 = (p_player->position.x + p_bbox->half_size.x/2) / TILE_SIZE;
unsigned int tile_x2 = (p_player->position.x + p_bbox->half_size.x *3/2) / TILE_SIZE;
unsigned int tile_y1 = (p_player->position.y + p_bbox->half_size.y/2) / TILE_SIZE;
unsigned int tile_y2 = (p_player->position.y + p_bbox->half_size.y*3/2) / TILE_SIZE;
for(unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
{
p_pstate->ladder_state = true;
p_player->position.y--;
for(unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
{
unsigned int tile_idx = tile_y * tilemap.width + tile_x;
if (tilemap.tiles[tile_idx].tile_type == LADDER)
{
p_pstate->ladder_state = true;
p_player->position.y--;
break;
}
}
}
}
//else if (p_pstate->player_dir.y > 0)
//{
// unsigned int tile_idx;
// if (p_mstate->ground_state & 1)
// {
// tile_idx = get_tile_idx(
// p_player->position.x + p_bbox->half_size.x,
// p_player->position.y + p_bbox->size.y,
// data->tilemap
// );
// }
// else
// {
// tile_idx = get_tile_idx(
// p_player->position.x + p_bbox->half_size.x,
// p_player->position.y + p_bbox->half_size.y,
// data->tilemap
// );
// }
// if (tile_idx < tilemap.n_tiles && tilemap.tiles[tile_idx].tile_type == LADDER)
// {
// p_pstate->ladder_state = true;
// p_player->position.y++;
// }
//}
}
}
else
{
unsigned int tile_x = (p_player->position.x + p_bbox->half_size.x) / TILE_SIZE;
unsigned int tile_y1 = (p_player->position.y + p_bbox->half_size.y) / TILE_SIZE;
unsigned int tile_x1 = (p_player->position.x) / TILE_SIZE;
unsigned int tile_x2 = (p_player->position.x + p_bbox->size.x) / TILE_SIZE;
unsigned int tile_y1 = (p_player->position.y) / TILE_SIZE;
unsigned int tile_y2 = (p_player->position.y + p_bbox->size.y) / TILE_SIZE;
p_pstate->ladder_state = false;
unsigned int tile_x = tile_x1;
if (!(p_mstate->ground_state & 1))
{
for(unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
for(tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
{
unsigned int tile_idx = tile_y * tilemap.width + tile_x;
p_pstate->ladder_state |= tilemap.tiles[tile_idx].tile_type == LADDER;
}
}
for(unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
{
unsigned int tile_idx = tile_y * tilemap.width + tile_x;
if (p_pstate->ladder_state)
{
p_ctransform->velocity.y = p_pstate->player_dir.y * 150 * (p_pstate->locked ? 0 : 1);
p_ctransform->velocity.x = p_pstate->player_dir.x * 40 * (p_pstate->locked ? 0 : 1);
if (p_pstate->player_dir.y != 0)
{
p_player->position.x = tile_x * tilemap.tile_size;
p_player->position.x += (tilemap.tile_size >> 1);
p_player->position.x -= p_bbox->half_size.x;
if (tilemap.tiles[tile_idx].tile_type == LADDER)
{
p_pstate->ladder_state = true;
p_ctransform->velocity.y = p_pstate->player_dir.y * 150 * (p_pstate->locked ? 0 : 1);
p_ctransform->velocity.x = p_pstate->player_dir.x * 60 * (p_pstate->locked ? 0 : 1);
if (p_pstate->player_dir.y != 0 && p_pstate->player_dir.x == 0)
{
float x_target = tile_x * tilemap.tile_size + (tilemap.tile_size >> 1) - p_bbox->half_size.x;
p_player->position.x += (x_target - p_player->position.x) * 0.25;
}
break;
}
}
}
}
}
@ -475,7 +463,7 @@ void player_movement_input_system(Scene_t* scene)
else if (p_pstate->ladder_state)
{
play_sfx(scene->engine, PLAYER_JMP_SFX);
p_ctransform->velocity.y = -p_cjump->jump_speed / 1.4;
p_ctransform->velocity.y = -p_cjump->jump_speed / 1.2;
}
}
else