From 62069b31c7d23055f999c70a58ccf7d58acd333f Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 20 Dec 2018 18:57:23 -0500 Subject: Added target velocity The acceleration of a Ponderable entity is now only really a magnitude. The direction of acceleration is such that the velocity goes toward the target velocity. If accelerating would cause the velocity to pass the target velocity, it is instead set to the target. This is currently being used to 1) generalize terminal velocity due to gravity, and 2) allow an Orientable entity to accelerate quickly to a walking speed (and to a halt) rather than instantly achieve it. --- src/components/ponderable.h | 5 +++++ src/systems/orienting.cpp | 32 ++++++++---------------------- src/systems/playing.cpp | 5 +++++ src/systems/pondering.cpp | 47 +++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/components/ponderable.h b/src/components/ponderable.h index 221d267..cc42048 100644 --- a/src/components/ponderable.h +++ b/src/components/ponderable.h @@ -55,6 +55,11 @@ public: */ vec2d accel = { 0.0, 0.0 }; + /** + * The target velocity of the body. + */ + vec2d targetVel = { 0.0, 0.0 }; + /** * The type of physical body that the entity is meant to assume. The body will * be acted upon differently based on this. See the enumeration above for more diff --git a/src/systems/orienting.cpp b/src/systems/orienting.cpp index d73ddd2..a2be34f 100644 --- a/src/systems/orienting.cpp +++ b/src/systems/orienting.cpp @@ -20,30 +20,6 @@ void OrientingSystem::tick(double) auto& ponderable = game_.getEntityManager(). getComponent(entity); - switch (orientable.getWalkState()) - { - case OrientableComponent::WalkState::still: - { - ponderable.vel.x() = 0.0; - - break; - } - - case OrientableComponent::WalkState::left: - { - ponderable.vel.x() = -WALK_SPEED; - - break; - } - - case OrientableComponent::WalkState::right: - { - ponderable.vel.x() = WALK_SPEED; - - break; - } - } - if (orientable.isJumping() && (ponderable.vel.y() > 0)) { orientable.setJumping(false); @@ -62,6 +38,8 @@ void OrientingSystem::moveLeft(id_type entity) orientable.setFacingRight(false); orientable.setWalkState(OrientableComponent::WalkState::left); + ponderable.targetVel.x() = -WALK_SPEED; + auto& animating = game_.getSystemManager().getSystem(); if (ponderable.grounded) { @@ -82,6 +60,8 @@ void OrientingSystem::moveRight(id_type entity) orientable.setFacingRight(true); orientable.setWalkState(OrientableComponent::WalkState::right); + ponderable.targetVel.x() = WALK_SPEED; + auto& animating = game_.getSystemManager().getSystem(); if (ponderable.grounded) { @@ -93,10 +73,14 @@ void OrientingSystem::moveRight(id_type entity) void OrientingSystem::stopWalking(id_type entity) { + auto& ponderable = game_.getEntityManager(). + getComponent(entity); + auto& orientable = game_.getEntityManager(). getComponent(entity); orientable.setWalkState(OrientableComponent::WalkState::still); + ponderable.targetVel.x() = 0; auto& animating = game_.getSystemManager().getSystem(); diff --git a/src/systems/playing.cpp b/src/systems/playing.cpp index 6652099..83f65d6 100644 --- a/src/systems/playing.cpp +++ b/src/systems/playing.cpp @@ -5,6 +5,7 @@ #include "components/playable.h" #include "components/controllable.h" #include "components/orientable.h" +#include "components/ponderable.h" #include "systems/mapping.h" #include "systems/pondering.h" #include "systems/orienting.h" @@ -46,6 +47,10 @@ void PlayingSystem::initPlayer() player, PonderableComponent::Type::freefalling); + auto& ponderable = game_.getEntityManager(). + getComponent(player); + ponderable.accel.x() = 720; + game_.getEntityManager().emplaceComponent(player); game_.getEntityManager().emplaceComponent(player); diff --git a/src/systems/pondering.cpp b/src/systems/pondering.cpp index d841679..649a03a 100644 --- a/src/systems/pondering.cpp +++ b/src/systems/pondering.cpp @@ -44,6 +44,7 @@ void PonderingSystem::initializeBody( if (type == PonderableComponent::Type::freefalling) { + ponderable.targetVel.y() = TERMINAL_VELOCITY; ponderable.accel.y() = NORMAL_GRAVITY; } } @@ -57,6 +58,8 @@ void PonderingSystem::initPrototype(id_type prototype) ponderable.vel.y() = 0.0; ponderable.accel.x() = 0.0; ponderable.accel.y() = 0.0; + ponderable.targetVel.x() = 0.0; + ponderable.targetVel.y() = 0.0; ponderable.grounded = false; ponderable.frozen = false; ponderable.collidable = true; @@ -98,12 +101,48 @@ void PonderingSystem::tickBody( // Accelerate if (!ponderable.frozen) { - ponderable.vel += ponderable.accel * dt; + // Determine the effective acceleration, which should be in the direction of + // the target velocity. + vec2d effAcc = ponderable.accel; - if ((ponderable.type == PonderableComponent::Type::freefalling) - && (ponderable.vel.y() > TERMINAL_VELOCITY)) + if (ponderable.vel.x() == ponderable.targetVel.x()) { - ponderable.vel.y() = TERMINAL_VELOCITY; + effAcc.x() = 0.0; + } + else if ((ponderable.accel.x() > 0 && + ponderable.targetVel.x() < ponderable.vel.x()) || + (ponderable.accel.x() < 0 && + ponderable.targetVel.x() > ponderable.vel.x())) + { + effAcc.x() = -effAcc.x(); + } + + if (ponderable.vel.y() == ponderable.targetVel.y()) + { + effAcc.y() = 0.0; + } + else if ((ponderable.accel.y() > 0 && + ponderable.targetVel.y() < ponderable.vel.y()) || + (ponderable.accel.y() < 0 && + ponderable.targetVel.y() > ponderable.vel.y())) + { + effAcc.y() = -effAcc.y(); + } + + // Accelerate + ponderable.vel += effAcc * dt; + + // If the velocity crossed the target velocity, set it to the target + if ((effAcc.x() > 0 && ponderable.vel.x() > ponderable.targetVel.x()) || + (effAcc.x() < 0 && ponderable.vel.x() < ponderable.targetVel.x())) + { + ponderable.vel.x() = ponderable.targetVel.x(); + } + + if ((effAcc.y() > 0 && ponderable.vel.y() > ponderable.targetVel.y()) || + (effAcc.y() < 0 && ponderable.vel.y() < ponderable.targetVel.y())) + { + ponderable.vel.y() = ponderable.targetVel.y(); } } -- cgit 1.4.1