]> git.localhorst.tv Git - orbi.git/blob - src/collision.cpp
some cleanup
[orbi.git] / src / collision.cpp
1 #include "app/SDL.h"
2 #include "graphics/Camera.h"
3 #include "graphics/Canvas.h"
4 #include "graphics/Color.h"
5 #include "graphics/Vector.h"
6 #include "graphics/Window.h"
7 #include "world/AABB.h"
8 #include "world/Collision.h"
9
10 #include <SDL.h>
11 #include <vector>
12
13 using namespace orbi;
14 using namespace std;
15
16
17 namespace {
18
19 struct World {
20
21         bool alive;
22
23         Vector<float> focus;
24         Camera cam;
25
26         Vector<int> move;
27
28         AABB controlled;
29         vector<AABB> stationary;
30
31         vector<Collision> coll;
32
33         World()
34         : alive(true)
35         , focus()
36         , cam(Vector<int>(), focus)
37         , controlled()
38         , stationary()
39         { }
40
41
42         void key_down(const SDL_KeyboardEvent &e) {
43                 switch (e.keysym.sym) {
44                         case SDLK_UP:
45                                 move.y -= 1;
46                                 break;
47                         case SDLK_DOWN:
48                                 move.y += 1;
49                                 break;
50                         case SDLK_LEFT:
51                                 move.x -= 1;
52                                 break;
53                         case SDLK_RIGHT:
54                                 move.x += 1;
55                                 break;
56                         default:
57                                 break;
58                 }
59         }
60
61         void key_up(const SDL_KeyboardEvent &e) {
62                 switch (e.keysym.sym) {
63                         case SDLK_UP:
64                                 move.y += 1;
65                                 break;
66                         case SDLK_DOWN:
67                                 move.y -= 1;
68                                 break;
69                         case SDLK_LEFT:
70                                 move.x += 1;
71                                 break;
72                         case SDLK_RIGHT:
73                                 move.x -= 1;
74                                 break;
75                         default:
76                                 break;
77                 }
78         }
79
80         void handle() {
81                 SDL_Event event;
82                 while (SDL_PollEvent(&event)) {
83                         switch (event.type) {
84                                 case SDL_QUIT:
85                                         alive = false;
86                                         break;
87                                 case SDL_WINDOWEVENT:
88                                         if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
89                                                 cam.Resize(event.window.data1, event.window.data2);
90                                         }
91                                         break;
92                                 case SDL_KEYDOWN:
93                                         if (!event.key.repeat) {
94                                                 key_down(event.key);
95                                         }
96                                         break;
97                                 case SDL_KEYUP:
98                                         if (!event.key.repeat) {
99                                                 key_up(event.key);
100                                         }
101                                         break;
102                         }
103                 }
104         }
105
106         void update(int dt) {
107                 const Vector<float> speed { 5, 5 };
108
109                 const float delta = dt / 1e3;
110
111                 controlled.Move(Vector<float>(move) * speed * delta);
112                 focus = controlled.Center();
113
114                 coll.clear();
115                 for (const AABB &e : stationary) {
116                         Collision c;
117                         if (controlled.Intersects(e, c)) {
118                                 coll.push_back(c);
119                         }
120                 }
121         }
122
123         void render(Canvas &canvas) const {
124                 constexpr Color background(0x00, 0x00, 0x00);
125                 constexpr Color outlineColor(0x00, 0x00, 0xFA);
126                 constexpr Color controlledColor(0xFA, 0xFA, 0x00);
127                 constexpr Color entityColor(0x00, 0xFA, 0x00);
128                 constexpr Color collisionColor(0xFA, 0x00, 0x00);
129                 constexpr Color normalColor(0xFA, 0x00, 0x00);
130
131                 canvas.SetColor(background);
132                 canvas.Fill();
133
134                 canvas.SetColor(outlineColor);
135                 canvas.Grid(
136                         cam.ToScreen(Vector<int>(0, 0)),
137                         cam.ToScale(Vector<float>(10, 10)),
138                         cam.ToScale(Vector<float>(1, 1)));
139
140                 canvas.SetColor(entityColor);
141                 for (const AABB &e : stationary) {
142                         canvas.OutlineRect(
143                                 cam.ToScreen(Vector<float>(e.Left(), e.Top())),
144                                 cam.ToScale(e.Size()));
145                 }
146
147                 canvas.SetColor(controlledColor);
148                 canvas.OutlineRect(
149                         cam.ToScreen(Vector<float>(controlled.Left(), controlled.Top())),
150                         cam.ToScale(controlled.Size()));
151
152                 if (coll.empty()) return;
153
154                 for (const Collision &c : coll) {
155                         canvas.SetColor(collisionColor);
156                         canvas.Arrow(
157                                 cam.ToScreen(c.pos),
158                                 cam.ToScreen(c.pos + c.depth));
159                         canvas.SetColor(normalColor);
160                         canvas.Arrow(
161                                 cam.ToScreen(c.pos),
162                                 cam.ToScreen(c.pos) + Vector<int>(c.norm * 25.0f));
163                 }
164         }
165
166         void run(Canvas &canvas) {
167                 cam.SetScale(Vector<float>(32, 32));
168                 controlled.Resize(Vector<float>(2, 3));
169                 controlled.Move(Vector<float>(1, 1.5));
170
171                 AABB e;
172                 e.Resize(Vector<float>(2, 2));
173                 e.Move(Vector<float>(5, 5));
174                 stationary.push_back(e);
175                 e.Move(Vector<float>(0, 2));
176                 stationary.push_back(e);
177                 e.Move(Vector<float>(-2, 0));
178                 stationary.push_back(e);
179
180                 Uint32 last = SDL_GetTicks();
181                 while (alive) {
182                         handle();
183                         Uint32 now = SDL_GetTicks();
184
185                         int delta = now - last;
186                         if (delta == 0) {
187                                 SDL_Delay(1);
188                                 continue;
189                         } else if (delta > 30) {
190                                 delta = 30;
191                         }
192
193                         update(delta);
194                         render(canvas);
195
196                         canvas.Present();
197                         last = now;
198                 }
199         }
200
201 };
202
203 }
204
205
206 int main(int argc, const char *argv[]) {
207         SDL sdl(SDL_INIT_VIDEO);
208
209         Window win(
210                 "orbi collision test",
211                 Window::POS_UNDEF,
212                 Vector<int>(800, 600),
213                 SDL_WINDOW_RESIZABLE
214         );
215         Canvas canv(win.CreateCanvas(
216                 0
217         ));
218
219         World world;
220         world.run(canv);
221
222         return 0;
223 }