Compare commits
4 Commits
8d94943547
...
ddcb71ed50
Author | SHA1 | Date |
---|---|---|
|
ddcb71ed50 | |
|
0a5eb36c34 | |
|
8ae647994a | |
|
45972d6416 |
|
@ -34,6 +34,7 @@ typedef struct _CTransform_t
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
Vector2 velocity;
|
Vector2 velocity;
|
||||||
Vector2 accel;
|
Vector2 accel;
|
||||||
|
Vector2 fric_coeff;
|
||||||
}CTransform_t;
|
}CTransform_t;
|
||||||
|
|
||||||
typedef struct _CMovementState_t
|
typedef struct _CMovementState_t
|
||||||
|
|
|
@ -319,6 +319,7 @@ void init_level_scene(LevelScene_t *scene)
|
||||||
// insert level scene systems
|
// insert level scene systems
|
||||||
sc_array_add(&scene->scene.systems, &player_movement_input_system);
|
sc_array_add(&scene->scene.systems, &player_movement_input_system);
|
||||||
sc_array_add(&scene->scene.systems, &player_bbox_update_system);
|
sc_array_add(&scene->scene.systems, &player_bbox_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &friction_coefficient_update_system);
|
||||||
sc_array_add(&scene->scene.systems, &global_external_forces_system);
|
sc_array_add(&scene->scene.systems, &global_external_forces_system);
|
||||||
sc_array_add(&scene->scene.systems, &movement_update_system);
|
sc_array_add(&scene->scene.systems, &movement_update_system);
|
||||||
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||||
|
|
|
@ -113,7 +113,6 @@ static bool check_collision_and_move(EntityManager_t* p_manager, TileGrid_t* til
|
||||||
// Store collision event here
|
// Store collision event here
|
||||||
// Check collision on x or y axis
|
// Check collision on x or y axis
|
||||||
// Encode key and value, -ve is left and up, +ve is right and down
|
// Encode key and value, -ve is left and up, +ve is right and down
|
||||||
uint8_t dir_to_move = 0;
|
|
||||||
Vector2 offset = {0, 0};
|
Vector2 offset = {0, 0};
|
||||||
if (fabs(prev_overlap.y) > fabs(prev_overlap.x))
|
if (fabs(prev_overlap.y) > fabs(prev_overlap.x))
|
||||||
{
|
{
|
||||||
|
@ -122,7 +121,6 @@ static bool check_collision_and_move(EntityManager_t* p_manager, TileGrid_t* til
|
||||||
}
|
}
|
||||||
else if (fabs(prev_overlap.x) > fabs(prev_overlap.y))
|
else if (fabs(prev_overlap.x) > fabs(prev_overlap.y))
|
||||||
{
|
{
|
||||||
dir_to_move = 1;
|
|
||||||
offset.y = overlap.y;
|
offset.y = overlap.y;
|
||||||
*collision_value = (((overlap.y > 0?3:2)<< 14) | ( (uint16_t)(fabs(overlap.y)) ));
|
*collision_value = (((overlap.y > 0?3:2)<< 14) | ( (uint16_t)(fabs(overlap.y)) ));
|
||||||
}
|
}
|
||||||
|
@ -133,7 +131,6 @@ static bool check_collision_and_move(EntityManager_t* p_manager, TileGrid_t* til
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dir_to_move = 1;
|
|
||||||
offset.y = overlap.y;
|
offset.y = overlap.y;
|
||||||
*collision_value = (((overlap.y > 0?3:2)<< 14) | ( (uint16_t)(fabs(overlap.y)) ));
|
*collision_value = (((overlap.y > 0?3:2)<< 14) | ( (uint16_t)(fabs(overlap.y)) ));
|
||||||
}
|
}
|
||||||
|
@ -144,21 +141,54 @@ static bool check_collision_and_move(EntityManager_t* p_manager, TileGrid_t* til
|
||||||
if (other_solid)
|
if (other_solid)
|
||||||
{
|
{
|
||||||
p_ct->position = Vector2Add(p_ct->position, offset);
|
p_ct->position = Vector2Add(p_ct->position, offset);
|
||||||
if (dir_to_move == 0)
|
|
||||||
//if (offset.x != 0)
|
|
||||||
{
|
|
||||||
p_ct->velocity.x = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_ct->velocity.y = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t check_bbox_edges(
|
||||||
|
EntityManager_t* p_manager, TileGrid_t* tilemap,
|
||||||
|
unsigned int ent_idx, Vector2 pos, Vector2 bbox
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint8_t detected = 0;
|
||||||
|
CollideEntity_t ent =
|
||||||
|
{
|
||||||
|
.idx = ent_idx,
|
||||||
|
.bbox = (Rectangle){pos.x - 1, pos.y, bbox.x, bbox.y},
|
||||||
|
.area = (TileArea_t){
|
||||||
|
.tile_x1 = (pos.x - 1) / TILE_SIZE,
|
||||||
|
.tile_y1 = (pos.y) / TILE_SIZE,
|
||||||
|
.tile_x2 = (pos.x - 1) / TILE_SIZE,
|
||||||
|
.tile_y2 = (pos.y + bbox.y - 1) / TILE_SIZE,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Left
|
||||||
|
detected |= (check_collision(&ent, tilemap, p_manager) ? 1 : 0) << 3;
|
||||||
|
|
||||||
|
//Right
|
||||||
|
ent.bbox.x += 2; // 2 to account for the previous subtraction
|
||||||
|
ent.area.tile_x1 = (pos.x + bbox.x) / TILE_SIZE;
|
||||||
|
ent.area.tile_x2 = ent.area.tile_x1;
|
||||||
|
detected |= (check_collision(&ent, tilemap, p_manager) ? 1 : 0) << 2;
|
||||||
|
|
||||||
|
// Up
|
||||||
|
ent.bbox.x -= 2;
|
||||||
|
ent.bbox.y--;
|
||||||
|
ent.area.tile_x1 = (pos.x) / TILE_SIZE,
|
||||||
|
ent.area.tile_x2 = (pos.x + bbox.x - 1) / TILE_SIZE,
|
||||||
|
ent.area.tile_y1 = (pos.y - 1) / TILE_SIZE,
|
||||||
|
ent.area.tile_y2 = ent.area.tile_y1;
|
||||||
|
detected |= (check_collision(&ent, tilemap, p_manager) ? 1 : 0) << 1;
|
||||||
|
|
||||||
|
// Down
|
||||||
|
ent.bbox.y += 2;
|
||||||
|
ent.area.tile_y1 = (pos.y + bbox.y) / TILE_SIZE,
|
||||||
|
ent.area.tile_y2 = ent.area.tile_y1;
|
||||||
|
detected |= (check_collision(&ent, tilemap, p_manager) ? 1 : 0);
|
||||||
|
return detected;
|
||||||
|
}
|
||||||
|
|
||||||
static Vector2 shift_bbox(Vector2 bbox, Vector2 new_bbox, AnchorPoint_t anchor)
|
static Vector2 shift_bbox(Vector2 bbox, Vector2 new_bbox, AnchorPoint_t anchor)
|
||||||
{
|
{
|
||||||
|
@ -258,6 +288,10 @@ void player_movement_input_system(Scene_t* scene)
|
||||||
p_ctransform->accel = Vector2Scale(Vector2Normalize(p_pstate->player_dir), MOVE_ACCEL/1.2);
|
p_ctransform->accel = Vector2Scale(Vector2Normalize(p_pstate->player_dir), MOVE_ACCEL/1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_pstate->is_crouch & 1)
|
||||||
|
{
|
||||||
|
p_ctransform->accel = Vector2Scale(p_ctransform->accel, 0.5);
|
||||||
|
}
|
||||||
// Short Hop
|
// Short Hop
|
||||||
// Jumped check is needed to make sure it is applied on jumps, not generally
|
// Jumped check is needed to make sure it is applied on jumps, not generally
|
||||||
// One issue caused is lower velocity in water
|
// One issue caused is lower velocity in water
|
||||||
|
@ -300,11 +334,11 @@ void player_movement_input_system(Scene_t* scene)
|
||||||
p_cjump->jumps--;
|
p_cjump->jumps--;
|
||||||
if (!in_water)
|
if (!in_water)
|
||||||
{
|
{
|
||||||
p_ctransform->velocity.y -= p_cjump->jump_speed;
|
p_ctransform->velocity.y = -p_cjump->jump_speed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p_ctransform->velocity.y -= p_cjump->jump_speed / 1.75;
|
p_ctransform->velocity.y = -p_cjump->jump_speed / 1.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_cjump->jumped = true;
|
p_cjump->jumped = true;
|
||||||
|
@ -442,6 +476,25 @@ void tile_collision_system(Scene_t *scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Post movement edge check to zero out velocity
|
||||||
|
uint8_t edges = check_bbox_edges(&scene->ent_manager, &data->tilemap, ent_idx, p_ctransform->position, p_bbox->size);
|
||||||
|
if (edges & (1<<3))
|
||||||
|
{
|
||||||
|
if (p_ctransform->velocity.x < 0) p_ctransform->velocity.x = 0;
|
||||||
|
}
|
||||||
|
if (edges & (1<<2))
|
||||||
|
{
|
||||||
|
if (p_ctransform->velocity.x > 0) p_ctransform->velocity.x = 0;
|
||||||
|
}
|
||||||
|
if (edges & (1<<1))
|
||||||
|
{
|
||||||
|
if (p_ctransform->velocity.y < 0) p_ctransform->velocity.y = 0;
|
||||||
|
}
|
||||||
|
if (edges & (1))
|
||||||
|
{
|
||||||
|
if (p_ctransform->velocity.y > 0) p_ctransform->velocity.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Resolve all collision events
|
// TODO: Resolve all collision events
|
||||||
//uint32_t collision_key;
|
//uint32_t collision_key;
|
||||||
//sc_map_foreach(&data->collision_events, collision_key, collision_value)
|
//sc_map_foreach(&data->collision_events, collision_key, collision_value)
|
||||||
|
@ -496,6 +549,40 @@ void tile_collision_system(Scene_t *scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void friction_coefficient_update_system(Scene_t *scene)
|
||||||
|
{
|
||||||
|
CTransform_t* p_ct;
|
||||||
|
unsigned long ent_idx;
|
||||||
|
sc_map_foreach(&scene->ent_manager.component_map[CTRANSFORM_COMP_T], ent_idx, p_ct)
|
||||||
|
{
|
||||||
|
Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx);
|
||||||
|
CMovementState_t* p_mstate = get_component(&scene->ent_manager, p_ent, CMOVEMENTSTATE_T);
|
||||||
|
|
||||||
|
|
||||||
|
// Friction
|
||||||
|
if (p_mstate->water_state & 1)
|
||||||
|
{
|
||||||
|
// Apply water friction
|
||||||
|
// Consistent in all direction
|
||||||
|
p_ct->fric_coeff = (Vector2){-5.5, -5.5};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For game feel, y is set to air resistance only
|
||||||
|
// x is set to ground resistance (even in air)
|
||||||
|
// If not, then player is can go faster by bunny hopping
|
||||||
|
// which is fun but not quite beneficial here
|
||||||
|
p_ct->fric_coeff = (Vector2){-3.3, -1};
|
||||||
|
}
|
||||||
|
|
||||||
|
CPlayerState_t* p_pstate = get_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T);
|
||||||
|
if (p_pstate != NULL && (p_pstate->is_crouch & 1))
|
||||||
|
{
|
||||||
|
p_ct->fric_coeff.x -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void global_external_forces_system(Scene_t *scene)
|
void global_external_forces_system(Scene_t *scene)
|
||||||
{
|
{
|
||||||
LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data;
|
LevelSceneData_t *data = (LevelSceneData_t *)scene->scene_data;
|
||||||
|
@ -525,59 +612,32 @@ void global_external_forces_system(Scene_t *scene)
|
||||||
}
|
}
|
||||||
p_ctransform->accel = Vector2Add(p_ctransform->accel, GRAVITY);
|
p_ctransform->accel = Vector2Add(p_ctransform->accel, GRAVITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Friction
|
// Friction
|
||||||
if (p_mstate->water_state & 1)
|
|
||||||
{
|
|
||||||
// Apply water friction
|
|
||||||
// Consistent in all direction
|
|
||||||
p_ctransform->accel = Vector2Add(
|
p_ctransform->accel = Vector2Add(
|
||||||
p_ctransform->accel,
|
p_ctransform->accel,
|
||||||
Vector2Scale(p_ctransform->velocity, -5.5)
|
Vector2Multiply(p_ctransform->fric_coeff, p_ctransform->velocity)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// For game feel, y is set to air resistance only
|
|
||||||
// x is set to ground resistance (even in air)
|
|
||||||
// If not, then player is can go faster by bunny hopping
|
|
||||||
// which is fun but not quite beneficial here
|
|
||||||
p_ctransform->accel.x += p_ctransform->velocity.x * -3.3;
|
|
||||||
p_ctransform->accel.y += p_ctransform->velocity.y * -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Zero out acceleration for contacts with sturdy entites and tiles
|
// Zero out acceleration for contacts with sturdy entites and tiles
|
||||||
//Vector2 new_pos = p_ctransform->position;
|
uint8_t edges = check_bbox_edges(&scene->ent_manager, &data->tilemap, ent_idx, p_ctransform->position, p_bbox->size);
|
||||||
CollideEntity_t ent =
|
if (edges & (1<<3))
|
||||||
{
|
{
|
||||||
.idx = ent_idx,
|
if (p_ctransform->accel.x < 0) p_ctransform->accel.x = 0;
|
||||||
.bbox = (Rectangle){p_ctransform->position.x - 1, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
|
}
|
||||||
.area = (TileArea_t){
|
if (edges & (1<<2))
|
||||||
.tile_x1 = (p_ctransform->position.x - 1) / TILE_SIZE,
|
{
|
||||||
.tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
|
if (p_ctransform->accel.x > 0) p_ctransform->accel.x = 0;
|
||||||
.tile_x2 = (p_ctransform->position.x - 1) / TILE_SIZE,
|
}
|
||||||
.tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
|
if (edges & (1<<1))
|
||||||
|
{
|
||||||
|
if (p_ctransform->accel.y < 0) p_ctransform->accel.y = 0;
|
||||||
|
}
|
||||||
|
if (edges & (1))
|
||||||
|
{
|
||||||
|
if (p_ctransform->accel.y > 0) p_ctransform->accel.y = 0;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if (check_collision(&ent, &data->tilemap, &scene->ent_manager) && p_ctransform->accel.x < 0) p_ctransform->accel.x = 0;
|
|
||||||
|
|
||||||
ent.bbox.x += 2; // 2 to account for the previous subtraction
|
|
||||||
ent.area.tile_x1 = (p_ctransform->position.x + p_bbox->size.x + 1) / TILE_SIZE;
|
|
||||||
ent.area.tile_x2 = ent.area.tile_x1;
|
|
||||||
if (check_collision(&ent, &data->tilemap, &scene->ent_manager) && p_ctransform->accel.x > 0) p_ctransform->accel.x = 0;
|
|
||||||
|
|
||||||
ent.bbox.x -= 2;
|
|
||||||
ent.bbox.y--;
|
|
||||||
ent.area.tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
|
|
||||||
ent.area.tile_x2 = (p_ctransform->position.x - 1) / TILE_SIZE,
|
|
||||||
ent.area.tile_y1 = (p_ctransform->position.y - 1) / TILE_SIZE,
|
|
||||||
ent.area.tile_y1 = ent.area.tile_y2;
|
|
||||||
if (check_collision(&ent, &data->tilemap, &scene->ent_manager) && p_ctransform->accel.y < 0) p_ctransform->accel.y = 0;
|
|
||||||
|
|
||||||
ent.bbox.y += 2;
|
|
||||||
ent.area.tile_y1 = (p_ctransform->position.y + p_bbox->size.y + 1) / TILE_SIZE,
|
|
||||||
ent.area.tile_y1 = ent.area.tile_y2;
|
|
||||||
if (check_collision(&ent, &data->tilemap, &scene->ent_manager) && p_ctransform->accel.y > 0) p_ctransform->accel.y = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ void term_level_scene_data(LevelSceneData_t *data);
|
||||||
void player_movement_input_system(Scene_t* scene);
|
void player_movement_input_system(Scene_t* scene);
|
||||||
void player_bbox_update_system(Scene_t *scene);
|
void player_bbox_update_system(Scene_t *scene);
|
||||||
void tile_collision_system(Scene_t *scene);
|
void tile_collision_system(Scene_t *scene);
|
||||||
|
void friction_coefficient_update_system(Scene_t *scene);
|
||||||
void global_external_forces_system(Scene_t *scene);
|
void global_external_forces_system(Scene_t *scene);
|
||||||
void movement_update_system(Scene_t* scene);
|
void movement_update_system(Scene_t* scene);
|
||||||
void player_ground_air_transition_system(Scene_t* scene);
|
void player_ground_air_transition_system(Scene_t* scene);
|
||||||
|
|
Loading…
Reference in New Issue