Improved configuration of texture assets. Added VersatileSprite and proper factory

This commit is contained in:
Maximilian Giller 2023-06-05 00:12:17 +02:00
parent 37ef4020a1
commit 68f2e407f1
24 changed files with 378 additions and 31 deletions

View file

@ -58,7 +58,7 @@ set(SOURCES
src/game/camera/tracking_area.h src/game/camera/tracking_area.h
src/game/camera/tracking_view_options.hpp src/game/camera/tracking_view_options.hpp
src/game/collectables/environment_collectable.cpp src/game/collectables/environment_collectable.cpp
src/game/collectables/environment_collectable.hpp src/sprites/texture_manager.cpp src/sprites/texture_manager.hpp src/sprites/sprite_sheet.cpp src/sprites/sprite_sheet.hpp src/sprites/animated_sprite.cpp src/sprites/animated_sprite.hpp src/sprites/single_sprite.cpp src/sprites/single_sprite.hpp src/texture_config.h) src/game/collectables/environment_collectable.hpp src/sprites/texture_manager.cpp src/sprites/texture_manager.hpp src/sprites/sprite_sheet.cpp src/sprites/sprite_sheet.hpp src/sprites/animated_sprite.cpp src/sprites/animated_sprite.hpp src/sprites/single_sprite.cpp src/sprites/single_sprite.hpp src/texture_config.h src/sprites/configs/sprite_config.hpp src/sprites/configs/sheet_config.hpp src/sprites/configs/animation_config.hpp src/sprites/versatile_sprite.cpp src/sprites/versatile_sprite.hpp src/sprites/sprite.hpp src/sprites/sprite_factory.cpp src/sprites/sprite_factory.hpp)
set(PHYSICS_00_SOURCES set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp) src/prototypes/physics_00.cpp)

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -52,3 +52,8 @@ void GameObject::addChildWorldOffset(const std::shared_ptr<GameObject> &child, W
children.push_back(child); children.push_back(child);
child->coordinates->setParent(coordinates, offset); child->coordinates->setParent(coordinates, offset);
} }
void GameObject::addChild(const std::shared_ptr<GameObject> &child)
{
addChildWorldOffset(child, {0, 0});
}

View file

@ -23,6 +23,7 @@ public:
void addChildScreenOffset(const std::shared_ptr<GameObject> &child, IsometricCoordinates offset = {0, 0}); void addChildScreenOffset(const std::shared_ptr<GameObject> &child, IsometricCoordinates offset = {0, 0});
void addChildWorldOffset(const std::shared_ptr<GameObject> &child, WorldCoordinates offset); void addChildWorldOffset(const std::shared_ptr<GameObject> &child, WorldCoordinates offset);
void addChild(const std::shared_ptr<GameObject> &child);
std::vector<std::shared_ptr<GameObject>> getChildren() const { return children; } std::vector<std::shared_ptr<GameObject>> getChildren() const { return children; }
std::shared_ptr<TranslatedCoordinates> coordinates; std::shared_ptr<TranslatedCoordinates> coordinates;

View file

@ -6,6 +6,7 @@
#include "input_device_group.h" #include "input_device_group.h"
#include "key_features.hpp" #include "key_features.hpp"
#include "../../utilities/magic_enum.hpp" #include "../../utilities/magic_enum.hpp"
#include "../../logging/easylogging++.h"
struct InputIdentity struct InputIdentity

View file

@ -1,25 +1,16 @@
#include "player.hpp" #include "player.hpp"
#include "../../sprites/texture_manager.hpp"
#include "../../sprites/single_sprite.hpp"
#include "../../sprites/animated_sprite.hpp"
#include "../../sprites/sprite_sheet.hpp"
#include <utility> #include <utility>
Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &image, WorldCoordinates initCoordinates) Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
WorldCoordinates initCoordinates)
{ {
coordinates->set(initCoordinates); coordinates->set(initCoordinates);
input = std::move(assignedInput); input = std::move(assignedInput);
// auto sprite = std::make_shared<SingleSprite>(TextureManager::getInstance()->getTexture(image), auto sprite = std::make_shared<VersatileSprite>(skinRessourceName, sf::Vector2f{width, width});
// sf::Vector2f{width, width}); addChildScreenOffset(sprite, {-width / 2.f, -width / 2.f});
// addChildScreenOffset(sprite, {-width / 2.f, -width / 2.f});
auto spriteSheet = std::make_shared<SpriteSheet>(TextureManager::getInstance()->getTexture(image), 4, 2);
auto animatedSprite = spriteSheet->getAnimation(0, 8);
animatedSprite->setSize({width, width});
addChildScreenOffset(animatedSprite, {-width / 2.f, -width / 2.f});
} }
sf::Vector2f Player::getTrackablePosition() const sf::Vector2f Player::getTrackablePosition() const

