diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2022-03-12 14:12:42 -0500 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2022-03-12 14:12:42 -0500 |
commit | 4b6e5eb5d3e0733c239a7a231da91a9977c38246 (patch) | |
tree | 90b18271f180c56efc9995458714b2b0aa3725fc | |
parent | be9ccb73bc20b03f62c77f5d529602a10ef4eda9 (diff) | |
download | ether-4b6e5eb5d3e0733c239a7a231da91a9977c38246.tar.gz ether-4b6e5eb5d3e0733c239a7a231da91a9977c38246.tar.bz2 ether-4b6e5eb5d3e0733c239a7a231da91a9977c38246.zip |
dynamic wall and floor textures
-rwxr-xr-x | res/runninbloods.png | bin | 0 -> 34239 bytes | |||
-rw-r--r-- | src/game.h | 13 | ||||
-rw-r--r-- | src/interpolation.h | 38 | ||||
-rw-r--r-- | src/main.cpp | 298 | ||||
-rw-r--r-- | src/renderer.cpp | 80 | ||||
-rw-r--r-- | src/renderer.h | 1 |
6 files changed, 342 insertions, 88 deletions
diff --git a/res/runninbloods.png b/res/runninbloods.png new file mode 100755 index 0000000..5d18f4c --- /dev/null +++ b/res/runninbloods.png | |||
Binary files differ | |||
diff --git a/src/game.h b/src/game.h index 2fd0f05..c91a001 100644 --- a/src/game.h +++ b/src/game.h | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "muxer.h" | 9 | #include "muxer.h" |
10 | #include "timer.h" | 10 | #include "timer.h" |
11 | #include "animation.h" | 11 | #include "animation.h" |
12 | #include "interpolation.h" | ||
12 | 13 | ||
13 | const int GAME_WIDTH = 640*2; | 14 | const int GAME_WIDTH = 640*2; |
14 | const int GAME_HEIGHT = 480*2; | 15 | const int GAME_HEIGHT = 480*2; |
@@ -19,6 +20,10 @@ const int ZOOM_X_FACTOR = 8; | |||
19 | const int ZOOM_Y_FACTOR = 6; | 20 | const int ZOOM_Y_FACTOR = 6; |
20 | const int RADIUS = 8; | 21 | const int RADIUS = 8; |
21 | 22 | ||
23 | constexpr int TilesetIndex(int x, int y) { | ||
24 | return x + y * 24; | ||
25 | } | ||
26 | |||
22 | enum class Tile { | 27 | enum class Tile { |
23 | Floor, | 28 | Floor, |
24 | Wall, | 29 | Wall, |
@@ -75,6 +80,8 @@ struct MapData { | |||
75 | Source lightType = Source::None; | 80 | Source lightType = Source::None; |
76 | int lightRadius = 0; | 81 | int lightRadius = 0; |
77 | std::set<coord> litTiles; | 82 | std::set<coord> litTiles; |
83 | int renderId = -1; | ||
84 | bool dirtyRender = true; | ||
78 | }; | 85 | }; |
79 | 86 | ||
80 | class Game { | 87 | class Game { |
@@ -97,11 +104,14 @@ public: | |||
97 | std::list<Kickup> kickups; | 104 | std::list<Kickup> kickups; |
98 | int litSpots = 0; | 105 | int litSpots = 0; |
99 | bool dirtyLighting = true; | 106 | bool dirtyLighting = true; |
107 | bool dirtyRender = true; | ||
100 | size_t numLamps = 0; | 108 | size_t numLamps = 0; |
101 | size_t numDust = 0; | 109 | size_t numDust = 0; |
102 | 110 | ||
103 | int player_x = 0; | 111 | int player_x = 0; |
104 | int player_y = 0; | 112 | int player_y = 0; |
113 | int player_oldx = 0; | ||
114 | int player_oldy = 0; | ||
105 | bool renderPlayer = true; | 115 | bool renderPlayer = true; |
106 | Animation playerAnim {"../res/player_anim.txt"}; | 116 | Animation playerAnim {"../res/player_anim.txt"}; |
107 | 117 | ||
@@ -123,6 +133,9 @@ public: | |||
123 | Input lastInput; | 133 | Input lastInput; |
124 | bool alreadyBumped = false; | 134 | bool alreadyBumped = false; |
125 | Timer bumpCooldown = {500}; | 135 | Timer bumpCooldown = {500}; |
136 | Interpolation moveProgress; | ||
137 | bool moving = false; | ||
138 | bool queueDash = false; | ||
126 | 139 | ||
127 | }; | 140 | }; |
128 | 141 | ||
diff --git a/src/interpolation.h b/src/interpolation.h new file mode 100644 index 0000000..68a6221 --- /dev/null +++ b/src/interpolation.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef INTERPOLATION_H_861230A8 | ||
2 | #define INTERPOLATION_H_861230A8 | ||
3 | |||
4 | class Interpolation { | ||
5 | public: | ||
6 | |||
7 | void start(int length) { | ||
8 | length_ = length; | ||
9 | thus_ = 0; | ||
10 | } | ||
11 | |||
12 | void tick(double dt) { | ||
13 | if (thus_ < length_) { | ||
14 | thus_ += dt; | ||
15 | if (thus_ >= length_) { | ||
16 | thus_ = length_; | ||
17 | } | ||
18 | } | ||
19 | } | ||
20 | |||
21 | // Info | ||
22 | |||
23 | double getProgress(double from, double to) const { | ||
24 | return (to - from) / length_ * thus_ + from; | ||
25 | } | ||
26 | |||
27 | bool isComplete() const { return thus_ == length_; } | ||
28 | |||
29 | private: | ||
30 | |||
31 | double progress_ = 0.0; | ||
32 | double dest_ = 0.0; | ||
33 | double start_ = 0.0; | ||
34 | double length_ = 0.0; | ||
35 | double thus_ = 0.0; | ||
36 | }; | ||
37 | |||
38 | #endif /* end of include guard: INTERPOLATION_H_861230A8 */ | ||
diff --git a/src/main.cpp b/src/main.cpp index 5178110..149e1cf 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -5,15 +5,25 @@ | |||
5 | #include "game.h" | 5 | #include "game.h" |
6 | #include "renderer.h" | 6 | #include "renderer.h" |
7 | 7 | ||
8 | void incrementIfSet(Game& game, int& count, int x, int y, Tile val = Tile::Wall) | 8 | inline bool isTileSetOrNotLit(const Map<MapData>& map, int x, int y) |
9 | { | 9 | { |
10 | if (game.map.inBounds(x, y) && game.map.at(x,y).tile == val) | 10 | return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit)); |
11 | } | ||
12 | |||
13 | inline bool isTileSet(const Map<MapData>& map, int x, int y, Tile val = Tile::Wall) | ||
14 | { | ||
15 | return (map.inBounds(x, y) && map.at(x,y).tile == val); | ||
16 | } | ||
17 | |||
18 | inline void incrementIfSet(const Game& game, int& count, int x, int y, Tile val = Tile::Wall) | ||
19 | { | ||
20 | if (isTileSet(game.map, x, y, val)) | ||
11 | { | 21 | { |
12 | count++; | 22 | count++; |
13 | } | 23 | } |
14 | } | 24 | } |
15 | 25 | ||
16 | int getZoomLevel(const Game& game) { | 26 | inline int getZoomLevel(const Game& game) { |
17 | return (game.curZoom - INIT_ZOOM) / 2; | 27 | return (game.curZoom - INIT_ZOOM) / 2; |
18 | } | 28 | } |
19 | 29 | ||
@@ -65,6 +75,11 @@ void tick( | |||
65 | } else { | 75 | } else { |
66 | temp.at(x,y).tile = Tile::Floor; | 76 | temp.at(x,y).tile = Tile::Floor; |
67 | } | 77 | } |
78 | |||
79 | if (temp.at(x,y).tile != game.map.at(x,y).tile) { | ||
80 | temp.at(x,y).dirtyRender = true; | ||
81 | game.dirtyRender = true; | ||
82 | } | ||
68 | } | 83 | } |
69 | } | 84 | } |
70 | 85 | ||
@@ -98,9 +113,13 @@ bool movePlayer(Game& game, int x, int y) | |||
98 | game.numDust++; | 113 | game.numDust++; |
99 | } | 114 | } |
100 | 115 | ||
116 | game.player_oldx = game.player_x; | ||
117 | game.player_oldy = game.player_y; | ||
101 | game.player_x = x; | 118 | game.player_x = x; |
102 | game.player_y = y; | 119 | game.player_y = y; |
103 | game.muxer.setPlayerLoc(x, y); | 120 | game.muxer.setPlayerLoc(x, y); |
121 | game.moving = true; | ||
122 | game.moveProgress.start(33); | ||
104 | 123 | ||
105 | game.dirtyLighting = true; | 124 | game.dirtyLighting = true; |
106 | 125 | ||
@@ -119,12 +138,17 @@ bool movePlayer(Game& game, int x, int y) | |||
119 | void recalculateLighting(Game& game) | 138 | void recalculateLighting(Game& game) |
120 | { | 139 | { |
121 | game.litSpots = 0; | 140 | game.litSpots = 0; |
141 | game.dirtyRender = true; | ||
122 | 142 | ||
123 | for (MapData& md : game.map.data()) | 143 | for (MapData& md : game.map.data()) |
124 | { | 144 | { |
125 | md.wasLit = md.lit; | 145 | md.wasLit = md.lit; |
126 | md.lit = false; | 146 | md.lit = false; |
127 | md.litTiles.clear(); | 147 | md.litTiles.clear(); |
148 | |||
149 | if (md.tile == Tile::Wall) { | ||
150 | md.dirtyRender = true; | ||
151 | } | ||
128 | } | 152 | } |
129 | 153 | ||
130 | fov_settings_type fov; | 154 | fov_settings_type fov; |
@@ -203,6 +227,103 @@ void recalculateLighting(Game& game) | |||
203 | game.dirtyLighting = false; | 227 | game.dirtyLighting = false; |
204 | } | 228 | } |
205 | 229 | ||
230 | void recalculateRender(Game& game) { | ||
231 | for (int y = game.map.getTop(); y < game.map.getBottom(); y++) | ||
232 | { | ||
233 | for (int x = game.map.getLeft(); x < game.map.getRight(); x++) | ||
234 | { | ||
235 | if (game.map.at(x,y).dirtyRender) { | ||
236 | game.map.at(x,y).dirtyRender = false; | ||
237 | |||
238 | if (game.map.at(x,y).tile == Tile::Floor) { | ||
239 | if (std::bernoulli_distribution(0.05)(game.rng)) { | ||
240 | static const std::vector<int> furnishings { | ||
241 | TilesetIndex(20, 16), | ||
242 | TilesetIndex(21, 2), | ||
243 | TilesetIndex(22, 2), | ||
244 | TilesetIndex(21, 3), | ||
245 | TilesetIndex(22, 3)}; | ||
246 | game.map.at(x,y).renderId = furnishings.at(std::uniform_int_distribution<int>(0, furnishings.size()-1)(game.rng)); | ||
247 | } else { | ||
248 | game.map.at(x,y).renderId = -1; | ||
249 | } | ||
250 | } else if (game.map.at(x,y).tile == Tile::Wall) { | ||
251 | static bool initWalls = false; | ||
252 | static std::vector<int> wallRenders(256, TilesetIndex(0, 0)); | ||
253 | if (!initWalls) { | ||
254 | initWalls = true; | ||
255 | |||
256 | // Start in top left and go clockwise. | ||
257 | wallRenders[0b00011100] = TilesetIndex(16, 14); | ||
258 | wallRenders[0b00111100] = TilesetIndex(16, 14); | ||
259 | wallRenders[0b00011110] = TilesetIndex(16, 14); | ||
260 | wallRenders[0b00111110] = TilesetIndex(16, 14); | ||
261 | |||
262 | wallRenders[0b00011111] = TilesetIndex(17, 14); | ||
263 | wallRenders[0b10011111] = TilesetIndex(17, 14); | ||
264 | wallRenders[0b00111111] = TilesetIndex(17, 14); | ||
265 | wallRenders[0b10111111] = TilesetIndex(17, 14); | ||
266 | |||
267 | wallRenders[0b00000111] = TilesetIndex(18, 14); | ||
268 | wallRenders[0b00001111] = TilesetIndex(18, 14); | ||
269 | wallRenders[0b10000111] = TilesetIndex(18, 14); | ||
270 | wallRenders[0b10001111] = TilesetIndex(18, 14); | ||
271 | |||
272 | wallRenders[0b01111100] = TilesetIndex(16, 15); | ||
273 | wallRenders[0b11111100] = TilesetIndex(16, 15); | ||
274 | wallRenders[0b01111110] = TilesetIndex(16, 15); | ||
275 | wallRenders[0b11111110] = TilesetIndex(16, 15); | ||
276 | |||
277 | wallRenders[0b11000111] = TilesetIndex(18, 15); | ||
278 | wallRenders[0b11001111] = TilesetIndex(18, 15); | ||
279 | wallRenders[0b11100111] = TilesetIndex(18, 15); | ||
280 | wallRenders[0b11101111] = TilesetIndex(18, 15); | ||
281 | |||
282 | wallRenders[0b01110000] = TilesetIndex(16, 16); | ||
283 | wallRenders[0b01111000] = TilesetIndex(16, 16); | ||
284 | wallRenders[0b11110000] = TilesetIndex(16, 16); | ||
285 | wallRenders[0b11111000] = TilesetIndex(16, 16); | ||
286 | |||
287 | wallRenders[0b11110001] = TilesetIndex(17, 16); | ||
288 | wallRenders[0b11110011] = TilesetIndex(17, 16); | ||
289 | wallRenders[0b11111001] = TilesetIndex(17, 16); | ||
290 | wallRenders[0b11111011] = TilesetIndex(17, 16); | ||
291 | |||
292 | wallRenders[0b11000001] = TilesetIndex(18, 16); | ||
293 | wallRenders[0b11000011] = TilesetIndex(18, 16); | ||
294 | wallRenders[0b11100001] = TilesetIndex(18, 16); | ||
295 | wallRenders[0b11100011] = TilesetIndex(18, 16); | ||
296 | |||
297 | |||
298 | wallRenders[0b11110111] = TilesetIndex(21, 14); | ||
299 | wallRenders[0b11111101] = TilesetIndex(22, 14); | ||
300 | wallRenders[0b11011111] = TilesetIndex(21, 15); | ||
301 | wallRenders[0b01111111] = TilesetIndex(22, 15); | ||
302 | } | ||
303 | |||
304 | int renderDesc = 0; | ||
305 | if (isTileSetOrNotLit(game.map, x-1, y-1)) renderDesc |= (1 << 7); | ||
306 | if (isTileSetOrNotLit(game.map, x , y-1)) renderDesc |= (1 << 6); | ||
307 | if (isTileSetOrNotLit(game.map, x+1, y-1)) renderDesc |= (1 << 5); | ||
308 | if (isTileSetOrNotLit(game.map, x+1, y )) renderDesc |= (1 << 4); | ||
309 | if (isTileSetOrNotLit(game.map, x+1, y+1)) renderDesc |= (1 << 3); | ||
310 | if (isTileSetOrNotLit(game.map, x , y+1)) renderDesc |= (1 << 2); | ||
311 | if (isTileSetOrNotLit(game.map, x-1, y+1)) renderDesc |= (1 << 1); | ||
312 | if (isTileSetOrNotLit(game.map, x-1, y )) renderDesc |= (1 << 0); | ||
313 | |||
314 | game.map.at(x,y).renderId = wallRenders.at(renderDesc); | ||
315 | |||
316 | if (wallRenders.at(renderDesc) == 0 && renderDesc != 255) { | ||
317 | std::cout << renderDesc << std::endl; | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | |||
324 | game.dirtyRender = false; | ||
325 | } | ||
326 | |||
206 | bool processKeys(Game& game, const Input& keystate) | 327 | bool processKeys(Game& game, const Input& keystate) |
207 | { | 328 | { |
208 | int px = game.player_x; | 329 | int px = game.player_x; |
@@ -435,6 +556,80 @@ void setZoom(Game& game, size_t zoom) | |||
435 | } | 556 | } |
436 | } | 557 | } |
437 | 558 | ||
559 | void performDash(Game& game, std::mt19937& rng) { | ||
560 | if (game.map.at(game.player_x, game.player_y).tile == | ||
561 | Tile::Floor) | ||
562 | { | ||
563 | std::vector<coord> freeSpaces; | ||
564 | |||
565 | auto addIfFree = [&] (int x, int y) { | ||
566 | if (game.map.inBounds(x,y) && | ||
567 | game.map.at(x,y).tile == Tile::Floor) | ||
568 | { | ||
569 | freeSpaces.emplace_back(x, y); | ||
570 | } | ||
571 | }; | ||
572 | |||
573 | addIfFree(game.player_x - 1, game.player_y - 1); | ||
574 | addIfFree(game.player_x , game.player_y - 1); | ||
575 | addIfFree(game.player_x + 1, game.player_y - 1); | ||
576 | addIfFree(game.player_x - 1, game.player_y ); | ||
577 | addIfFree(game.player_x + 1, game.player_y ); | ||
578 | addIfFree(game.player_x - 1, game.player_y + 1); | ||
579 | addIfFree(game.player_x , game.player_y + 1); | ||
580 | addIfFree(game.player_x + 1, game.player_y + 1); | ||
581 | |||
582 | if (!freeSpaces.empty()) | ||
583 | { | ||
584 | game.map.at(game.player_x, game.player_y).tile = Tile::Lamp; | ||
585 | game.numLamps++; | ||
586 | game.dirtyLighting = true; | ||
587 | kickUpDust(game, game.player_x, game.player_y, 0); | ||
588 | game.muxer.playSoundAtPosition("drop", game.player_x, game.player_y); | ||
589 | |||
590 | if (game.firstInput) | ||
591 | { | ||
592 | for (int i = 0; i < 5; i++) | ||
593 | { | ||
594 | if (!processKeys(game, game.lastInput)) | ||
595 | { | ||
596 | std::uniform_int_distribution<int> freeDist( | ||
597 | 0, freeSpaces.size() - 1); | ||
598 | |||
599 | int freeIndex = freeDist(rng); | ||
600 | coord& moveTo = freeSpaces[freeIndex]; | ||
601 | |||
602 | movePlayer( | ||
603 | game, | ||
604 | std::get<0>(moveTo), | ||
605 | std::get<1>(moveTo)); | ||
606 | } | ||
607 | |||
608 | tick( | ||
609 | game, | ||
610 | game.player_x - (RADIUS - 1), | ||
611 | game.player_y - (RADIUS - 1), | ||
612 | game.player_x + RADIUS, | ||
613 | game.player_y + RADIUS); | ||
614 | } | ||
615 | } else { | ||
616 | std::uniform_int_distribution<int> freeDist( | ||
617 | 0, freeSpaces.size() - 1); | ||
618 | |||
619 | int freeIndex = freeDist(rng); | ||
620 | coord& moveTo = freeSpaces[freeIndex]; | ||
621 | |||
622 | movePlayer( | ||
623 | game, | ||
624 | std::get<0>(moveTo), | ||
625 | std::get<1>(moveTo)); | ||
626 | } | ||
627 | |||
628 | //game.muxer.playSoundAtPosition("dash", game.player_x, game.player_y); | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | |||
438 | int main(int, char**) | 633 | int main(int, char**) |
439 | { | 634 | { |
440 | std::random_device randomEngine; | 635 | std::random_device randomEngine; |
@@ -527,76 +722,10 @@ int main(int, char**) | |||
527 | { | 722 | { |
528 | if (losing == LoseState::None) | 723 | if (losing == LoseState::None) |
529 | { | 724 | { |
530 | if (game.map.at(game.player_x, game.player_y).tile == | 725 | if (game.moving) { |
531 | Tile::Floor) | 726 | game.queueDash = true; |
532 | { | 727 | } else { |
533 | std::vector<coord> freeSpaces; | 728 | performDash(game, rng); |
534 | |||
535 | auto addIfFree = [&] (int x, int y) { | ||
536 | if (game.map.inBounds(x,y) && | ||
537 | game.map.at(x,y).tile == Tile::Floor) | ||
538 | { | ||
539 | freeSpaces.emplace_back(x, y); | ||
540 | } | ||
541 | }; | ||
542 | |||
543 | addIfFree(game.player_x - 1, game.player_y - 1); | ||
544 | addIfFree(game.player_x , game.player_y - 1); | ||
545 | addIfFree(game.player_x + 1, game.player_y - 1); | ||
546 | addIfFree(game.player_x - 1, game.player_y ); | ||
547 | addIfFree(game.player_x + 1, game.player_y ); | ||
548 | addIfFree(game.player_x - 1, game.player_y + 1); | ||
549 | addIfFree(game.player_x , game.player_y + 1); | ||
550 | addIfFree(game.player_x + 1, game.player_y + 1); | ||
551 | |||
552 | if (!freeSpaces.empty()) | ||
553 | { | ||
554 | game.map.at(game.player_x, game.player_y).tile = Tile::Lamp; | ||
555 | game.numLamps++; | ||
556 | game.dirtyLighting = true; | ||
557 | kickUpDust(game, game.player_x, game.player_y, 0); | ||
558 | game.muxer.playSoundAtPosition("drop", game.player_x, game.player_y); | ||
559 | |||
560 | if (game.firstInput) | ||
561 | { | ||
562 | for (int i = 0; i < 5; i++) | ||
563 | { | ||
564 | if (!processKeys(game, game.lastInput)) | ||
565 | { | ||
566 | std::uniform_int_distribution<int> freeDist( | ||
567 | 0, freeSpaces.size() - 1); | ||
568 | |||
569 | int freeIndex = freeDist(rng); | ||
570 | coord& moveTo = freeSpaces[freeIndex]; | ||
571 | |||
572 | movePlayer( | ||
573 | game, | ||
574 | std::get<0>(moveTo), | ||
575 | std::get<1>(moveTo)); | ||
576 | } | ||
577 | |||
578 | tick( | ||
579 | game, | ||
580 | game.player_x - (RADIUS - 1), | ||
581 | game.player_y - (RADIUS - 1), | ||
582 | game.player_x + RADIUS, | ||
583 | game.player_y + RADIUS); | ||
584 | } | ||
585 | } else { | ||
586 | std::uniform_int_distribution<int> freeDist( | ||
587 | 0, freeSpaces.size() - 1); | ||
588 | |||
589 | int freeIndex = freeDist(rng); | ||
590 | coord& moveTo = freeSpaces[freeIndex]; | ||
591 | |||
592 | movePlayer( | ||
593 | game, | ||
594 | std::get<0>(moveTo), | ||
595 | std::get<1>(moveTo)); | ||
596 | } | ||
597 | |||
598 | //game.muxer.playSoundAtPosition("dash", game.player_x, game.player_y); | ||
599 | } | ||
600 | } | 729 | } |
601 | } | 730 | } |
602 | 731 | ||
@@ -617,6 +746,13 @@ int main(int, char**) | |||
617 | game.alreadyBumped = false; | 746 | game.alreadyBumped = false; |
618 | } | 747 | } |
619 | 748 | ||
749 | if (game.queueDash && !game.moving) { | ||
750 | game.queueDash = false; | ||
751 | if (state[SDL_SCANCODE_SPACE]) { | ||
752 | performDash(game, rng); | ||
753 | } | ||
754 | } | ||
755 | |||
620 | if (keystate.left || keystate.right || keystate.up || keystate.down) | 756 | if (keystate.left || keystate.right || keystate.up || keystate.down) |
621 | { | 757 | { |
622 | game.firstInput = true; | 758 | game.firstInput = true; |
@@ -657,9 +793,18 @@ int main(int, char**) | |||
657 | { | 793 | { |
658 | case LoseState::None: | 794 | case LoseState::None: |
659 | { | 795 | { |
796 | if (game.moving) { | ||
797 | game.moveProgress.tick(frameTime); | ||
798 | if (game.moveProgress.isComplete()) { | ||
799 | game.moving = false; | ||
800 | } | ||
801 | } | ||
802 | |||
660 | while (inputAcc >= inputDt) | 803 | while (inputAcc >= inputDt) |
661 | { | 804 | { |
662 | processKeys(game, keystate); | 805 | if (!game.moving) { |
806 | processKeys(game, keystate); | ||
807 | } | ||
663 | 808 | ||
664 | inputAcc -= inputDt; | 809 | inputAcc -= inputDt; |
665 | } | 810 | } |
@@ -747,6 +892,7 @@ int main(int, char**) | |||
747 | } else { | 892 | } else { |
748 | game.map.at(x,y).tile = Tile::Floor; | 893 | game.map.at(x,y).tile = Tile::Floor; |
749 | } | 894 | } |
895 | game.map.at(x,y).dirtyRender = true; | ||
750 | } | 896 | } |
751 | } | 897 | } |
752 | } | 898 | } |
@@ -759,6 +905,10 @@ int main(int, char**) | |||
759 | setZoom(game, game.litSpots / 1500 * 2 + INIT_ZOOM); | 905 | setZoom(game, game.litSpots / 1500 * 2 + INIT_ZOOM); |
760 | } | 906 | } |
761 | 907 | ||
908 | if (game.dirtyRender) { | ||
909 | recalculateRender(game); | ||
910 | } | ||
911 | |||
762 | zoomAcc += frameTime; | 912 | zoomAcc += frameTime; |
763 | 913 | ||
764 | while (zoomAcc >= zoomDt) | 914 | while (zoomAcc >= zoomDt) |
diff --git a/src/renderer.cpp b/src/renderer.cpp index 0aaa14a..00b557a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -122,6 +122,18 @@ Renderer::Renderer() | |||
122 | } | 122 | } |
123 | 123 | ||
124 | SDL_SetTextureBlendMode(playerSheet_.get(), SDL_BLENDMODE_BLEND); | 124 | SDL_SetTextureBlendMode(playerSheet_.get(), SDL_BLENDMODE_BLEND); |
125 | |||
126 | { | ||
127 | surface_ptr pfs(IMG_Load("../res/runninbloods.png")); | ||
128 | if (!pfs) | ||
129 | { | ||
130 | throw img_error(); | ||
131 | } | ||
132 | |||
133 | tileset_ = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), pfs.get())); | ||
134 | } | ||
135 | |||
136 | SDL_SetTextureBlendMode(tileset_.get(), SDL_BLENDMODE_BLEND); | ||
125 | } | 137 | } |
126 | 138 | ||
127 | void Renderer::render( | 139 | void Renderer::render( |
@@ -151,12 +163,19 @@ void Renderer::render( | |||
151 | for (int x = game.map.getLeft(); x < game.map.getRight(); x++) | 163 | for (int x = game.map.getLeft(); x < game.map.getRight(); x++) |
152 | { | 164 | { |
153 | bool draw = true; | 165 | bool draw = true; |
166 | bool drawColour = false; | ||
167 | SDL_Rect rect { | ||
168 | game.map.getTrueX(x) * TILE_WIDTH, | ||
169 | game.map.getTrueY(y) * TILE_HEIGHT, | ||
170 | TILE_WIDTH, | ||
171 | TILE_HEIGHT}; | ||
154 | 172 | ||
155 | if (!game.map.at(x,y).lit) | 173 | if (!game.map.at(x,y).lit) |
156 | { | 174 | { |
157 | if (drawDark) | 175 | if (drawDark) |
158 | { | 176 | { |
159 | SDL_SetRenderDrawColor(ren_.get(), 40, 40, 40, 255); | 177 | SDL_SetRenderDrawColor(ren_.get(), 40, 40, 40, 255); |
178 | drawColour = true; | ||
160 | } else { | 179 | } else { |
161 | draw = false; | 180 | draw = false; |
162 | } | 181 | } |
@@ -186,6 +205,7 @@ void Renderer::render( | |||
186 | case Tile::Lamp: | 205 | case Tile::Lamp: |
187 | { | 206 | { |
188 | SDL_SetRenderDrawColor(ren_.get(), 0, 255, 255, alpha); | 207 | SDL_SetRenderDrawColor(ren_.get(), 0, 255, 255, alpha); |
208 | drawColour = true; | ||
189 | break; | 209 | break; |
190 | } | 210 | } |
191 | } | 211 | } |
@@ -193,22 +213,47 @@ void Renderer::render( | |||
193 | 213 | ||
194 | if (draw) | 214 | if (draw) |
195 | { | 215 | { |
196 | SDL_Rect rect { | 216 | if (game.map.at(x,y).tile == Tile::Floor || game.map.at(x,y).tile == Tile::Dust) { |
197 | game.map.getTrueX(x) * TILE_WIDTH, | 217 | SDL_Rect tileRect {17 * 16, 15 * 16, 16, 16}; |
198 | game.map.getTrueY(y) * TILE_HEIGHT, | 218 | SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect); |
199 | TILE_WIDTH, | 219 | |
200 | TILE_HEIGHT}; | 220 | if (game.map.at(x,y).renderId != -1) { |
201 | 221 | tileRect.x = game.map.at(x,y).renderId % 24 * 16; | |
202 | SDL_RenderFillRect(ren_.get(), &rect); | 222 | tileRect.y = game.map.at(x,y).renderId / 24 * 16; |
223 | SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect); | ||
224 | } | ||
225 | } else if (game.map.at(x,y).tile == Tile::Wall) { | ||
226 | SDL_Rect tileRect { | ||
227 | game.map.at(x,y).renderId % 24 * 16, | ||
228 | game.map.at(x,y).renderId / 24 * 16, | ||
229 | 16, | ||
230 | 16}; | ||
231 | |||
232 | SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect); | ||
233 | } | ||
203 | 234 | ||
204 | if ((game.player_x == x && game.player_y == y) && game.renderPlayer) | 235 | if (drawColour) { |
205 | { | 236 | SDL_RenderFillRect(ren_.get(), &rect); |
206 | SDL_RenderCopy(ren_.get(), playerSheet_.get(), &game.playerAnim.getRenderRect(), &rect); | ||
207 | } | 237 | } |
208 | } | 238 | } |
209 | } | 239 | } |
210 | } | 240 | } |
211 | 241 | ||
242 | if (game.renderPlayer) { | ||
243 | SDL_Rect rect { | ||
244 | game.map.getTrueX(game.player_x) * TILE_WIDTH, | ||
245 | game.map.getTrueY(game.player_y) * TILE_HEIGHT, | ||
246 | TILE_WIDTH, | ||
247 | TILE_HEIGHT}; | ||
248 | |||
249 | if (game.moving) { | ||
250 | rect.x = game.moveProgress.getProgress(game.map.getTrueX(game.player_oldx) * TILE_WIDTH, rect.x); | ||
251 | rect.y = game.moveProgress.getProgress(game.map.getTrueY(game.player_oldy) * TILE_HEIGHT, rect.y); | ||
252 | } | ||
253 | |||
254 | SDL_RenderCopy(ren_.get(), playerSheet_.get(), &game.playerAnim.getRenderRect(), &rect); | ||
255 | } | ||
256 | |||
212 | texture_ptr mask( | 257 | texture_ptr mask( |
213 | SDL_CreateTexture( | 258 | SDL_CreateTexture( |
214 | ren_.get(), | 259 | ren_.get(), |
@@ -250,10 +295,17 @@ void Renderer::render( | |||
250 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); | 295 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); |
251 | SDL_RenderClear(ren_.get()); | 296 | SDL_RenderClear(ren_.get()); |
252 | 297 | ||
253 | int fadeX = game.map.getTrueX(x) - game.map.at(x,y).lightRadius; | 298 | int posToUseX = game.map.getTrueX(x); |
254 | int fadeY = game.map.getTrueY(y) - game.map.at(x,y).lightRadius; | 299 | int posToUseY = game.map.getTrueY(y); |
255 | int fadeRight = game.map.getTrueX(x) + game.map.at(x,y).lightRadius; | 300 | if (game.map.at(x,y).lightType == Source::Player && game.moving) { |
256 | int fadeBottom = game.map.getTrueY(y) + game.map.at(x,y).lightRadius; | 301 | posToUseX = game.moveProgress.getProgress(game.map.getTrueX(game.player_oldx), posToUseX); |
302 | posToUseY = game.moveProgress.getProgress(game.map.getTrueY(game.player_oldy), posToUseY); | ||
303 | } | ||
304 | |||
305 | int fadeX = posToUseX - game.map.at(x,y).lightRadius; | ||
306 | int fadeY = posToUseY - game.map.at(x,y).lightRadius; | ||
307 | int fadeRight = posToUseX + game.map.at(x,y).lightRadius; | ||
308 | int fadeBottom = posToUseY + game.map.at(x,y).lightRadius; | ||
257 | 309 | ||
258 | SDL_Rect fadeRect { | 310 | SDL_Rect fadeRect { |
259 | fadeX * TILE_WIDTH, | 311 | fadeX * TILE_WIDTH, |
diff --git a/src/renderer.h b/src/renderer.h index 0416c9e..8551e26 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
@@ -130,6 +130,7 @@ private: | |||
130 | texture_ptr lampFade_; | 130 | texture_ptr lampFade_; |
131 | texture_ptr dustFade_; | 131 | texture_ptr dustFade_; |
132 | texture_ptr playerSheet_; | 132 | texture_ptr playerSheet_; |
133 | texture_ptr tileset_; | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | #endif /* end of include guard: RENDERER_H_6A58EC30 */ | 136 | #endif /* end of include guard: RENDERER_H_6A58EC30 */ |