From 3c18280a322bdcb024abed4e5916623a28654b1b Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Thu, 4 Jan 2024 17:18:31 +0100 Subject: [PATCH] Polish kinematic movement --- game/components.c | 4 ++-- game/components.h | 7 +++++- game/entity_factory.c | 6 ++++- game/systems/s_entity.c | 53 ++++++++++++++++------------------------- game/systems/s_input.c | 4 ++-- game/systems/systems.c | 4 ++-- game/systems/systems.h | 13 +++++----- 7 files changed, 43 insertions(+), 48 deletions(-) diff --git a/game/components.c b/game/components.c index be2786c..7136898 100644 --- a/game/components.c +++ b/game/components.c @@ -32,7 +32,7 @@ ECS_TAG_DECLARE(Selectable); ECS_TAG_DECLARE(Selected); ECS_COMPONENT_DECLARE(Worker); -ECS_TAG_DECLARE(Unit); +ECS_COMPONENT_DECLARE(Unit); ECS_TAG_DECLARE(Storage); ECS_TAG_DECLARE(Harvestable); ECS_TAG_DECLARE(Buildable); @@ -69,7 +69,7 @@ void initComponentIDs(ecs_world_t *ecs) { ECS_TAG_DEFINE(ecs, Selected); ECS_COMPONENT_DEFINE(ecs, Worker); - ECS_TAG_DEFINE(ecs, Unit); + ECS_COMPONENT_DEFINE(ecs, Unit); ECS_TAG_DEFINE(ecs, Storage); ECS_TAG_DEFINE(ecs, Harvestable); ECS_TAG_DEFINE(ecs, Buildable); diff --git a/game/components.h b/game/components.h index 31e1238..efed150 100644 --- a/game/components.h +++ b/game/components.h @@ -191,7 +191,12 @@ extern ECS_COMPONENT_DECLARE(Worker); // Unit can: // - Attack -extern ECS_TAG_DECLARE(Unit); +typedef struct Unit { + f32 maxSpeed; + f32 acceleration; + f32 deceleration; +} Unit; +extern ECS_COMPONENT_DECLARE(Unit); extern ECS_TAG_DECLARE(Storage); extern ECS_TAG_DECLARE(Harvestable); extern ECS_TAG_DECLARE(Buildable); diff --git a/game/entity_factory.c b/game/entity_factory.c index 00462c0..7be0052 100644 --- a/game/entity_factory.c +++ b/game/entity_factory.c @@ -36,7 +36,11 @@ ecs_entity_t entityCreateWorker(const Position position, Game *game) { }); ecs_set(ECS, e, UnitAction, { NULL, NULL }); ecs_add_id(ECS, e, Selectable); - ecs_add_id(ECS, e, Unit); + ecs_set(ECS, e, Unit, { + .acceleration = 80.0f, + .maxSpeed = 15.0f, + .deceleration = 0.1f + }); ecs_set(ECS, e, Worker, { .collectSpeed = 0.8f, .depositSpeed = 0.2f, diff --git a/game/systems/s_entity.c b/game/systems/s_entity.c index 3e8abc9..1d286d6 100644 --- a/game/systems/s_entity.c +++ b/game/systems/s_entity.c @@ -61,67 +61,54 @@ void entityUpdateSpatialID(ecs_iter_t *it) { void entityUpdateKinematic(ecs_iter_t *it) { Position *position = ecs_field(it, Position, 1); - Rotation *rotation = ecs_field(it, Rotation, 2); - Velocity *velocity = ecs_field(it, Velocity, 3); - Steering *steering = ecs_field(it, Steering, 4); + Velocity *velocity = ecs_field(it, Velocity, 2); + Steering *steering = ecs_field(it, Steering, 3); + Unit *unit = ecs_field(it, Unit, 4); f32 dt = it->delta_time; for (i32 i = 0; i < it->count; i++) { - // Update position and rotation - // position += velocity * dt - position[i] = Vector2Add(position[i], Vector2Scale(velocity[i], dt)); - // Update velocity and angular velocity - // velocity += steering.liner * dt - velocity[i] = Vector2Add(velocity[i], Vector2Scale(steering[i], dt * 10)); + steering[i] = Vector2Normalize(steering[i]); + // velocity += steering * dt + Vector2 accel = Vector2Scale(steering[i], dt); + accel = Vector2Scale(accel, unit->acceleration); + velocity[i] = Vector2Add(velocity[i], accel); + // Apply deceleration if (Vector2LengthSqr(steering[i]) == 0) { - // Decay velocity - velocity[i] = Vector2Scale(velocity[i], 1 - (dt * 5.0f)); + // velocity *= (1.0 - decel) + velocity[i] = Vector2Scale(velocity[i], 1.0 - unit->deceleration); } + // Reset steering steering[i] = Vector2Zero(); - { - const InputState *input = ecs_singleton_get(ECS, InputState); - - Vector2 mouse = input->mouseDownWorld; - f32 rot = Vector2Angle(position[i], mouse) + 270 * DEG2RAD; - //rotation[i] = rot; - } - // Check for speeding and clip - const f32 maxSpeed = 15.0f; + const f32 maxSpeed = unit->maxSpeed; if (Vector2Length(velocity[i]) > maxSpeed) { velocity[i] = Vector2Normalize(velocity[i]); velocity[i] = Vector2Scale(velocity[i], maxSpeed); } + + // position += velocity * dt + position[i] = Vector2Add(position[i], Vector2Scale(velocity[i], dt)); } } void entityMoveToTarget(ecs_iter_t *it) { Position *position = ecs_field(it, Position, 1); - Rotation *rotation = ecs_field(it, Rotation, 2); - Velocity *velocity = ecs_field(it, Velocity, 3); + Velocity *velocity = ecs_field(it, Velocity, 2); - TargetPosition *targetPos = ecs_field(it, TargetPosition, 4); - Steering *steering = ecs_field(it, Steering, 5); + TargetPosition *targetPos = ecs_field(it, TargetPosition, 3); + Steering *steering = ecs_field(it, Steering, 4); for (i32 i = 0; i < it->count; i++) { Position target = targetPos[i]; steering[i] = Vector2Subtract(target, position[i]); f32 dst = Vector2LengthSqr(steering[i]); - f32 maxAccel = 10.0f; - steering[i] = Vector2Normalize(steering[i]); - steering[i] = Vector2Scale(steering[i], maxAccel); - if (Vector2Length(velocity[i]) > 10.0f) { - f32 rot = Vector2Angle(position[i], target); - //rotation[i] = rot; - } - - if (dst < 8.0f) { + if (dst < 2.0f) { // Arrived ecs_remove(ECS, it->entities[i], TargetPosition); } diff --git a/game/systems/s_input.c b/game/systems/s_input.c index 2e3957a..ab34b55 100644 --- a/game/systems/s_input.c +++ b/game/systems/s_input.c @@ -53,7 +53,7 @@ void inputPrimaryAction(Game *game, InputState *input) { resetInputState(input); input->state = INPUT_SELECTED_UNITS; } else if (isInputBtnJustUp(input, primaryBtn)) { - if (pickEntity(game->entityGrid, input->mouseDownWorld, Unit)) { + if (pickEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Unit))) { resetInputState(input); input->state = INPUT_SELECTED_UNITS; } else if (pickEntity(game->entityGrid, input->mouseDownWorld, Harvestable)) { @@ -432,7 +432,7 @@ void pickUnits(BzSpatialGrid *entityGrid, Rectangle area) { BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height); while (bzSpatialGridQueryNext(&it)) { ecs_entity_t entity = *(ecs_entity_t *) it.data; - if (!ecs_has_id(ECS, entity, Unit)) continue; + if (!ecs_has_id(ECS, entity, ecs_id(Unit))) continue; Rectangle bounds; if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue; diff --git a/game/systems/systems.c b/game/systems/systems.c index dd1d3fb..b32f39f 100644 --- a/game/systems/systems.c +++ b/game/systems/systems.c @@ -39,9 +39,9 @@ void setupSystems() { ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path); ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID); - ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Rotation, Velocity, Steering); + ECS_SYSTEM(ECS, entityUpdateKinematic, EcsOnUpdate, Position, Velocity, Steering, Unit); - ECS_SYSTEM(ECS, entityMoveToTarget, EcsOnUpdate, Position, Rotation, Velocity, TargetPosition, Steering); + ECS_SYSTEM(ECS, entityMoveToTarget, EcsOnUpdate, Position, Velocity, TargetPosition, Steering); ECS_SYSTEM(ECS, entityFollowPath, EcsOnUpdate, Path); ECS_SYSTEM(ECS, handleUnitActionsSystem, EcsOnUpdate, UnitAction); diff --git a/game/systems/systems.h b/game/systems/systems.h index fbdd0ac..432f2ac 100644 --- a/game/systems/systems.h +++ b/game/systems/systems.h @@ -81,18 +81,17 @@ void entityUpdateSpatialID(ecs_iter_t *it); /* * 0: Game (singleton) for collisions * 1: Position - * 2: Rotation - * 3: Velocity - * 4: Steering + * 2: Velocity + * 3: Steering + * 4: Unit */ void entityUpdateKinematic(ecs_iter_t *it); /* * 1: Position - * 2: Rotation - * 3: Velocity - * 4: TargetPosition - * 5: Steering + * 2: Velocity + * 3: TargetPosition + * 4: Steering */ void entityMoveToTarget(ecs_iter_t *it);