case SDLK_d:
control.x += 1;
break;
+ case SDLK_z:
+ cam.DoubleZoom();
+ break;
+ case SDLK_x:
+ cam.HalfZoom();
+ break;
default:
break;
}
void Application::Update(int dt) {
const float delta = dt / 1e3;
controlled->acc = Vector<float>(control * 10);
+ cam.Update(delta);
univ.Update(delta);
focus.Update(delta);
}
constexpr Color focusColor(0xFA, 0xFA, 0x00);
SDL_Surface *dst = screen.Screen();
- const Vector<int> begin = cam.Offset();
+ const Vector<int> begin = cam.ToScreen(Vector<float>(0, 0));
const Vector<int> end =
- begin + (univ.size * univ.secSize * univ.areaSize) + Vector<int>(1, 1);
+ cam.ToScreen((univ.size * univ.secSize * univ.areaSize)) + Vector<int>(1, 1);;
Fill(dst, background);
- Grid(dst, begin, end, univ.areaSize, secGrid);
- Grid(dst, begin, end, univ.secSize * univ.areaSize, univGrid);
- Cross(dst, begin + Vector<int>(focus.Pos()), 15, focusColor);
+ Grid(dst, begin, end, cam.ToScale(univ.areaSize), secGrid);
+ Grid(dst, begin, end, cam.ToScale(univ.secSize * univ.areaSize), univGrid);
+ Cross(dst, cam.ToScreen(focus.Pos()), 15, focusColor);
for (const Entity &e : univ.Entities()) {
- Cross(dst, begin + (e.area * univ.areaSize) + Vector<int>(e.pos), 10, entityColor);
+ Cross(dst, cam.ToScreen((e.area * univ.areaSize) + Vector<int>(e.pos)), 10, entityColor);
}
}
Camera::Camera(int w, int h, const Vector<float> &t)
: target(&t)
-, offset(w/2, h/2) {
+, offset(w/2, h/2)
+, zoom(0) {
}
offset = Vector<float>(w/2, h/2);
}
+void Camera::Update(float delta) {
+
+}
+
+void Camera::DoubleZoom() {
+ zoom += 1;
+}
+
+void Camera::HalfZoom() {
+ zoom -= 1;
+}
+
}
Camera(int w, int h, const Vector<float> &);
public:
+ void SetTarget(const Vector<float> &t) { target = &t; }
+ void SetZoom(float z) { zoom = z; }
+
void Resize(int w, int h);
+ void Update(float deltaT);
+
+ void DoubleZoom();
+ void HalfZoom();
- Vector<float> Offset() {
- return -(*target - offset);
+ Vector<int> ToScreen(Vector<float> v) const {
+ return Vector<int>(OffsetOf(v));
+ }
+ Vector<float> OffsetOf(Vector<float> v) const {
+ return ToScale(v - *target) + offset;
+ }
+ Vector<float> ToScale(Vector<float> v) const {
+ if (zoom == 0) {
+ return v;
+ } else if (zoom > 0) {
+ return v * float(1 << zoom);
+ } else {
+ return v / float(1 << -zoom);
+ }
}
private:
const Vector<float> *target;
Vector<float> offset;
+ int zoom;
+
};
}
}
}
+void Grid(
+ SDL_Surface *dst,
+ Vector<int> first,
+ Vector<int> second,
+ Vector<float> size,
+ Color color) {
+ Uint32 c = color.MapRGBA(dst);
+
+ Vector<int> from = min(first, second);
+ Vector<int> to = max(first, second);
+
+ if (size.x <= 1 || size.y <= 1) {
+ FillRect(dst, from, to - from, c);
+ return;
+ }
+
+ if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) {
+ return;
+ }
+
+ while (from.x < -size.x) from.x += size.x;
+ while (from.y < -size.y) from.y += size.y;
+ while (to.x > dst->w + size.x) to.x -= size.x;
+ while (to.y > dst->h + size.y) to.y -= size.y;
+
+ float width = to.x - from.x;
+ float height = to.y - from.y;
+
+ for (Vector<float> pos(from); pos.x <= to.x; pos.x += size.x) {
+ VLine(dst, pos, height, c);
+ }
+ for (Vector<float> pos(from); pos.y <= to.y; pos.y += size.y) {
+ HLine(dst, pos, width, c);
+ }
+}
+
}
Vector<int> to,
Vector<int> size,
Color);
+void Grid(
+ SDL_Surface *,
+ Vector<int> from,
+ Vector<int> to,
+ Vector<float> size,
+ Color);
}
#define SPACE_VECTOR_H_
#include <algorithm>
+#include <ostream>
namespace space {
return Vector<Scalar>(lhs.x * rhs.x, lhs.y * rhs.y);
}
+
+template<class Scalar>
+constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Scalar rhs) {
+ return Vector<Scalar>(lhs.x / rhs, lhs.y / rhs);
+}
+
+template<class Scalar>
+constexpr Vector<Scalar> operator /(Scalar lhs, Vector<Scalar> rhs) {
+ return rhs / lhs;
+}
+template<class Scalar>
+constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+ return Vector<Scalar>(lhs.x / rhs.x, lhs.y / rhs.y);
+}
+
+
+template<class Scalar>
+constexpr bool operator ==(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+ return lhs.x == rhs.x && lhs.y == rhs.y;
+}
+template<class Scalar>
+constexpr bool operator !=(Vector<Scalar> lhs, Vector<Scalar> rhs) {
+ return lhs.x != rhs.x && lhs.y != rhs.y;
+}
+
+
+template<class Scalar>
+inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
+ return out << '<' << v.x << ',' << v.y << '>';
+}
+
}