From 699437a474de8b87ccb6749d44adf740e680d620 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 23 Dec 2013 21:55:15 +0100 Subject: [PATCH] force based movement --- src/app/Application.cpp | 17 +++++++++++------ src/app/Application.h | 4 ++-- src/entity/Entity.h | 30 ----------------------------- src/entity/Ship.h | 42 ++++++++++++++++++++++++++++++++++++++++- src/graphics/Canvas.cpp | 4 ++-- src/graphics/Vector.h | 33 ++++++++++++++++++++++++++++++++ src/world/Universe.cpp | 34 ++++++++++++++++----------------- src/world/Universe.h | 8 ++++---- 8 files changed, 110 insertions(+), 62 deletions(-) delete mode 100644 src/entity/Entity.h diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 488b952..5820c57 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -13,7 +13,7 @@ Application::Application(Canvas &c) , cam(c.Size(), focus.Pos()) , last(SDL_GetTicks()) , running(false) { - controlled = univ.AddEntity(Entity()); + controlled = univ.AddShip(Ship()); } @@ -142,7 +142,8 @@ void Application::OnKeyUp(const SDL_KeyboardEvent &e) { void Application::Update(int dt) { const float delta = dt / 1e3; - controlled->acc = Vector(control * 10); + controlled->rotThrottle = control.x; + controlled->linThrottle = -control.y; cam.Update(delta); univ.Update(delta); focus.SetSpeed(500 / cam.Zoom()); @@ -172,10 +173,14 @@ void Application::Render() { canvas.Cross(cam.ToScreen(focus.Pos()), 15); canvas.SetColor(entityColor); - for (const Entity &e : univ.Entities()) { - canvas.Cross( - cam.ToScreen(Vector(e.area * univ.areaSize) + e.pos), - 10); + for (const Ship &s : univ.Ships()) { + const Vector direction = s.Dir(); + const Vector position = cam.ToScreen(Vector(s.area * univ.areaSize) + s.pos); + const Vector nose = position + Vector(direction * 15.0f); + const Vector left = position + Vector((Rotate90(direction) * 8.0f) - (direction * 4.0f)); + const Vector right = position + Vector((Rotate270(direction) * 8.0f) - (direction * 4.0f)); + canvas.Line(position, nose); + canvas.Quad(nose, left, position, right); } } diff --git a/src/app/Application.h b/src/app/Application.h index b5f0a6b..7e3d91b 100644 --- a/src/app/Application.h +++ b/src/app/Application.h @@ -12,7 +12,7 @@ namespace space { class Canvas; -class Entity; +class Ship; class Application { @@ -41,7 +41,7 @@ private: Moveable focus; Camera cam; - Entity *controlled; + Ship *controlled; Vector control; Uint32 last; diff --git a/src/entity/Entity.h b/src/entity/Entity.h deleted file mode 100644 index eb95331..0000000 --- a/src/entity/Entity.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef SPACE_ENTITY_H_ -#define SPACE_ENTITY_H_ - -#include "../graphics/Vector.h" - - -namespace space { - -class Entity { - -public: - constexpr Entity() { } - -public: - Vector area; - Vector pos; - Vector vel; - Vector acc; - -public: - void Update(float delta) { - pos += vel * delta; - vel += acc * delta; - } - -}; - -} - -#endif diff --git a/src/entity/Ship.h b/src/entity/Ship.h index 8bcc4bc..a21f4b1 100644 --- a/src/entity/Ship.h +++ b/src/entity/Ship.h @@ -1,12 +1,52 @@ #ifndef SPACE_SHIP_H_ #define SPACE_SHIP_H_ +#include "../graphics/Vector.h" + +#include + namespace space { class Ship { -private: +public: + constexpr Ship() { } + +public: + float mass = 1; + float linForce = 1; + float revForce = 1; + float rotForce = 1; + + Vector area; + + Vector pos; + Vector vel; + Vector Dir() const { + return Vector::FromPolar(1, orient); + } + Vector Acc() const { + float force = (linThrottle < 0 ? revForce : linForce); + return Dir() * force / mass * linThrottle; + } + + float orient = 0; + float rotVel = 0; + float RotAcc() const { + return rotForce / mass * rotThrottle; + } + + float linThrottle = 0; + float rotThrottle = 0; + +public: + void Update(float delta) { + rotVel += RotAcc() * delta; + orient += rotVel * delta; + vel += Acc() * delta; + pos += vel * delta; + } }; diff --git a/src/graphics/Canvas.cpp b/src/graphics/Canvas.cpp index e4befc0..93e3f21 100644 --- a/src/graphics/Canvas.cpp +++ b/src/graphics/Canvas.cpp @@ -97,12 +97,12 @@ void Canvas::Cross(Vector pos, int extent) { void Canvas::Triangle(Vector v1, Vector v2, Vector v3) { SDL_Point points[4] = { v1, v2, v3, v1 }; - SDL_RenderDrawPoints(canv, points, 4); + SDL_RenderDrawLines(canv, points, 4); } void Canvas::Quad(Vector v1, Vector v2, Vector v3, Vector v4) { SDL_Point points[5] = { v1, v2, v3, v4, v1 }; - SDL_RenderDrawPoints(canv, points, 5); + SDL_RenderDrawLines(canv, points, 5); } diff --git a/src/graphics/Vector.h b/src/graphics/Vector.h index 34d8297..992ba1e 100644 --- a/src/graphics/Vector.h +++ b/src/graphics/Vector.h @@ -2,6 +2,7 @@ #define SPACE_VECTOR_H_ #include +#include #include #include @@ -18,6 +19,12 @@ public: template constexpr Vector(Vector other) : x(other.x), y(other.y) { } + static Vector FromPolar(Scalar rad, Scalar az) { + return Vector(rad * std::cos(az), rad * std::sin(az)); + } + + static constexpr Vector unit45 = Vector(-0.7071, 0.7071); + public: Vector &operator +=(Vector other) { x += other.x; @@ -43,6 +50,9 @@ public: }; +template +constexpr Vector Vector::unit45; + /// specialization with same layout as SDL_Point template<> class Vector @@ -132,6 +142,29 @@ constexpr bool operator !=(Vector lhs, Vector rhs) { } +template +constexpr Scalar Dot(Vector lhs, Vector rhs) { + return (lhs.x * rhs.x) + (lhs.y * rhs.y); +} +template +constexpr Scalar Length(Vector v) { + return std::sqrt(Dot(v, v)); +} + +template +constexpr Vector Rotate90(Vector v) { + return Vector(-v.y, v.x); +} +template +constexpr Vector Rotate180(Vector v) { + return -v; +} +template +constexpr Vector Rotate270(Vector v) { + return Vector(v.y, -v.x); +} + + template inline std::ostream &operator <<(std::ostream &out, Vector v) { return out << '<' << v.x << ',' << v.y << '>'; diff --git a/src/world/Universe.cpp b/src/world/Universe.cpp index 9f9efe6..6f2e5c1 100644 --- a/src/world/Universe.cpp +++ b/src/world/Universe.cpp @@ -18,30 +18,30 @@ Universe::~Universe() { } -Entity *Universe::AddEntity(const Entity &e) { - entities.emplace_back(e); - return &entities.back(); +Ship *Universe::AddShip(const Ship &s) { + ships.emplace_back(s); + return &ships.back(); } void Universe::Update(float delta) { - for (Entity &e : entities) { - e.Update(delta); - while (e.pos.x > areaSize.x) { - e.pos.x -= areaSize.x; - ++e.area.x; + for (Ship &s : ships) { + s.Update(delta); + while (s.pos.x > areaSize.x) { + s.pos.x -= areaSize.x; + ++s.area.x; } - while (e.pos.x < 0) { - e.pos.x += areaSize.x; - --e.area.x; + while (s.pos.x < 0) { + s.pos.x += areaSize.x; + --s.area.x; } - while (e.pos.y > areaSize.y) { - e.pos.y -= areaSize.y; - ++e.area.y; + while (s.pos.y > areaSize.y) { + s.pos.y -= areaSize.y; + ++s.area.y; } - while (e.pos.y < 0) { - e.pos.y += areaSize.y; - --e.area.y; + while (s.pos.y < 0) { + s.pos.y += areaSize.y; + --s.area.y; } } } diff --git a/src/world/Universe.h b/src/world/Universe.h index 55b86f9..18db4dc 100644 --- a/src/world/Universe.h +++ b/src/world/Universe.h @@ -1,7 +1,7 @@ #ifndef SPACE_UNIVERSE_H_ #define SPACE_UNIVERSE_H_ -#include "../entity/Entity.h" +#include "../entity/Ship.h" #include "../graphics/Vector.h" #include @@ -67,14 +67,14 @@ public: Area AreaAt(Vector coords) const { return Area(*this, coords); } public: - Entity *AddEntity(const Entity &); - const std::list &Entities() const { return entities; } + Ship *AddShip(const Ship &); + const std::list &Ships() const { return ships; } public: void Update(float deltaT); private: - std::list entities; + std::list ships; }; -- 2.39.2