Improved map wallout, fixed spawned player in wall glitch and now actually rendering collectables. Player handling has also been reworked

This commit is contained in:
Maximilian Giller 2023-06-13 21:59:50 +02:00
parent d3e6e35c9b
commit 414f3b79fc
27 changed files with 345 additions and 111 deletions

View file

@ -52,8 +52,6 @@ set(SOURCES
src/game/camera/ITrackable.h
src/game/input/input_identity.h
src/utilities/magic_enum.hpp
src/game/player/player_spawner.cpp
src/game/player/player_spawner.hpp
src/game/camera/tracking_area.h
src/game/camera/tracking_view_options.hpp
src/game/collectables/collectable.cpp
@ -96,7 +94,7 @@ set(SOURCES
src/game/collectables/collection/collectables_collection.cpp
src/game/collectables/collection/collectables_collection.hpp
src/game/collectables/collection/collectables_depth_collection.cpp
src/game/collectables/collection/collectables_depth_collection.hpp src/game/collectables/collectable_in_level.hpp src/game/collectables/collectable_factory.cpp src/game/collectables/collectable_factory.hpp)
src/game/collectables/collection/collectables_depth_collection.hpp src/game/collectables/collectable_in_level.hpp src/game/collectables/collectable_factory.cpp src/game/collectables/collectable_factory.hpp src/game/player/player_collection.cpp src/game/player/player_collection.hpp)
set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp)

View file

@ -34,8 +34,10 @@
#define DEF_TV_MIN_VIEW_SIZE sf::Vector2f(6, 6) * WORLD_TO_ISO_SCALE
#define DEF_TV_MAX_VIEW_SIZE sf::Vector2f(0, 0)
#define DEF_TV_VIEW_SIZE_PADDING sf::Vector2f(0.5f, 0.5f)
#define DEF_TV_ADD_PLAYERS_DYNAMICALLY true
// Simulations
#define MAPSIM_WALL_THICKNESS 3.f
#define MAPSIM_VELOCITY_ITERATIONS 6
#define MAPSIM_POSITION_ITERATIONS 2
#define HOLESIM_VELOCITY_ITERATIONS 8

View file

@ -68,3 +68,8 @@ void TranslatedCoordinates::setScreenOffset(IsometricCoordinates offset)
{
setWorldOffset(CoordinateTransformer::isometricToWorld(offset));
}
TranslatedCoordinates::TranslatedCoordinates(GridCoordinates gridCoordinates)
{
set(gridCoordinates);
}

View file

@ -9,12 +9,13 @@ class TranslatedCoordinates
{
public:
explicit TranslatedCoordinates(WorldCoordinates worldCoordinates);
explicit TranslatedCoordinates(GridCoordinates gridCoordinates);
WorldCoordinates world() const;
[[nodiscard]] WorldCoordinates world() const;
IsometricCoordinates isometric() const;
[[nodiscard]] IsometricCoordinates isometric() const;
GridCoordinates grid() const;
[[nodiscard]] GridCoordinates grid() const;
void set(WorldCoordinates newWorldCoordinates);
@ -35,7 +36,7 @@ public:
void setScreenOffset(IsometricCoordinates offset);
private:
WorldCoordinates worldCoordinates;
WorldCoordinates worldCoordinates{};
std::shared_ptr<TranslatedCoordinates> parent = nullptr;
};

View file

