From e8420d47578b3ba5ce83238ee8f61c747cdf2521 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 30 May 2018 22:18:00 -0400 Subject: map zooms in and out based on how lit it is --- src/main.cpp | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 157 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9534678..2d8adf0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,6 +39,17 @@ public: using renderer_ptr = std::unique_ptr; +class texture_deleter { +public: + + void operator()(SDL_Texture* ptr) + { + SDL_DestroyTexture(ptr); + } +}; + +using texture_ptr = std::unique_ptr; + enum class Tile { Floor, Wall, @@ -56,9 +67,10 @@ enum class LoseState { const int GAME_WIDTH = 640*2; const int GAME_HEIGHT = 480*2; const int TILE_WIDTH = 8*2; -const int TILE_HEIGHT = 8*2; -const int VIEW_WIDTH = GAME_WIDTH / TILE_WIDTH; -const int VIEW_HEIGHT = GAME_HEIGHT / TILE_HEIGHT; +const int TILE_HEIGHT = TILE_WIDTH; +const int INIT_ZOOM = 10; +const int ZOOM_X_FACTOR = 8; +const int ZOOM_Y_FACTOR = 6; const int RADIUS = 8; struct Input { @@ -86,14 +98,21 @@ struct MapData { class Game { public: - Game() : - map(-VIEW_WIDTH/2, -VIEW_HEIGHT/2, VIEW_WIDTH, VIEW_HEIGHT) + Game(std::mt19937& rng) : + rng(rng), + map( + -INIT_ZOOM * ZOOM_X_FACTOR / 2, + -INIT_ZOOM * ZOOM_Y_FACTOR / 2, + INIT_ZOOM * ZOOM_X_FACTOR, + INIT_ZOOM * ZOOM_Y_FACTOR) { } + std::mt19937& rng; + Map map; std::list kickups; - int lightedSpots = 0; + int litSpots = 0; bool dirtyLighting = true; size_t numLamps = 0; size_t numDust = 0; @@ -101,6 +120,14 @@ public: int player_x = 0; int player_y = 0; bool renderPlayer = true; + + int curZoom = INIT_ZOOM; + int maxZoom = INIT_ZOOM; + + bool zooming = false; + //size_t oldZoom; + int zoomProgress = 0; + }; void render( @@ -108,6 +135,21 @@ void render( const Game& game, bool drawDark = true) { + texture_ptr canvas( + SDL_CreateTexture( + ren, + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, + TILE_WIDTH * game.map.getWidth(), + TILE_HEIGHT * game.map.getHeight())); + + if (!canvas) + { + throw sdl_error(); + } + + SDL_SetRenderTarget(ren, canvas.get()); + SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); SDL_RenderClear(ren); @@ -174,6 +216,25 @@ void render( } } + SDL_SetRenderTarget(ren, nullptr); + + if (!game.zooming) + { + SDL_RenderCopy(ren, canvas.get(), nullptr, nullptr); + } else { + // TODO: zooming back in to the player + SDL_Rect zoomRect { + ((game.maxZoom - game.curZoom) * TILE_WIDTH + game.zoomProgress) + * ZOOM_X_FACTOR / 2, + ((game.maxZoom - game.curZoom) * TILE_HEIGHT + game.zoomProgress) + * ZOOM_Y_FACTOR / 2, + (game.curZoom * TILE_WIDTH - game.zoomProgress) * ZOOM_X_FACTOR, + (game.curZoom * TILE_HEIGHT - game.zoomProgress) * ZOOM_Y_FACTOR + }; + + SDL_RenderCopy(ren, canvas.get(), &zoomRect, nullptr); + } + SDL_RenderPresent(ren); } @@ -270,7 +331,7 @@ void movePlayer(Game& game, int x, int y) void recalculateLighting(Game& game, fov_settings_type* fov) { - game.lightedSpots = 0; + game.litSpots = 0; for (MapData& md : game.map.data()) { @@ -296,7 +357,7 @@ void recalculateLighting(Game& game, fov_settings_type* fov) { if (!game.map.at(x,y).lit) { - game.lightedSpots++; + game.litSpots++; } game.map.at(x,y).lit = true; @@ -444,6 +505,61 @@ void processKickup(Game& game) }); } +void growMap(Game& game, size_t zoom) +{ + int ol = game.map.getLeft(); + int ot = game.map.getTop(); + int ow = game.map.getWidth(); + int oh = game.map.getHeight(); + + game.map.resize( + -zoom * ZOOM_X_FACTOR / 2, + -zoom * ZOOM_Y_FACTOR / 2, + zoom * ZOOM_X_FACTOR, + zoom * ZOOM_Y_FACTOR); + + game.maxZoom = zoom; + + // TODO: is this working properly? + for (int y = game.map.getTop(); y < game.map.getBottom(); y++) + { + for (int x = game.map.getLeft(); x < game.map.getRight(); x++) + { + if (!(x >= ol && x < (ol + ow) && y >= ot && y < (ot + oh))) + { + if (std::bernoulli_distribution(0.5)(game.rng)) + { + game.map.at(x,y).tile = Tile::Wall; + } + } + } + } + + for (int i = 0; i < 3; i++) + { + tick(game, ol, ot, ow, oh, true); + } +} + +void setZoom(Game& game, size_t zoom) +{ + if (zoom == game.curZoom) + { + return; + } + + if (zoom > game.maxZoom) + { + growMap(game, zoom); + } + + // TODO: don't think this works well with rapid zoom changes + game.zoomProgress += (zoom - game.curZoom) * TILE_WIDTH; + //game.oldZoom = game.curZoom; + game.curZoom = zoom; + game.zooming = true; +} + int main(int, char**) { std::random_device randomEngine; @@ -477,7 +593,7 @@ int main(int, char**) SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND); - Game game; + Game game(rng); std::unique_ptr fov(new fov_settings_type()); fov_settings_init(fov.get()); @@ -505,12 +621,15 @@ int main(int, char**) size_t inputDt = 50; size_t inputAcc = 0; - size_t losePopLampDt = 1000; + size_t losePopLampDt = 800; size_t losePopLampAcc = losePopLampDt; - size_t losePopPlayerDt = 4000; + size_t losePopPlayerDt = 3000; size_t losePopPlayerAcc = 0; + size_t zoomDt = 62; + size_t zoomAcc = 0; + size_t lastTime = SDL_GetTicks(); while (!quit) @@ -647,7 +766,7 @@ int main(int, char**) std::uniform_int_distribution lampDist(0, lamps.size() - 1); std::tuple popPos = lamps[lampDist(rng)]; - popLamp(game, std::get<0>(popPos), std::get<1>(popPos), 0); + popLamp(game, std::get<0>(popPos), std::get<1>(popPos), 1); losePopLampAcc -= losePopLampDt; } @@ -705,6 +824,32 @@ int main(int, char**) tick(game, true); tick(game, true); tick(game, true); + + // TODO: better zoom algorithm + setZoom(game, game.litSpots / 1500 * 2 + INIT_ZOOM); + } + + zoomAcc += frameTime; + + while (zoomAcc >= zoomDt) + { + if (game.zooming) + { + if (game.zoomProgress > 0) + { + game.zoomProgress--; + } else if (game.zoomProgress < 0) + { + game.zoomProgress++; + } + + if (game.zoomProgress == 0) + { + game.zooming = false; + } + } + + zoomAcc -= zoomDt; } render(ren.get(), game, true); -- cgit 1.4.1