Polish kinematic movement
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user