@ -1,11 +1,13 @@
#include "tracking_view.h"
#include "../../utilities/vector_utils.hpp"
#include "../player/player_collection.hpp"
TrackingView::TrackingView(TrackingViewOptions options) : options(options),
view(nullptr),
hasViewChanged(false),
trackables({})
{;
{
;
marker = new CircleObject(DB_CIRCLE_RADIUS, sf::Color::Yellow);
Game::getInstance()->registerView(this);
}
@ -65,7 +67,8 @@ void TrackingView::setSize(sf::Vector2f newSize)
didAspectRationChange = true;
}
if (options.softResizeSpeed != 0 && !didAspectRationChange) {
if (options.softResizeSpeed != 0 && !didAspectRationChange)
{
// Smooth out transition to new size
newSize = size + (newSize - size) * options.softResizeSpeed * FRAME_TIME.asSeconds();
}
@ -271,3 +274,39 @@ float TrackingView::getRadius(float threshold) const
// Only half of the side, since we are calculating radius
return smallestSide / 2.f * threshold;
}
void TrackingView::update()
{
if (options.addPlayersDynamically)
{
addPlayersDynamically();
}
}
void TrackingView::addPlayersDynamically()
{
// Update based on PlayerCollection
// Add new
for (const auto &player: PlayerCollection::getInstance()->getNewPlayers())
{
if (player->getTrackableState() == TrackableState::TRACKING)
{
addTrackable(player);
}
}
// Remove old
for (const auto &player: PlayerCollection::getInstance()->getRemovedPlayers())
{
removeTrackable(player);
}
}
void TrackingView::removeTrackable(const std::shared_ptr<ITrackable> &trackable)
{
trackables.erase(
std::remove_if(trackables.begin(), trackables.end(), [&trackable](const std::shared_ptr<ITrackable> &t)
{
return t == trackable;
}), trackables.end());
}

View file

@ -17,6 +17,7 @@ public:
~TrackingView();
void update() override;
void draw(sf::RenderWindow *window) override;
@ -24,6 +25,8 @@ public:
void addTrackable(const std::shared_ptr<ITrackable>& trackable);
void removeTrackable(const std::shared_ptr<ITrackable> &trackable);
sf::Vector2f getSize() const;
sf::Vector2f getCenter() const;
@ -57,6 +60,8 @@ private:
float getRadius(float threshold) const;
sf::Vector2f getWindowSize() const;
void addPlayersDynamically();
};

View file

@ -37,6 +37,11 @@ struct TrackingViewOptions
* Value between 0 and 1 to set relative padding.
*/
sf::Vector2f viewSizePadding = DEF_TV_VIEW_SIZE_PADDING;
/**
* If set to true, view will add all new players automatically and remove them accordingly, based on PlayerCollection.
*/
bool addPlayersDynamically = DEF_TV_ADD_PLAYERS_DYNAMICALLY;
};
#endif //HOLESOME_TRACKING_VIEW_OPTIONS_HPP

View file

@ -8,11 +8,6 @@ Collectable::Collectable()
collectableCount++;
}
void Collectable::draw(sf::RenderWindow *window)
{
}
void Collectable::setRotation(float angle)
{

View file

@ -9,8 +9,6 @@ class Collectable : public GameObject
public:
Collectable();
void draw(sf::RenderWindow *window) override;
void setSprite(const std::string &spriteName);
void setRotation(float angle);

View file

@ -66,7 +66,7 @@ void CollectablesCollection::update()
void CollectablesCollection::draw(sf::RenderWindow *window)
{
// Render collectables in reverse order of depth
int maxDepth = depthCollections.size();
int maxDepth = (int) depthCollections.size();
for (int depth = maxDepth - 1; depth >= 0; depth--)
{
auto depthCollection = depthCollections.at(depth);
@ -87,3 +87,14 @@ void CollectablesCollection::updateCollectables()
}
}
}
std::shared_ptr<CollectablesDepthCollection> CollectablesCollection::getDepthCollection(int depth)
{
if (depthCollections.find(depth) == depthCollections.end())
{
LOG(ERROR) << "Depth collection for depth " << depth << " does not exist! Returning empty collection ...";
return std::make_shared<CollectablesDepthCollection>(depth);
}
return depthCollections[depth];
}

View file

@ -23,6 +23,8 @@ public:
void add(const std::shared_ptr<Collectable>& collectable);
void remove(const std::shared_ptr<Collectable>& collectable);
std::shared_ptr<CollectablesDepthCollection> getDepthCollection(int depth);
private:
static inline std::shared_ptr<CollectablesCollection> singletonInstance = nullptr;

View file

