Modify water upthrust behaviour
Changelog: - Upthrust now depends on water area overlap with entity - Fix complete overlap checksscene_man
parent
72c27ed92e
commit
0b5f34b9f3
|
@ -3,13 +3,17 @@
|
|||
uint8_t find_1D_overlap(Vector2 l1, Vector2 l2, float* overlap)
|
||||
{
|
||||
// No Overlap
|
||||
if (l1.y <= l2.x || l2.y <= l1.x) return 0;
|
||||
if (l1.y < l2.x || l2.y < l1.x) return 0;
|
||||
|
||||
if (l1.x >= l2.x && l1.y <= l2.y)
|
||||
if (
|
||||
(l1.x >= l2.x && l1.y <= l2.y)
|
||||
|| (l2.x >= l1.x && l2.y <= l1.y)
|
||||
)
|
||||
{
|
||||
// Complete Overlap, any direction is possible
|
||||
// Cannot give a singular value, but return something anyways
|
||||
*overlap = l2.y-l2.x + l1.y-l1.x;
|
||||
//*overlap = l2.y-l2.x + l1.y-l1.x;
|
||||
*overlap = fmin(fabs(l2.y-l2.x), fabs(l1.y-l1.x));
|
||||
return 2;
|
||||
}
|
||||
//Partial overlap
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef struct _CMovementState_t {
|
|||
uint8_t ground_state;
|
||||
uint8_t water_state;
|
||||
uint8_t x_dir;
|
||||
float water_overlap;
|
||||
} CMovementState_t;
|
||||
|
||||
// This is to store the occupying tiles
|
||||
|
|
|
@ -916,37 +916,55 @@ void global_external_forces_system(Scene_t* scene)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(p_mstate->ground_state & 1))
|
||||
// Upthrust depends on water overlapping
|
||||
if (p_bbox != NULL)
|
||||
{
|
||||
// Only apply upthrust if center is in water
|
||||
// If need more accuracy, need to find area of overlap
|
||||
if (p_mstate->water_state & 1)
|
||||
unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
|
||||
unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
|
||||
unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE;
|
||||
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
|
||||
float water_area = 0;
|
||||
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
|
||||
{
|
||||
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(
|
||||
player_center.x,
|
||||
player_center.y,
|
||||
data->tilemap.width
|
||||
);
|
||||
if (data->tilemap.tiles[tile_idx].water_level > 0)
|
||||
for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
|
||||
{
|
||||
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))
|
||||
unsigned int tile_idx = tile_y * data->tilemap.width + tile_x;
|
||||
if (data->tilemap.tiles[tile_idx].water_level > 0)
|
||||
{
|
||||
p_ctransform->accel = Vector2Multiply(Vector2Add(p_ctransform->accel, UPTHRUST), p_ctransform->shape_factor);
|
||||
uint32_t water_height = data->tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
|
||||
Vector2 water_tl = {
|
||||
.x = (tile_idx % data->tilemap.width) * data->tilemap.tile_size,
|
||||
.y = (tile_idx / data->tilemap.width + 1) * data->tilemap.tile_size - water_height};
|
||||
|
||||
Vector2 water_sz = {
|
||||
.x = data->tilemap.tile_size,
|
||||
.y = water_height,
|
||||
};
|
||||
|
||||
Vector2 overlap;
|
||||
if (find_AABB_overlap(
|
||||
p_ctransform->position, p_bbox->size,
|
||||
water_tl, water_sz, &overlap
|
||||
))
|
||||
{
|
||||
water_area += fabs(overlap.x * overlap.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
p_mstate->water_overlap = water_area/(p_bbox->size.x * p_bbox->size.y);
|
||||
}
|
||||
|
||||
if (!(p_mstate->ground_state & 1))
|
||||
{
|
||||
p_ctransform->accel = Vector2Multiply(
|
||||
Vector2Add(
|
||||
p_ctransform->accel,
|
||||
Vector2Scale(UPTHRUST, p_mstate->water_overlap)
|
||||
),
|
||||
p_ctransform->shape_factor
|
||||
);
|
||||
|
||||
p_ctransform->accel = Vector2Add(p_ctransform->accel, GRAVITY);
|
||||
}
|
||||
|
||||
|
@ -1407,54 +1425,7 @@ void state_transition_update_system(Scene_t* scene)
|
|||
p_ctransform->grav_timer = p_ctransform->grav_delay;
|
||||
}
|
||||
|
||||
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(
|
||||
player_center.x,
|
||||
player_center.y,
|
||||
data->tilemap.width
|
||||
);
|
||||
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
|
||||
{
|
||||
unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
|
||||
unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
|
||||
unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE;
|
||||
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
|
||||
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
|
||||
{
|
||||
for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
|
||||
{
|
||||
unsigned int tile_idx = tile_y * data->tilemap.width + tile_x;
|
||||
if (data->tilemap.tiles[tile_idx].water_level == 0) continue;
|
||||
|
||||
uint32_t water_height = data->tilemap.tiles[tile_idx].water_level * WATER_BBOX_STEP;
|
||||
Vector2 tl = {tile_x * data->tilemap.tile_size, (tile_y + 1) * data->tilemap.tile_size - water_height};
|
||||
in_water |= find_AABB_overlap(
|
||||
p_ctransform->position, p_bbox->size,
|
||||
tl, (Vector2){data->tilemap.tile_size, water_height}
|
||||
, NULL
|
||||
) > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool in_water = p_mstate->water_overlap > 0.4;
|
||||
p_mstate->ground_state <<= 1;
|
||||
p_mstate->ground_state |= on_ground? 1:0;
|
||||
p_mstate->ground_state &= 3;
|
||||
|
|
Loading…
Reference in New Issue