View file

@ -3,12 +3,13 @@
#include "../game_object.h" #include "../game_object.h"
#include "../camera/ITrackable.h" #include "../camera/ITrackable.h"
#include "../../primitives/circle_object.h" #include "../../sprites/versatile_sprite.hpp"
#include "../input/input_identity.h"
class Player : public GameObject, public ITrackable class Player : public GameObject, public ITrackable
{ {
public: public:
Player(std::shared_ptr<InputIdentity> assignedInput, const std::string& image, WorldCoordinates initCoordinates); Player(std::shared_ptr<InputIdentity> assignedInput, const std::string& skinRessourceName, WorldCoordinates initCoordinates);
~Player(); ~Player();

View file

@ -7,7 +7,7 @@ void PlayerSpawner::update()
// Create player for new input identities // Create player for new input identities
for (auto &inputIdentity: InputMapper::getInstance()->newInputIdentities) for (auto &inputIdentity: InputMapper::getInstance()->newInputIdentities)
{ {
auto player = new Player(inputIdentity, PLAYER_TEXTURE, {0, 0}); auto player = new Player(inputIdentity, PLAYER_SKIN, {0, 0});
Game::getInstance()->addGameObject(player); Game::getInstance()->addGameObject(player);
Game::getInstance()->views[0]->addTrackable(player); Game::getInstance()->views[0]->addTrackable(player);
} }

View file

@ -3,6 +3,7 @@
#include "../game_object.h" #include "../game_object.h"
#include "../game.h"
class PlayerSpawner : public GameObject class PlayerSpawner : public GameObject
{ {

View file

@ -2,7 +2,7 @@
#include "../config.h" #include "../config.h"
#include "../logging/easylogging++.h" #include "../logging/easylogging++.h"
AnimatedSprite::AnimatedSprite(const std::vector<sf::Sprite> &sprites, const sf::Vector2f& size) AnimatedSprite::AnimatedSprite(const std::vector<sf::Sprite> &sprites, const sf::Vector2f &size)
{ {
this->sprites = sprites; this->sprites = sprites;
setSize(size); setSize(size);
@ -37,3 +37,10 @@ void AnimatedSprite::setSize(const sf::Vector2f &size)
sprite.setScale(size.x / sprite.getTextureRect().width, size.y / sprite.getTextureRect().height); sprite.setScale(size.x / sprite.getTextureRect().width, size.y / sprite.getTextureRect().height);
} }
} }
sf::Vector2f AnimatedSprite::getSize() const
{
auto scale = sprites[currentFrame].getScale();
auto textureSize = sprites[currentFrame].getTextureRect();
return {textureSize.width * scale.x, textureSize.height * scale.y};
}

View file

@ -4,8 +4,9 @@
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include "../game/game_object.h" #include "../game/game_object.h"
#include "sprite.hpp"
class AnimatedSprite : public GameObject class AnimatedSprite : public GameObject, public Sprite
{ {
public: public:
AnimatedSprite(const std::vector<sf::Sprite>& sprites, const sf::Vector2f& size = sf::Vector2f(0, 0)); AnimatedSprite(const std::vector<sf::Sprite>& sprites, const sf::Vector2f& size = sf::Vector2f(0, 0));
@ -16,13 +17,14 @@ public:
sf::Time frameDuration = sf::seconds(0.1f); sf::Time frameDuration = sf::seconds(0.1f);
void setSize(const sf::Vector2f &size); void setSize(const sf::Vector2f &size) override;
sf::Vector2f getSize() const override;
private: private:
int currentFrame = 0; int currentFrame = 0;
sf::Time timeSinceLastFrame = sf::Time::Zero; sf::Time timeSinceLastFrame = sf::Time::Zero;
std::vector<sf::Sprite> sprites; std::vector<sf::Sprite> sprites;
}; };

View file

@ -0,0 +1,27 @@
#ifndef HOLESOME_ANIMATION_CONFIG_HPP
#define HOLESOME_ANIMATION_CONFIG_HPP
#include <SFML/System/Time.hpp>
#include <string>
#include <SFML/System/Vector2.hpp>
#include <utility>
struct AnimationConfig
{
std::string sheetName;
int startingSheetIndex;
int frameCount;
sf::Time frameDuration;
sf::Vector2f size;
AnimationConfig(std::string sheetName, int startingSheetIndex, int frameCount, sf::Time frameDuration,
sf::Vector2f size = sf::Vector2f(0, 0)) :
sheetName(std::move(sheetName)),
startingSheetIndex(startingSheetIndex),
frameCount(frameCount),
frameDuration(frameDuration),
size(size)
{}
};
#endif //HOLESOME_ANIMATION_CONFIG_HPP

View file

@ -0,0 +1,20 @@
#ifndef HOLESOME_SHEET_CONFIG_HPP
#define HOLESOME_SHEET_CONFIG_HPP
#include <string>
#include <map>
struct SheetConfig
{
std::string textureName;
int columns;
int rows;
SheetConfig(std::string textureName, int columns, int rows) :
textureName(std::move(textureName)),
columns(columns),
rows(rows)
{}
};
#endif //HOLESOME_SHEET_CONFIG_HPP

View file

@ -0,0 +1,32 @@
#ifndef HOLESOME_SPRITE_CONFIG_HPP
#define HOLESOME_SPRITE_CONFIG_HPP
#include <string>
#include <SFML/System/Vector2.hpp>
#include <SFML/System/Time.hpp>
struct SpriteConfig
{
std::string resourceName;
bool isFromSheet;
int sheetIndex;
sf::Vector2f size;
SpriteConfig(std::string sheetName, int sheetIndex, sf::Vector2f size = sf::Vector2f(0, 0))
:
resourceName(std::move(sheetName)),
sheetIndex(sheetIndex),
size(size),
isFromSheet(true)
{}
SpriteConfig(std::string textureName, sf::Vector2f size = sf::Vector2f(0, 0))
:
resourceName(std::move(textureName)),
sheetIndex(0),
size(size),
isFromSheet(false)
{}
};
#endif //HOLESOME_SPRITE_CONFIG_HPP

View file

@ -35,3 +35,9 @@ void SingleSprite::setSize(const sf::Vector2f &size)
auto textureSize = sprite.getTextureRect(); auto textureSize = sprite.getTextureRect();
sprite.setScale(size.x / textureSize.width, size.y / textureSize.height); sprite.setScale(size.x / textureSize.width, size.y / textureSize.height);
} }
sf::Vector2f SingleSprite::getSize() const
{
auto textureSize = sprite.getTextureRect();
return {textureSize.width * sprite.getScale().x, textureSize.height * sprite.getScale().y};
}

