, cam(c.Size(), focus.Pos())
, last(SDL_GetTicks())
, running(false) {
- controlled = univ.AddEntity(Entity());
+ controlled = univ.AddShip(Ship());
}
void Application::Update(int dt) {
const float delta = dt / 1e3;
- controlled->acc = Vector<float>(control * 10);
+ controlled->rotThrottle = control.x;
+ controlled->linThrottle = -control.y;
cam.Update(delta);
univ.Update(delta);
focus.SetSpeed(500 / cam.Zoom());
canvas.Cross(cam.ToScreen(focus.Pos()), 15);
canvas.SetColor(entityColor);
- for (const Entity &e : univ.Entities()) {
- canvas.Cross(
- cam.ToScreen(Vector<float>(e.area * univ.areaSize) + e.pos),
- 10);
+ for (const Ship &s : univ.Ships()) {
+ const Vector<float> direction = s.Dir();
+ const Vector<int> position = cam.ToScreen(Vector<float>(s.area * univ.areaSize) + s.pos);
+ const Vector<int> nose = position + Vector<int>(direction * 15.0f);
+ const Vector<int> left = position + Vector<int>((Rotate90(direction) * 8.0f) - (direction * 4.0f));
+ const Vector<int> right = position + Vector<int>((Rotate270(direction) * 8.0f) - (direction * 4.0f));
+ canvas.Line(position, nose);
+ canvas.Quad(nose, left, position, right);
}
}
namespace space {
class Canvas;
-class Entity;
+class Ship;
class Application {
Moveable<float> focus;
Camera cam;
- Entity *controlled;
+ Ship *controlled;
Vector<int> control;
Uint32 last;
+++ /dev/null
-#ifndef SPACE_ENTITY_H_
-#define SPACE_ENTITY_H_
-
-#include "../graphics/Vector.h"
-
-
-namespace space {
-
-class Entity {
-
-public:
- constexpr Entity() { }
-
-public:
- Vector<int> area;
- Vector<float> pos;
- Vector<float> vel;
- Vector<float> acc;
-
-public:
- void Update(float delta) {
- pos += vel * delta;
- vel += acc * delta;
- }
-
-};
-
-}
-
-#endif
#ifndef SPACE_SHIP_H_
#define SPACE_SHIP_H_
+#include "../graphics/Vector.h"
+
+#include <cmath>
+
namespace space {
class Ship {
-private:
+public:
+ constexpr Ship() { }
+
+public:
+ float mass = 1;
+ float linForce = 1;
+ float revForce = 1;
+ float rotForce = 1;
+
+ Vector<int> area;
+
+ Vector<float> pos;
+ Vector<float> vel;
+ Vector<float> Dir() const {
+ return Vector<float>::FromPolar(1, orient);
+ }
+ Vector<float> 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;
+ }
};
void Canvas::Triangle(Vector<int> v1, Vector<int> v2, Vector<int> v3) {
SDL_Point points[4] = { v1, v2, v3, v1 };
- SDL_RenderDrawPoints(canv, points, 4);
+ SDL_RenderDrawLines(canv, points, 4);
}
void Canvas::Quad(Vector<int> v1, Vector<int> v2, Vector<int> v3, Vector<int> v4) {
SDL_Point points[5] = { v1, v2, v3, v4, v1 };
- SDL_RenderDrawPoints(canv, points, 5);
+ SDL_RenderDrawLines(canv, points, 5);
}
#define SPACE_VECTOR_H_
#include <algorithm>
+#include <cmath>
#include <ostream>
#include <SDL.h>
template<class Other>
constexpr Vector(Vector<Other> other) : x(other.x), y(other.y) { }
+ static Vector<Scalar> FromPolar(Scalar rad, Scalar az) {
+ return Vector<Scalar>(rad * std::cos(az), rad * std::sin(az));
+ }
+
+ static constexpr Vector<Scalar> unit45 = Vector<Scalar>(-0.7071, 0.7071);
+
public:
Vector<Scalar> &operator +=(Vector<Scalar> other) {
x += other.x;
};
+template<class T>
+constexpr Vector<T> Vector<T>::unit45;
+
/// specialization with same layout as SDL_Point
template<>
class Vector<int>
}
+template<class Scalar>
+constexpr Scalar Dot(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+ return (lhs.x * rhs.x) + (lhs.y * rhs.y);
+}
+template<class Scalar>
+constexpr Scalar Length(Vector<Scalar> v) {
+ return std::sqrt(Dot(v, v));
+}
+
+template<class Scalar>
+constexpr Vector<Scalar> Rotate90(Vector<Scalar> v) {
+ return Vector<Scalar>(-v.y, v.x);
+}
+template<class Scalar>
+constexpr Vector<Scalar> Rotate180(Vector<Scalar> v) {
+ return -v;
+}
+template<class Scalar>
+constexpr Vector<Scalar> Rotate270(Vector<Scalar> v) {
+ return Vector<Scalar>(v.y, -v.x);
+}
+
+
template<class Scalar>
inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
return out << '<' << v.x << ',' << v.y << '>';
}
-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;
}
}
}
#ifndef SPACE_UNIVERSE_H_
#define SPACE_UNIVERSE_H_
-#include "../entity/Entity.h"
+#include "../entity/Ship.h"
#include "../graphics/Vector.h"
#include <list>
Area AreaAt(Vector<int> coords) const { return Area(*this, coords); }
public:
- Entity *AddEntity(const Entity &);
- const std::list<Entity> &Entities() const { return entities; }
+ Ship *AddShip(const Ship &);
+ const std::list<Ship> &Ships() const { return ships; }
public:
void Update(float deltaT);
private:
- std::list<Entity> entities;
+ std::list<Ship> ships;
};