First tile map properly working
This commit is contained in:
parent
120fdb0a88
commit
27b6e1b324
35 changed files with 216 additions and 227 deletions
|
@ -98,7 +98,7 @@ set(SOURCES
|
|||
src/levels.hpp
|
||||
src/sprites/tiling/tilemap.cpp
|
||||
src/sprites/tiling/tilemap.hpp
|
||||
src/sprites/tiling/tilemap_config.hpp src/tilemaps.hpp src/sprites/tiling/tileset_config.hpp src/sprites/tiling/tileset.cpp src/sprites/tiling/tileset.hpp)
|
||||
src/sprites/tiling/tilemap_config.hpp src/sprites/tiling/tileset_config.hpp src/sprites/tiling/tileset.cpp src/sprites/tiling/tileset.hpp)
|
||||
|
||||
set(PHYSICS_00_SOURCES
|
||||
src/prototypes/physics_00.cpp)
|
||||
|
|
|
@ -10,7 +10,7 @@ struct WorldCoordinates
|
|||
WorldCoordinates(float x, float y, float z = 0) : x(x), y(y), z(z)
|
||||
{}
|
||||
|
||||
WorldCoordinates(sf::Vector2f vector) : x(vector.x), y(vector.y), z(0)
|
||||
explicit WorldCoordinates(sf::Vector2f vector) : x(vector.x), y(vector.y), z(0)
|
||||
{}
|
||||
|
||||
float x;
|
||||
|
@ -62,7 +62,7 @@ struct IsometricCoordinates
|
|||
float y;
|
||||
float depth; // Bigger means further back. Can be used for accurate rendering order.
|
||||
|
||||
sf::Vector2f toScreen() const
|
||||
[[nodiscard]] sf::Vector2f toScreen() const
|
||||
{
|
||||
return {x, y};
|
||||
}
|
||||
|
@ -85,6 +85,9 @@ struct GridCoordinates
|
|||
|
||||
GridCoordinates(float x, float y) : x(x), y(y)
|
||||
{}
|
||||
|
||||
GridCoordinates(int x, int y) : x(static_cast<float>(x)), y(static_cast<float>(y))
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@ GridCoordinates TranslatedCoordinates::grid() const {
|
|||
return {referenceWordCoordinates.x - 0.5f, referenceWordCoordinates.y - 0.5f};
|
||||
}
|
||||
|
||||
void TranslatedCoordinates::set(WorldCoordinates newWorldCoordinates) {
|
||||
void TranslatedCoordinates::setWorld(WorldCoordinates newWorldCoordinates) {
|
||||
this->worldCoordinates = newWorldCoordinates;
|
||||
}
|
||||
|
||||
void TranslatedCoordinates::set(IsometricCoordinates newIsometricCoordinates) {
|
||||
void TranslatedCoordinates::setIsometric(IsometricCoordinates newIsometricCoordinates) {
|
||||
this->worldCoordinates = CoordinateTransformer::isometricToWorld(newIsometricCoordinates);
|
||||
}
|
||||
|
||||
void TranslatedCoordinates::set(const TranslatedCoordinates& newCoordinates) {
|
||||
void TranslatedCoordinates::setTranslated(const TranslatedCoordinates& newCoordinates) {
|
||||
this->worldCoordinates = newCoordinates.world();
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ void TranslatedCoordinates::setParent(std::shared_ptr<TranslatedCoordinates> par
|
|||
this->worldCoordinates = offset;
|
||||
}
|
||||
|
||||
void TranslatedCoordinates::set(GridCoordinates newGridCoordinates)
|
||||
void TranslatedCoordinates::setGrid(GridCoordinates newGridCoordinates)
|
||||
{
|
||||
this->worldCoordinates = {newGridCoordinates.x + 0.5f, newGridCoordinates.y + 0.5f, 0};
|
||||
}
|
||||
|
@ -71,5 +71,5 @@ void TranslatedCoordinates::setScreenOffset(IsometricCoordinates offset)
|
|||
|
||||
TranslatedCoordinates::TranslatedCoordinates(GridCoordinates gridCoordinates)
|
||||
{
|
||||
set(gridCoordinates);
|
||||
setGrid(gridCoordinates);
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ public:
|
|||
|
||||
[[nodiscard]] GridCoordinates grid() const;
|
||||
|
||||
void set(WorldCoordinates newWorldCoordinates);
|
||||
void setWorld(WorldCoordinates newWorldCoordinates);
|
||||
|
||||
void set(const TranslatedCoordinates& newCoordinates);
|
||||
void setTranslated(const TranslatedCoordinates& newCoordinates);
|
||||
|
||||
void set(IsometricCoordinates newIsometricCoordinates);
|
||||
void setIsometric(IsometricCoordinates newIsometricCoordinates);
|
||||
|
||||
void set(GridCoordinates newGridCoordinates);
|
||||
void setGrid(GridCoordinates newGridCoordinates);
|
||||
|
||||
void move(WorldCoordinates deltaWorldCoordinates);
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ void TrackingView::followTrackables()
|
|||
auto trackingPoint = getTrackingArea().getCenter();
|
||||
if (DEVELOPER_MODE)
|
||||
{
|
||||
marker->coordinates->set(IsometricCoordinates(trackingPoint));
|
||||
marker->coordinates->setIsometric(IsometricCoordinates(trackingPoint));
|
||||
}
|
||||
|
||||
// Calculate distance to target to check how to handle it
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
struct TrackingViewOptions
|
||||
{
|
||||
/**
|
||||
* Value >1 to set pixel radius.
|
||||
* Value between 0 and 1 to set relative radius based on smallest half-axis-size.
|
||||
* Value >1 to setWorld pixel radius.
|
||||
* Value between 0 and 1 to setWorld relative radius based on smallest half-axis-size.
|
||||
*/
|
||||
float freeMoveThreshold = DEF_TV_FREE_MOVE_THRESHOLD;
|
||||
|
||||
|
@ -22,24 +22,24 @@ struct TrackingViewOptions
|
|||
float softResizeSpeed = DEF_TV_SOFT_RESIZE_SPEED;
|
||||
|
||||
/**
|
||||
* If set to 0, view will not be limited.
|
||||
* If setWorld to 0, view will not be limited.
|
||||
*/
|
||||
sf::Vector2f minViewSize = DEF_TV_MIN_VIEW_SIZE;
|
||||
|
||||
/**
|
||||
* If set to 0, view will not be limited.
|
||||
* If setWorld to 0, view will not be limited.
|
||||
*/
|
||||
sf::Vector2f maxViewSize = DEF_TV_MAX_VIEW_SIZE;
|
||||
|
||||
/**
|
||||
* Will be added to tracked area size twice, as padding for each side.
|
||||
* Value >1 to set pixel padding.
|
||||
* Value between 0 and 1 to set relative padding.
|
||||
* Value >1 to setWorld pixel padding.
|
||||
* Value between 0 and 1 to setWorld 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.
|
||||
* If setWorld to true, view will add all new players automatically and remove them accordingly, based on PlayerCollection.
|
||||
*/
|
||||
bool addPlayersDynamically = DEF_TV_ADD_PLAYERS_DYNAMICALLY;
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@ std::shared_ptr<Collectable> CollectableFactory::createFromInLevelConfig(const C
|
|||
auto collectableConfig = config.collectableConfig;
|
||||
auto collectable = std::make_shared<Collectable>();
|
||||
|
||||
collectable->coordinates->set(config.position);
|
||||
collectable->coordinates->setGrid(config.position);
|
||||
collectable->setSprite(collectableConfig.spriteName);
|
||||
|
||||
return collectable;
|
||||
|
|
|
@ -8,24 +8,24 @@
|
|||
#include "../collectables/collectable_in_level.hpp"
|
||||
#include <vector>
|
||||
#include "../../sprites/tiling/tilemap_config.hpp"
|
||||
#include "../../sprites/sprite_factory.hpp"
|
||||
|
||||
struct LevelConfig
|
||||
{
|
||||
std::string name;
|
||||
sf::Vector2f worldMapSize = {};
|
||||
sf::Vector2i worldMapSize = {};
|
||||
TileMapConfig tileMapConfig = {};
|
||||
std::vector<GridCoordinates> playerSpawnPoints = {};
|
||||
std::vector<CollectableInLevel> collectables = {};
|
||||
|
||||
LevelConfig(std::string name,
|
||||
const std::string &tileMapName,
|
||||
const std::vector<GridCoordinates> &playerSpawnPoints,
|
||||
const std::vector<CollectableInLevel> &collectables = {})
|
||||
const std::vector<CollectableInLevel> &collectables,
|
||||
const TileMapConfig &tileMapConfig)
|
||||
: name(std::move(name)),
|
||||
worldMapSize(worldMapSize),
|
||||
playerSpawnPoints(playerSpawnPoints)
|
||||
playerSpawnPoints(playerSpawnPoints),
|
||||
tileMapConfig(tileMapConfig)
|
||||
{
|
||||
tileMapConfig = TileMapConfig(tileMapName, {});
|
||||
worldMapSize = tileMapConfig.getSize();
|
||||
|
||||
// Remove invalid collectables
|
||||
|
|
|
@ -20,6 +20,8 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
|||
PlayerCollection::getInstance()->clear();
|
||||
|
||||
// Add basic game objects
|
||||
game->addGameObject(SpriteFactory::createTileMap(levelConfig.tileMapConfig));
|
||||
|
||||
if (DEVELOPER_MODE)
|
||||
{
|
||||
game->addGameObject(std::make_shared<GridDebugLayer>(0, 50, 0, 50));
|
||||
|
@ -43,12 +45,6 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
|||
|
||||
// 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 << "'.";
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ void MapPlayer::updateSimulationPosition()
|
|||
void MapPlayer::updatePlayerPosition() const
|
||||
{
|
||||
b2Vec2 playerPosition = body->GetPosition();
|
||||
player->coordinates->set(sf::Vector2f(playerPosition.x, playerPosition.y));
|
||||
player->coordinates->setWorld({playerPosition.x, playerPosition.y});
|
||||
}
|
||||
|
||||
void MapPlayer::updateShape()
|
||||
|
@ -28,7 +28,8 @@ void MapPlayer::updateShape()
|
|||
shapeRadius = player->getWorldRadius();
|
||||
|
||||
b2Fixture *oldFixture = body->GetFixtureList();
|
||||
if (oldFixture != nullptr) {
|
||||
if (oldFixture != nullptr)
|
||||
{
|
||||
body->DestroyFixture(oldFixture);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void MapSimulation::physicsUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
void MapSimulation::resetMap(sf::Vector2f worldMapSize)
|
||||
void MapSimulation::resetMap(sf::Vector2<int> worldMapSize)
|
||||
{
|
||||
// Clear all players
|
||||
for (auto &mapPlayer: mapPlayersById)
|
||||
|
|
|
@ -16,7 +16,7 @@ public:
|
|||
|
||||
void physicsUpdate() override;
|
||||
|
||||
void resetMap(sf::Vector2f worldMapSize);
|
||||
void resetMap(sf::Vector2<int> worldMapSize);
|
||||
|
||||
static std::shared_ptr<MapSimulation> getInstance();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &
|
|||
: spawnPosition(initCoordinates)
|
||||
{
|
||||
playerId = playerCreationCounter++;
|
||||
coordinates->set(spawnPosition);
|
||||
coordinates->setTranslated(spawnPosition);
|
||||
|
||||
input = std::move(assignedInput);
|
||||
|
||||
|
@ -94,8 +94,3 @@ void Player::setWorldRadius(float newWorldRadius)
|
|||
skinSprite->setSize(newSize);
|
||||
skinSprite->coordinates->setScreenOffset(IsometricCoordinates(-newSize / 2.f));
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
{
|
||||
LOG(INFO) << "Player " << playerId << " destroyed.";
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ public:
|
|||
Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
|
||||
GridCoordinates initCoordinates);
|
||||
|
||||
~Player();
|
||||
|
||||
void update() override;
|
||||
|
||||
[[nodiscard]] sf::Vector2f getTrackablePosition() const override;
|
||||
|
|
|
@ -8,9 +8,19 @@
|
|||
#define INITIAL_LEVEL "default"
|
||||
|
||||
std::map<std::string, LevelConfig> const all_levels = {
|
||||
{"default", LevelConfig("Default", "grass", {{0, 0}}, {
|
||||
CollectableInLevel("box", {5, 5})
|
||||
})}
|
||||
{"default", LevelConfig("Default", {{0, 0}}, {
|
||||
CollectableInLevel("box", {5, 5})},
|
||||
TileMapConfig("iso-tiles", {{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 0, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 1, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4}})
|
||||
)}
|
||||
};
|
||||
|
||||
#endif //HOLESOME_LEVELS_HPP
|
||||
|
|
|
@ -694,7 +694,7 @@ class ConfigurationTypeHelper : base::StaticClass {
|
|||
/// This bool represent whether or not to exit iterating through configurations.
|
||||
static inline void forEachConfigType(base::type::EnumType* startIndex, const std::function<bool(void)>& fn);
|
||||
};
|
||||
/// @brief Flags used while writing logs. This flags are set by user
|
||||
/// @brief Flags used while writing logs. This flags are setWorld by user
|
||||
enum class LoggingFlag : base::type::EnumType {
|
||||
/// @brief Makes sure we have new line for each container log entry
|
||||
NewLineForContainer = 1,
|
||||
|
@ -1701,7 +1701,7 @@ class Configuration : public Loggable {
|
|||
}
|
||||
|
||||
/// @brief Set string based configuration value
|
||||
/// @param value Value to set. Values have to be std::string; For boolean values use "true", "false", for any integral values
|
||||
/// @param value Value to setWorld. Values have to be std::string; For boolean values use "true", "false", for any integral values
|
||||
/// use them in quotes. They will be parsed when configuring
|
||||
inline void setValue(const std::string& value) {
|
||||
m_value = value;
|
||||
|
@ -1735,9 +1735,9 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @brief Default constructor with empty repository
|
||||
Configurations(void);
|
||||
|
||||
/// @brief Constructor used to set configurations using configuration file.
|
||||
/// @brief Constructor used to setWorld configurations using configuration file.
|
||||
/// @param configurationFile Full path to configuration file
|
||||
/// @param useDefaultsForRemaining Lets you set the remaining configurations to default.
|
||||
/// @param useDefaultsForRemaining Lets you setWorld the remaining configurations to default.
|
||||
/// @param base If provided, this configuration will be based off existing repository that this argument is pointing to.
|
||||
/// @see parseFromFile(const std::string&, Configurations* base)
|
||||
/// @see setRemainingToDefault()
|
||||
|
@ -1750,7 +1750,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @brief Parses configuration from file.
|
||||
/// @param configurationFile Full path to configuration file
|
||||
/// @param base Configurations to base new configuration repository off. This value is used when you want to use
|
||||
/// existing Configurations to base all the values and then set rest of configuration via configuration file.
|
||||
/// existing Configurations to base all the values and then setWorld rest of configuration via configuration file.
|
||||
/// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you
|
||||
/// do not proceed without successful parse.
|
||||
bool parseFromFile(const std::string& configurationFile, Configurations* base = nullptr);
|
||||
|
@ -1760,7 +1760,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @detail This configuration string has same syntax as configuration file contents. Make sure all the necessary
|
||||
/// new line characters are provided.
|
||||
/// @param base Configurations to base new configuration repository off. This value is used when you want to use
|
||||
/// existing Configurations to base all the values and then set rest of configuration via configuration text.
|
||||
/// existing Configurations to base all the values and then setWorld rest of configuration via configuration text.
|
||||
/// @return True if successfully parsed, false otherwise. You may define 'ELPP_DEBUG_ASSERT_FAILURE' to make sure you
|
||||
/// do not proceed without successful parse.
|
||||
bool parseFromText(const std::string& configurationsString, Configurations* base = nullptr);
|
||||
|
@ -1783,9 +1783,9 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @brief Sets value of configuration for specified level.
|
||||
///
|
||||
/// @detail Any existing configuration for specified level will be replaced. Also note that configuration types
|
||||
/// ConfigurationType::SubsecondPrecision and ConfigurationType::PerformanceTracking will be ignored if not set for
|
||||
/// ConfigurationType::SubsecondPrecision and ConfigurationType::PerformanceTracking will be ignored if not setWorld for
|
||||
/// Level::Global because these configurations are not dependant on level.
|
||||
/// @param level Level to set configuration for (el::Level).
|
||||
/// @param level Level to setWorld configuration for (el::Level).
|
||||
/// @param configurationType Type of configuration (el::ConfigurationType)
|
||||
/// @param value A string based value. Regardless of what the data type of configuration is, it will always be string
|
||||
/// from users' point of view. This is then parsed later to be used internally.
|
||||
|
@ -1795,7 +1795,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
void set(Level level, ConfigurationType configurationType, const std::string& value);
|
||||
|
||||
/// @brief Sets single configuration based on other single configuration.
|
||||
/// @see set(Level level, ConfigurationType configurationType, const std::string& value)
|
||||
/// @see setWorld(Level level, ConfigurationType configurationType, const std::string& value)
|
||||
void set(Configuration* conf);
|
||||
|
||||
inline Configuration* get(Level level, ConfigurationType configurationType) {
|
||||
|
@ -1806,7 +1806,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @brief Sets configuration for all levels.
|
||||
/// @param configurationType Type of configuration
|
||||
/// @param value String based value
|
||||
/// @see Configurations::set(Level level, ConfigurationType configurationType, const std::string& value)
|
||||
/// @see Configurations::setWorld(Level level, ConfigurationType configurationType, const std::string& value)
|
||||
inline void setGlobally(ConfigurationType configurationType, const std::string& value) {
|
||||
setGlobally(configurationType, value, false);
|
||||
}
|
||||
|
@ -1819,7 +1819,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
|
||||
/// @brief Gets configuration file used in parsing this configurations.
|
||||
///
|
||||
/// @detail If this repository was set manually or by text this returns empty string.
|
||||
/// @detail If this repository was setWorld manually or by text this returns empty string.
|
||||
inline const std::string& configurationFile(void) const {
|
||||
return m_configurationFile;
|
||||
}
|
||||
|
@ -1827,11 +1827,11 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @brief Sets configurations to "factory based" configurations.
|
||||
void setToDefault(void);
|
||||
|
||||
/// @brief Lets you set the remaining configurations to default.
|
||||
/// @brief Lets you setWorld the remaining configurations to default.
|
||||
///
|
||||
/// @detail By remaining, it means that the level/type a configuration does not exist for.
|
||||
/// This function is useful when you want to minimize chances of failures, e.g, if you have a configuration file that sets
|
||||
/// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is set to default i.e,
|
||||
/// configuration for all the configurations except for Enabled or not, we use this so that ENABLED is setWorld to default i.e,
|
||||
/// true. If you dont do this explicitly (either by calling this function or by using second param in Constructor
|
||||
/// and try to access a value, an error is thrown
|
||||
void setRemainingToDefault(void);
|
||||
|
@ -1846,7 +1846,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @param configurationFile Full path to configuration file
|
||||
/// @param sender Sender configurations pointer. Usually 'this' is used from calling class
|
||||
/// @param base Configurations to base new configuration repository off. This value is used when you want to use
|
||||
/// existing Configurations to base all the values and then set rest of configuration via configuration file.
|
||||
/// existing Configurations to base all the values and then setWorld rest of configuration via configuration file.
|
||||
/// @return True if successfully parsed, false otherwise. You may define '_STOP_ON_FIRSTELPP_ASSERTION' to make sure you
|
||||
/// do not proceed without successful parse.
|
||||
static bool parseFromFile(const std::string& configurationFile, Configurations* sender,
|
||||
|
@ -1860,7 +1860,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @param configurationsString the configuration in plain text format
|
||||
/// @param sender Sender configurations pointer. Usually 'this' is used from calling class
|
||||
/// @param base Configurations to base new configuration repository off. This value is used when you want to use
|
||||
/// existing Configurations to base all the values and then set rest of configuration via configuration text.
|
||||
/// existing Configurations to base all the values and then setWorld rest of configuration via configuration text.
|
||||
/// @return True if successfully parsed, false otherwise.
|
||||
static bool parseFromText(const std::string& configurationsString, Configurations* sender,
|
||||
Configurations* base = nullptr);
|
||||
|
@ -1883,7 +1883,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||
/// @brief Unsafely sets configuration if does not already exist
|
||||
void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string& value);
|
||||
|
||||
/// @brief Thread unsafe set
|
||||
/// @brief Thread unsafe setWorld
|
||||
void unsafeSet(Level level, ConfigurationType configurationType, const std::string& value);
|
||||
|
||||
/// @brief Sets configurations for all levels including Level::Global if includeGlobalLevel is true
|
||||
|
@ -3839,7 +3839,7 @@ class Loggers : base::StaticClass {
|
|||
static std::vector<std::string>* populateAllLoggerIds(std::vector<std::string>* targetList);
|
||||
/// @brief Sets configurations from global configuration file.
|
||||
static void configureFromGlobal(const char* globalConfigurationFilePath);
|
||||
/// @brief Configures loggers using command line arg. Ensure you have already set command line args,
|
||||
/// @brief Configures loggers using command line arg. Ensure you have already setWorld command line args,
|
||||
/// @return False if invalid argument or argument with no value provided, true if attempted to configure logger.
|
||||
/// If true is returned that does not mean it has been configured successfully, it only means that it
|
||||
/// has attempted to configure logger using configuration file provided in argument
|
||||
|
|
|
@ -44,3 +44,8 @@ sf::Vector2f AnimatedSprite::getSize() const
|
|||
auto textureSize = sprites[currentFrame].getTextureRect();
|
||||
return {textureSize.width * scale.x, textureSize.height * scale.y};
|
||||
}
|
||||
|
||||
sf::Sprite AnimatedSprite::getSprite() const
|
||||
{
|
||||
return sprites[currentFrame];
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
class AnimatedSprite : public GameObject, public Sprite
|
||||
{
|
||||
public:
|
||||
AnimatedSprite(const std::vector<sf::Sprite>& sprites, const sf::Vector2f& size = sf::Vector2f(0, 0));
|
||||
explicit AnimatedSprite(const std::vector<sf::Sprite>& sprites, const sf::Vector2f& size = sf::Vector2f(0, 0));
|
||||
|
||||
void update() override;
|
||||
|
||||
|
@ -19,7 +19,9 @@ public:
|
|||
|
||||
void setSize(const sf::Vector2f &size) override;
|
||||
|
||||
sf::Vector2f getSize() const override;
|
||||
[[nodiscard]] sf::Vector2f getSize() const override;
|
||||
|
||||
sf::Sprite getSprite() const override;
|
||||
|
||||
private:
|
||||
int currentFrame = 0;
|
||||
|
|
|
@ -37,3 +37,8 @@ sf::Vector2f SingleSprite::getSize() const
|
|||
auto textureSize = sprite.getTextureRect();
|
||||
return {textureSize.width * sprite.getScale().x, textureSize.height * sprite.getScale().y};
|
||||
}
|
||||
|
||||
sf::Sprite SingleSprite::getSprite() const
|
||||
{
|
||||
return sprite;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
|
||||
sf::Vector2f getSize() const override;
|
||||
|
||||
sf::Sprite getSprite() const override;
|
||||
|
||||
private:
|
||||
sf::Sprite sprite;
|
||||
};
|
||||
|
|
|
@ -3,16 +3,26 @@
|
|||
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
virtual void setSize(const sf::Vector2f &size)
|
||||
{}
|
||||
{
|
||||
throw std::runtime_error("Sprite::setSize() not implemented");
|
||||
}
|
||||
|
||||
virtual sf::Vector2f getSize() const
|
||||
{ return {0, 0}; }
|
||||
[[nodiscard]] virtual sf::Vector2f getSize() const
|
||||
{
|
||||
throw std::runtime_error("Sprite::getSize() not implemented");
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual sf::Sprite getSprite() const
|
||||
{
|
||||
throw std::runtime_error("Sprite::getSprite() not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
#endif //HOLESOME_SPRITE_HPP
|
||||
|
|
|
@ -96,32 +96,6 @@ std::shared_ptr<SpriteSheet> SpriteFactory::createSheet(const std::string& name)
|
|||
return std::make_shared<SpriteSheet>(texture, config.columns, config.rows);
|
||||
}
|
||||
|
||||
std::shared_ptr<TileMap> SpriteFactory::createTileMap(const std::string &name)
|
||||
{
|
||||
// Get config
|
||||
auto tilemap_config = all_tilemaps.find(name);
|
||||
|
||||
if (tilemap_config == all_tilemaps.end())
|
||||
{
|
||||
LOG(ERROR) << "Tilemap " << name << " not found. Could not create tilemap.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Construct tilemap
|
||||
auto config = tilemap_config->second;
|
||||
std::shared_ptr<TileSet> tileSet = createTileSet(config.tileSheet);
|
||||
if (sheet == nullptr)
|
||||
{
|
||||
LOG(ERROR) << "Sheet " << config.sheetName << " not found. Could not create tilemap.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Creating tilemap " << name;
|
||||
auto tilemap = std::make_shared<TileMap>(sheet, config.tileSize, config.tileCount);
|
||||
tilemap->setTilemap(config.tilemap);
|
||||
return tilemap;
|
||||
}
|
||||
|
||||
std::shared_ptr<TileSet> SpriteFactory::createTileSet(const std::string &name)
|
||||
{
|
||||
// Get config
|
||||
|
@ -145,3 +119,20 @@ std::shared_ptr<TileSet> SpriteFactory::createTileSet(const std::string &name)
|
|||
LOG(INFO) << "Creating tileset " << name;
|
||||
return std::make_shared<TileSet>(sheet, config.tileIndices);
|
||||
}
|
||||
|
||||
std::shared_ptr<SingleSprite> SpriteFactory::copySingleSprite(const std::shared_ptr<SingleSprite>& sprite)
|
||||
{
|
||||
return std::make_shared<SingleSprite>(sprite->getSprite(), sprite->getSize());
|
||||
}
|
||||
|
||||
std::shared_ptr<TileMap> SpriteFactory::createTileMap(TileMapConfig config)
|
||||
{
|
||||
auto tileSet = createTileSet(config.tileSet);
|
||||
if (tileSet == nullptr)
|
||||
{
|
||||
LOG(ERROR) << "Tileset " << config.tileSet << " not found. Could not create tilemap.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<TileMap>(tileSet, config.tiles);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../logging/easylogging++.h"
|
||||
#include "tiling/tilemap.hpp"
|
||||
#include "tiling/tileset.hpp"
|
||||
#include "tiling/tilemap_config.hpp"
|
||||
|
||||
class SpriteFactory
|
||||
{
|
||||
|
@ -17,8 +18,9 @@ public:
|
|||
static std::shared_ptr<SingleSprite> createSingleSprite(const std::string& name, sf::Vector2f size = sf::Vector2f(0, 0));
|
||||
static std::shared_ptr<AnimatedSprite> createAnimatedSprite(const std::string& name, sf::Vector2f size = sf::Vector2f(0, 0));
|
||||
static std::shared_ptr<SpriteSheet> createSheet(const std::string& name);
|
||||
static std::shared_ptr<TileMap> createTileMap(const std::string& name);
|
||||
std::shared_ptr<TileSet> createTileSet(const std::string &name);
|
||||
static std::shared_ptr<TileSet> createTileSet(const std::string &name);
|
||||
static std::shared_ptr<SingleSprite> copySingleSprite(const std::shared_ptr<SingleSprite>& sprite);
|
||||
static std::shared_ptr<TileMap> createTileMap(TileMapConfig config);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "tilemap.hpp"
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef HOLESOME_TILEMAP_HPP
|
||||
#define HOLESOME_TILEMAP_HPP
|
||||
|
||||
|
||||
#include "../../game/game_object.h"
|
||||
|
||||
class Tilemap : public GameObject
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //HOLESOME_TILEMAP_HPP
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef HOLESOME_TILEMAP_CONFIG_HPP
|
||||
#define HOLESOME_TILEMAP_CONFIG_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct TilemapConfig {
|
||||
std::string tileSheetName;
|
||||
std::vector<std::vector<int>> tiles;
|
||||
};
|
||||
|
||||
#endif //HOLESOME_TILEMAP_CONFIG_HPP
|
|
@ -1,57 +1,35 @@
|
|||
#include "tilemap.hpp"
|
||||
#include "../sprite_factory.hpp"
|
||||
|
||||
TileMap::TileMap(std::shared_ptr<TileSet> tileSet, std::vector<std::vector<int>> tiles)
|
||||
TileMap::TileMap(const std::shared_ptr<TileSet> &tileSet, std::vector<std::vector<int>> tiles)
|
||||
{
|
||||
// resize the vertex array to fit the level size
|
||||
vertices.setPrimitiveType(sf::Quads);
|
||||
|
||||
unsigned int size = tiles.size();
|
||||
vertices.resize(size * size * 4);
|
||||
|
||||
// populate the vertex array, with one quad per tile
|
||||
for (unsigned int y = 0; y < size; ++y)
|
||||
for (unsigned int x = 0; x < size; ++x)
|
||||
for (int i = 2 * (size - 1); i >= 0 ; i--)
|
||||
{
|
||||
// get the current tile number
|
||||
int tileNumber = tiles[size - 1 - y][x];
|
||||
|
||||
// TODO
|
||||
// Follow: https://www.sfml-dev.org/tutorials/2.5/graphics-vertex-array.php#example-tile-map
|
||||
// find its position in the tileset texture
|
||||
int tu = tileNumber % (tileset.getSize().y / tileSize.y);
|
||||
int tv = tileNumber / (tileset.getSize().y / tileSize.y);
|
||||
|
||||
// get a pointer to the current tile's quad
|
||||
sf::Vertex *quad = &vertices[(y + x * width) * 4];
|
||||
|
||||
// define its 4 corners
|
||||
quad[0].position = sf::Vector2f(y * tileSize.y, x * tileSize.y);
|
||||
quad[1].position = sf::Vector2f((y + 1) * tileSize.y, x * tileSize.y);
|
||||
quad[2].position = sf::Vector2f((y + 1) * tileSize.y, (x + 1) * tileSize.y);
|
||||
quad[3].position = sf::Vector2f(y * tileSize.y, (x + 1) * tileSize.y);
|
||||
|
||||
// define its 4 texture coordinates
|
||||
quad[0].texCoords = sf::Vector2f(tu * tileSize.y, tv * tileSize.y);
|
||||
quad[1].texCoords = sf::Vector2f((tu + 1) * tileSize.y, tv * tileSize.y);
|
||||
quad[2].texCoords = sf::Vector2f((tu + 1) * tileSize.y, (tv + 1) * tileSize.y);
|
||||
quad[3].texCoords = sf::Vector2f(tu * tileSize.y, (tv + 1) * tileSize.y);
|
||||
}
|
||||
int x, y;
|
||||
if (i < size) {
|
||||
x = i;
|
||||
y = 0;
|
||||
} else {
|
||||
x = size - 1;
|
||||
y = i - size + 1;
|
||||
}
|
||||
|
||||
void TileMap::draw(sf::RenderWindow *window)
|
||||
for (; x >= 0 && y < size; x--, y++)
|
||||
{
|
||||
window->draw(*this);
|
||||
auto tileId = tiles[size - 1 - y][x];
|
||||
auto sprite = tileSet->getTile(tileId);
|
||||
createTileAtGridPosition(sprite, {x, y});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileMap::draw(sf::RenderTarget &target, sf::RenderStates states) const
|
||||
void TileMap::createTileAtGridPosition(const std::shared_ptr<SingleSprite> &sprite, GridCoordinates coordinates)
|
||||
{
|
||||
// apply the transform
|
||||
// TODO? NEEDED?
|
||||
// states.transform *= getTransform();
|
||||
auto tile = SpriteFactory::copySingleSprite(sprite);
|
||||
|
||||
// apply the tileset texture
|
||||
states.texture = &tileMapTexture;
|
||||
// Move to tile diagonal top left, since center of that tile is correct position for sprite corner
|
||||
coordinates.y += 1;
|
||||
|
||||
// draw the vertex array
|
||||
target.draw(vertices, states);
|
||||
addChildScreenOffset(tile, TranslatedCoordinates(coordinates).isometric());
|
||||
}
|
||||
|
|
|
@ -8,18 +8,12 @@
|
|||
#include "../../game/game_object.h"
|
||||
#include "tileset.hpp"
|
||||
|
||||
class TileMap : public GameObject, public sf::Drawable
|
||||
class TileMap : public GameObject
|
||||
{
|
||||
public:
|
||||
TileMap(std::shared_ptr<TileSet> tileSet, std::vector<std::vector<int>> tiles);
|
||||
TileMap(const std::shared_ptr<TileSet>& tileSet, std::vector<std::vector<int>> tiles);
|
||||
|
||||
void draw(sf::RenderWindow *window) override;
|
||||
|
||||
void draw(sf::RenderTarget &target, sf::RenderStates states) const override;
|
||||
|
||||
private:
|
||||
sf::VertexArray vertices;
|
||||
sf::Texture tileMapTexture;
|
||||
void createTileAtGridPosition(const std::shared_ptr<SingleSprite>& sprite, GridCoordinates coordinates);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -9,21 +9,17 @@
|
|||
|
||||
struct TileMapConfig
|
||||
{
|
||||
std::string tileSheet;
|
||||
|
||||
std::vector<int> backgroundTileSelection = {};
|
||||
std::string tileSet;
|
||||
|
||||
std::vector<std::vector<int>> tiles = {};
|
||||
|
||||
TileMapConfig(std::string tileSheet, std::vector<std::vector<int>> tiles,
|
||||
std::vector<int> backgroundTileSelection = {})
|
||||
TileMapConfig(std::string tileSheet, const std::vector<std::vector<int>> &tiles)
|
||||
{
|
||||
this->tileSheet = std::move(tileSheet);
|
||||
this->backgroundTileSelection = std::move(backgroundTileSelection);
|
||||
this->tiles = std::move(tiles);
|
||||
this->tileSet = std::move(tileSheet);
|
||||
this->tiles = tiles;
|
||||
|
||||
// Make sure all rows are the same length and that the map is square
|
||||
int size = tiles.size();
|
||||
unsigned int size = tiles.size();
|
||||
for (auto &row: tiles)
|
||||
{
|
||||
if (row.size() != size)
|
||||
|
@ -35,10 +31,10 @@ struct TileMapConfig
|
|||
|
||||
TileMapConfig() = default;
|
||||
|
||||
sf::Vector2f getSize() const
|
||||
[[nodiscard]] sf::Vector2<int> getSize() const
|
||||
{
|
||||
int size = tiles.size();
|
||||
return {static_cast<float>(size), static_cast<float>(size)};
|
||||
return {size, size};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2,5 +2,25 @@
|
|||
|
||||
TileSet::TileSet(const std::shared_ptr<SpriteSheet> &sheet, const std::vector<int> &tileIndices)
|
||||
{
|
||||
float tileWidth = TranslatedCoordinates(WorldCoordinates{1, 0}).isometric().x -
|
||||
TranslatedCoordinates(WorldCoordinates{0, 1}).isometric().x;
|
||||
sf::Vector2f tileSize = sf::Vector2f(1, 1) * tileWidth;
|
||||
|
||||
// Load desired tiles from sheet
|
||||
for (auto index: tileIndices)
|
||||
{
|
||||
auto sprite = sheet->getSprite(index);
|
||||
sprite->setSize(tileSize);
|
||||
tiles.push_back(sprite);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SingleSprite> TileSet::getTile(int index) const
|
||||
{
|
||||
if (index < 0 || index >= tiles.size())
|
||||
{
|
||||
throw std::runtime_error("Tile index out of range");
|
||||
}
|
||||
|
||||
return tiles[index];
|
||||
}
|
||||
|
|
|
@ -3,11 +3,17 @@
|
|||
|
||||
|
||||
#include "../sprite_sheet.hpp"
|
||||
#include "../versatile_sprite.hpp"
|
||||
|
||||
class TileSet
|
||||
{
|
||||
public:
|
||||
TileSet(const std::shared_ptr<SpriteSheet>& sheet, const std::vector<int>& tileIndices);
|
||||
|
||||
[[nodiscard]] std::shared_ptr<SingleSprite> getTile(int index) const;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<SingleSprite>> tiles;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -47,3 +47,17 @@ sf::Vector2f VersatileSprite::getSize() const
|
|||
return Sprite::getSize();
|
||||
}
|
||||
}
|
||||
|
||||
sf::Sprite VersatileSprite::getSprite() const
|
||||
{
|
||||
if (singleSprite != nullptr)
|
||||
{
|
||||
return singleSprite->getSprite();
|
||||
} else if (animatedSprite != nullptr)
|
||||
{
|
||||
return animatedSprite->getSprite();
|
||||
} else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
class VersatileSprite : public GameObject, public Sprite
|
||||
{
|
||||
public:
|
||||
VersatileSprite(const std::string& name, sf::Vector2f size = sf::Vector2f(0, 0));
|
||||
explicit VersatileSprite(const std::string& name, sf::Vector2f size = sf::Vector2f(0, 0));
|
||||
|
||||
void setSize(const sf::Vector2f &size) override;
|
||||
|
||||
sf::Vector2f getSize() const override;
|
||||
[[nodiscard]] sf::Vector2f getSize() const override;
|
||||
|
||||
sf::Sprite getSprite() const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<SingleSprite> singleSprite = nullptr;
|
||||
|
|
|
@ -20,7 +20,8 @@ std::map<std::string, std::string> const all_textures = {
|
|||
{"edge", "assets/edge.png"},
|
||||
{"ring", "assets/ring.png"},
|
||||
{"grasses", "assets/grass_plus.png"},
|
||||
{"hole", "assets/hole.png"}
|
||||
{"hole", "assets/hole.png"},
|
||||
{"iso-tiles", "assets/isometric-tiles.png"}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -29,7 +30,8 @@ std::map<std::string, std::string> const all_textures = {
|
|||
*/
|
||||
std::map<std::string, SheetConfig> const all_sheets = {
|
||||
{"numbers", SheetConfig("numbers", 4, 2)},
|
||||
{"grasses", SheetConfig("grasses", 25, 14)}
|
||||
{"grasses", SheetConfig("grasses", 25, 14)},
|
||||
{"iso-tiles", SheetConfig("iso-tiles", 6, 2)}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -51,8 +53,12 @@ std::map<std::string, SpriteConfig> const all_sprites = {
|
|||
{"hole", SpriteConfig("hole")}
|
||||
};
|
||||
|
||||
/**
|
||||
* All tilesets used in the game.
|
||||
* The key is the name of the tileset, the value is the tileset config.
|
||||
*/
|
||||
std::map<std::string, TileSetConfig> const all_tilesets = {
|
||||
{"grass", TileSetConfig("grasses", {58})}
|
||||
{"iso-tiles", TileSetConfig("iso-tiles", {0, 1, 2, 3, 4, 5})}
|
||||
};
|
||||
|
||||
#endif //HOLESOME_TEXTURE_CONFIG_H
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef HOLESOME_TILEMAPS_HPP
|
||||
#define HOLESOME_TILEMAPS_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "sprites/tiling/tilemap_config.hpp"
|
||||
|
||||
std::map<std::string, TileMapConfig> const all_tilemaps = {
|
||||
{"grass", TileMapConfig("grass", {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},})}
|
||||
};
|
||||
|
||||
#endif //HOLESOME_TILEMAPS_HPP
|
Loading…
Reference in a new issue