From 016d1cdf036039792f50e1ed0431386c7b9e93d7 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sun, 13 Mar 2022 13:21:17 -0400 Subject: refactored game code into the game class (for titles / multiple games) --- src/game.cpp | 885 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/game.h | 56 +++- src/main.cpp | 920 +------------------------------------------------------ src/renderer.cpp | 2 +- src/renderer.h | 2 +- src/timer.h | 2 + 6 files changed, 941 insertions(+), 926 deletions(-) create mode 100644 src/game.cpp (limited to 'src') diff --git a/src/game.cpp b/src/game.cpp new file mode 100644 index 0000000..8de9b7b --- /dev/null +++ b/src/game.cpp @@ -0,0 +1,885 @@ +#include "game.h" +#include +#include +#include +#include "util.h" +#include "renderer.h" + +Game::Game(std::mt19937& rng, Muxer& muxer) : + rng(rng), + muxer(muxer), + map( + -INIT_ZOOM * ZOOM_X_FACTOR / 2, + -INIT_ZOOM * ZOOM_Y_FACTOR / 2, + INIT_ZOOM * ZOOM_X_FACTOR, + INIT_ZOOM * ZOOM_Y_FACTOR) +{ + losePopLampTimer.accumulate(losePopLampTimer.getDt()); + + for (MapData& md : map.data()) + { + if (std::bernoulli_distribution(0.5)(rng)) + { + md.tile = Tile::Wall; + } + } + + tick(); + tick(); + + for (int y = -1; y <= 1; y++) + { + for (int x = -1; x <= 1; x++) + { + map.at(x,y).tile = Tile::Floor; + } + } + + tick(); +} + +inline bool isTileSetOrNotLit(const Map& map, int x, int y) +{ + return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit)); +} + +inline bool isTileSet(const Map& map, int x, int y, Tile val = Tile::Wall) +{ + return (map.inBounds(x, y) && map.at(x,y).tile == val); +} + +inline void incrementIfSet(const Game& game, int& count, int x, int y, Tile val = Tile::Wall) +{ + if (isTileSet(game.map, x, y, val)) + { + count++; + } +} + +inline int getZoomLevel(const Game& game) { + return game.curZoom - INIT_ZOOM; +} + +void Game::tick( + int x1, + int y1, + int x2, + int y2, + bool invert, + bool onlyDark) +{ + Map temp(map); + + for (int y = map.getTop(); y < map.getBottom(); y++) + { + for (int x = map.getLeft(); x < map.getRight(); x++) + { + if (invert == (x >= x1 && x < x2 && y >= y1 && y < y2)) + { + continue; + } + + if (onlyDark && map.at(x,y).lit) + { + continue; + } + + if (map.at(x,y).tile == Tile::Lamp) + { + continue; + } + + int count = 0; + + incrementIfSet(*this, count, x-1, y-1); + incrementIfSet(*this, count, x-1, y ); + incrementIfSet(*this, count, x-1, y+1); + incrementIfSet(*this, count, x , y-1); + incrementIfSet(*this, count, x , y ); + incrementIfSet(*this, count, x , y+1); + incrementIfSet(*this, count, x+1, y-1); + incrementIfSet(*this, count, x+1, y ); + incrementIfSet(*this, count, x+1, y+1); + + if (count >= 5) + { + temp.at(x,y).tile = Tile::Wall; + } else { + temp.at(x,y).tile = Tile::Floor; + } + + if (temp.at(x,y).tile != map.at(x,y).tile) { + temp.at(x,y).dirtyRender = true; + dirtyRender = true; + } + } + } + + map = std::move(temp); +} + +void Game::tick(bool onlyDark) +{ + tick( + map.getLeft(), + map.getTop(), + map.getRight(), + map.getBottom(), + false, + onlyDark); +} + +bool Game::movePlayer(int x, int y) +{ + if (x >= curBoundX && + y >= curBoundY && + x < curBoundX + curZoom * ZOOM_X_FACTOR && + y < curBoundY + curZoom * ZOOM_Y_FACTOR && + map.at(x,y).tile == Tile::Floor) + { + if (map.at(player_x, player_y).tile == Tile::Floor) + { + map.at(player_x, player_y).tile = Tile::Dust; + map.at(player_x, player_y).dustLife = 1; + numDust++; + } + + player_oldx = player_x; + player_oldy = player_y; + player_x = x; + player_y = y; + muxer.setPlayerLoc(x, y); + moving = true; + moveProgress.start(66); + dirtyLighting = true; + + return true; + } else { + if (!alreadyBumped) { + muxer.playSoundAtPosition("bump", x, y); + alreadyBumped = true; + bumpCooldown.reset(); + } + + return false; + } +} + +void Game::recalculateLighting() +{ + litSpots = 0; + dirtyRender = true; + + for (MapData& md : map.data()) + { + md.wasLit = md.lit; + md.lit = false; + md.litTiles.clear(); + + if (md.tile == Tile::Wall) { + md.dirtyRender = true; + } + } + + fov_settings_type fov; + fov_settings_init(&fov); + + fov_settings_set_opacity_test_function( + &fov, + [] (void* data, int x, int y) { + Game& game = *static_cast(data); + + return game.map.inBounds(x,y) && game.map.at(x,y).tile == Tile::Wall; + }); + + fov_settings_set_apply_lighting_function( + &fov, + [] (void* data, int x, int y, int dx, int dy, void* source) { + Game& game = *static_cast(data); + + if (game.map.inBounds(x, y)) + { + MapData& sourceData = *static_cast(source); + double lightRadius = static_cast(sourceData.lightRadius); + + if (!game.map.at(x,y).lit) + { + game.litSpots++; + } + + game.map.at(x,y).lit = true; + + sourceData.litTiles.emplace(x,y); + } + }); + + for (int y = map.getTop(); y < map.getBottom(); y++) + { + for (int x = map.getLeft(); x < map.getRight(); x++) + { + Source ls = Source::None; + int lightRadius; + + if (renderPlayer && player_x == x && player_y == y) + { + ls = Source::Player; + lightRadius = RADIUS; + } else if (map.at(x,y).tile == Tile::Dust) + { + ls = Source::Dust; + lightRadius = 2; + } else if (map.at(x,y).tile == Tile::Lamp) + { + ls = Source::Lamp; + lightRadius = RADIUS; + } + + map.at(x,y).lightType = ls; + + if (ls != Source::None) + { + map.at(x,y).lightRadius = lightRadius; + map.at(x,y).litTiles.emplace(x,y); + + fov_circle( + &fov, + static_cast(this), + static_cast(&map.at(x,y)), + x, + y, + lightRadius); + + map.at(x,y).lit = true; + } + } + } + + dirtyLighting = false; +} + +void Game::recalculateRender() { + for (int y = map.getTop(); y < map.getBottom(); y++) + { + for (int x = map.getLeft(); x < map.getRight(); x++) + { + if (map.at(x,y).dirtyRender) { + map.at(x,y).dirtyRender = false; + + if (map.at(x,y).tile == Tile::Floor) { + if (std::bernoulli_distribution(0.05)(rng)) { + static const std::vector furnishings { + TilesetIndex(20, 16), + TilesetIndex(21, 2), + TilesetIndex(22, 2), + TilesetIndex(21, 3), + TilesetIndex(22, 3)}; + map.at(x,y).renderId = furnishings.at(std::uniform_int_distribution(0, furnishings.size()-1)(rng)); + } else { + map.at(x,y).renderId = -1; + } + } else if (map.at(x,y).tile == Tile::Wall) { + static bool initWalls = false; + static std::vector wallRenders(256, TilesetIndex(0, 0)); + if (!initWalls) { + initWalls = true; + + // Start in top left and go clockwise. + wallRenders[0b00011100] = TilesetIndex(16, 14); + wallRenders[0b00111100] = TilesetIndex(16, 14); + wallRenders[0b00011110] = TilesetIndex(16, 14); + wallRenders[0b00111110] = TilesetIndex(16, 14); + + wallRenders[0b00011111] = TilesetIndex(17, 14); + wallRenders[0b10011111] = TilesetIndex(17, 14); + wallRenders[0b00111111] = TilesetIndex(17, 14); + wallRenders[0b10111111] = TilesetIndex(17, 14); + + wallRenders[0b00000111] = TilesetIndex(18, 14); + wallRenders[0b00001111] = TilesetIndex(18, 14); + wallRenders[0b10000111] = TilesetIndex(18, 14); + wallRenders[0b10001111] = TilesetIndex(18, 14); + + wallRenders[0b01111100] = TilesetIndex(16, 15); + wallRenders[0b11111100] = TilesetIndex(16, 15); + wallRenders[0b01111110] = TilesetIndex(16, 15); + wallRenders[0b11111110] = TilesetIndex(16, 15); + + wallRenders[0b11000111] = TilesetIndex(18, 15); + wallRenders[0b11001111] = TilesetIndex(18, 15); + wallRenders[0b11100111] = TilesetIndex(18, 15); + wallRenders[0b11101111] = TilesetIndex(18, 15); + + wallRenders[0b01110000] = TilesetIndex(16, 16); + wallRenders[0b01111000] = TilesetIndex(16, 16); + wallRenders[0b11110000] = TilesetIndex(16, 16); + wallRenders[0b11111000] = TilesetIndex(16, 16); + + wallRenders[0b11110001] = TilesetIndex(17, 16); + wallRenders[0b11110011] = TilesetIndex(17, 16); + wallRenders[0b11111001] = TilesetIndex(17, 16); + wallRenders[0b11111011] = TilesetIndex(17, 16); + + wallRenders[0b11000001] = TilesetIndex(18, 16); + wallRenders[0b11000011] = TilesetIndex(18, 16); + wallRenders[0b11100001] = TilesetIndex(18, 16); + wallRenders[0b11100011] = TilesetIndex(18, 16); + + + wallRenders[0b11110111] = TilesetIndex(21, 14); + wallRenders[0b11111101] = TilesetIndex(22, 14); + wallRenders[0b11011111] = TilesetIndex(21, 15); + wallRenders[0b01111111] = TilesetIndex(22, 15); + } + + int renderDesc = 0; + if (isTileSetOrNotLit(map, x-1, y-1)) renderDesc |= (1 << 7); + if (isTileSetOrNotLit(map, x , y-1)) renderDesc |= (1 << 6); + if (isTileSetOrNotLit(map, x+1, y-1)) renderDesc |= (1 << 5); + if (isTileSetOrNotLit(map, x+1, y )) renderDesc |= (1 << 4); + if (isTileSetOrNotLit(map, x+1, y+1)) renderDesc |= (1 << 3); + if (isTileSetOrNotLit(map, x , y+1)) renderDesc |= (1 << 2); + if (isTileSetOrNotLit(map, x-1, y+1)) renderDesc |= (1 << 1); + if (isTileSetOrNotLit(map, x-1, y )) renderDesc |= (1 << 0); + + map.at(x,y).renderId = wallRenders.at(renderDesc); + + if (wallRenders.at(renderDesc) == 0 && renderDesc != 255) { + std::cout << renderDesc << std::endl; + } + } + } + } + } + + dirtyRender = false; +} + +bool Game::processKeys(const Input& keystate) +{ + int px = player_x; + int py = player_y; + Direction dir = Direction::up; + + if (keystate.up) + { + py--; + } + + if (keystate.down) + { + py++; + dir = Direction::down; + } + + if (keystate.left) + { + px--; + dir = Direction::left; + } + + if (keystate.right) + { + px++; + dir = Direction::right; + } + + if (!(player_x == px && player_y == py)) + { + playerAnim.setAnimation("walk"); + playerAnim.setDirection(dir); + + bool succeeds = movePlayer(px, py); + if (!succeeds && px != player_x) { + succeeds = movePlayer(px, player_y); + } + if (!succeeds && py != player_y) { + succeeds = movePlayer(player_x, py); + } + return succeeds; + } else { + return false; + } +} + +void Game::kickUpDust(int x, int y, size_t chain) +{ + Kickup dk; + dk.x = x; + dk.y = y; + dk.chain = chain; + dk.cur = 0; + dk.radius = RADIUS + (chain + 1) * (chain + 1); + dk.front.emplace(x, y); + dk.done.emplace(x, y); + + kickups.push_back(dk); +} + +void Game::popLamp(int x, int y, size_t chain) +{ + muxer.playSoundAtPosition("pop", x, y); + + if (map.at(x,y).tile == Tile::Lamp) + { + numLamps--; + } + + map.at(x,y).tile = Tile::Dust; + map.at(x,y).dustLife = 2; + numDust++; + dirtyLighting = true; + + kickUpDust(x, y, chain); +} + +void Game::processKickup() +{ + for (Kickup& kickup : kickups) + { + kickup.cur++; + + std::set newFront; + for (const coord& xy : kickup.front) + { + auto processDir = [&] (int x, int y) { + coord c {x,y}; + + if (map.inBounds(x,y) && + (map.at(x,y).tile == Tile::Floor || map.at(x,y).tile == Tile::Lamp) && + !kickup.done.count(c)) + { + newFront.insert(c); + kickup.done.insert(c); + + if (map.at(x,y).tile == Tile::Floor) + { + map.at(x,y).tile = Tile::Dust; + map.at(x,y).dustLife = 2; + numDust++; + dirtyLighting = true; + } else if (map.at(x,y).tile == Tile::Lamp) + { + popLamp(x, y, kickup.chain + 1); + } + } + }; + + processDir(std::get<0>(xy) - 1, std::get<1>(xy) ); + processDir(std::get<0>(xy) + 1, std::get<1>(xy) ); + processDir(std::get<0>(xy) , std::get<1>(xy) - 1); + processDir(std::get<0>(xy) , std::get<1>(xy) + 1); + + if (std::bernoulli_distribution(0.5)(rng)) + { + processDir(std::get<0>(xy) - 1, std::get<1>(xy) - 1); + } + + if (std::bernoulli_distribution(0.5)(rng)) + { + processDir(std::get<0>(xy) - 1, std::get<1>(xy) + 1); + } + + if (std::bernoulli_distribution(0.5)(rng)) + { + processDir(std::get<0>(xy) + 1, std::get<1>(xy) - 1); + } + + if (std::bernoulli_distribution(0.5)(rng)) + { + processDir(std::get<0>(xy) + 1, std::get<1>(xy) + 1); + } + } + + kickup.front.swap(newFront); + } + + erase_if( + kickups, + [] (const Kickup& kickup) { + return kickup.cur == kickup.radius; + }); +} + +void Game::growMap(size_t zoom) +{ + int ol = map.getLeft(); + int ot = map.getTop(); + int ow = map.getWidth(); + int oh = map.getHeight(); + + map.resize( + -zoom * ZOOM_X_FACTOR / 2, + -zoom * ZOOM_Y_FACTOR / 2, + zoom * ZOOM_X_FACTOR, + zoom * ZOOM_Y_FACTOR); + + maxZoom = zoom; + + for (int y = map.getTop(); y < map.getBottom(); y++) + { + for (int x = map.getLeft(); x < map.getRight(); x++) + { + if (!(x >= ol && x < (ol + ow) && y >= ot && y < (ot + oh))) + { + if (std::bernoulli_distribution(0.5)(rng)) + { + map.at(x,y).tile = Tile::Wall; + } + } + } + } + + for (int i = 0; i < 3; i++) + { + tick(ol, ot, ol + ow, ot + oh, true); + } +} + +void Game::setZoom(size_t zoom) +{ + if (zoom == curZoom) + { + return; + } + + if (zoom > maxZoom) + { + growMap(zoom); + } + + std::tie( + lastZoomLeft, + lastZoomTop, + lastZoomWidth, + lastZoomHeight) = + Renderer::calculateZoomRect(*this); + + zoomProgress = 0; + zoomLength = std::abs(static_cast(zoom - curZoom)) * TILE_WIDTH; + curZoom = zoom; + zooming = true; + + curBoundX = player_x - zoom * ZOOM_X_FACTOR / 2; + if (curBoundX < map.getLeft()) + { + curBoundX = map.getLeft(); + } else if (curBoundX + zoom * ZOOM_X_FACTOR >= map.getRight()) + { + curBoundX = map.getRight() - zoom * ZOOM_X_FACTOR; + } + + curBoundY = player_y - zoom * ZOOM_Y_FACTOR / 2; + if (curBoundY < map.getTop()) + { + curBoundY = map.getTop(); + } else if (curBoundY + zoom * ZOOM_Y_FACTOR >= map.getBottom()) + { + curBoundY = map.getBottom() - zoom * ZOOM_Y_FACTOR; + } + + int zoomLevel = getZoomLevel(*this); + if (zoomLevel == 0) { + muxer.setMusicLevel(0); + } else if (zoomLevel < 3) { + muxer.setMusicLevel(1); + } else if (zoomLevel < 5) { + muxer.setMusicLevel(2); + } else if (zoomLevel < 7) { + muxer.setMusicLevel(3); + } else { + muxer.setMusicLevel(4); + } +} + +void Game::performDash() { + if (map.at(player_x, player_y).tile == Tile::Floor) { + std::vector freeSpaces; + + auto addIfFree = [&] (int x, int y) { + if (map.inBounds(x,y) && map.at(x,y).tile == Tile::Floor) + { + freeSpaces.emplace_back(x, y); + } + }; + + addIfFree(player_x - 1, player_y - 1); + addIfFree(player_x , player_y - 1); + addIfFree(player_x + 1, player_y - 1); + addIfFree(player_x - 1, player_y ); + addIfFree(player_x + 1, player_y ); + addIfFree(player_x - 1, player_y + 1); + addIfFree(player_x , player_y + 1); + addIfFree(player_x + 1, player_y + 1); + + if (!freeSpaces.empty()) + { + map.at(player_x, player_y).tile = Tile::Lamp; + numLamps++; + dirtyLighting = true; + kickUpDust(player_x, player_y, 0); + muxer.playSoundAtPosition("drop", player_x, player_y); + + if (firstInput) + { + for (int i = 0; i < 5; i++) + { + if (!processKeys(lastInput)) + { + std::uniform_int_distribution freeDist(0, freeSpaces.size() - 1); + + int freeIndex = freeDist(rng); + coord& moveTo = freeSpaces[freeIndex]; + + movePlayer(std::get<0>(moveTo), std::get<1>(moveTo)); + } + + tick( + player_x - (RADIUS - 1), + player_y - (RADIUS - 1), + player_x + RADIUS, + player_y + RADIUS); + } + } else { + std::uniform_int_distribution freeDist(0, freeSpaces.size() - 1); + + int freeIndex = freeDist(rng); + coord& moveTo = freeSpaces[freeIndex]; + + movePlayer(std::get<0>(moveTo), std::get<1>(moveTo)); + } + + //muxer.playSoundAtPosition("dash", player_x, player_y); + } + } +} + +void Game::update(size_t frameTime) { + SDL_Event e; + + while (SDL_PollEvent(&e)) + { + if (e.type == SDL_QUIT) + { + if (losing != LoseState::None) + { + quit = true; + } else { + losing = LoseState::PoppingLamps; + muxer.stopMusic(); + } + } else if (e.type == SDL_KEYDOWN) + { + switch (e.key.keysym.sym) + { + case SDLK_ESCAPE: + { + if (losing != LoseState::None) + { + quit = true; + } else { + losing = LoseState::PoppingLamps; + muxer.stopMusic(); + } + + break; + } + + case SDLK_SPACE: + { + if (losing == LoseState::None) + { + if (moving) { + queueDash = true; + } else { + performDash(); + } + } + + break; + } + } + } + } + + const Uint8* state = SDL_GetKeyboardState(NULL); + keystate.left = state[SDL_SCANCODE_LEFT]; + keystate.right = state[SDL_SCANCODE_RIGHT]; + keystate.up = state[SDL_SCANCODE_UP]; + keystate.down = state[SDL_SCANCODE_DOWN]; + + bumpCooldown.accumulate(frameTime); + if (alreadyBumped && keystate != lastInput && bumpCooldown.step()) { + alreadyBumped = false; + } + + if (queueDash && !moving) { + queueDash = false; + performDash(); + } + + if (keystate.left || keystate.right || keystate.up || keystate.down) + { + firstInput = true; + lastInput = keystate; + } else if (losing == LoseState::None) { + playerAnim.setAnimation("still"); + } + + dustTimer.accumulate(frameTime); + inputTimer.accumulate(frameTime); + + while (dustTimer.step()) + { + numDust = 0; + + for (MapData& md : map.data()) + { + if (md.tile == Tile::Dust) + { + md.dustLife--; + + if (md.dustLife <= 0) + { + md.tile = Tile::Floor; + dirtyLighting = true; + } else { + numDust++; + } + } + } + + processKickup(); + } + + switch (losing) + { + case LoseState::None: + { + if (moving) { + moveProgress.tick(frameTime); + if (moveProgress.isComplete()) { + moving = false; + } + } + + while (inputTimer.step()) + { + if (!moving) { + processKeys(keystate); + } + } + + break; + } + + case LoseState::PoppingLamps: + { + if (numLamps == 0) + { + if (numDust == 0) + { + losing = LoseState::PoppingPlayer; + } + } else { + losePopLampTimer.accumulate(frameTime); + + while (losePopLampTimer.step()) + { + std::vector> lamps; + + for (int y = map.getTop(); y < map.getBottom(); y++) + { + for (int x = map.getLeft(); x < map.getRight(); x++) + { + if (map.at(x,y).tile == Tile::Lamp) + { + lamps.emplace_back(x, y); + } + } + } + + std::uniform_int_distribution lampDist(0, lamps.size() - 1); + std::tuple popPos = lamps[lampDist(rng)]; + + popLamp(std::get<0>(popPos), std::get<1>(popPos), 1); + } + } + + break; + } + + case LoseState::PoppingPlayer: + { + losePopPlayerTimer.accumulate(frameTime); + + if (losePopPlayerTimer.step()) + { + popLamp(player_x, player_y, 10); + renderPlayer = false; + + losing = LoseState::Outro; + } + + break; + } + + case LoseState::Outro: + { + if (numDust == 0) + { + quit = true; + } + + break; + } + } + + if (dirtyLighting) + { + recalculateLighting(); + + for (int y = map.getTop(); y < map.getBottom(); y++) + { + for (int x = map.getLeft(); x < map.getRight(); x++) + { + if (!map.at(x,y).lit && map.at(x,y).wasLit) + { + if (std::bernoulli_distribution(0.5)(rng)) + { + map.at(x,y).tile = Tile::Wall; + } else { + map.at(x,y).tile = Tile::Floor; + } + map.at(x,y).dirtyRender = true; + } + } + } + + tick(true); + tick(true); + tick(true); + + // TODO: better zoom algorithm + setZoom(litSpots / 1500 + INIT_ZOOM); + } + + if (dirtyRender) { + recalculateRender(); + } + + zoomTimer.accumulate(frameTime); + while (zoomTimer.step()) + { + if (zooming) + { + zoomProgress++; + + if (zoomProgress == zoomLength) + { + zooming = false; + } + } + } + + playerAnim.update(frameTime); +} diff --git a/src/game.h b/src/game.h index 9feb774..89b9eb2 100644 --- a/src/game.h +++ b/src/game.h @@ -87,18 +87,15 @@ struct MapData { class Game { public: - 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) - { - } + Game(std::mt19937& rng, Muxer& muxer); + + void update(size_t dt); std::mt19937& rng; - Muxer muxer; + Muxer& muxer; + + bool quit = false; + LoseState losing = LoseState::None; Map map; std::list kickups; @@ -129,6 +126,7 @@ public: int lastZoomWidth; int lastZoomHeight; + Input keystate; bool firstInput = false; Input lastInput; bool alreadyBumped = false; @@ -137,6 +135,44 @@ public: bool moving = false; bool queueDash = false; + Timer dustTimer = {40}; + Timer inputTimer = {50}; + Timer losePopLampTimer = {800}; + Timer losePopPlayerTimer = {3000}; + Timer zoomTimer = {62}; + +private: + + void tick( + int x1, + int y1, + int x2, + int y2, + bool invert = false, + bool onlyDark = false); + + void tick(bool onlyDark = false); + + bool movePlayer(int x, int y); + + void recalculateLighting(); + + void recalculateRender(); + + bool processKeys(const Input& keystate); + + void kickUpDust(int x, int y, size_t chain); + + void popLamp(int x, int y, size_t chain); + + void processKickup(); + + void growMap(size_t zoom); + + void setZoom(size_t zoom); + + void performDash(); + }; #endif /* end of include guard: GAME_H_7D2B65AE */ diff --git a/src/main.cpp b/src/main.cpp index c0d5b14..ec253ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,638 +5,6 @@ #include "game.h" #include "renderer.h" -inline bool isTileSetOrNotLit(const Map& map, int x, int y) -{ - return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit)); -} - -inline bool isTileSet(const Map& map, int x, int y, Tile val = Tile::Wall) -{ - return (map.inBounds(x, y) && map.at(x,y).tile == val); -} - -inline void incrementIfSet(const Game& game, int& count, int x, int y, Tile val = Tile::Wall) -{ - if (isTileSet(game.map, x, y, val)) - { - count++; - } -} - -inline int getZoomLevel(const Game& game) { - return game.curZoom - INIT_ZOOM; -} - -void tick( - Game& game, - int x1, - int y1, - int x2, - int y2, - bool invert = false, - bool onlyDark = false) -{ - Map temp(game.map); - - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - if (invert == (x >= x1 && x < x2 && y >= y1 && y < y2)) - { - continue; - } - - if (onlyDark && game.map.at(x,y).lit) - { - continue; - } - - if (game.map.at(x,y).tile == Tile::Lamp) - { - continue; - } - - int count = 0; - - incrementIfSet(game, count, x-1, y-1); - incrementIfSet(game, count, x-1, y ); - incrementIfSet(game, count, x-1, y+1); - incrementIfSet(game, count, x , y-1); - incrementIfSet(game, count, x , y ); - incrementIfSet(game, count, x , y+1); - incrementIfSet(game, count, x+1, y-1); - incrementIfSet(game, count, x+1, y ); - incrementIfSet(game, count, x+1, y+1); - - if (count >= 5) - { - temp.at(x,y).tile = Tile::Wall; - } else { - temp.at(x,y).tile = Tile::Floor; - } - - if (temp.at(x,y).tile != game.map.at(x,y).tile) { - temp.at(x,y).dirtyRender = true; - game.dirtyRender = true; - } - } - } - - game.map = std::move(temp); -} - -void tick(Game& game, bool onlyDark = false) -{ - tick( - game, - game.map.getLeft(), - game.map.getTop(), - game.map.getRight(), - game.map.getBottom(), - false, - onlyDark); -} - -bool movePlayer(Game& game, int x, int y) -{ - if (x >= game.curBoundX && - y >= game.curBoundY && - x < game.curBoundX + game.curZoom * ZOOM_X_FACTOR && - y < game.curBoundY + game.curZoom * ZOOM_Y_FACTOR && - game.map.at(x,y).tile == Tile::Floor) - { - if (game.map.at(game.player_x, game.player_y).tile == Tile::Floor) - { - game.map.at(game.player_x, game.player_y).tile = Tile::Dust; - game.map.at(game.player_x, game.player_y).dustLife = 1; - game.numDust++; - } - - game.player_oldx = game.player_x; - game.player_oldy = game.player_y; - game.player_x = x; - game.player_y = y; - game.muxer.setPlayerLoc(x, y); - game.moving = true; - game.moveProgress.start(66); - - game.dirtyLighting = true; - - return true; - } else { - if (!game.alreadyBumped) { - game.muxer.playSoundAtPosition("bump", x, y); - game.alreadyBumped = true; - game.bumpCooldown.reset(); - } - - return false; - } -} - -void recalculateLighting(Game& game) -{ - game.litSpots = 0; - game.dirtyRender = true; - - for (MapData& md : game.map.data()) - { - md.wasLit = md.lit; - md.lit = false; - md.litTiles.clear(); - - if (md.tile == Tile::Wall) { - md.dirtyRender = true; - } - } - - fov_settings_type fov; - fov_settings_init(&fov); - - fov_settings_set_opacity_test_function( - &fov, - [] (void* data, int x, int y) { - Game& game = *static_cast(data); - - return game.map.inBounds(x,y) && game.map.at(x,y).tile == Tile::Wall; - }); - - fov_settings_set_apply_lighting_function( - &fov, - [] (void* data, int x, int y, int dx, int dy, void* source) { - Game& game = *static_cast(data); - - if (game.map.inBounds(x, y)) - { - MapData& sourceData = *static_cast(source); - double lightRadius = static_cast(sourceData.lightRadius); - - if (!game.map.at(x,y).lit) - { - game.litSpots++; - } - - game.map.at(x,y).lit = true; - - sourceData.litTiles.emplace(x,y); - } - }); - - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - Source ls = Source::None; - int lightRadius; - - if (game.renderPlayer && game.player_x == x && game.player_y == y) - { - ls = Source::Player; - lightRadius = RADIUS; - } else if (game.map.at(x,y).tile == Tile::Dust) - { - ls = Source::Dust; - lightRadius = 2; - } else if (game.map.at(x,y).tile == Tile::Lamp) - { - ls = Source::Lamp; - lightRadius = RADIUS; - } - - game.map.at(x,y).lightType = ls; - - if (ls != Source::None) - { - game.map.at(x,y).lightRadius = lightRadius; - game.map.at(x,y).litTiles.emplace(x,y); - - fov_circle( - &fov, - static_cast(&game), - static_cast(&game.map.at(x,y)), - x, - y, - lightRadius); - - game.map.at(x,y).lit = true; - } - } - } - - game.dirtyLighting = false; -} - -void recalculateRender(Game& game) { - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - if (game.map.at(x,y).dirtyRender) { - game.map.at(x,y).dirtyRender = false; - - if (game.map.at(x,y).tile == Tile::Floor) { - if (std::bernoulli_distribution(0.05)(game.rng)) { - static const std::vector furnishings { - TilesetIndex(20, 16), - TilesetIndex(21, 2), - TilesetIndex(22, 2), - TilesetIndex(21, 3), - TilesetIndex(22, 3)}; - game.map.at(x,y).renderId = furnishings.at(std::uniform_int_distribution(0, furnishings.size()-1)(game.rng)); - } else { - game.map.at(x,y).renderId = -1; - } - } else if (game.map.at(x,y).tile == Tile::Wall) { - static bool initWalls = false; - static std::vector wallRenders(256, TilesetIndex(0, 0)); - if (!initWalls) { - initWalls = true; - - // Start in top left and go clockwise. - wallRenders[0b00011100] = TilesetIndex(16, 14); - wallRenders[0b00111100] = TilesetIndex(16, 14); - wallRenders[0b00011110] = TilesetIndex(16, 14); - wallRenders[0b00111110] = TilesetIndex(16, 14); - - wallRenders[0b00011111] = TilesetIndex(17, 14); - wallRenders[0b10011111] = TilesetIndex(17, 14); - wallRenders[0b00111111] = TilesetIndex(17, 14); - wallRenders[0b10111111] = TilesetIndex(17, 14); - - wallRenders[0b00000111] = TilesetIndex(18, 14); - wallRenders[0b00001111] = TilesetIndex(18, 14); - wallRenders[0b10000111] = TilesetIndex(18, 14); - wallRenders[0b10001111] = TilesetIndex(18, 14); - - wallRenders[0b01111100] = TilesetIndex(16, 15); - wallRenders[0b11111100] = TilesetIndex(16, 15); - wallRenders[0b01111110] = TilesetIndex(16, 15); - wallRenders[0b11111110] = TilesetIndex(16, 15); - - wallRenders[0b11000111] = TilesetIndex(18, 15); - wallRenders[0b11001111] = TilesetIndex(18, 15); - wallRenders[0b11100111] = TilesetIndex(18, 15); - wallRenders[0b11101111] = TilesetIndex(18, 15); - - wallRenders[0b01110000] = TilesetIndex(16, 16); - wallRenders[0b01111000] = TilesetIndex(16, 16); - wallRenders[0b11110000] = TilesetIndex(16, 16); - wallRenders[0b11111000] = TilesetIndex(16, 16); - - wallRenders[0b11110001] = TilesetIndex(17, 16); - wallRenders[0b11110011] = TilesetIndex(17, 16); - wallRenders[0b11111001] = TilesetIndex(17, 16); - wallRenders[0b11111011] = TilesetIndex(17, 16); - - wallRenders[0b11000001] = TilesetIndex(18, 16); - wallRenders[0b11000011] = TilesetIndex(18, 16); - wallRenders[0b11100001] = TilesetIndex(18, 16); - wallRenders[0b11100011] = TilesetIndex(18, 16); - - - wallRenders[0b11110111] = TilesetIndex(21, 14); - wallRenders[0b11111101] = TilesetIndex(22, 14); - wallRenders[0b11011111] = TilesetIndex(21, 15); - wallRenders[0b01111111] = TilesetIndex(22, 15); - } - - int renderDesc = 0; - if (isTileSetOrNotLit(game.map, x-1, y-1)) renderDesc |= (1 << 7); - if (isTileSetOrNotLit(game.map, x , y-1)) renderDesc |= (1 << 6); - if (isTileSetOrNotLit(game.map, x+1, y-1)) renderDesc |= (1 << 5); - if (isTileSetOrNotLit(game.map, x+1, y )) renderDesc |= (1 << 4); - if (isTileSetOrNotLit(game.map, x+1, y+1)) renderDesc |= (1 << 3); - if (isTileSetOrNotLit(game.map, x , y+1)) renderDesc |= (1 << 2); - if (isTileSetOrNotLit(game.map, x-1, y+1)) renderDesc |= (1 << 1); - if (isTileSetOrNotLit(game.map, x-1, y )) renderDesc |= (1 << 0); - - game.map.at(x,y).renderId = wallRenders.at(renderDesc); - - if (wallRenders.at(renderDesc) == 0 && renderDesc != 255) { - std::cout << renderDesc << std::endl; - } - } - } - } - } - - game.dirtyRender = false; -} - -bool processKeys(Game& game, const Input& keystate) -{ - int px = game.player_x; - int py = game.player_y; - Direction dir = Direction::up; - - if (keystate.up) - { - py--; - } - - if (keystate.down) - { - py++; - dir = Direction::down; - } - - if (keystate.left) - { - px--; - dir = Direction::left; - } - - if (keystate.right) - { - px++; - dir = Direction::right; - } - - if (!(game.player_x == px && game.player_y == py)) - { - game.playerAnim.setAnimation("walk"); - game.playerAnim.setDirection(dir); - - bool succeeds = movePlayer(game, px, py); - if (!succeeds && px != game.player_x) { - succeeds = movePlayer(game, px, game.player_y); - } - if (!succeeds && py != game.player_y) { - succeeds = movePlayer(game, game.player_x, py); - } - return succeeds; - } else { - return false; - } -} - -void kickUpDust(Game& game, int x, int y, size_t chain) -{ - Kickup dk; - dk.x = x; - dk.y = y; - dk.chain = chain; - dk.cur = 0; - dk.radius = RADIUS + (chain + 1) * (chain + 1); - dk.front.emplace(x, y); - dk.done.emplace(x, y); - - game.kickups.push_back(dk); -} - -void popLamp(Game& game, int x, int y, size_t chain) -{ - game.muxer.playSoundAtPosition("pop", x, y); - - if (game.map.at(x,y).tile == Tile::Lamp) - { - game.numLamps--; - } - - game.map.at(x,y).tile = Tile::Dust; - game.map.at(x,y).dustLife = 2; - game.numDust++; - game.dirtyLighting = true; - - kickUpDust(game, x, y, chain); -} - -void processKickup(Game& game) -{ - for (Kickup& kickup : game.kickups) - { - kickup.cur++; - - std::set newFront; - for (const coord& xy : kickup.front) - { - auto processDir = [&] (int x, int y) { - coord c {x,y}; - - if (game.map.inBounds(x,y) && - (game.map.at(x,y).tile == Tile::Floor || - game.map.at(x,y).tile == Tile::Lamp) && - !kickup.done.count(c)) - { - newFront.insert(c); - kickup.done.insert(c); - - if (game.map.at(x,y).tile == Tile::Floor) - { - game.map.at(x,y).tile = Tile::Dust; - game.map.at(x,y).dustLife = 2; - game.numDust++; - game.dirtyLighting = true; - } else if (game.map.at(x,y).tile == Tile::Lamp) - { - popLamp(game, x, y, kickup.chain + 1); - } - } - }; - - processDir(std::get<0>(xy) - 1, std::get<1>(xy) ); - processDir(std::get<0>(xy) + 1, std::get<1>(xy) ); - processDir(std::get<0>(xy) , std::get<1>(xy) - 1); - processDir(std::get<0>(xy) , std::get<1>(xy) + 1); - - if (std::bernoulli_distribution(0.5)(game.rng)) - { - processDir(std::get<0>(xy) - 1, std::get<1>(xy) - 1); - } - - if (std::bernoulli_distribution(0.5)(game.rng)) - { - processDir(std::get<0>(xy) - 1, std::get<1>(xy) + 1); - } - - if (std::bernoulli_distribution(0.5)(game.rng)) - { - processDir(std::get<0>(xy) + 1, std::get<1>(xy) - 1); - } - - if (std::bernoulli_distribution(0.5)(game.rng)) - { - processDir(std::get<0>(xy) + 1, std::get<1>(xy) + 1); - } - } - - kickup.front.swap(newFront); - } - - erase_if( - game.kickups, - [] (const Kickup& kickup) { - return kickup.cur == kickup.radius; - }); -} - -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; - - 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, ol + ow, ot + oh, true); - } -} - -void setZoom(Game& game, size_t zoom) -{ - if (zoom == game.curZoom) - { - return; - } - - if (zoom > game.maxZoom) - { - growMap(game, zoom); - } - - std::tie( - game.lastZoomLeft, - game.lastZoomTop, - game.lastZoomWidth, - game.lastZoomHeight) = - Renderer::calculateZoomRect(game); - - game.zoomProgress = 0; - game.zoomLength = - std::abs(static_cast(zoom - game.curZoom)) * TILE_WIDTH; - game.curZoom = zoom; - game.zooming = true; - - game.curBoundX = game.player_x - zoom * ZOOM_X_FACTOR / 2; - if (game.curBoundX < game.map.getLeft()) - { - game.curBoundX = game.map.getLeft(); - } else if (game.curBoundX + zoom * ZOOM_X_FACTOR >= game.map.getRight()) - { - game.curBoundX = game.map.getRight() - zoom * ZOOM_X_FACTOR; - } - - game.curBoundY = game.player_y - zoom * ZOOM_Y_FACTOR / 2; - if (game.curBoundY < game.map.getTop()) - { - game.curBoundY = game.map.getTop(); - } else if (game.curBoundY + zoom * ZOOM_Y_FACTOR >= game.map.getBottom()) - { - game.curBoundY = game.map.getBottom() - zoom * ZOOM_Y_FACTOR; - } - - int zoomLevel = getZoomLevel(game); - if (zoomLevel == 0) { - game.muxer.setMusicLevel(0); - } else if (zoomLevel < 3) { - game.muxer.setMusicLevel(1); - } else if (zoomLevel < 5) { - game.muxer.setMusicLevel(2); - } else if (zoomLevel < 7) { - game.muxer.setMusicLevel(3); - } else { - game.muxer.setMusicLevel(4); - } -} - -void performDash(Game& game, std::mt19937& rng) { - if (game.map.at(game.player_x, game.player_y).tile == - Tile::Floor) - { - std::vector freeSpaces; - - auto addIfFree = [&] (int x, int y) { - if (game.map.inBounds(x,y) && - game.map.at(x,y).tile == Tile::Floor) - { - freeSpaces.emplace_back(x, y); - } - }; - - addIfFree(game.player_x - 1, game.player_y - 1); - addIfFree(game.player_x , game.player_y - 1); - addIfFree(game.player_x + 1, game.player_y - 1); - addIfFree(game.player_x - 1, game.player_y ); - addIfFree(game.player_x + 1, game.player_y ); - addIfFree(game.player_x - 1, game.player_y + 1); - addIfFree(game.player_x , game.player_y + 1); - addIfFree(game.player_x + 1, game.player_y + 1); - - if (!freeSpaces.empty()) - { - game.map.at(game.player_x, game.player_y).tile = Tile::Lamp; - game.numLamps++; - game.dirtyLighting = true; - kickUpDust(game, game.player_x, game.player_y, 0); - game.muxer.playSoundAtPosition("drop", game.player_x, game.player_y); - - if (game.firstInput) - { - for (int i = 0; i < 5; i++) - { - if (!processKeys(game, game.lastInput)) - { - std::uniform_int_distribution freeDist( - 0, freeSpaces.size() - 1); - - int freeIndex = freeDist(rng); - coord& moveTo = freeSpaces[freeIndex]; - - movePlayer( - game, - std::get<0>(moveTo), - std::get<1>(moveTo)); - } - - tick( - game, - game.player_x - (RADIUS - 1), - game.player_y - (RADIUS - 1), - game.player_x + RADIUS, - game.player_y + RADIUS); - } - } else { - std::uniform_int_distribution freeDist( - 0, freeSpaces.size() - 1); - - int freeIndex = freeDist(rng); - coord& moveTo = freeSpaces[freeIndex]; - - movePlayer( - game, - std::get<0>(moveTo), - std::get<1>(moveTo)); - } - - //game.muxer.playSoundAtPosition("dash", game.player_x, game.player_y); - } - } -} - int main(int, char**) { std::random_device randomEngine; @@ -645,296 +13,20 @@ int main(int, char**) try { Renderer renderer; + Muxer muxer; - Game game(rng); - - for (MapData& md : game.map.data()) - { - if (std::bernoulli_distribution(0.5)(rng)) - { - md.tile = Tile::Wall; - } - } - - tick(game); - tick(game); - - for (int y = -1; y <= 1; y++) - { - for (int x = -1; x <= 1; x++) - { - game.map.at(x,y).tile = Tile::Floor; - } - } - - tick(game); - - bool quit = false; - LoseState losing = LoseState::None; - Input keystate; - SDL_Event e; - - size_t dustDt = 40; - size_t dustAcc = 0; - - size_t inputDt = 50; - size_t inputAcc = 0; - - size_t losePopLampDt = 800; - size_t losePopLampAcc = losePopLampDt; - - size_t losePopPlayerDt = 3000; - size_t losePopPlayerAcc = 0; - - size_t zoomDt = 62; - size_t zoomAcc = 0; + Game game(rng, muxer); size_t lastTime = SDL_GetTicks(); - - while (!quit) + while (!game.quit) { size_t currentTime = SDL_GetTicks(); size_t frameTime = currentTime - lastTime; lastTime = currentTime; - while (SDL_PollEvent(&e)) - { - if (e.type == SDL_QUIT) - { - if (losing != LoseState::None) - { - quit = true; - } else { - losing = LoseState::PoppingLamps; - game.muxer.stopMusic(); - } - } else if (e.type == SDL_KEYDOWN) - { - switch (e.key.keysym.sym) - { - case SDLK_ESCAPE: - { - if (losing != LoseState::None) - { - quit = true; - } else { - losing = LoseState::PoppingLamps; - game.muxer.stopMusic(); - } - - break; - } - - case SDLK_SPACE: - { - if (losing == LoseState::None) - { - if (game.moving) { - game.queueDash = true; - } else { - performDash(game, rng); - } - } - - break; - } - } - } - } - - const Uint8* state = SDL_GetKeyboardState(NULL); - keystate.left = state[SDL_SCANCODE_LEFT]; - keystate.right = state[SDL_SCANCODE_RIGHT]; - keystate.up = state[SDL_SCANCODE_UP]; - keystate.down = state[SDL_SCANCODE_DOWN]; - - game.bumpCooldown.accumulate(frameTime); - if (game.alreadyBumped && keystate != game.lastInput && game.bumpCooldown.step()) { - game.alreadyBumped = false; - } - - if (game.queueDash && !game.moving) { - game.queueDash = false; - performDash(game, rng); - } - - if (keystate.left || keystate.right || keystate.up || keystate.down) - { - game.firstInput = true; - game.lastInput = keystate; - } else if (losing == LoseState::None) { - game.playerAnim.setAnimation("still"); - } - - dustAcc += frameTime; - inputAcc += frameTime; - - while (dustAcc >= dustDt) - { - game.numDust = 0; - - for (MapData& md : game.map.data()) - { - if (md.tile == Tile::Dust) - { - md.dustLife--; - - if (md.dustLife <= 0) - { - md.tile = Tile::Floor; - game.dirtyLighting = true; - } else { - game.numDust++; - } - } - } - - processKickup(game); - - dustAcc -= dustDt; - } - - switch (losing) - { - case LoseState::None: - { - if (game.moving) { - game.moveProgress.tick(frameTime); - if (game.moveProgress.isComplete()) { - game.moving = false; - } - } - - while (inputAcc >= inputDt) - { - if (!game.moving) { - processKeys(game, keystate); - } - - inputAcc -= inputDt; - } - - break; - } - - case LoseState::PoppingLamps: - { - if (game.numLamps == 0) - { - if (game.numDust == 0) - { - losing = LoseState::PoppingPlayer; - } - } else { - losePopLampAcc += frameTime; - - while (losePopLampAcc >= losePopLampDt) - { - std::vector> lamps; - - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - if (game.map.at(x,y).tile == Tile::Lamp) - { - lamps.emplace_back(x, y); - } - } - } - - 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), 1); - - losePopLampAcc -= losePopLampDt; - } - } - - break; - } - - case LoseState::PoppingPlayer: - { - losePopPlayerAcc += frameTime; - - if (losePopPlayerAcc >= losePopPlayerDt) - { - popLamp(game, game.player_x, game.player_y, 10); - game.renderPlayer = false; - - losing = LoseState::Outro; - } - - break; - } - - case LoseState::Outro: - { - if (game.numDust == 0) - { - quit = true; - } - - break; - } - } - - if (game.dirtyLighting) - { - recalculateLighting(game); - - for (int y = game.map.getTop(); y < game.map.getBottom(); y++) - { - for (int x = game.map.getLeft(); x < game.map.getRight(); x++) - { - if (!game.map.at(x,y).lit && game.map.at(x,y).wasLit) - { - if (std::bernoulli_distribution(0.5)(rng)) - { - game.map.at(x,y).tile = Tile::Wall; - } else { - game.map.at(x,y).tile = Tile::Floor; - } - game.map.at(x,y).dirtyRender = true; - } - } - } - - tick(game, true); - tick(game, true); - tick(game, true); - - // TODO: better zoom algorithm - setZoom(game, game.litSpots / 1500 + INIT_ZOOM); - } - - if (game.dirtyRender) { - recalculateRender(game); - } - - zoomAcc += frameTime; - - while (zoomAcc >= zoomDt) - { - if (game.zooming) - { - game.zoomProgress++; - - if (game.zoomProgress == game.zoomLength) - { - game.zooming = false; - } - } - - zoomAcc -= zoomDt; - } - - game.playerAnim.update(frameTime); - - game.muxer.update(); - renderer.render(game, true); + game.update(frameTime); + renderer.renderGame(game, true); + muxer.update(); } } catch (const sdl_error& ex) { diff --git a/src/renderer.cpp b/src/renderer.cpp index 1858520..90ce03f 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -150,7 +150,7 @@ Renderer::Renderer() SDL_SetTextureBlendMode(lamp_.get(), SDL_BLENDMODE_BLEND); } -void Renderer::render( +void Renderer::renderGame( const Game& game, bool drawDark) { diff --git a/src/renderer.h b/src/renderer.h index 57d9702..ca4e607 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -113,7 +113,7 @@ public: Renderer(); - void render( + void renderGame( const Game& game, bool drawDark = true); diff --git a/src/timer.h b/src/timer.h index ec34f3e..65d5a50 100644 --- a/src/timer.h +++ b/src/timer.h @@ -23,6 +23,8 @@ public: acc_ = 0; } + int getDt() const { return dt_; } + private: int dt_; -- cgit 1.4.1