View file

@ -4,21 +4,25 @@
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include "../game/game_object.h" #include "../game/game_object.h"
#include "sprite.hpp"
class SingleSprite : public GameObject class SingleSprite : public GameObject, public Sprite
{ {
public: public:
SingleSprite(const sf::Sprite& sprite, const sf::Vector2f& size = sf::Vector2f(0, 0)); SingleSprite(const sf::Sprite &sprite, const sf::Vector2f &size = sf::Vector2f(0, 0));
SingleSprite(const std::shared_ptr<sf::Texture>& texture, const sf::Vector2f& size = sf::Vector2f(0, 0));
SingleSprite(const std::shared_ptr<sf::Texture> &texture, const sf::Vector2f &size = sf::Vector2f(0, 0));
void draw(sf::RenderWindow *window) const override; void draw(sf::RenderWindow *window) const override;
void lateUpdate() override; void lateUpdate() override;
void setSize(const sf::Vector2f &size) override;
sf::Vector2f getSize() const override;
private: private:
sf::Sprite sprite; sf::Sprite sprite;
void setSize(const sf::Vector2f &size);
}; };

18
src/sprites/sprite.hpp Normal file
View file

@ -0,0 +1,18 @@
#ifndef HOLESOME_SPRITE_HPP
#define HOLESOME_SPRITE_HPP
#include <SFML/System/Vector2.hpp>
#include <vector>
#include <SFML/Graphics/Sprite.hpp>
class Sprite
{
public:
virtual void setSize(const sf::Vector2f &size)
{}
virtual sf::Vector2f getSize() const
{ return {0, 0}; }
};
#endif //HOLESOME_SPRITE_HPP

View file

