]> git.localhorst.tv Git - orbi.git/blobdiff - src/world/World.cpp
simple controller
[orbi.git] / src / world / World.cpp
index e390914fae7eb34adccc08de26649c697fe15165..f4d80f95476beab74a2e32eac354f5f10c062659 100644 (file)
@@ -15,65 +15,78 @@ World::World(Vector<int> size)
 }
 
 
-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);
-
-                       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));
-
-                       const Vector<int> cBegin(b.Left(), b.Top());
-                       const Vector<int> cEnd(b.Right(), b.Bottom());
-
-                       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);
+void World::Update(float dt) {
+       for (Entity &e : entities) {
+               e.Update(dt, gravity, terminal);
+               e.onGround = false;
+
+               const AABB &b = e.bounds;
+
+               // 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() + 1, b.Bottom() + 1);
+
+               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(pos, Vector<float>(1, 1));
+                               Vector<float> pos;
+                               Vector<float> norm;
+                               Vector<float> depth;
+                               if (!e.bounds.Intersects(tBounds, pos, norm, depth)) {
+                                       continue;
                                }
-                       } else if (!IsZero(bottomResponse)) {
-                               e.Move(bottomResponse);
+                               if (depth.x < min.x) min.x = depth.x;
+                               if (depth.x > max.x) max.x = depth.x;
+                               if (depth.y < min.y) min.y = depth.y;
+                               if (depth.y > max.y) max.y = 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;
                        }
                }
        }