From 962405ec344818a7f6850d243feca7989ae5d41b Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 10 Apr 2014 09:54:31 +0200 Subject: [PATCH] some cleanup --- src/app/Application.cpp | 16 +-- src/app/Controller.cpp | 2 +- src/collision.cpp | 293 ++++++++++++++++++++-------------------- src/graphics/Vector.h | 8 ++ src/orbi.cpp | 6 +- src/world/AABB.cpp | 41 +++--- src/world/AABB.h | 4 +- src/world/Collision.h | 19 +++ src/world/World.cpp | 23 ++-- src/world/World.h | 4 + 10 files changed, 229 insertions(+), 187 deletions(-) create mode 100644 src/world/Collision.h diff --git a/src/app/Application.cpp b/src/app/Application.cpp index cbfafd3..b6a08f1 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -148,15 +148,15 @@ void Application::OnKeyUp(const SDL_KeyboardEvent &e) { void Application::Update(int dt) { const float delta = dt / 1e3; - ctrl.Update(delta); + for (int i = 0; i < dt; ++i) { + ctrl.Update(1e-3); + world.Update(1e-3); + } target.Update(delta); focus = ctrl.Controlling() ? ctrl.Controlled().bounds.Center() : target.Pos(); cam.Update(delta); - for (int i = 0; i < dt; ++i) { - world.Update(1e-3); - } } @@ -169,9 +169,13 @@ void Application::Render() { void Application::RenderBackground() { constexpr Color background(0x00, 0x00, 0x00); + constexpr Color outlineColor(0x00, 0x00, 0xFA); canvas.SetColor(background); canvas.Fill(); + + canvas.SetColor(outlineColor); + canvas.Grid(cam.ToScreen(Vector(0, 0)), cam.ToScale(world.Size()), cam.ToScale(Vector(1, 1))); } void Application::RenderWorld() { @@ -197,12 +201,8 @@ void Application::RenderEntities() { } void Application::RenderUI() { - constexpr Color outlineColor(0x00, 0x00, 0xFA); constexpr Color targetColor(0xFA, 0xFA, 0x00); - canvas.SetColor(outlineColor); - canvas.Grid(cam.ToScreen(Vector(0, 0)), cam.ToScale(world.Size()), cam.ToScale(Vector(1, 1))); - canvas.SetColor(targetColor); canvas.Cross(cam.ToScreen(target.Pos()), 15); } diff --git a/src/app/Controller.cpp b/src/app/Controller.cpp index 88dd5eb..4d1bf0f 100644 --- a/src/app/Controller.cpp +++ b/src/app/Controller.cpp @@ -14,7 +14,7 @@ Controller::Controller(Entity *ent) , moveAcc(3.5) , moveTerm(5) , jumping(false) -, jumpVel(-5) { +, jumpVel(-6) { } diff --git a/src/collision.cpp b/src/collision.cpp index af4234a..4212507 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -5,6 +5,7 @@ #include "graphics/Vector.h" #include "graphics/Window.h" #include "world/AABB.h" +#include "world/Collision.h" #include #include @@ -27,11 +28,6 @@ struct World { AABB controlled; vector stationary; - struct Collision { - Vector pos; - Vector norm; - Vector depth; - }; vector coll; World() @@ -42,171 +38,167 @@ struct World { , stationary() { } -}; - -void key_down(const SDL_KeyboardEvent &e, World &world) { - switch (e.keysym.sym) { - case SDLK_UP: - world.move.y -= 1; - break; - case SDLK_DOWN: - world.move.y += 1; - break; - case SDLK_LEFT: - world.move.x -= 1; - break; - case SDLK_RIGHT: - world.move.x += 1; - break; - default: - break; - } -} -void key_up(const SDL_KeyboardEvent &e, World &world) { - switch (e.keysym.sym) { - case SDLK_UP: - world.move.y += 1; - break; - case SDLK_DOWN: - world.move.y -= 1; - break; - case SDLK_LEFT: - world.move.x += 1; - break; - case SDLK_RIGHT: - world.move.x -= 1; - break; - default: - break; + void key_down(const SDL_KeyboardEvent &e) { + switch (e.keysym.sym) { + case SDLK_UP: + move.y -= 1; + break; + case SDLK_DOWN: + move.y += 1; + break; + case SDLK_LEFT: + move.x -= 1; + break; + case SDLK_RIGHT: + move.x += 1; + break; + default: + break; + } } -} -void handle(World &world) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - world.alive = false; + void key_up(const SDL_KeyboardEvent &e) { + switch (e.keysym.sym) { + case SDLK_UP: + move.y += 1; + break; + case SDLK_DOWN: + move.y -= 1; break; - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - world.cam.Resize(event.window.data1, event.window.data2); - } + case SDLK_LEFT: + move.x += 1; break; - case SDL_KEYDOWN: - if (!event.key.repeat) { - key_down(event.key, world); - } + case SDLK_RIGHT: + move.x -= 1; break; - case SDL_KEYUP: - if (!event.key.repeat) { - key_up(event.key, world); - } + default: break; } } -} -void update(int dt, World &world) { - const Vector speed { 5, 5 }; + void handle() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + alive = false; + break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + cam.Resize(event.window.data1, event.window.data2); + } + break; + case SDL_KEYDOWN: + if (!event.key.repeat) { + key_down(event.key); + } + break; + case SDL_KEYUP: + if (!event.key.repeat) { + key_up(event.key); + } + break; + } + } + } + + void update(int dt) { + const Vector speed { 5, 5 }; - const float delta = dt / 1e3; + const float delta = dt / 1e3; - world.controlled.Move(Vector(world.move) * speed * delta); - world.focus = world.controlled.Center(); + controlled.Move(Vector(move) * speed * delta); + focus = controlled.Center(); - world.coll.clear(); - for (const AABB &e : world.stationary) { - World::Collision coll; - if (world.controlled.Intersects( - e, - coll.pos, - coll.norm, - coll.depth)) { - world.coll.push_back(coll); + coll.clear(); + for (const AABB &e : stationary) { + Collision c; + if (controlled.Intersects(e, c)) { + coll.push_back(c); + } } } -} -void render(Canvas &canvas, const World &world) { - constexpr Color background(0x00, 0x00, 0x00); - constexpr Color outlineColor(0x00, 0x00, 0xFA); - constexpr Color controlledColor(0xFA, 0xFA, 0x00); - constexpr Color entityColor(0x00, 0xFA, 0x00); - constexpr Color collisionColor(0xFA, 0x00, 0x00); - constexpr Color normalColor(0xFA, 0x00, 0x00); - - canvas.SetColor(background); - canvas.Fill(); - - canvas.SetColor(outlineColor); - canvas.Grid( - world.cam.ToScreen(Vector(0, 0)), - world.cam.ToScale(Vector(10, 10)), - world.cam.ToScale(Vector(1, 1))); - - canvas.SetColor(entityColor); - for (const AABB &e : world.stationary) { - canvas.OutlineRect( - world.cam.ToScreen(Vector(e.Left(), e.Top())), - world.cam.ToScale(e.Size())); - } + void render(Canvas &canvas) const { + constexpr Color background(0x00, 0x00, 0x00); + constexpr Color outlineColor(0x00, 0x00, 0xFA); + constexpr Color controlledColor(0xFA, 0xFA, 0x00); + constexpr Color entityColor(0x00, 0xFA, 0x00); + constexpr Color collisionColor(0xFA, 0x00, 0x00); + constexpr Color normalColor(0xFA, 0x00, 0x00); + + canvas.SetColor(background); + canvas.Fill(); + + canvas.SetColor(outlineColor); + canvas.Grid( + cam.ToScreen(Vector(0, 0)), + cam.ToScale(Vector(10, 10)), + cam.ToScale(Vector(1, 1))); + + canvas.SetColor(entityColor); + for (const AABB &e : stationary) { + canvas.OutlineRect( + cam.ToScreen(Vector(e.Left(), e.Top())), + cam.ToScale(e.Size())); + } - canvas.SetColor(controlledColor); - canvas.OutlineRect( - world.cam.ToScreen(Vector(world.controlled.Left(), world.controlled.Top())), - world.cam.ToScale(world.controlled.Size())); - - if (world.coll.empty()) return; - - for (const World::Collision &c : world.coll) { - canvas.SetColor(collisionColor); - canvas.Arrow( - world.cam.ToScreen(c.pos), - world.cam.ToScreen(c.pos + c.depth)); - canvas.SetColor(normalColor); - canvas.Arrow( - world.cam.ToScreen(c.pos), - world.cam.ToScreen(c.pos) + Vector(c.norm * 25.0f)); + canvas.SetColor(controlledColor); + canvas.OutlineRect( + cam.ToScreen(Vector(controlled.Left(), controlled.Top())), + cam.ToScale(controlled.Size())); + + if (coll.empty()) return; + + for (const Collision &c : coll) { + canvas.SetColor(collisionColor); + canvas.Arrow( + cam.ToScreen(c.pos), + cam.ToScreen(c.pos + c.depth)); + canvas.SetColor(normalColor); + canvas.Arrow( + cam.ToScreen(c.pos), + cam.ToScreen(c.pos) + Vector(c.norm * 25.0f)); + } } -} -void run(Canvas &canvas) { - World world; - world.cam.SetScale(Vector(32, 32)); - world.controlled.Resize(Vector(2, 3)); - world.controlled.Move(Vector(1, 1.5)); - - AABB e; - e.Resize(Vector(2, 2)); - e.Move(Vector(5, 5)); - world.stationary.push_back(e); - e.Move(Vector(0, 2)); - world.stationary.push_back(e); - e.Move(Vector(-2, 0)); - world.stationary.push_back(e); - - Uint32 last = SDL_GetTicks(); - while (world.alive) { - handle(world); - Uint32 now = SDL_GetTicks(); - - int delta = now - last; - if (delta == 0) { - SDL_Delay(1); - continue; - } else if (delta > 30) { - delta = 30; + void run(Canvas &canvas) { + cam.SetScale(Vector(32, 32)); + controlled.Resize(Vector(2, 3)); + controlled.Move(Vector(1, 1.5)); + + AABB e; + e.Resize(Vector(2, 2)); + e.Move(Vector(5, 5)); + stationary.push_back(e); + e.Move(Vector(0, 2)); + stationary.push_back(e); + e.Move(Vector(-2, 0)); + stationary.push_back(e); + + Uint32 last = SDL_GetTicks(); + while (alive) { + handle(); + Uint32 now = SDL_GetTicks(); + + int delta = now - last; + if (delta == 0) { + SDL_Delay(1); + continue; + } else if (delta > 30) { + delta = 30; + } + + update(delta); + render(canvas); + + canvas.Present(); + last = now; } - - update(delta, world); - render(canvas, world); - - canvas.Present(); - last = now; } -} + +}; } @@ -224,7 +216,8 @@ int main(int argc, const char *argv[]) { 0 )); - run(canv); + World world; + world.run(canv); return 0; } diff --git a/src/graphics/Vector.h b/src/graphics/Vector.h index c355091..0fd5bfe 100644 --- a/src/graphics/Vector.h +++ b/src/graphics/Vector.h @@ -163,6 +163,14 @@ template constexpr Vector abs(Vector v) { return Vector(std::abs(v.x), std::abs(v.y)); } +template +constexpr Vector min(Vector lhs, Vector rhs) { + return Vector(std::min(lhs.x, rhs.x), std::min(lhs.y, rhs.y)); +} +template +constexpr Vector max(Vector lhs, Vector rhs) { + return Vector(std::max(lhs.x, rhs.x), std::max(lhs.y, rhs.y)); +} template diff --git a/src/orbi.cpp b/src/orbi.cpp index b052441..59c0e0c 100644 --- a/src/orbi.cpp +++ b/src/orbi.cpp @@ -48,8 +48,12 @@ int main(int argc, const char *argv[]) { world.SetTile(Vector(9, 5), Tile(0)); world.SetTile(Vector(9, 6), Tile(0)); + world.SetTile(Vector(3, 8), Tile(0)); + world.SetTile(Vector(2, 9), Tile(0)); + world.SetTile(Vector(3, 9), Tile(0)); + Entity e; - e.bounds = AABB(Vector(5, 0), Vector(2, 3)); + e.bounds = AABB(Vector(5, 0), Vector(1.9, 2.9)); Entity &player = world.AddEntity(e); Application app(canv, world, tiles); diff --git a/src/world/AABB.cpp b/src/world/AABB.cpp index c54537e..0ed5a63 100644 --- a/src/world/AABB.cpp +++ b/src/world/AABB.cpp @@ -1,39 +1,46 @@ #include "AABB.h" +#include "Collision.h" + + namespace orbi { -bool AABB::Intersects(const AABB &other, Vector &p, Vector &n, Vector &d) const { +bool AABB::Intersects(const AABB &other, Collision &coll) const { if (Bottom() < other.Top()) return false; if (other.Bottom() < Top()) return false; if (Right() < other.Left()) return false; if (other.Right() < Left()) return false; AABB diff; - diff.lt.x = std::max(Left(), other.Left()); - diff.lt.y = std::max(Top(), other.Top()); - diff.rb.x = std::min(Right(), other.Right()); - diff.rb.y = std::min(Bottom(), other.Bottom()); + diff.lt = max(lt, other.lt); + diff.rb = min(rb, other.rb); const Vector sdiff = diff.Size(); if (sdiff.x < sdiff.y) { + coll.pos.y = diff.Center().y; + coll.norm.y = 0; + coll.depth.y = 0; if (Center().x < other.Center().x) { - p = Vector(Right(), ((Top() + Bottom()) / 2 + (other.Top() + other.Bottom()) / 2) / 2); - n = Vector(-1, 0); - d = Vector(other.Left() - Right(), 0); + coll.pos.x = Right(); + coll.norm.x = -1; + coll.depth.x = other.Left() - Right(); } else { - p = Vector(Left(), ((Top() + Bottom()) / 2 + (other.Top() + other.Bottom()) / 2) / 2); - n = Vector(1, 0); - d = Vector(other.Right() - Left(), 0); + coll.pos.x = Left(); + coll.norm.x = 1; + coll.depth.x = other.Right() - Left(); } } else { + coll.pos.x = diff.Center().x; + coll.norm.x = 0; + coll.depth.x = 0; if (Center().y < other.Center().y) { - p = Vector(((Left() + Right()) / 2 + (other.Left() + other.Right()) / 2) / 2, Bottom()); - n = Vector(0, -1); - d = Vector(0, other.Top() - Bottom()); + coll.pos.y = Bottom(); + coll.norm.y = -1; + coll.depth.y = other.Top() - Bottom(); } else { - p = Vector(((Left() + Right()) / 2 + (other.Left() + other.Right()) / 2) / 2, Top()); - n = Vector(0, 1); - d = Vector(0, other.Bottom() - Top()); + coll.pos.y = Top(); + coll.norm.y = 1; + coll.depth.y = other.Bottom() - Top(); } } return true; diff --git a/src/world/AABB.h b/src/world/AABB.h index 20580ca..9a2d5eb 100644 --- a/src/world/AABB.h +++ b/src/world/AABB.h @@ -6,6 +6,8 @@ namespace orbi { +class Collision; + class AABB { public: @@ -30,7 +32,7 @@ public: void Move(Vector delta) { lt += delta; rb += delta; } void Resize(Vector size) { *this = AABB(lt, size); } - bool Intersects(const AABB &other, Vector &p, Vector &n, Vector &d) const; + bool Intersects(const AABB &other, Collision &) const; private: Vector lt; diff --git a/src/world/Collision.h b/src/world/Collision.h new file mode 100644 index 0000000..740afa4 --- /dev/null +++ b/src/world/Collision.h @@ -0,0 +1,19 @@ +#ifndef ORBI_COLLISION_H_ +#define ORBI_COLLISION_H_ + +#include "../graphics/Vector.h" + + +namespace orbi { + +struct Collision { + + Vector pos; + Vector norm; + Vector depth; + +}; + +} + +#endif diff --git a/src/world/World.cpp b/src/world/World.cpp index f4d80f9..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" @@ -50,17 +51,15 @@ void World::Update(float dt) { 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(pos, Vector(1, 1)); - Vector pos; - Vector norm; - Vector depth; - if (!e.bounds.Intersects(tBounds, pos, norm, depth)) { + const AABB &tBounds = TileShapeAt(pos); + Collision coll; + if (!e.bounds.Intersects(tBounds, coll)) { continue; } - 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; + 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; } } @@ -93,6 +92,12 @@ void World::Update(float dt) { } +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(); diff --git a/src/world/World.h b/src/world/World.h index d77b15b..7c98205 100644 --- a/src/world/World.h +++ b/src/world/World.h @@ -1,6 +1,7 @@ #ifndef ORBI_WORLD_H_ #define ORBI_WORLD_H_ +#include "AABB.h" #include "Entity.h" #include "Tile.h" #include "../graphics/Vector.h" @@ -29,6 +30,7 @@ public: Tile &TileAt(Vector pos) { return tiles[Index(pos)]; } const Tile &TileAt(Vector pos) const { return tiles[Index(pos)]; } void SetTile(Vector pos, const Tile &t) { tiles[Index(pos)] = t; } + const AABB &TileShapeAt(Vector pos) const; const std::list &Entities() const { return entities; } Entity &AddEntity(const Entity &); @@ -44,6 +46,8 @@ private: std::list entities; + mutable AABB tileShape; + }; } -- 2.39.2