X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2FWorld.cpp;h=7276ece6fdaa5b16519e3e24c0724e16a6b2d7f8;hb=962405ec344818a7f6850d243feca7989ae5d41b;hp=e390914fae7eb34adccc08de26649c697fe15165;hpb=4a51a83bdff30d1e25a5867cfb19936adc0034b1;p=orbi.git diff --git a/src/world/World.cpp b/src/world/World.cpp index e390914..7276ece 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -1,5 +1,6 @@ #include "World.h" +#include "Collision.h" #include "../graphics/const.h" @@ -15,71 +16,88 @@ World::World(Vector 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); +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(0, -b.Top())); - if (b.Right() > size.x) e.Move(Vector(size.x - b.Right(), 0)); - if (b.Bottom() > size.y) e.Move(Vector(0, size.y - b.Bottom())); - if (b.Left() < 0) e.Move(Vector(-b.Left(), 0)); + // world bounds collision + if (b.Top() < 0) { + e.Move(Vector(0, -b.Top())); + e.vel.y = 0; + } + if (b.Right() > size.x) { + e.Move(Vector(size.x - b.Right(), 0)); + e.vel.x = 0; + } + if (b.Bottom() > size.y) { + e.Move(Vector(0, size.y - b.Bottom())); + e.vel.y = 0; + e.onGround = true; + } + if (b.Left() < 0) { + e.Move(Vector(-b.Left(), 0)); + e.vel.x = 0; + } - const Vector cBegin(b.Left(), b.Top()); - const Vector cEnd(b.Right(), b.Bottom()); + const Vector cBegin(b.Left(), b.Top()); + const Vector cEnd(b.Right() + 1, b.Bottom() + 1); - Vector topResponse; - for (Vector pos(cBegin); pos.x < cEnd.x; ++pos.x) { - if (TileAt(pos).IsSolid()) { - topResponse = Vector(0, pos.y + 1 - b.Top()); - break; - } - } - Vector bottomResponse; - for (Vector pos(cBegin.x, cEnd.y); pos.x < cEnd.x; ++pos.x) { - if (TileAt(pos).IsSolid()) { - bottomResponse = Vector(0, pos.y - b.Bottom()); - break; - } - } - if (!IsZero(topResponse)) { - if (IsZero(bottomResponse)) { - e.Move(topResponse); + Vector min; + Vector max; + + for (Vector 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 leftResponse; - for (Vector pos(cBegin); pos.y < cEnd.y; ++pos.y) { - if (TileAt(pos).IsSolid()) { - leftResponse = Vector(pos.x + 1 - b.Left(), 0); - break; - } + Vector resp; + if (min.x != 0) { + if (max.x == 0) { + resp.x = min.x; } - Vector rightResponse; - for (Vector pos(cEnd.x, cBegin.y); pos.y < cEnd.y; ++pos.y) { - if (TileAt(pos).IsSolid()) { - rightResponse = Vector(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 pos) const { + tileShape = AABB(pos, Vector(1, 1)); + return tileShape; +} + + Entity &World::AddEntity(const Entity &e) { entities.emplace_back(e); return entities.back();