Compare commits

..

No commits in common. "ddcb71ed5026b60ec35c70dab92e07733dea4c1c" and "8d9494354704a099997a401bebeb3bcb73fa1e65" have entirely different histories.

4 changed files with 62 additions and 125 deletions

View File

@ -34,7 +34,6 @@ 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

View File

@ -319,7 +319,6 @@ 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);

View File

@ -113,6 +113,7 @@ 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))
{ {
@ -121,6 +122,7 @@ 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)) ));
} }
@ -131,6 +133,7 @@ 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)) ));
} }
@ -141,54 +144,21 @@ 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)
{ {
@ -288,10 +258,6 @@ 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
@ -334,11 +300,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;
@ -476,25 +442,6 @@ 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)
@ -549,40 +496,6 @@ 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;
@ -612,32 +525,59 @@ 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
p_ctransform->accel = Vector2Add( if (p_mstate->water_state & 1)
p_ctransform->accel, {
Vector2Multiply(p_ctransform->fric_coeff, p_ctransform->velocity) // Apply water friction
); // Consistent in all direction
p_ctransform->accel = Vector2Add(
p_ctransform->accel,
Vector2Scale(p_ctransform->velocity, -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_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
uint8_t edges = check_bbox_edges(&scene->ent_manager, &data->tilemap, ent_idx, p_ctransform->position, p_bbox->size); //Vector2 new_pos = p_ctransform->position;
if (edges & (1<<3)) CollideEntity_t ent =
{ {
if (p_ctransform->accel.x < 0) p_ctransform->accel.x = 0; .idx = ent_idx,
} .bbox = (Rectangle){p_ctransform->position.x - 1, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
if (edges & (1<<2)) .area = (TileArea_t){
{ .tile_x1 = (p_ctransform->position.x - 1) / TILE_SIZE,
if (p_ctransform->accel.x > 0) p_ctransform->accel.x = 0; .tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
} .tile_x2 = (p_ctransform->position.x - 1) / TILE_SIZE,
if (edges & (1<<1)) .tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
{ }
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;
if (edges & (1))
{ ent.bbox.x += 2; // 2 to account for the previous subtraction
if (p_ctransform->accel.y > 0) p_ctransform->accel.y = 0; 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;
} }
} }

View File

@ -7,7 +7,6 @@ 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);