]> git.localhorst.tv Git - orbi.git/blob - src/world/World.cpp
f4d80f95476beab74a2e32eac354f5f10c062659
[orbi.git] / src / world / World.cpp
1 #include "World.h"
2
3 #include "../graphics/const.h"
4
5
6 namespace orbi {
7
8 World::World(Vector<int> size)
9 : size(size)
10 , count(size.x * size.y)
11 , gravity(0, 5)
12 , terminal(50, 50)
13 , tiles(count) {
14
15 }
16
17
18 void World::Update(float dt) {
19         for (Entity &e : entities) {
20                 e.Update(dt, gravity, terminal);
21                 e.onGround = false;
22
23                 const AABB &b = e.bounds;
24
25                 // world bounds collision
26                 if (b.Top() < 0) {
27                         e.Move(Vector<float>(0, -b.Top()));
28                         e.vel.y = 0;
29                 }
30                 if (b.Right() > size.x) {
31                         e.Move(Vector<float>(size.x - b.Right(), 0));
32                         e.vel.x = 0;
33                 }
34                 if (b.Bottom() > size.y) {
35                         e.Move(Vector<float>(0, size.y - b.Bottom()));
36                         e.vel.y = 0;
37                         e.onGround = true;
38                 }
39                 if (b.Left() < 0) {
40                         e.Move(Vector<float>(-b.Left(), 0));
41                         e.vel.x = 0;
42                 }
43
44                 const Vector<int> cBegin(b.Left(), b.Top());
45                 const Vector<int> cEnd(b.Right() + 1, b.Bottom() + 1);
46
47                 Vector<float> min;
48                 Vector<float> max;
49
50                 for (Vector<int> pos(cBegin); pos.y < cEnd.y; ++pos.y) {
51                         for (pos.x = cBegin.x; pos.x < cEnd.x; ++pos.x) {
52                                 if (!TileAt(pos).IsSolid()) continue;
53                                 const AABB tBounds(pos, Vector<float>(1, 1));
54                                 Vector<float> pos;
55                                 Vector<float> norm;
56                                 Vector<float> depth;
57                                 if (!e.bounds.Intersects(tBounds, pos, norm, depth)) {
58                                         continue;
59                                 }
60                                 if (depth.x < min.x) min.x = depth.x;
61                                 if (depth.x > max.x) max.x = depth.x;
62                                 if (depth.y < min.y) min.y = depth.y;
63                                 if (depth.y > max.y) max.y = depth.y;
64                         }
65                 }
66
67                 Vector<float> resp;
68                 if (min.x != 0) {
69                         if (max.x == 0) {
70                                 resp.x = min.x;
71                         }
72                 } else {
73                         resp.x = max.x;
74                 }
75                 if (min.y != 0) {
76                         if (max.y == 0) {
77                                 resp.y = min.y;
78                         }
79                 } else {
80                         resp.y = max.y;
81                 }
82                 e.Move(resp);
83                 if (resp.x != 0) {
84                         e.vel.x = 0;
85                 }
86                 if (resp.y != 0) {
87                         e.vel.y = 0;
88                         if (resp.y < 0) {
89                                 e.onGround = true;
90                         }
91                 }
92         }
93 }
94
95
96 Entity &World::AddEntity(const Entity &e) {
97         entities.emplace_back(e);
98         return entities.back();
99 }
100
101 }