From 72e83df4876d799cc7b7993813533041a112e250 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 29 May 2018 16:32:28 -0400 Subject: dust kickup spreads outward instead of being instantaneous --- src/main.cpp | 194 ++++++++++++++++++++++++++++++++++++------------------- src/untitled.txt | 0 src/util.h | 20 ++++++ 3 files changed, 149 insertions(+), 65 deletions(-) delete mode 100644 src/untitled.txt create mode 100644 src/util.h (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 2840439..e26a5a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,10 +2,11 @@ #include #include #include +#include #include #include -#include #include +#include "util.h" class sdl_error : public std::logic_error { public: @@ -59,6 +60,14 @@ struct Input { bool down = false; }; +struct Kickup { + int x; + int y; + size_t cur; + size_t radius; + size_t chain; +}; + class Map { public: @@ -73,7 +82,9 @@ public: std::vector lighting; std::vector oldLighting; std::vector lightStrength; + std::list kickups; int lightedSpots = 0; + bool dirtyLighting = true; }; int player_x = VIEW_WIDTH / 2; @@ -210,6 +221,8 @@ void movePlayer(int x, int y, Map& map) player_x = x; player_y = y; + + map.dirtyLighting = true; } } @@ -266,22 +279,19 @@ void recalculateLighting(Map& map, fov_settings_type* fov) { for (int x = 0; x < VIEW_WIDTH; x++) { - if ((player_x == x && player_y == y) || map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) + if ((player_x == x && player_y == y) || + map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || + map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) { fov_circle(fov, static_cast(&map), nullptr, x, y, RADIUS); - } - if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp || - map.tiles[x+VIEW_WIDTH*y] == Tile::Dust) - { map.lighting[x+VIEW_WIDTH*y] = true; map.lightStrength[x+VIEW_WIDTH*y] = 1.0; } } } - map.lighting[player_x+VIEW_WIDTH*player_y] = true; - map.lightStrength[player_x+VIEW_WIDTH*player_y] = 1.0; + map.dirtyLighting = false; } void processKeys(Map& map, const Input& keystate) @@ -315,6 +325,81 @@ void processKeys(Map& map, const Input& keystate) } } +void kickUpDust(Map& map, int x, int y, size_t chain) +{ + std::cout << "kickup " << x << " " << y << " " << chain << std::endl; + Kickup dk; + dk.x = x; + dk.y = y; + dk.chain = chain; + dk.cur = 0; + dk.radius = RADIUS + (chain + 1) * (chain + 1); + + map.kickups.push_back(dk); +} + +void processKickup(Map& map) +{ + for (Kickup& kickup : map.kickups) + { + kickup.cur++; + + if (map.tiles[kickup.x+VIEW_WIDTH*kickup.y] == Tile::Floor) + { + map.tiles[kickup.x+VIEW_WIDTH*kickup.y] = Tile::Dust; + } + + std::unique_ptr dusty(new fov_settings_type); + fov_settings_set_opacity_test_function( + dusty.get(), + [] (void* map, int x, int y) { + return + x >= 0 && + x < VIEW_WIDTH && + y >= 0 && + y < VIEW_HEIGHT && + static_cast(map)->tiles.at(x+VIEW_WIDTH*y) == Tile::Wall; + }); + + fov_settings_set_apply_lighting_function( + dusty.get(), + [] (void* data, int x, int y, int, int, void* source) { + Map& map = *static_cast(data); + Kickup& kickup = *static_cast(source); + + if ((x >= 0) && (x < VIEW_WIDTH) && + (y >= 0) && (y < VIEW_HEIGHT)) + { + if (map.tiles[x+VIEW_WIDTH*y] == Tile::Floor) + { + map.tiles[x+VIEW_WIDTH*y] = Tile::Dust; + map.dirtyLighting = true; + } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) + { + map.tiles[x+VIEW_WIDTH*y] = Tile::Dust; + map.dirtyLighting = true; + + kickUpDust(map, x, y, kickup.chain + 1); + } + } + }); + + fov_circle( + dusty.get(), + static_cast(&map), + static_cast(&kickup), + kickup.x, + kickup.y, + kickup.cur); + } + + erase_if( + map.kickups, + [] (const Kickup& kickup) { + return kickup.cur == kickup.radius; + }); +} + int main(int, char**) { std::random_device randomEngine; @@ -371,8 +456,21 @@ int main(int, char**) bool quit = false; Input keystate; SDL_Event e; + + size_t dustDt = 30; + size_t dustAcc = 0; + + size_t inputDt = 50; + size_t inputAcc = 0; + + size_t lastTime = SDL_GetTicks(); + while (!quit) { + size_t currentTime = SDL_GetTicks(); + size_t frameTime = currentTime - lastTime; + lastTime = currentTime; + //bool input = false; //int presses = 0; bool pressedSpace = false; @@ -396,10 +494,6 @@ int main(int, char**) case SDLK_SPACE: { pressedSpace = true; - //input = true; - - std::deque> lamps; - lamps.emplace_back(player_x, player_y); setIfValid(map, player_x , player_y , Tile::Lamp); @@ -414,56 +508,12 @@ int main(int, char**) player_x + RADIUS, player_y + RADIUS); - render(ren.get(), map, false); - SDL_Delay(30); + //render(ren.get(), map, false); + //SDL_Delay(30); } - int lamped = 0; - while (!lamps.empty()) - { - lamped++; - - int px, py; - std::tie(px, py) = lamps.front(); - lamps.pop_front(); - - std::unique_ptr dusty(new fov_settings_type); - fov_settings_set_opacity_test_function( - dusty.get(), - [] (void* map, int x, int y) { - return - x >= 0 && - x < VIEW_WIDTH && - y >= 0 && - y < VIEW_HEIGHT && - static_cast(map)->tiles.at(x+VIEW_WIDTH*y) == Tile::Wall; - }); - - fov_settings_set_apply_lighting_function( - dusty.get(), - [] (void* map, int x, int y, int, int, void* source) { - Map& m = *static_cast(map); - auto& lamps = *static_cast>*>(source); - - if ((x >= 0) && (x < VIEW_WIDTH) && - (y >= 0) && (y < VIEW_HEIGHT)) - { - if (m.tiles[x+VIEW_WIDTH*y] == Tile::Floor) - { - m.tiles[x+VIEW_WIDTH*y] = Tile::Dust; - } else if (m.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) - { - m.tiles[x+VIEW_WIDTH*y] = Tile::Dust; - lamps.emplace_back(x, y); - } - } - }); - - fov_circle(dusty.get(), static_cast(&map), static_cast(&lamps), px, py, RADIUS+lamped*lamped); - - render(ren.get(), map, false); - SDL_Delay(50); - } + map.dirtyLighting = true; + kickUpDust(map, player_x, player_y, 0); break; } @@ -479,7 +529,10 @@ int main(int, char**) bool input = keystate.left || keystate.right || keystate.up || keystate.down || pressedSpace; - if (input) + dustAcc += frameTime; + inputAcc += frameTime; + + while (dustAcc >= dustDt) { for (int y = 0; y < VIEW_HEIGHT; y++) { @@ -488,16 +541,27 @@ int main(int, char**) if (map.tiles[x+y*VIEW_WIDTH] == Tile::Dust) { map.tiles[x+y*VIEW_WIDTH] = Tile::Floor; + map.dirtyLighting = true; } } } + + processKickup(map); + + dustAcc -= dustDt; } - processKeys(map, keystate); - recalculateLighting(map, fov.get()); + while (inputAcc >= inputDt) + { + processKeys(map, keystate); - if (input) + inputAcc -= inputDt; + } + + if (map.dirtyLighting) { + recalculateLighting(map, fov.get()); + for (int y = 0; y < VIEW_HEIGHT; y++) { for (int x = 0; x < VIEW_WIDTH; x++) @@ -520,7 +584,7 @@ int main(int, char**) } render(ren.get(), map, true); - SDL_Delay(50); + //SDL_Delay(50); } } catch (const sdl_error& ex) { diff --git a/src/untitled.txt b/src/untitled.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..150a6a5 --- /dev/null +++ b/src/util.h @@ -0,0 +1,20 @@ +#ifndef UTIL_H_E9110D4C +#define UTIL_H_E9110D4C + +template +void erase_if(Container& items, const Predicate& predicate) +{ + for (auto it = std::begin(items); it != std::end(items);) + { + if (predicate(*it)) + { + it = items.erase(it); + } + else + { + ++it; + } + } +}; + +#endif /* end of include guard: UTIL_H_E9110D4C */ -- cgit 1.4.1