Polish kinematic movement
This commit is contained in:
@@ -32,7 +32,7 @@ ECS_TAG_DECLARE(Selectable);
|
|||||||
ECS_TAG_DECLARE(Selected);
|
ECS_TAG_DECLARE(Selected);
|
||||||
|
|
||||||
ECS_COMPONENT_DECLARE(Worker);
|
ECS_COMPONENT_DECLARE(Worker);
|
||||||
ECS_TAG_DECLARE(Unit);
|
ECS_COMPONENT_DECLARE(Unit);
|
||||||
ECS_TAG_DECLARE(Storage);
|
ECS_TAG_DECLARE(Storage);
|
||||||
ECS_TAG_DECLARE(Harvestable);
|
ECS_TAG_DECLARE(Harvestable);
|
||||||
ECS_TAG_DECLARE(Buildable);
|
ECS_TAG_DECLARE(Buildable);
|
||||||
@@ -69,7 +69,7 @@ void initComponentIDs(ecs_world_t *ecs) {
|
|||||||
ECS_TAG_DEFINE(ecs, Selected);
|
ECS_TAG_DEFINE(ecs, Selected);
|
||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, Worker);
|
ECS_COMPONENT_DEFINE(ecs, Worker);
|
||||||
ECS_TAG_DEFINE(ecs, Unit);
|
ECS_COMPONENT_DEFINE(ecs, Unit);
|
||||||
ECS_TAG_DEFINE(ecs, Storage);
|
ECS_TAG_DEFINE(ecs, Storage);
|
||||||
ECS_TAG_DEFINE(ecs, Harvestable);
|
ECS_TAG_DEFINE(ecs, Harvestable);
|
||||||
ECS_TAG_DEFINE(ecs, Buildable);
|
ECS_TAG_DEFINE(ecs, Buildable);
|
||||||
|
|||||||
@@ -191,7 +191,12 @@ extern ECS_COMPONENT_DECLARE(Worker);
|
|||||||
|
|
||||||
// Unit can:
|
// Unit can:
|
||||||
// - Attack
|
// - 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(Storage);
|
||||||
extern ECS_TAG_DECLARE(Harvestable);
|
extern ECS_TAG_DECLARE(Harvestable);
|
||||||
extern ECS_TAG_DECLARE(Buildable);
|
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_set(ECS, e, UnitAction, { NULL, NULL });
|
||||||
ecs_add_id(ECS, e, Selectable);
|
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, {
|
ecs_set(ECS, e, Worker, {
|
||||||
.collectSpeed = 0.8f,
|
.collectSpeed = 0.8f,
|
||||||
.depositSpeed = 0.2f,
|
.depositSpeed = 0.2f,
|
||||||
|
|||||||
@@ -61,67 +61,54 @@ void entityUpdateSpatialID(ecs_iter_t *it) {
|
|||||||
|
|
||||||
void entityUpdateKinematic(ecs_iter_t *it) {
|
void entityUpdateKinematic(ecs_iter_t *it) {
|
||||||
Position *position = ecs_field(it, Position, 1);
|
Position *position = ecs_field(it, Position, 1);
|
||||||
Rotation *rotation = ecs_field(it, Rotation, 2);
|
Velocity *velocity = ecs_field(it, Velocity, 2);
|
||||||
Velocity *velocity = ecs_field(it, Velocity, 3);
|
Steering *steering = ecs_field(it, Steering, 3);
|
||||||
Steering *steering = ecs_field(it, Steering, 4);
|
Unit *unit = ecs_field(it, Unit, 4);
|
||||||
|
|
||||||
f32 dt = it->delta_time;
|
f32 dt = it->delta_time;
|
||||||
|
|
||||||
for (i32 i = 0; i < it->count; i++) {
|
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
|
steering[i] = Vector2Normalize(steering[i]);
|
||||||
// velocity += steering.liner * dt
|
// velocity += steering * dt
|
||||||
velocity[i] = Vector2Add(velocity[i], Vector2Scale(steering[i], dt * 10));
|
Vector2 accel = Vector2Scale(steering[i], dt);
|
||||||
|
accel = Vector2Scale(accel, unit->acceleration);
|
||||||
|
velocity[i] = Vector2Add(velocity[i], accel);
|
||||||
|
|
||||||
|
// Apply deceleration
|
||||||
if (Vector2LengthSqr(steering[i]) == 0) {
|
if (Vector2LengthSqr(steering[i]) == 0) {
|
||||||
// Decay velocity
|
// velocity *= (1.0 - decel)
|
||||||
velocity[i] = Vector2Scale(velocity[i], 1 - (dt * 5.0f));
|
velocity[i] = Vector2Scale(velocity[i], 1.0 - unit->deceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset steering
|
// Reset steering
|
||||||
steering[i] = Vector2Zero();
|
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
|
// Check for speeding and clip
|
||||||
const f32 maxSpeed = 15.0f;
|
const f32 maxSpeed = unit->maxSpeed;
|
||||||
if (Vector2Length(velocity[i]) > maxSpeed) {
|
if (Vector2Length(velocity[i]) > maxSpeed) {
|
||||||
velocity[i] = Vector2Normalize(velocity[i]);
|
velocity[i] = Vector2Normalize(velocity[i]);
|
||||||
velocity[i] = Vector2Scale(velocity[i], maxSpeed);
|
velocity[i] = Vector2Scale(velocity[i], maxSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// position += velocity * dt
|
||||||
|
position[i] = Vector2Add(position[i], Vector2Scale(velocity[i], dt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void entityMoveToTarget(ecs_iter_t *it) {
|
void entityMoveToTarget(ecs_iter_t *it) {
|
||||||
Position *position = ecs_field(it, Position, 1);
|
Position *position = ecs_field(it, Position, 1);
|
||||||
Rotation *rotation = ecs_field(it, Rotation, 2);
|
Velocity *velocity = ecs_field(it, Velocity, 2);
|
||||||
Velocity *velocity = ecs_field(it, Velocity, 3);
|
|
||||||
|
|
||||||
TargetPosition *targetPos = ecs_field(it, TargetPosition, 4);
|
TargetPosition *targetPos = ecs_field(it, TargetPosition, 3);
|
||||||
Steering *steering = ecs_field(it, Steering, 5);
|
Steering *steering = ecs_field(it, Steering, 4);
|
||||||
|
|
||||||
for (i32 i = 0; i < it->count; i++) {
|
for (i32 i = 0; i < it->count; i++) {
|
||||||
Position target = targetPos[i];
|
Position target = targetPos[i];
|
||||||
steering[i] = Vector2Subtract(target, position[i]);
|
steering[i] = Vector2Subtract(target, position[i]);
|
||||||
f32 dst = Vector2LengthSqr(steering[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) {
|
if (dst < 2.0f) {
|
||||||
f32 rot = Vector2Angle(position[i], target);
|
|
||||||
//rotation[i] = rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst < 8.0f) {
|
|
||||||
// Arrived
|
// Arrived
|
||||||
ecs_remove(ECS, it->entities[i], TargetPosition);
|
ecs_remove(ECS, it->entities[i], TargetPosition);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void inputPrimaryAction(Game *game, InputState *input) {
|
|||||||
resetInputState(input);
|
resetInputState(input);
|
||||||
input->state = INPUT_SELECTED_UNITS;
|
input->state = INPUT_SELECTED_UNITS;
|
||||||
} else if (isInputBtnJustUp(input, primaryBtn)) {
|
} else if (isInputBtnJustUp(input, primaryBtn)) {
|
||||||
if (pickEntity(game->entityGrid, input->mouseDownWorld, Unit)) {
|
if (pickEntity(game->entityGrid, input->mouseDownWorld, ecs_id(Unit))) {
|
||||||
resetInputState(input);
|
resetInputState(input);
|
||||||
input->state = INPUT_SELECTED_UNITS;
|
input->state = INPUT_SELECTED_UNITS;
|
||||||
} else if (pickEntity(game->entityGrid, input->mouseDownWorld, Harvestable)) {
|
} 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);
|
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
||||||
while (bzSpatialGridQueryNext(&it)) {
|
while (bzSpatialGridQueryNext(&it)) {
|
||||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
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;
|
Rectangle bounds;
|
||||||
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ void setupSystems() {
|
|||||||
ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path);
|
ECS_OBSERVER(ECS, entityPathRemove, EcsOnRemove, Path);
|
||||||
|
|
||||||
ECS_SYSTEM(ECS, entityUpdateSpatialID, EcsOnUpdate, Position, Size, Velocity, SpatialGridID);
|
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, entityFollowPath, EcsOnUpdate, Path);
|
||||||
|
|
||||||
ECS_SYSTEM(ECS, handleUnitActionsSystem, EcsOnUpdate, UnitAction);
|
ECS_SYSTEM(ECS, handleUnitActionsSystem, EcsOnUpdate, UnitAction);
|
||||||
|
|||||||
@@ -81,18 +81,17 @@ void entityUpdateSpatialID(ecs_iter_t *it);
|
|||||||
/*
|
/*
|
||||||
* 0: Game (singleton) for collisions
|
* 0: Game (singleton) for collisions
|
||||||
* 1: Position
|
* 1: Position
|
||||||
* 2: Rotation
|
* 2: Velocity
|
||||||
* 3: Velocity
|
* 3: Steering
|
||||||
* 4: Steering
|
* 4: Unit
|
||||||
*/
|
*/
|
||||||
void entityUpdateKinematic(ecs_iter_t *it);
|
void entityUpdateKinematic(ecs_iter_t *it);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1: Position
|
* 1: Position
|
||||||
* 2: Rotation
|
* 2: Velocity
|
||||||
* 3: Velocity
|
* 3: TargetPosition
|
||||||
* 4: TargetPosition
|
* 4: Steering
|
||||||
* 5: Steering
|
|
||||||
*/
|
*/
|
||||||
void entityMoveToTarget(ecs_iter_t *it);
|
void entityMoveToTarget(ecs_iter_t *it);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user