#include "World.h"
+#include "Collision.h"
#include "../graphics/const.h"
}
-void World::Update(int delta) {
- for (int i = 0; i < delta; ++i) {
- const float dt = 1e-3;
- for (Entity &e : entities) {
- e.Update(dt, gravity, terminal);
+void World::Update(float dt) {
+ for (Entity &e : entities) {
+ e.Update(dt, gravity, terminal);
+ e.onGround = false;
- const AABB &b = e.Bounds();
+ const AABB &b = e.bounds;
- // world bounds collision
- if (b.Top() < 0) e.Move(Vector<float>(0, -b.Top()));
- if (b.Right() > size.x) e.Move(Vector<float>(size.x - b.Right(), 0));
- if (b.Bottom() > size.y) e.Move(Vector<float>(0, size.y - b.Bottom()));
- if (b.Left() < 0) e.Move(Vector<float>(-b.Left(), 0));
+ // world bounds collision
+ if (b.Top() < 0) {
+ e.Move(Vector<float>(0, -b.Top()));
+ e.vel.y = 0;
+ }
+ if (b.Right() > size.x) {
+ e.Move(Vector<float>(size.x - b.Right(), 0));
+ e.vel.x = 0;
+ }
+ if (b.Bottom() > size.y) {
+ e.Move(Vector<float>(0, size.y - b.Bottom()));
+ e.vel.y = 0;
+ e.onGround = true;
+ }
+ if (b.Left() < 0) {
+ e.Move(Vector<float>(-b.Left(), 0));
+ e.vel.x = 0;
+ }
- const Vector<int> cBegin(b.Left(), b.Top());
- const Vector<int> cEnd(b.Right(), b.Bottom());
+ const Vector<int> cBegin(b.Left(), b.Top());
+ const Vector<int> cEnd(b.Right() + 1, b.Bottom() + 1);
- Vector<float> topResponse;
- for (Vector<int> pos(cBegin); pos.x < cEnd.x; ++pos.x) {
- if (TileAt(pos).IsSolid()) {
- topResponse = Vector<float>(0, pos.y + 1 - b.Top());
- break;
- }
- }
- Vector<float> bottomResponse;
- for (Vector<int> pos(cBegin.x, cEnd.y); pos.x < cEnd.x; ++pos.x) {
- if (TileAt(pos).IsSolid()) {
- bottomResponse = Vector<float>(0, pos.y - b.Bottom());
- break;
- }
- }
- if (!IsZero(topResponse)) {
- if (IsZero(bottomResponse)) {
- e.Move(topResponse);
+ Vector<float> min;
+ Vector<float> max;
+
+ for (Vector<int> pos(cBegin); pos.y < cEnd.y; ++pos.y) {
+ for (pos.x = cBegin.x; pos.x < cEnd.x; ++pos.x) {
+ if (!TileAt(pos).IsSolid()) continue;
+ const AABB &tBounds = TileShapeAt(pos);
+ Collision coll;
+ if (!e.bounds.Intersects(tBounds, coll)) {
+ continue;
}
- } else if (!IsZero(bottomResponse)) {
- e.Move(bottomResponse);
+ if (coll.depth.x < min.x) min.x = coll.depth.x;
+ if (coll.depth.x > max.x) max.x = coll.depth.x;
+ if (coll.depth.y < min.y) min.y = coll.depth.y;
+ if (coll.depth.y > max.y) max.y = coll.depth.y;
}
+ }
- Vector<float> leftResponse;
- for (Vector<int> pos(cBegin); pos.y < cEnd.y; ++pos.y) {
- if (TileAt(pos).IsSolid()) {
- leftResponse = Vector<float>(pos.x + 1 - b.Left(), 0);
- break;
- }
+ Vector<float> resp;
+ if (min.x != 0) {
+ if (max.x == 0) {
+ resp.x = min.x;
}
- Vector<float> rightResponse;
- for (Vector<int> pos(cEnd.x, cBegin.y); pos.y < cEnd.y; ++pos.y) {
- if (TileAt(pos).IsSolid()) {
- rightResponse = Vector<float>(pos.x - b.Right(), 0);
- break;
- }
+ } else {
+ resp.x = max.x;
+ }
+ if (min.y != 0) {
+ if (max.y == 0) {
+ resp.y = min.y;
}
- if (!IsZero(leftResponse)) {
- if (IsZero(rightResponse)) {
- e.Move(leftResponse);
- }
- } else if (!IsZero(rightResponse)) {
- e.Move(rightResponse);
+ } else {
+ resp.y = max.y;
+ }
+ e.Move(resp);
+ if (resp.x != 0) {
+ e.vel.x = 0;
+ }
+ if (resp.y != 0) {
+ e.vel.y = 0;
+ if (resp.y < 0) {
+ e.onGround = true;
}
}
}
}
+const AABB &World::TileShapeAt(Vector<int> pos) const {
+ tileShape = AABB(pos, Vector<float>(1, 1));
+ return tileShape;
+}
+
+
Entity &World::AddEntity(const Entity &e) {
entities.emplace_back(e);
return entities.back();