@ -5,6 +5,7 @@
#include "game.h"
#include "level/level_loader.hpp"
#include "physics/map/map_simulation.hpp"
#include "../logging/easylogging++.h"
Game::Game(std::shared_ptr<sf::RenderWindow> window) : window(std::move(window))
{
@ -15,6 +16,7 @@ void Game::run()
sf::Clock clock;
sf::Time TimeSinceLastUpdate = sf::seconds(0);
LOG(INFO) << "Game loop started ...";
while (window->isOpen())
{
@ -29,6 +31,8 @@ void Game::run()
}
drawFrame();
}
LOG(INFO) << "Game closing ...";
}
void Game::exit()
@ -83,14 +87,18 @@ void Game::update()
}
}
InputMapper::getInstance()->updateIdentities();
if (isLevelLoaded())
// Physics updates
for (const auto &gameObject: gameObjects)
{
MapSimulation::getInstance()->updateSimulation();
if (gameObject->getActive())
{
gameObject->physicsUpdate();
}
}
InputMapper::getInstance()->updateIdentities();
}
std::shared_ptr<Game> Game::getInstance()
{
if (singletonInstance == nullptr)

View file

@ -57,3 +57,25 @@ void GameObject::addChild(const std::shared_ptr<GameObject> &child)
{
addChildWorldOffset(child, {0, 0});
}
void GameObject::removeChild(const std::shared_ptr<GameObject> &child)
{
auto it = std::find(children.begin(), children.end(), child);
if (it != children.end())
{
children.erase(it);
}
}
void GameObject::clearChildren()
{
children.clear();
}
void GameObject::physicsUpdate()
{
for (auto &child: children)
{
child->physicsUpdate();
}
}

View file

@ -18,12 +18,16 @@ public:
virtual void lateUpdate();
virtual void physicsUpdate();
void setActive(bool active);
bool getActive() const { return isActive; }
void addChildScreenOffset(const std::shared_ptr<GameObject> &child, IsometricCoordinates offset = {0, 0});
void addChildWorldOffset(const std::shared_ptr<GameObject> &child, WorldCoordinates offset);
void addChild(const std::shared_ptr<GameObject> &child);
void removeChild(const std::shared_ptr<GameObject> &child);
void clearChildren();
[[nodiscard]] std::vector<std::shared_ptr<GameObject>> getChildren() const { return children; }
std::shared_ptr<TranslatedCoordinates> coordinates;

View file

@ -2,10 +2,11 @@
#include "../game.h"
#include "../physics/map/map_simulation.hpp"
#include "../../debug/grid_debug_layer.h"
#include "../player/player_spawner.hpp"
#include "../../levels.hpp"
#include "../collectables/collection/collectables_collection.hpp"
#include "../collectables/collectable_factory.hpp"
#include "../player/player_collection.hpp"
#include "../physics/hole/hole_depth_simulation.hpp"
void LevelLoader::loadLevel(const LevelConfig &levelConfig)
{
@ -16,6 +17,7 @@ void LevelLoader::loadLevel(const LevelConfig& levelConfig)
game->setLevel(levelConfig);
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
PlayerCollection::getInstance()->clear();
// Add basic game objects
if (DEVELOPER_MODE)
@ -24,12 +26,14 @@ void LevelLoader::loadLevel(const LevelConfig& levelConfig)
}
game->addGameObject(std::make_shared<TrackingView>());
game->addGameObject(std::make_shared<PlayerSpawner>(levelConfig.playerSpawnPoints));
game->addGameObject(PlayerCollection::getInstance());
PlayerCollection::getInstance()->setSpawnPoints(levelConfig.playerSpawnPoints);
// Prepare collectables framework
auto maxDepth = levelConfig.worldMapSize.x * 2;
CollectablesCollection::getInstance()->createEmpty(maxDepth);
game->addGameObject(CollectablesCollection::getInstance());
auto maxDepth = (int) levelConfig.worldMapSize.x * 2;
auto collectablesCollection = CollectablesCollection::getInstance();
collectablesCollection->createEmpty(maxDepth);
game->addGameObject(collectablesCollection);
// Spawn collectibles
for (auto const &collectableInfo: levelConfig.collectables)
@ -37,6 +41,15 @@ void LevelLoader::loadLevel(const LevelConfig& levelConfig)
spawnCollectable(collectableInfo);
}
// Add physics simulations
game->addGameObject(MapSimulation::getInstance());
// For every depth, add a hole depth simulation
for (int depth = 0; depth < maxDepth; depth++)
{
auto depthCollection = collectablesCollection->getDepthCollection(depth);
game->addGameObject(std::make_shared<HoleDepthSimulation>(depthCollection));
}
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
}

