Polish kinematic movement

This commit is contained in:
2024-01-04 17:18:31 +01:00
parent c0b94a9cc3
commit 3c18280a32
7 changed files with 43 additions and 48 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);