@ -0,0 +1,97 @@
#include "sprite_factory.hpp"
#include "../texture_config.h"
#include "texture_manager.hpp"
std::shared_ptr<SingleSprite> SpriteFactory::createSingleSprite(const std::string& name, sf::Vector2f size)
{
// Get sprite config
auto sprite_config = all_sprites.find(name);
if (sprite_config == all_sprites.end())
{
LOG(ERROR) << "Sprite " << name << " not found. Could not create single sprite.";
return nullptr;
}
// Construct sprite
auto config = sprite_config->second;
// Construct simply from texture
if (!config.isFromSheet)
{
auto texture = TextureManager::getInstance()->getTexture(config.resourceName);
if (texture == nullptr)
{
LOG(ERROR) << "Texture " << config.resourceName << " not found. Could not create single sprite.";
return nullptr;
}
LOG(INFO) << "Creating single sprite from texture " << config.resourceName;
return std::make_shared<SingleSprite>(texture, size);
}
// Construct from sheet
auto sheet = createSheet(config.resourceName);
if (sheet == nullptr)
{
LOG(ERROR) << "Sheet " << config.resourceName << " not found. Could not create single sprite.";
return nullptr;
}
LOG(INFO) << "Creating single sprite from sheet " << config.resourceName;
auto sprite = sheet->getSprite(config.sheetIndex);
sprite->setSize(size);
return sprite;
}
std::shared_ptr<AnimatedSprite> SpriteFactory::createAnimatedSprite(const std::string& name, sf::Vector2f size)
{
// Get animation config
auto animation_config = all_animations.find(name);
if (animation_config == all_animations.end())
{
LOG(ERROR) << "Animation " << name << " not found. Could not create animated sprite.";
return nullptr;
}
// Construct animation
auto config = animation_config->second;
auto sheet = createSheet(config.sheetName);
if (sheet == nullptr)
{
LOG(ERROR) << "Sheet " << config.sheetName << " not found. Could not create animated sprite.";
return nullptr;
}
LOG(INFO) << "Creating animated sprite from sheet " << config.sheetName;
auto animation = sheet->getAnimation(config.startingSheetIndex, config.frameCount);
animation->frameDuration = config.frameDuration;
animation->setSize(size);
return animation;
}
std::shared_ptr<SpriteSheet> SpriteFactory::createSheet(const std::string& name)
{
// Get config
auto sheet_config = all_sheets.find(name);
if (sheet_config == all_sheets.end())
{
LOG(ERROR) << "Sheet " << name << " not found. Could not create sheet.";
return nullptr;
}
// Construct sheet
auto config = sheet_config->second;
auto texture = TextureManager::getInstance()->getTexture(config.textureName);
if (texture == nullptr)
{
LOG(ERROR) << "Texture " << config.textureName << " not found. Could not create sheet.";
return nullptr;
}
LOG(INFO) << "Creating sheet " << name;
return std::make_shared<SpriteSheet>(texture, config.columns, config.rows);
}

View file

@ -0,0 +1,21 @@
#ifndef HOLESOME_SPRITE_FACTORY_HPP
#define HOLESOME_SPRITE_FACTORY_HPP
#include <string>
#include <SFML/System/Vector2.hpp>
#include "single_sprite.hpp"
#include "animated_sprite.hpp"
#include "sprite_sheet.hpp"
#include "../logging/easylogging++.h"
class SpriteFactory
{
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);
};
#endif //HOLESOME_SPRITE_FACTORY_HPP

View file

@ -1,4 +1,5 @@
#include "sprite_sheet.hpp" #include "sprite_sheet.hpp"
#include "single_sprite.hpp"
SpriteSheet::SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int columns, int rows) SpriteSheet::SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int columns, int rows)
{ {
@ -18,13 +19,14 @@ SpriteSheet::SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int column
} }
} }
sf::Sprite SpriteSheet::getSprite(int sequenceIndex) const std::shared_ptr<SingleSprite> SpriteSheet::getSprite(int sequenceIndex) const
{ {
if (sequenceIndex < 0 || sequenceIndex >= sprites.size()) if (sequenceIndex < 0 || sequenceIndex >= sprites.size())
{ {
throw std::runtime_error("Invalid sequence index"); throw std::runtime_error("Invalid sequence index");
} }
return sprites[sequenceIndex]; auto sprite = sprites[sequenceIndex];
return std::make_shared<SingleSprite>(sprite);
} }
std::shared_ptr<AnimatedSprite> SpriteSheet::getAnimation(int startingSequenceIndex, int numberOfFrames) const std::shared_ptr<AnimatedSprite> SpriteSheet::getAnimation(int startingSequenceIndex, int numberOfFrames) const