View file

@ -7,7 +7,7 @@ HoleDepthSimulation::HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollec
simWorld = std::make_shared<b2World>(WORLD_GRAVITY);
}
void HoleDepthSimulation::updateSimulation()
void HoleDepthSimulation::physicsUpdate()
{
updateBodiesFromCollectionHistory();

View file

@ -10,12 +10,12 @@
/**
* @brief Simulates the hole(s) for the specific depth
*/
class HoleDepthSimulation
class HoleDepthSimulation : public GameObject
{
public:
HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables);
explicit HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables);
void updateSimulation();
void physicsUpdate() override;
private:
std::shared_ptr<CollectablesDepthCollection> collectables;

View file

@ -1,5 +1,6 @@
#include "map_simulation.hpp"
#include "../../../config.h"
#include "../../player/player_collection.hpp"
MapSimulation::MapSimulation()
{
@ -15,7 +16,7 @@ std::shared_ptr<MapSimulation> MapSimulation::getInstance()
return singletonInstance;
}
void MapSimulation::updateSimulation()
void MapSimulation::physicsUpdate()
{
// Update simulation positions
for (auto &mapPlayer: mapPlayersById)
@ -34,15 +35,20 @@ void MapSimulation::updateSimulation()
void MapSimulation::resetMap(sf::Vector2f worldMapSize)
{
// Clear all players
for (auto &mapPlayer: mapPlayersById)
{
removePlayer(mapPlayer.second->player);
}
// No gravity, since this a top-down view of the map
world = std::make_shared<b2World>(b2Vec2(0.0f, 0.0f));
mapPlayersById.clear();
// Create map borders
constructSquareObstacle(-1, 0, 0, worldMapSize.y);
constructSquareObstacle(0, -1, worldMapSize.x, 0);
constructSquareObstacle(worldMapSize.x, 0, worldMapSize.x + 1, worldMapSize.y);
constructSquareObstacle(0, worldMapSize.y, worldMapSize.x, worldMapSize.y + 1);
constructSquareObstacle(-MAPSIM_WALL_THICKNESS, -MAPSIM_WALL_THICKNESS, 0, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Bottom left
constructSquareObstacle(0, -MAPSIM_WALL_THICKNESS, worldMapSize.x, 0); // Bottom right
constructSquareObstacle(worldMapSize.x, -MAPSIM_WALL_THICKNESS, worldMapSize.x + MAPSIM_WALL_THICKNESS, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Top right
constructSquareObstacle(0, worldMapSize.y, worldMapSize.x, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Top left
}
void MapSimulation::constructSquareObstacle(float minX, float minY, float maxX, float maxY)
@ -66,7 +72,30 @@ void MapSimulation::addPlayer(const std::shared_ptr<Player>& player)
{
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(player->coordinates->world().x, player->coordinates->world().y);
bodyDef.position.Set(player->spawnPosition.world().x, player->spawnPosition.world().y);
b2Body *body = world->CreateBody(&bodyDef);
mapPlayersById[player->getPlayerId()] = std::make_shared<MapPlayer>(player, body);
}
void MapSimulation::update()
{
// Update players from player collection
// New player
for (auto &player: PlayerCollection::getInstance()->getNewPlayers())
{
addPlayer(player);
}
// Removed players
for (auto &player: PlayerCollection::getInstance()->getRemovedPlayers())
{
removePlayer(player);
}
}
void MapSimulation::removePlayer(std::shared_ptr<Player> &player)
{
// Remove body from simulation
int playerId = player->getPlayerId();
world->DestroyBody(mapPlayersById[playerId]->body);
mapPlayersById.erase(playerId);
}

View file

@ -7,12 +7,14 @@
#include "../../player/player.hpp"
#include "map_player.hpp"
class MapSimulation
class MapSimulation : public GameObject
{
public:
MapSimulation();
void updateSimulation();
void update() override;
void physicsUpdate() override;
void resetMap(sf::Vector2f worldMapSize);
@ -29,6 +31,7 @@ private:
void constructSquareObstacle(float minX, float minY, float maxX, float maxY);
void removePlayer(std::shared_ptr<Player> &player);
};

View file

@ -1,19 +1,21 @@
#include "player.hpp"
#include "../../config.h"
#include "../../logging/easylogging++.h"
#include <utility>
Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
GridCoordinates initCoordinates)
: spawnPosition(initCoordinates)
{
playerId = playerCreationCounter++;
this->spawnPosition = initCoordinates;
coordinates->set(initCoordinates);
coordinates->set(spawnPosition);
input = std::move(assignedInput);
skinSprite = std::make_shared<VersatileSprite>(skinRessourceName, getIsoSize());
addChildScreenOffset(skinSprite, IsometricCoordinates(-getIsoSize() / 2.f));
LOG(INFO) << "Player " << playerId << " created.";
}
sf::Vector2f Player::getTrackablePosition() const
@ -92,3 +94,8 @@ void Player::setWorldRadius(float newWorldRadius)
skinSprite->setSize(newSize);
skinSprite->coordinates->setScreenOffset(IsometricCoordinates(-newSize / 2.f));
}
Player::~Player()
{
LOG(INFO) << "Player " << playerId << " destroyed.";
}

View file

@ -13,6 +13,8 @@ public:
Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
GridCoordinates initCoordinates);
~Player();
void update() override;
[[nodiscard]] sf::Vector2f getTrackablePosition() const override;
@ -29,13 +31,12 @@ public:
[[nodiscard]] float getWorldRadius() const;
TranslatedCoordinates spawnPosition;
private:
std::shared_ptr<InputIdentity> input;
float radiusInWorld = DEFAULT_PLAYER_RADIUS;
std::shared_ptr<VersatileSprite> skinSprite;
GridCoordinates spawnPosition;
int playerId;
static inline int playerCreationCounter = 0;

View file

@ -0,0 +1,106 @@
#include "player_collection.hpp"
#include <utility>
#include "../input/input_mapper.h"
#include "../../texture_config.h"
PlayerCollection::PlayerCollection()
{
// Set default spawn point
setSpawnPoints({{0, 0}});
// Create player for existing input identities
for (auto &inputIdentity: InputMapper::getInstance()->getInputIdentities())
{
spawnPlayer(inputIdentity);
}
}
std::shared_ptr<PlayerCollection> PlayerCollection::getInstance()
{
if (singletonInstance == nullptr)
{
singletonInstance = std::make_shared<PlayerCollection>();
}
return singletonInstance;
}
void PlayerCollection::addPlayer(const std::shared_ptr<Player> &player)
{
newPlayerBuffer.push_back(player);
addChild(player);
}
void PlayerCollection::clear()
{
newPlayerBuffer.clear();
removedPlayerBuffer.clear();
// Fill in removed players
for (auto &child: getChildren())
{
auto player = std::dynamic_pointer_cast<Player>(child);
if (player != nullptr)
{
removedPlayerBuffer.push_back(player);
}
}
clearChildren();
}
void PlayerCollection::lateUpdate()
{
GameObject::lateUpdate();
newPlayerBuffer.clear();
removedPlayerBuffer.clear();
// Create player for new input identities
for (auto &inputIdentity: InputMapper::getInstance()->newInputIdentities)
{
spawnPlayer(inputIdentity);
}
// Remove players, that are not active anymore
for (auto &child: getChildren())
{
if (child != nullptr && !child->getActive())
{
removedPlayerBuffer.push_back(std::dynamic_pointer_cast<Player>(child));
removeChild(child);
}
}
}
void PlayerCollection::removePlayer(const std::shared_ptr<Player> &player)
{
removedPlayerBuffer.push_back(player);
removeChild(player);
}
std::vector<std::shared_ptr<Player>> PlayerCollection::getNewPlayers() const
{
return newPlayerBuffer;
}
std::vector<std::shared_ptr<Player>> PlayerCollection::getRemovedPlayers() const
{
return removedPlayerBuffer;
}
void PlayerCollection::setSpawnPoints(std::vector<GridCoordinates> newSpawnPoints)
{
this->spawnPoints = std::move(newSpawnPoints);
nextSpawnPointIndex = 0;
}
void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity)
{
// Get proper Spawn point, if available
auto spawn = spawnPoints[nextSpawnPointIndex];
nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size());
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
PlayerCollection::getInstance()->addPlayer(player);
}

