#include "graphics/Vector.h"
#include "graphics/Window.h"
#include "world/AABB.h"
+#include "world/Collision.h"
#include <SDL.h>
#include <vector>
AABB controlled;
vector<AABB> stationary;
- struct Collision {
- Vector<float> pos;
- Vector<float> norm;
- Vector<float> depth;
- };
vector<Collision> coll;
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<float> 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<float> speed { 5, 5 };
- const float delta = dt / 1e3;
+ const float delta = dt / 1e3;
- world.controlled.Move(Vector<float>(world.move) * speed * delta);
- world.focus = world.controlled.Center();
+ controlled.Move(Vector<float>(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<int>(0, 0)),
- world.cam.ToScale(Vector<float>(10, 10)),
- world.cam.ToScale(Vector<float>(1, 1)));
-
- canvas.SetColor(entityColor);
- for (const AABB &e : world.stationary) {
- canvas.OutlineRect(
- world.cam.ToScreen(Vector<float>(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<int>(0, 0)),
+ cam.ToScale(Vector<float>(10, 10)),
+ cam.ToScale(Vector<float>(1, 1)));
+
+ canvas.SetColor(entityColor);
+ for (const AABB &e : stationary) {
+ canvas.OutlineRect(
+ cam.ToScreen(Vector<float>(e.Left(), e.Top())),
+ cam.ToScale(e.Size()));
+ }
- canvas.SetColor(controlledColor);
- canvas.OutlineRect(
- world.cam.ToScreen(Vector<float>(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<int>(c.norm * 25.0f));
+ canvas.SetColor(controlledColor);
+ canvas.OutlineRect(
+ cam.ToScreen(Vector<float>(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<int>(c.norm * 25.0f));
+ }
}
-}
-void run(Canvas &canvas) {
- World world;
- world.cam.SetScale(Vector<float>(32, 32));
- world.controlled.Resize(Vector<float>(2, 3));
- world.controlled.Move(Vector<float>(1, 1.5));
-
- AABB e;
- e.Resize(Vector<float>(2, 2));
- e.Move(Vector<float>(5, 5));
- world.stationary.push_back(e);
- e.Move(Vector<float>(0, 2));
- world.stationary.push_back(e);
- e.Move(Vector<float>(-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<float>(32, 32));
+ controlled.Resize(Vector<float>(2, 3));
+ controlled.Move(Vector<float>(1, 1.5));
+
+ AABB e;
+ e.Resize(Vector<float>(2, 2));
+ e.Move(Vector<float>(5, 5));
+ stationary.push_back(e);
+ e.Move(Vector<float>(0, 2));
+ stationary.push_back(e);
+ e.Move(Vector<float>(-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;
}
-}
+
+};
}
0
));
- run(canv);
+ World world;
+ world.run(canv);
return 0;
}
#include "AABB.h"
+#include "Collision.h"
+
+
namespace orbi {
-bool AABB::Intersects(const AABB &other, Vector<float> &p, Vector<float> &n, Vector<float> &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<float> 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<float>(Right(), ((Top() + Bottom()) / 2 + (other.Top() + other.Bottom()) / 2) / 2);
- n = Vector<float>(-1, 0);
- d = Vector<float>(other.Left() - Right(), 0);
+ coll.pos.x = Right();
+ coll.norm.x = -1;
+ coll.depth.x = other.Left() - Right();
} else {
- p = Vector<float>(Left(), ((Top() + Bottom()) / 2 + (other.Top() + other.Bottom()) / 2) / 2);
- n = Vector<float>(1, 0);
- d = Vector<float>(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<float>(((Left() + Right()) / 2 + (other.Left() + other.Right()) / 2) / 2, Bottom());
- n = Vector<float>(0, -1);
- d = Vector<float>(0, other.Top() - Bottom());
+ coll.pos.y = Bottom();
+ coll.norm.y = -1;
+ coll.depth.y = other.Top() - Bottom();
} else {
- p = Vector<float>(((Left() + Right()) / 2 + (other.Left() + other.Right()) / 2) / 2, Top());
- n = Vector<float>(0, 1);
- d = Vector<float>(0, other.Bottom() - Top());
+ coll.pos.y = Top();
+ coll.norm.y = 1;
+ coll.depth.y = other.Bottom() - Top();
}
}
return true;