View file

@ -6,13 +6,14 @@
#include <SFML/Graphics/Texture.hpp> #include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Sprite.hpp>
#include "animated_sprite.hpp" #include "animated_sprite.hpp"
#include "single_sprite.hpp"
class SpriteSheet class SpriteSheet
{ {
public: public:
SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int columns, int rows); SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int columns, int rows);
sf::Sprite getSprite(int sequenceIndex) const; std::shared_ptr<SingleSprite> getSprite(int sequenceIndex) const;
std::shared_ptr<AnimatedSprite> getAnimation(int startingSequenceIndex, int numberOfFrames) const; std::shared_ptr<AnimatedSprite> getAnimation(int startingSequenceIndex, int numberOfFrames) const;

View file

@ -0,0 +1,49 @@
#include "versatile_sprite.hpp"
#include "sprite_factory.hpp"
#include "../texture_config.h"
VersatileSprite::VersatileSprite(const std::string &name, sf::Vector2f size)
{
// Try to find in sprites
if (all_sprites.find(name) != all_sprites.end())
{
singleSprite = SpriteFactory::createSingleSprite(name, size);
addChild(singleSprite);
} else if (all_animations.find(name) != all_animations.end())
{
animatedSprite = SpriteFactory::createAnimatedSprite(name, size);
addChild(animatedSprite);
} else
{
LOG(ERROR) << "Sprite " << name << " not found. Could not create versatile sprite.";
return;
}
}
void VersatileSprite::setSize(const sf::Vector2f &size)
{
if (singleSprite != nullptr)
{
singleSprite->setSize(size);
} else if (animatedSprite != nullptr)
{
animatedSprite->setSize(size);
} else
{
Sprite::setSize(size);
}
}
sf::Vector2f VersatileSprite::getSize() const
{
if (singleSprite != nullptr)
{
return singleSprite->getSize();
} else if (animatedSprite != nullptr)
{
return animatedSprite->getSize();
} else
{
return Sprite::getSize();
}
}

View file

@ -0,0 +1,27 @@
#ifndef HOLESOME_VERSATILE_SPRITE_HPP
#define HOLESOME_VERSATILE_SPRITE_HPP
#include <SFML/System/Vector2.hpp>
#include <string>
#include "sprite.hpp"
#include "../game/game_object.h"
#include "single_sprite.hpp"
#include "animated_sprite.hpp"
class VersatileSprite : public GameObject, public Sprite
{
public:
VersatileSprite(const std::string& name, sf::Vector2f size = sf::Vector2f(0, 0));
void setSize(const sf::Vector2f &size) override;
sf::Vector2f getSize() const override;
private:
std::shared_ptr<SingleSprite> singleSprite = nullptr;
std::shared_ptr<AnimatedSprite> animatedSprite = nullptr;
};
#endif //HOLESOME_VERSATILE_SPRITE_HPP

View file

@ -3,11 +3,45 @@
#include <string> #include <string>
#include <map> #include <map>
#include "sprites/configs/animation_config.hpp"
#include "sprites/configs/sheet_config.hpp"
#include "sprites/configs/sprite_config.hpp"
#define PLAYER_TEXTURE "player" #define PLAYER_SKIN "edge"
/**
* All textures used in the game.
* The key is the name of the texture, the value is the path to the texture.
*/
std::map<std::string, std::string> const all_textures = { std::map<std::string, std::string> const all_textures = {
{PLAYER_TEXTURE, "assets/numbers.png"} {"numbers", "assets/numbers.png"},
{"64", "assets/64.png"},
{"edge", "assets/edge.png"}
};
/**
* All sheets used in the game.
* The key is the name of the sheet, the value is the sheet config.
*/
std::map<std::string, SheetConfig> const all_sheets = {
{"numbers", SheetConfig("numbers", 4, 2)}
};
/**
* All animations used in the game.
* The key is the name of the animation, the value is the animation config.
*/
std::map<std::string, AnimationConfig> const all_animations = {
{"numbers", AnimationConfig("numbers", 0, 8, sf::seconds(0.1f))}
};
/**
* All sprites used in the game.
* The key is the name of the singleSprite, the value is the singleSprite config.
*/
std::map<std::string, SpriteConfig> const all_sprites = {
{"64", SpriteConfig("64")},
{"edge", SpriteConfig("edge")}
}; };
#endif //HOLESOME_TEXTURE_CONFIG_H #endif //HOLESOME_TEXTURE_CONFIG_H