Smoother movement

Interpolation & Extrapolation still todo.
This commit is contained in:
2025-01-15 02:11:27 -05:00
parent d26237762e
commit a86ac432fb
8 changed files with 271 additions and 61 deletions

View File

@@ -43,6 +43,7 @@ public:
[[nodiscard]] bool ShouldTick() const;
[[nodiscard]] float TickDeltaTime() const;
[[nodiscard]] float FrameDeltaTime() const;
[[nodiscard]] u8 GetTickRate() const;
/// @returns the number of microseconds since Jan 1st 1970 that the last tick was finished on.
[[nodiscard]] unsigned long LastTickTime() const;
public:

View File

@@ -7,28 +7,126 @@ namespace Engine {
}
// Movable Object.
// TODO currently assumes no mass.
class Engine::Movable {
protected:
// Assuming 0 radians is up.
float face_angle = 0.0f;
private:
float previous_decay = 0;
float previous_velocity = 0;
float previous_heading = 0;
float previous_face_angle = 0;
float previous_constant_force_heading = 0;
float previous_constant_force_velocity = 0;
float previous_friction = 0;
Vector2 previous_position = Vector2::Zero;
[[nodiscard]] inline float NormalizeRadians(float radians) const;
private:
float decay = 0;
float velocity = 0;
float heading = 0;
//float heading_rotational_velocity = 0;
//float heading_rotational_velocity_decay = 0;
float face_angle = 0;
//float face_angle_rotational_velocity = 0;
//float face_angle_rotational_velocity_decay = 0;
float constant_force_heading = 0;
float constant_force_velocity = 0;
float friction = 0;
Vector2 position = {0, 0};
public:
// Movements independent of the face_angle.
void MoveX(float speed);
void MoveY(float speed);
void Move(float angle_rad, float speed);
protected:
/// Instantly changes the direction of travel.
/// @note Radians, Zero is interpreted as to the right.
void SetHeading(float heading_rad);
// Movements dependent on face angle.
void MoveForward(float speed);
void MoveBackward(float speed);
void MoveLeft(float speed);
void MoveRight(float speed);
/** Instantly changes the heading of a constant force to be applied
* to this movable after everything else, Like gravity. */
/// @note Radians, Zero is interpreted as to the right.
void SetConstantForceHeading(float heading_rad);
void Rotate(float speed);
void SetRotation(float new_rotation);
/// Instantly changes the amount constant velocity For ex, Gravity.
void SetConstantForce(float new_velocity);
/// Instantly changes the rate at which this object naturally shows down.
/// @note 0 never loses speed, 1 loses speed at the beginning of the next tick.
void SetDecay(float new_decay);
/// Instantly changes the amount of velocity.
void SetVelocity(float new_velocity);
/// Instantly changes the amount of friction
/// @note Zero is no friction. 1 is full friction.
void SetFriction(float new_friction);
/// Instantly move from the current position to a new position.
/// @param reset Whether the other values should be preserved.
void SetPosition(const Vector2& new_position, bool reset = false);
void SetVisualRotation(float rad_rotation);
public:
[[nodiscard]] float GetRotation() const;
/// @returns The direction of travel in radians.
/// @note Radians, Zero is interpreted as to the right.
[[nodiscard]] float GetHeading() const;
/// @returns The rate at which this object will naturally slow down.
/// @note 0 never loses speed, 1 loses speed on the next update.
[[nodiscard]] float GetDecay() const;
/// @returns The current velocity / speed.
[[nodiscard]] float GetVelocity() const;
/// @returns The current friction.
/// @note Zero is no friction. 1 is full friction.
[[nodiscard]] float GetFriction() const;
/// @returns The current position.
[[nodiscard]] Vector2 GetPosition() const;
/// @returns The direction of travel the constant force will move this object in.
/// @note Radians, Zero is interpreted as to the right.
[[nodiscard]] float GetConstantForceHeading() const;
/// @returns The current velocity / speed.
[[nodiscard]] float GetConstantForceVelocity() const;
/// @returns The direction we're *visually* facing.
/// @note Radians, Zero is interpreted as to the right.
[[nodiscard]] float GetVisualRotation() const;
public:
explicit Movable(const Vector2& position, float rad_rotation = 0.0f) : position(position), face_angle(rad_rotation) {}
/// Advance state.
void Move(const u8& tick_rate);
/// Adds velocity in a given direction.
/// @param heading_rad The heading in which to apply the velocity.
/// @param vel The velocity to apply.
/// @note Velocities will smoothly combine.
void AddVelocity(float heading_rad, float vel);
/// @returns the relative direction in radians for the forward.
[[nodiscard]] float HeadingRelativeForward() const;
[[nodiscard]] float FaceRelativeForward() const;
/// @returns The direction in radians for the back.
[[nodiscard]] float FaceRelativeBackward() const;
[[nodiscard]] float HeadingRelativeBackward() const;
/// @returns The relative direction in radians for left.
[[nodiscard]] float FaceRelativeLeft() const;
[[nodiscard]] float HeadingRelativeLeft() const;
[[nodiscard]] float FaceRelativeRight() const;
[[nodiscard]] float HeadingRelativeRight() const;
//virtual Movable Extrapolate(const unsigned long& last_tick_time, const unsigned long& target_time);
public:
[[nodiscard]] static float WorldUp();
[[nodiscard]] static float WorldDown();
[[nodiscard]] static float WorldLeft();
[[nodiscard]] static float WorldRight();
/// @returns an interpolation of this Movable.
//virtual Movable Interpolate(unsigned long previous_tick_time, u8 tick_rate, unsigned long now);
explicit Movable(const Vector2& position, float face_angle = 0.0f) : position(position), face_angle(face_angle) {}
};