]> git.localhorst.tv Git - orbi.git/blob - src/app/Application.cpp
cbfafd374537935625dbaad63955d4d7edacbcd6
[orbi.git] / src / app / Application.cpp
1 #include "Application.h"
2
3 #include "../graphics/Canvas.h"
4 #include "../graphics/Color.h"
5 #include "../world/Entity.h"
6 #include "../world/Tileset.h"
7 #include "../world/World.h"
8
9
10 namespace orbi {
11
12 Application::Application(Canvas &c, World &w, Tileset &t)
13 : canvas(c)
14 , world(w)
15 , tiles(t)
16 , ctrl()
17 , focus(5, 5)
18 , target(focus, 2)
19 , cam(c.Size(), focus)
20 , last(SDL_GetTicks())
21 , running(false)
22 , paused(false) {
23         cam.SetScale(tiles.TileSize());
24 }
25
26
27 void Application::Control(Entity &e) {
28         ctrl.Control(e);
29 }
30
31 void Application::Relinquish() {
32         ctrl.Relinquish();
33 }
34
35
36 void Application::Run() {
37         running = true;
38         while (running) {
39                 Uint32 now = SDL_GetTicks();
40                 int delta = now - last;
41                 Loop(delta);
42                 last = now;
43         }
44 }
45
46
47 void Application::Loop(int delta) {
48         HandleEvents();
49
50         if (delta == 0) {
51                 SDL_Delay(1);
52                 return;
53         } else if (delta > 30) {
54                 delta = 30;
55         }
56
57         if (!paused) {
58                 Update(delta);
59         }
60
61         Render();
62
63         canvas.Present();
64
65 }
66
67
68 void Application::HandleEvents() {
69         SDL_Event event;
70         while (SDL_PollEvent(&event)) {
71                 switch (event.type) {
72                         case SDL_QUIT:
73                                 running = false;
74                                 break;
75                         case SDL_WINDOWEVENT:
76                                 if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
77                                         cam.Resize(event.window.data1, event.window.data2);
78                                 }
79                                 break;
80                         case SDL_KEYDOWN:
81                                 if (!event.key.repeat) {
82                                         OnKeyDown(event.key);
83                                 }
84                                 break;
85                         case SDL_KEYUP:
86                                 if (!event.key.repeat) {
87                                         OnKeyUp(event.key);
88                                 }
89                                 break;
90                         default:
91                                 // skip event
92                                 break;
93                 }
94         }
95 }
96
97 void Application::OnKeyDown(const SDL_KeyboardEvent &e) {
98         switch (e.keysym.sym) {
99                 case SDLK_w:
100                         target.MoveUp();
101                         break;
102                 case SDLK_s:
103                         target.MoveDown();
104                         break;
105                 case SDLK_a:
106                         ctrl.MoveLeft();
107                         target.MoveLeft();
108                         break;
109                 case SDLK_d:
110                         ctrl.MoveRight();
111                         target.MoveRight();
112                         break;
113                 case SDLK_SPACE:
114                         ctrl.StartJump();
115                         break;
116                 case SDLK_p:
117                         paused = !paused;
118                         break;
119                 default:
120                         break;
121         }
122 }
123
124 void Application::OnKeyUp(const SDL_KeyboardEvent &e) {
125         switch (e.keysym.sym) {
126                 case SDLK_w:
127                         target.StopUp();
128                         break;
129                 case SDLK_s:
130                         target.StopDown();
131                         break;
132                 case SDLK_a:
133                         ctrl.StopLeft();
134                         target.StopLeft();
135                         break;
136                 case SDLK_d:
137                         ctrl.StopRight();
138                         target.StopRight();
139                         break;
140                 case SDLK_SPACE:
141                         ctrl.StopJump();
142                         break;
143                 default:
144                         break;
145         }
146 }
147
148
149 void Application::Update(int dt) {
150         const float delta = dt / 1e3;
151         ctrl.Update(delta);
152         target.Update(delta);
153         focus = ctrl.Controlling()
154                 ? ctrl.Controlled().bounds.Center()
155                 : target.Pos();
156         cam.Update(delta);
157         for (int i = 0; i < dt; ++i) {
158                 world.Update(1e-3);
159         }
160 }
161
162
163 void Application::Render() {
164         RenderBackground();
165         RenderWorld();
166         RenderEntities();
167         RenderUI();
168 }
169
170 void Application::RenderBackground() {
171         constexpr Color background(0x00, 0x00, 0x00);
172
173         canvas.SetColor(background);
174         canvas.Fill();
175 }
176
177 void Application::RenderWorld() {
178         const Vector<int> begin(0, 0);
179         const Vector<int> end(world.Size());
180
181         for (Vector<int> pos(begin); pos.y < end.y; ++pos.y) {
182                 for (pos.x = 0; pos.x < end.x; ++pos.x) {
183                         tiles.DrawFG(canvas, cam.ToScreen(pos), world, pos);
184                 }
185         }
186 }
187
188 void Application::RenderEntities() {
189         constexpr Color entityColor(0x00, 0xFA, 0x00);
190         canvas.SetColor(entityColor);
191
192         for (const Entity &e : world.Entities()) {
193                 const Vector<float> pos(e.bounds.Left(), e.bounds.Top());
194                 const Vector<float> size(e.bounds.Size());
195                 canvas.OutlineRect(cam.ToScreen(pos), cam.ToScale(size));
196         }
197 }
198
199 void Application::RenderUI() {
200         constexpr Color outlineColor(0x00, 0x00, 0xFA);
201         constexpr Color targetColor(0xFA, 0xFA, 0x00);
202
203         canvas.SetColor(outlineColor);
204         canvas.Grid(cam.ToScreen(Vector<int>(0, 0)), cam.ToScale(world.Size()), cam.ToScale(Vector<float>(1, 1)));
205
206         canvas.SetColor(targetColor);
207         canvas.Cross(cam.ToScreen(target.Pos()), 15);
208 }
209
210 }