diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2019-03-10 12:07:40 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2019-03-10 12:07:40 -0400 |
commit | 57fe8f3c4124819b95164547333a33f4c45eac8d (patch) | |
tree | 99dd89a0c1cf0a8ceaa2ff941549d631950efd11 | |
parent | bf34f891c5c09e6c8a42797085860fa80ab53814 (diff) | |
download | dispatcher-57fe8f3c4124819b95164547333a33f4c45eac8d.tar.gz dispatcher-57fe8f3c4124819b95164547333a33f4c45eac8d.tar.bz2 dispatcher-57fe8f3c4124819b95164547333a33f4c45eac8d.zip |
Editor now allows tile placement
You can scroll through the three layers (map, track, object) with Z/X. You can swap between focusing on the map and the tileset with TAB. You can place tiles with enter or space. Pretty rudimentary, but it's a start.
-rw-r--r-- | res/map.png | bin | 0 -> 124 bytes | |||
-rw-r--r-- | res/object.png | bin | 0 -> 125 bytes | |||
-rw-r--r-- | res/track.png | bin | 0 -> 775 bytes | |||
-rw-r--r-- | src/consts.h | 6 | ||||
-rw-r--r-- | src/editor.cpp | 246 | ||||
-rw-r--r-- | src/editor.h | 30 | ||||
-rw-r--r-- | src/input.h | 39 | ||||
-rw-r--r-- | src/input_lag.h | 66 | ||||
-rw-r--r-- | src/level.cpp | 41 | ||||
-rw-r--r-- | src/level.h | 64 | ||||
-rw-r--r-- | src/main.cpp | 20 | ||||
-rw-r--r-- | src/simulation.cpp | 2 | ||||
-rw-r--r-- | src/tileset.h | 38 |
13 files changed, 496 insertions, 56 deletions
diff --git a/res/map.png b/res/map.png new file mode 100644 index 0000000..e41bd05 --- /dev/null +++ b/res/map.png | |||
Binary files differ | |||
diff --git a/res/object.png b/res/object.png new file mode 100644 index 0000000..fe84b88 --- /dev/null +++ b/res/object.png | |||
Binary files differ | |||
diff --git a/res/track.png b/res/track.png new file mode 100644 index 0000000..d3a9a93 --- /dev/null +++ b/res/track.png | |||
Binary files differ | |||
diff --git a/src/consts.h b/src/consts.h index f3a073c..a6b5094 100644 --- a/src/consts.h +++ b/src/consts.h | |||
@@ -4,7 +4,9 @@ | |||
4 | #include "vector.h" | 4 | #include "vector.h" |
5 | 5 | ||
6 | constexpr vec2s TILE_SIZE { 32, 32 }; | 6 | constexpr vec2s TILE_SIZE { 32, 32 }; |
7 | constexpr vec2s LEVEL_SIZE { 16, 16 }; | 7 | constexpr vec2s MAP_SIZE { 16, 16 }; |
8 | constexpr vec2s WINDOW_SIZE = TILE_SIZE * LEVEL_SIZE; | 8 | constexpr vec2s LEVEL_SIZE = TILE_SIZE * MAP_SIZE; |
9 | constexpr vec2s BORDER_SIZE = TILE_SIZE; | ||
10 | constexpr vec2s WINDOW_SIZE = LEVEL_SIZE * vec2s { 2, 1 } + BORDER_SIZE * 2; | ||
9 | 11 | ||
10 | #endif /* end of include guard: CONSTS_H_8019F1B3 */ | 12 | #endif /* end of include guard: CONSTS_H_8019F1B3 */ |
diff --git a/src/editor.cpp b/src/editor.cpp index 92c6b67..30dde45 100644 --- a/src/editor.cpp +++ b/src/editor.cpp | |||
@@ -5,27 +5,150 @@ void Editor::tick( | |||
5 | double dt, | 5 | double dt, |
6 | const Uint8* keystate) | 6 | const Uint8* keystate) |
7 | { | 7 | { |
8 | if (keystate[SDL_SCANCODE_LEFT] || | ||
9 | keystate[SDL_SCANCODE_UP] || | ||
10 | keystate[SDL_SCANCODE_RIGHT] || | ||
11 | keystate[SDL_SCANCODE_DOWN]) | ||
12 | { | ||
13 | // If the player is holding down a directional key, accumulate the time | ||
14 | // since the last tick, and then apply the directional key as many times as | ||
15 | // needed. The input lag class automatically handles the delays necessary | ||
16 | // for key repeat. | ||
17 | inputLag_.accumulate(dt); | ||
8 | 18 | ||
9 | } | 19 | while (inputLag_.step()) |
20 | { | ||
21 | if (mapFocus_) | ||
22 | { | ||
23 | // If we are focused on the map, move the map cursor. | ||
24 | if (keystate[SDL_SCANCODE_LEFT] && cursor_.x() > 0) | ||
25 | { | ||
26 | cursor_.x()--; | ||
27 | } | ||
10 | 28 | ||
11 | void Editor::render(SDL_Renderer* ren) | 29 | if (keystate[SDL_SCANCODE_UP] && cursor_.y() > 0) |
12 | { | 30 | { |
13 | if (!background_) | 31 | cursor_.y()--; |
32 | } | ||
33 | |||
34 | if (keystate[SDL_SCANCODE_RIGHT] && | ||
35 | cursor_.x() < level_.getSize().w() - 1) | ||
36 | { | ||
37 | cursor_.x()++; | ||
38 | } | ||
39 | |||
40 | if (keystate[SDL_SCANCODE_DOWN] && | ||
41 | cursor_.y() < level_.getSize().h() - 1) | ||
42 | { | ||
43 | cursor_.y()++; | ||
44 | } | ||
45 | } else { | ||
46 | // If we are focused on the tileset, rotate through the selection of | ||
47 | // tiles. | ||
48 | if (keystate[SDL_SCANCODE_UP]) | ||
49 | { | ||
50 | selectedTile_--; | ||
51 | } else if (keystate[SDL_SCANCODE_DOWN]) | ||
52 | { | ||
53 | selectedTile_++; | ||
54 | } | ||
55 | |||
56 | selectedTile_ %= level_.getTileset(layer_).getNumTiles(); | ||
57 | } | ||
58 | } | ||
59 | } else if (inputLag_.isActive()) | ||
14 | { | 60 | { |
15 | surface_ptr bgSurf(IMG_Load("../res/editor_bg.png")); | 61 | // If the player is not holding down a directional key, reset the input lag. |
62 | inputLag_.reset(); | ||
63 | } | ||
64 | |||
65 | // Check for keypress changes since the last tick. | ||
66 | input_.tick(keystate); | ||
16 | 67 | ||
17 | if (!bgSurf) | 68 | if (input_.wasPressed(SDL_SCANCODE_Z)) |
69 | { | ||
70 | switch (layer_) | ||
18 | { | 71 | { |
19 | throw img_error(); | 72 | case Layer::map: |
73 | { | ||
74 | layer_ = Layer::object; | ||
75 | |||
76 | break; | ||
77 | } | ||
78 | |||
79 | case Layer::track: | ||
80 | { | ||
81 | layer_ = Layer::map; | ||
82 | |||
83 | break; | ||
84 | } | ||
85 | |||
86 | case Layer::object: | ||
87 | { | ||
88 | layer_ = Layer::track; | ||
89 | |||
90 | break; | ||
91 | } | ||
20 | } | 92 | } |
21 | 93 | ||
22 | background_.reset(SDL_CreateTextureFromSurface(ren, bgSurf.get())); | 94 | selectedTile_ = 0; |
23 | bgSize_ = { bgSurf->w, bgSurf->h }; | 95 | |
96 | // Reset the cached map so that it gets redrawn with the focused layer. | ||
97 | renderedMap_.reset(); | ||
98 | } else if (input_.wasPressed(SDL_SCANCODE_X)) | ||
99 | { | ||
100 | switch (layer_) | ||
101 | { | ||
102 | case Layer::map: | ||
103 | { | ||
104 | layer_ = Layer::track; | ||
105 | |||
106 | break; | ||
107 | } | ||
108 | |||
109 | case Layer::track: | ||
110 | { | ||
111 | layer_ = Layer::object; | ||
112 | |||
113 | break; | ||
114 | } | ||
115 | |||
116 | case Layer::object: | ||
117 | { | ||
118 | layer_ = Layer::map; | ||
119 | |||
120 | break; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | selectedTile_ = 0; | ||
125 | |||
126 | // Reset the cached map so that it gets redrawn with the focused layer. | ||
127 | renderedMap_.reset(); | ||
128 | } else if (input_.wasPressed(SDL_SCANCODE_TAB)) | ||
129 | { | ||
130 | mapFocus_ = !mapFocus_; | ||
24 | } | 131 | } |
25 | 132 | ||
26 | for (int y = 0; y < WINDOW_SIZE.h() / bgSize_.h(); y++) | 133 | if (mapFocus_) |
27 | { | 134 | { |
28 | for (int x = 0; x < WINDOW_SIZE.w() / bgSize_.w(); x++) | 135 | if (keystate[SDL_SCANCODE_RETURN] || |
136 | keystate[SDL_SCANCODE_SPACE]) | ||
137 | { | ||
138 | level_.at(cursor_.x(), cursor_.y(), layer_) = selectedTile_; | ||
139 | |||
140 | // Reset the cached map so that it gets redrawn with the new tile. | ||
141 | renderedMap_.reset(); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | void Editor::render(SDL_Renderer* ren) | ||
147 | { | ||
148 | // Tile the background art. | ||
149 | for (int y = 0; y <= WINDOW_SIZE.h() / bgSize_.h(); y++) | ||
150 | { | ||
151 | for (int x = 0; x <= WINDOW_SIZE.w() / bgSize_.w(); x++) | ||
29 | { | 152 | { |
30 | SDL_Rect rect { | 153 | SDL_Rect rect { |
31 | x * bgSize_.w(), | 154 | x * bgSize_.w(), |
@@ -37,4 +160,105 @@ void Editor::render(SDL_Renderer* ren) | |||
37 | SDL_RenderCopy(ren, background_.get(), nullptr, &rect); | 160 | SDL_RenderCopy(ren, background_.get(), nullptr, &rect); |
38 | } | 161 | } |
39 | } | 162 | } |
163 | |||
164 | // Render and cache the map if the cache is currently empty. | ||
165 | if (!renderedMap_) | ||
166 | { | ||
167 | renderedMap_.reset( | ||
168 | SDL_CreateTexture( | ||
169 | ren, | ||
170 | SDL_PIXELFORMAT_RGBA8888, | ||
171 | SDL_TEXTUREACCESS_TARGET, | ||
172 | LEVEL_SIZE.w(), | ||
173 | LEVEL_SIZE.h())); | ||
174 | |||
175 | // Render each layer separately, then compose them atop each other. Layers | ||
176 | // above the currently selected one are drawn semi-transparently. | ||
177 | texture_ptr mapRender = level_.render(ren, Layer::map); | ||
178 | texture_ptr trackRender = level_.render(ren, Layer::track); | ||
179 | texture_ptr objectRender = level_.render(ren, Layer::object); | ||
180 | |||
181 | if (layer_ < Layer::track) | ||
182 | { | ||
183 | SDL_SetTextureBlendMode(trackRender.get(), SDL_BLENDMODE_BLEND); | ||
184 | SDL_SetTextureAlphaMod(trackRender.get(), 127); | ||
185 | } | ||
186 | |||
187 | if (layer_ < Layer::object) | ||
188 | { | ||
189 | SDL_SetTextureBlendMode(objectRender.get(), SDL_BLENDMODE_BLEND); | ||
190 | SDL_SetTextureAlphaMod(objectRender.get(), 127); | ||
191 | } | ||
192 | |||
193 | SDL_SetRenderTarget(ren, renderedMap_.get()); | ||
194 | SDL_RenderCopy(ren, mapRender.get(), nullptr, nullptr); | ||
195 | SDL_RenderCopy(ren, trackRender.get(), nullptr, nullptr); | ||
196 | SDL_RenderCopy(ren, objectRender.get(), nullptr, nullptr); | ||
197 | SDL_SetRenderTarget(ren, nullptr); | ||
198 | } | ||
199 | |||
200 | // Copy the rendered map onto the editor. | ||
201 | SDL_Rect mapLoc { | ||
202 | static_cast<int>(BORDER_SIZE.w()), | ||
203 | static_cast<int>(BORDER_SIZE.h()), | ||
204 | static_cast<int>(LEVEL_SIZE.w()), | ||
205 | static_cast<int>(LEVEL_SIZE.h()) | ||
206 | }; | ||
207 | |||
208 | SDL_RenderCopy(ren, renderedMap_.get(), nullptr, &mapLoc); | ||
209 | |||
210 | // If the map is focused, draw an outline around it. | ||
211 | if (mapFocus_) | ||
212 | { | ||
213 | SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); | ||
214 | SDL_RenderDrawRect(ren, &mapLoc); | ||
215 | } | ||
216 | |||
217 | // Draw a box indicating the position of the map cursor. | ||
218 | vec2s cursorLoc = BORDER_SIZE + TILE_SIZE * cursor_; | ||
219 | |||
220 | SDL_Rect cursorRect { | ||
221 | static_cast<int>(cursorLoc.x()), | ||
222 | static_cast<int>(cursorLoc.y()), | ||
223 | static_cast<int>(TILE_SIZE.w()), | ||
224 | static_cast<int>(TILE_SIZE.h()) | ||
225 | }; | ||
226 | |||
227 | SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); | ||
228 | SDL_RenderDrawRect(ren, &cursorRect); | ||
229 | |||
230 | // Draw the tileset for the currently selected layer. | ||
231 | SDL_Rect tilesetLoc { | ||
232 | static_cast<int>(BORDER_SIZE.w() * 2 + LEVEL_SIZE.w()), | ||
233 | static_cast<int>(BORDER_SIZE.h()), | ||
234 | static_cast<int>(TILE_SIZE.w()), | ||
235 | level_.getTileset(layer_).getSize().h() | ||
236 | }; | ||
237 | |||
238 | SDL_SetRenderDrawColor(ren, 255, 255, 255, 255); | ||
239 | SDL_RenderFillRect(ren, &tilesetLoc); | ||
240 | |||
241 | SDL_RenderCopy( | ||
242 | ren, | ||
243 | level_.getTileset(layer_).getImage().get(), | ||
244 | nullptr, | ||
245 | &tilesetLoc); | ||
246 | |||
247 | // If the tileset is focused, draw an outline around it. | ||
248 | if (!mapFocus_) | ||
249 | { | ||
250 | SDL_SetRenderDrawColor(ren, 255, 0, 0, 255); | ||
251 | SDL_RenderDrawRect(ren, &tilesetLoc); | ||
252 | } | ||
253 | |||
254 | // Draw a box indicating which tile is currently selected. | ||
255 | SDL_Rect tileCursorRect { | ||
256 | tilesetLoc.x, | ||
257 | static_cast<int>((1 + selectedTile_) * TILE_SIZE.h()), | ||
258 | static_cast<int>(TILE_SIZE.w()), | ||
259 | static_cast<int>(TILE_SIZE.h()) | ||
260 | }; | ||
261 | |||
262 | SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); | ||
263 | SDL_RenderDrawRect(ren, &tileCursorRect); | ||
40 | } | 264 | } |
diff --git a/src/editor.h b/src/editor.h index dc908b9..dbf50c0 100644 --- a/src/editor.h +++ b/src/editor.h | |||
@@ -3,10 +3,26 @@ | |||
3 | 3 | ||
4 | #include "state.h" | 4 | #include "state.h" |
5 | #include "vector.h" | 5 | #include "vector.h" |
6 | #include "level.h" | ||
7 | #include "input.h" | ||
8 | #include "input_lag.h" | ||
6 | 9 | ||
7 | class Editor : public State { | 10 | class Editor : public State { |
8 | public: | 11 | public: |
9 | 12 | ||
13 | Editor(SDL_Renderer* ren) : level_(ren) | ||
14 | { | ||
15 | surface_ptr bgSurf(IMG_Load("../res/editor_bg.png")); | ||
16 | |||
17 | if (!bgSurf) | ||
18 | { | ||
19 | throw img_error(); | ||
20 | } | ||
21 | |||
22 | background_.reset(SDL_CreateTextureFromSurface(ren, bgSurf.get())); | ||
23 | bgSize_ = { bgSurf->w, bgSurf->h }; | ||
24 | } | ||
25 | |||
10 | void tick( | 26 | void tick( |
11 | double dt, | 27 | double dt, |
12 | const Uint8* keystate) override; | 28 | const Uint8* keystate) override; |
@@ -15,9 +31,23 @@ public: | |||
15 | 31 | ||
16 | private: | 32 | private: |
17 | 33 | ||
34 | Level level_; | ||
35 | |||
18 | texture_ptr background_; | 36 | texture_ptr background_; |
19 | vec2i bgSize_; | 37 | vec2i bgSize_; |
20 | 38 | ||
39 | texture_ptr renderedMap_; | ||
40 | |||
41 | bool mapFocus_ = true; | ||
42 | vec2s cursor_; | ||
43 | |||
44 | size_t selectedTile_ = 0; | ||
45 | |||
46 | Input input_; | ||
47 | InputLag inputLag_; | ||
48 | |||
49 | Layer layer_ = Layer::map; | ||
50 | |||
21 | }; | 51 | }; |
22 | 52 | ||
23 | #endif /* end of include guard: EDITOR_H_8BB54FE3 */ | 53 | #endif /* end of include guard: EDITOR_H_8BB54FE3 */ |
diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..ad8b761 --- /dev/null +++ b/src/input.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef INPUT_H_0FB34C42 | ||
2 | #define INPUT_H_0FB34C42 | ||
3 | |||
4 | #include <SDL.h> | ||
5 | #include <vector> | ||
6 | |||
7 | /** | ||
8 | * Helper class that detects when a key is newly pressed. | ||
9 | */ | ||
10 | class Input { | ||
11 | public: | ||
12 | |||
13 | Input() | ||
14 | { | ||
15 | const Uint8* s = SDL_GetKeyboardState(&length_); | ||
16 | |||
17 | curstate_.assign(s, s + length_); | ||
18 | prevstate_ = curstate_; | ||
19 | } | ||
20 | |||
21 | void tick(const Uint8* keystate) | ||
22 | { | ||
23 | prevstate_ = std::move(curstate_); | ||
24 | curstate_.assign(keystate, keystate + length_); | ||
25 | } | ||
26 | |||
27 | bool wasPressed(int scancode) const | ||
28 | { | ||
29 | return curstate_.at(scancode) && !prevstate_.at(scancode); | ||
30 | } | ||
31 | |||
32 | private: | ||
33 | |||
34 | int length_; | ||
35 | std::vector<Uint8> curstate_; | ||
36 | std::vector<Uint8> prevstate_; | ||
37 | }; | ||
38 | |||
39 | #endif /* end of include guard: INPUT_H_0FB34C42 */ | ||
diff --git a/src/input_lag.h b/src/input_lag.h new file mode 100644 index 0000000..40bc4a1 --- /dev/null +++ b/src/input_lag.h | |||
@@ -0,0 +1,66 @@ | |||
1 | #ifndef INPUT_LAG_H_DF16F381 | ||
2 | #define INPUT_LAG_H_DF16F381 | ||
3 | |||
4 | /** | ||
5 | * Helper class that handles key repeat. | ||
6 | */ | ||
7 | class InputLag { | ||
8 | public: | ||
9 | |||
10 | bool isActive() const | ||
11 | { | ||
12 | return active_; | ||
13 | } | ||
14 | |||
15 | void reset() | ||
16 | { | ||
17 | accum_ = 0.0; | ||
18 | active_ = false; | ||
19 | repeat_ = false; | ||
20 | } | ||
21 | |||
22 | void accumulate(double dt) | ||
23 | { | ||
24 | accum_ += dt; | ||
25 | } | ||
26 | |||
27 | bool step() | ||
28 | { | ||
29 | if (!active_) | ||
30 | { | ||
31 | active_ = true; | ||
32 | |||
33 | return true; | ||
34 | } else if (!repeat_) | ||
35 | { | ||
36 | if (accum_ > delay_) | ||
37 | { | ||
38 | accum_ -= delay_; | ||
39 | repeat_ = true; | ||
40 | |||
41 | return true; | ||
42 | } | ||
43 | } else { | ||
44 | if (accum_ > tick_) | ||
45 | { | ||
46 | accum_ -= tick_; | ||
47 | |||
48 | return true; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | return false; | ||
53 | } | ||
54 | |||
55 | private: | ||
56 | |||
57 | double tick_ = 1.0 / 15.0; | ||
58 | double delay_ = tick_ * 3.0; | ||
59 | |||
60 | double accum_ = 0.0; | ||
61 | bool active_ = false; | ||
62 | bool repeat_ = false; | ||
63 | |||
64 | }; | ||
65 | |||
66 | #endif /* end of include guard: INPUT_LAG_H_DF16F381 */ | ||
diff --git a/src/level.cpp b/src/level.cpp index b97eb70..e22a43f 100644 --- a/src/level.cpp +++ b/src/level.cpp | |||
@@ -7,30 +7,37 @@ texture_ptr Level::render(SDL_Renderer* ren, Layer layer) const | |||
7 | ren, | 7 | ren, |
8 | SDL_PIXELFORMAT_RGBA8888, | 8 | SDL_PIXELFORMAT_RGBA8888, |
9 | SDL_TEXTUREACCESS_TARGET, | 9 | SDL_TEXTUREACCESS_TARGET, |
10 | WINDOW_SIZE.w(), | 10 | LEVEL_SIZE.w(), |
11 | WINDOW_SIZE.h())); | 11 | LEVEL_SIZE.h())); |
12 | 12 | ||
13 | SDL_SetRenderTarget(ren, canvas.get()); | 13 | SDL_SetRenderTarget(ren, canvas.get()); |
14 | SDL_SetTextureBlendMode(canvas.get(), SDL_BLENDMODE_BLEND); | ||
15 | SDL_SetRenderDrawColor(ren, 0, 0, 0, 0); | ||
16 | SDL_RenderFillRect(ren, nullptr); | ||
14 | 17 | ||
15 | for (size_t y = 0; y < size_.h(); y++) | 18 | for (size_t y = 0; y < size_.h(); y++) |
16 | { | 19 | { |
17 | for (size_t x = 0; x < size_.w(); x++) | 20 | for (size_t x = 0; x < size_.w(); x++) |
18 | { | 21 | { |
19 | if (layer == Layer::map) | 22 | SDL_Rect src { |
20 | { | 23 | 0, |
21 | int val = 255 - at(x, y) * 10; | 24 | static_cast<int>(at(x, y, layer) * TILE_SIZE.h()), |
22 | 25 | TILE_SIZE.w(), | |
23 | SDL_SetRenderDrawColor(ren, val, val, val, 255); | 26 | TILE_SIZE.h() |
24 | 27 | }; | |
25 | SDL_Rect rect { | 28 | |
26 | static_cast<int>(x * TILE_SIZE.w()), | 29 | SDL_Rect dest { |
27 | static_cast<int>(y * TILE_SIZE.h()), | 30 | static_cast<int>(x * TILE_SIZE.w()), |
28 | TILE_SIZE.w(), | 31 | static_cast<int>(y * TILE_SIZE.h()), |
29 | TILE_SIZE.h() | 32 | TILE_SIZE.w(), |
30 | }; | 33 | TILE_SIZE.h() |
31 | 34 | }; | |
32 | SDL_RenderFillRect(ren, &rect); | 35 | |
33 | } | 36 | SDL_RenderCopy( |
37 | ren, | ||
38 | getTileset(layer).getImage().get(), | ||
39 | &src, | ||
40 | &dest); | ||
34 | } | 41 | } |
35 | } | 42 | } |
36 | 43 | ||
diff --git a/src/level.h b/src/level.h index bc05837..9b01f64 100644 --- a/src/level.h +++ b/src/level.h | |||
@@ -6,15 +6,22 @@ | |||
6 | #include "vector.h" | 6 | #include "vector.h" |
7 | #include "consts.h" | 7 | #include "consts.h" |
8 | #include "tileset.h" | 8 | #include "tileset.h" |
9 | #include "enums.h" | ||
9 | 10 | ||
10 | class Level { | 11 | class Level { |
11 | public: | 12 | public: |
12 | 13 | ||
13 | Level() | 14 | Level( |
15 | SDL_Renderer* ren) : | ||
16 | mapTileset_(ren, "map.png"), | ||
17 | trackTileset_(ren, "track.png"), | ||
18 | objectTileset_(ren, "object.png") | ||
14 | { | 19 | { |
15 | size_ = LEVEL_SIZE; | 20 | size_ = MAP_SIZE; |
16 | 21 | ||
17 | tiles_.resize(size_.w() * size_.h()); | 22 | mapTiles_.resize(size_.w() * size_.h()); |
23 | trackTiles_.resize(size_.w() * size_.h()); | ||
24 | objectTiles_.resize(size_.w() * size_.h()); | ||
18 | } | 25 | } |
19 | 26 | ||
20 | const vec2s& getSize() const | 27 | const vec2s& getSize() const |
@@ -22,19 +29,48 @@ public: | |||
22 | return size_; | 29 | return size_; |
23 | } | 30 | } |
24 | 31 | ||
25 | size_t at(vec2s pos) const | 32 | size_t at(vec2s pos, Layer layer = Layer::map) const |
26 | { | 33 | { |
27 | return at(pos.x(), pos.y()); | 34 | return at(pos.x(), pos.y(), layer); |
28 | } | 35 | } |
29 | 36 | ||
30 | size_t at(size_t x, size_t y) const | 37 | size_t& at(vec2s pos, Layer layer = Layer::map) |
31 | { | 38 | { |
32 | return tiles_.at(x + size_.w() * y); | 39 | return at(pos.x(), pos.y(), layer); |
33 | } | 40 | } |
34 | 41 | ||
35 | const Tileset& getTileset() const | 42 | size_t at(size_t x, size_t y, Layer layer = Layer::map) const |
36 | { | 43 | { |
37 | return tileset_; | 44 | size_t index = x + size_.w() * y; |
45 | |||
46 | switch (layer) | ||
47 | { | ||
48 | case Layer::map: return mapTiles_.at(index); | ||
49 | case Layer::track: return trackTiles_.at(index); | ||
50 | case Layer::object: return objectTiles_.at(index); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | size_t& at(size_t x, size_t y, Layer layer = Layer::map) | ||
55 | { | ||
56 | size_t index = x + size_.w() * y; | ||
57 | |||
58 | switch (layer) | ||
59 | { | ||
60 | case Layer::map: return mapTiles_.at(index); | ||
61 | case Layer::track: return trackTiles_.at(index); | ||
62 | case Layer::object: return objectTiles_.at(index); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | const Tileset& getTileset(Layer layer) const | ||
67 | { | ||
68 | switch (layer) | ||
69 | { | ||
70 | case Layer::map: return mapTileset_; | ||
71 | case Layer::track: return trackTileset_; | ||
72 | case Layer::object: return objectTileset_; | ||
73 | } | ||
38 | } | 74 | } |
39 | 75 | ||
40 | texture_ptr render(SDL_Renderer* ren, Layer layer) const; | 76 | texture_ptr render(SDL_Renderer* ren, Layer layer) const; |
@@ -42,8 +78,14 @@ public: | |||
42 | private: | 78 | private: |
43 | 79 | ||
44 | vec2s size_; | 80 | vec2s size_; |
45 | std::vector<size_t> tiles_; | 81 | |
46 | Tileset tileset_; | 82 | std::vector<size_t> mapTiles_; |
83 | std::vector<size_t> trackTiles_; | ||
84 | std::vector<size_t> objectTiles_; | ||
85 | |||
86 | Tileset mapTileset_; | ||
87 | Tileset trackTileset_; | ||
88 | Tileset objectTileset_; | ||
47 | }; | 89 | }; |
48 | 90 | ||
49 | #endif /* end of include guard: LEVEL_H_678CFCCF */ | 91 | #endif /* end of include guard: LEVEL_H_678CFCCF */ |
diff --git a/src/main.cpp b/src/main.cpp index cbac5bb..cd8ee3e 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -39,13 +39,13 @@ int main(int argc, char** argv) | |||
39 | throw sdl_error(); | 39 | throw sdl_error(); |
40 | } | 40 | } |
41 | 41 | ||
42 | Level level; | 42 | Level level(ren.get()); |
43 | 43 | ||
44 | std::unique_ptr<State> state; | 44 | std::unique_ptr<State> state; |
45 | 45 | ||
46 | if (argc == 2 && !strcmp(argv[1], "--editor")) | 46 | if (argc == 2 && !strcmp(argv[1], "--editor")) |
47 | { | 47 | { |
48 | state.reset(new Editor()); | 48 | state.reset(new Editor(ren.get())); |
49 | } else { | 49 | } else { |
50 | state.reset(new Simulation(level)); | 50 | state.reset(new Simulation(level)); |
51 | } | 51 | } |
@@ -63,20 +63,12 @@ int main(int argc, char** argv) | |||
63 | 63 | ||
64 | while (SDL_PollEvent(&e)) | 64 | while (SDL_PollEvent(&e)) |
65 | { | 65 | { |
66 | if (e.type == SDL_QUIT) | 66 | if (e.type == SDL_QUIT || |
67 | (e.type == SDL_KEYDOWN && | ||
68 | e.key.keysym.sym == SDLK_ESCAPE)) | ||
67 | { | 69 | { |
68 | quit = true; | 70 | quit = true; |
69 | } else if (e.type == SDL_KEYDOWN) | 71 | break; |
70 | { | ||
71 | switch (e.key.keysym.sym) | ||
72 | { | ||
73 | case SDLK_ESCAPE: | ||
74 | { | ||
75 | quit = true; | ||
76 | |||
77 | break; | ||
78 | } | ||
79 | } | ||
80 | } | 72 | } |
81 | } | 73 | } |
82 | 74 | ||
diff --git a/src/simulation.cpp b/src/simulation.cpp index 4d8ec02..62026a6 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp | |||
@@ -342,7 +342,7 @@ bool Simulation::moveEntityOnGrid( | |||
342 | } | 342 | } |
343 | } | 343 | } |
344 | 344 | ||
345 | if (!level_.getTileset().canEntityMoveTo( | 345 | if (!level_.getTileset(Layer::map).canEntityMoveTo( |
346 | entity.colliderType, | 346 | entity.colliderType, |
347 | level_.at(shouldMoveTo))) | 347 | level_.at(shouldMoveTo))) |
348 | { | 348 | { |
diff --git a/src/tileset.h b/src/tileset.h index 8a565bc..745ea1d 100644 --- a/src/tileset.h +++ b/src/tileset.h | |||
@@ -1,15 +1,53 @@ | |||
1 | #ifndef TILESET_H_B89AE7A1 | 1 | #ifndef TILESET_H_B89AE7A1 |
2 | #define TILESET_H_B89AE7A1 | 2 | #define TILESET_H_B89AE7A1 |
3 | 3 | ||
4 | #include <string> | ||
5 | #include "renderer.h" | ||
4 | #include "enums.h" | 6 | #include "enums.h" |
7 | #include "consts.h" | ||
5 | 8 | ||
6 | class Tileset { | 9 | class Tileset { |
7 | public: | 10 | public: |
8 | 11 | ||
12 | Tileset(SDL_Renderer* ren, std::string filename) | ||
13 | { | ||
14 | surface_ptr surf(IMG_Load(("../res/" + filename).c_str())); | ||
15 | |||
16 | if (!surf) | ||
17 | { | ||
18 | throw img_error(); | ||
19 | } | ||
20 | |||
21 | image_.reset(SDL_CreateTextureFromSurface(ren, surf.get())); | ||
22 | size_ = { surf->w, surf->h }; | ||
23 | numTiles_ = size_.h() / TILE_SIZE.h(); | ||
24 | } | ||
25 | |||
9 | bool canEntityMoveTo(ColliderType collider, size_t tile) const | 26 | bool canEntityMoveTo(ColliderType collider, size_t tile) const |
10 | { | 27 | { |
11 | return true; | 28 | return true; |
12 | } | 29 | } |
30 | |||
31 | const texture_ptr& getImage() const | ||
32 | { | ||
33 | return image_; | ||
34 | } | ||
35 | |||
36 | const vec2i& getSize() const | ||
37 | { | ||
38 | return size_; | ||
39 | } | ||
40 | |||
41 | size_t getNumTiles() const | ||
42 | { | ||
43 | return numTiles_; | ||
44 | } | ||
45 | |||
46 | private: | ||
47 | |||
48 | texture_ptr image_; | ||
49 | vec2i size_; | ||
50 | size_t numTiles_; | ||
13 | }; | 51 | }; |
14 | 52 | ||
15 | #endif /* end of include guard: TILESET_H_B89AE7A1 */ | 53 | #endif /* end of include guard: TILESET_H_B89AE7A1 */ |