View file

@ -0,0 +1,42 @@
#ifndef HOLESOME_PLAYER_COLLECTION_HPP
#define HOLESOME_PLAYER_COLLECTION_HPP
#include "../game_object.h"
#include "player.hpp"
class PlayerCollection : public GameObject
{
public:
PlayerCollection();
static std::shared_ptr<PlayerCollection> getInstance();
void setSpawnPoints(std::vector<GridCoordinates> newSpawnPoints);
void addPlayer(const std::shared_ptr<Player>& player);
void removePlayer(const std::shared_ptr<Player>& player);
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
void lateUpdate() override;
void clear();
private:
static inline std::shared_ptr<PlayerCollection> singletonInstance = nullptr;
std::vector<std::shared_ptr<Player>> newPlayerBuffer = {};
std::vector<std::shared_ptr<Player>> removedPlayerBuffer = {};
std::vector<GridCoordinates> spawnPoints;
int nextSpawnPointIndex = 0;
void spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity);
};
#endif //HOLESOME_PLAYER_COLLECTION_HPP

View file

@ -1,39 +0,0 @@
#include "player_spawner.hpp"
#include "player.hpp"
#include "../../texture_config.h"
#include "../physics/map/map_simulation.hpp"
PlayerSpawner::PlayerSpawner(std::vector<GridCoordinates> spawnPoints)
{
this->spawnPoints = spawnPoints;
// Create player for existing input identities
for (auto &inputIdentity: InputMapper::getInstance()->getInputIdentities())
{
spawnPlayer(inputIdentity);
}
}
void PlayerSpawner::update()
{
// Create player for new input identities
for (auto &inputIdentity: InputMapper::getInstance()->newInputIdentities)
{
spawnPlayer(inputIdentity);
}
}
void PlayerSpawner::spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity)
{
// Get proper Spawn point, if available
auto spawn = spawnPoints[nextSpawnPointIndex];
nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size());
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
MapSimulation::getInstance()->addPlayer(player);
Game::getInstance()->addGameObject(player);
// TODO: Better view handling
Game::getInstance()->views[0]->addTrackable(player);
}

View file

@ -1,23 +0,0 @@
#ifndef HOLESOME_PLAYER_SPAWNER_HPP
#define HOLESOME_PLAYER_SPAWNER_HPP
#include "../game_object.h"
#include "../game.h"
class PlayerSpawner : public GameObject
{
public:
PlayerSpawner(std::vector<GridCoordinates> spawnPoints);
void update() override;
void spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity);
private:
std::vector<GridCoordinates> spawnPoints;
int nextSpawnPointIndex = 0;
};
#endif //HOLESOME_PLAYER_SPAWNER_HPP

View file

@ -3870,7 +3870,7 @@ class Loggers : base::StaticClass {
private:
LoggingFlag m_flag;
};
/// @brief Removes flag and add it when scope goes out
/// @brief Removes flag and addPlayer it when scope goes out
class ScopedRemoveFlag {
public:
ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) {

View file

@ -7,7 +7,7 @@
#include "sprites/configs/sheet_config.hpp"
#include "sprites/configs/sprite_config.hpp"
#define PLAYER_SKIN "hole"
#define PLAYER_SKIN "ring"
/**
* All textures used in the game.