Modify player collision with water blocks

Collision now handles different water level
scene_man
En Yi 2023-07-24 21:19:16 +08:00
parent 4a09550c0b
commit 0a76826c27
4 changed files with 44 additions and 19 deletions

View File

@ -39,4 +39,5 @@
#define GROUND_Y_FRICTION 1.0
#define MAX_WATER_LEVEL 4
#define WATER_BBOX_STEP (TILE_SIZE / MAX_WATER_LEVEL)
#endif // __CONSTANTS_H

View File

@ -113,14 +113,14 @@ static void level_scene_render_func(Scene_t* scene)
}
// Draw water tile
float water_height = tilemap.tiles[i].water_level * 1.0f / tilemap.max_water_level;
uint32_t water_height = tilemap.tiles[i].water_level * WATER_BBOX_STEP;
// Draw water tile
Color water_colour = ColorAlpha(BLUE, 0.5);
DrawRectangle(
x,
y + (1.0f - water_height) * TILE_SIZE,
y + (TILE_SIZE - water_height),
TILE_SIZE,
water_height * TILE_SIZE,
water_height,
water_colour
);
}

View File

@ -869,27 +869,35 @@ void global_external_forces_system(Scene_t* scene)
continue;
}
Vector2 half_size = {0, 0};
if (p_bbox != NULL)
{
half_size = p_bbox->half_size;
}
if (!(p_mstate->ground_state & 1))
{
// Only apply upthrust if center is in water
// If need more accuracy, need to find area of overlap
if (p_mstate->water_state & 1)
{
Vector2 player_center = (Vector2){
.x = p_ctransform->position.x + p_bbox->half_size.x,
.y = p_ctransform->position.y + p_bbox->half_size.y,
};
unsigned int tile_idx = get_tile_idx(
p_ctransform->position.x + half_size.x,
p_ctransform->position.y + half_size.y,
player_center.x,
player_center.y,
data->tilemap.width
);
if (data->tilemap.tiles[tile_idx].water_level > 0)
{
p_ctransform->accel = Vector2Add(p_ctransform->accel, UPTHRUST);
uint32_t water_height = data->tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
Rectangle box = {
.x = (tile_idx % data->tilemap.width) * data->tilemap.tile_size,
.y = (tile_idx / data->tilemap.width + 1) * data->tilemap.tile_size - water_height,
.width = data->tilemap.tile_size,
.height = water_height,
};
if (point_in_AABB(player_center, box))
{
p_ctransform->accel = Vector2Add(p_ctransform->accel, UPTHRUST);
}
}
}
p_ctransform->accel = Vector2Add(p_ctransform->accel, GRAVITY);
@ -1318,12 +1326,27 @@ void state_transition_update_system(Scene_t* scene)
bool in_water = false;
if (!(p_mstate->water_state & 1))
{
Vector2 player_center = (Vector2){
.x = p_ctransform->position.x + p_bbox->half_size.x,
.y = p_ctransform->position.y + p_bbox->half_size.y,
};
unsigned int tile_idx = get_tile_idx(
p_ctransform->position.x + p_bbox->half_size.x,
p_ctransform->position.y + p_bbox->half_size.y,
player_center.x,
player_center.y,
data->tilemap.width
);
in_water = (data->tilemap.tiles[tile_idx].water_level > 0);
if (data->tilemap.tiles[tile_idx].water_level > 0)
{
uint32_t water_height = data->tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
Rectangle box = {
.x = (tile_idx % data->tilemap.width) * data->tilemap.tile_size,
.y = (tile_idx / data->tilemap.width + 1) * data->tilemap.tile_size - water_height,
.width = data->tilemap.tile_size,
.height = water_height,
};
in_water = point_in_AABB(player_center, box);
}
}
else
{

View File

@ -166,7 +166,7 @@ void update_water_runner_system(Scene_t* scene)
{
// Use previously store tile position
// Clear from those positions
unsigned int tile_idx = p_tilecoord->tiles[i];
int tile_idx = p_tilecoord->tiles[i];
sc_map_del_64v(&(tilemap.tiles[tile_idx].entities_set), ent_idx);
}
free_water_runner(ent, &scene->ent_manager);
@ -192,8 +192,8 @@ void update_water_runner_system(Scene_t* scene)
runner_BFS(&tilemap, p_crunner, &lowest_tile, p_crunner->current_tile);
p_crunner->target_tile = lowest_tile;
// Trace path from lowest_tile
unsigned int prev_idx = lowest_tile;
unsigned int curr_idx = p_crunner->bfs_tilemap.tilemap[prev_idx].from;
int prev_idx = lowest_tile;
int curr_idx = p_crunner->bfs_tilemap.tilemap[prev_idx].from;
while (p_crunner->bfs_tilemap.tilemap[prev_idx].from >= 0)
{
p_crunner->bfs_tilemap.tilemap[curr_idx].to = prev_idx;
@ -271,6 +271,7 @@ void update_water_runner_system(Scene_t* scene)
break;
case SCANLINE_FILL:
{
// Unsigned usage here is okay
unsigned int start_tile =
(p_crunner->current_tile / p_crunner->bfs_tilemap.width) * p_crunner->bfs_tilemap.width;
//for (size_t i = 0; i < 10; ++i)