Implemented texture ressource management, sprites, animated sprite sheets and scaffoling for collectables

This commit is contained in:
Maximilian Giller 2023-06-03 19:33:41 +02:00
parent 543c9e9728
commit f778e702e4
21 changed files with 376 additions and 34 deletions

View file

@ -57,8 +57,8 @@ set(SOURCES
src/game/player/player_spawner.hpp src/game/player/player_spawner.hpp
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/depth_renderer.cpp src/game/collectables/environment_collectable.cpp
src/game/depth_renderer.hpp) 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)
set(PHYSICS_00_SOURCES set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp) src/prototypes/physics_00.cpp)
@ -80,3 +80,9 @@ target_link_libraries(Holesome Eigen3::Eigen)
#target_link_libraries(Physics_00 Box2D::Box2D) #target_link_libraries(Physics_00 Box2D::Box2D)
target_link_libraries(Math_00 Eigen3::Eigen) target_link_libraries(Math_00 Eigen3::Eigen)
# Assets
add_custom_target(copy_assets
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets
)
add_dependencies(Holesome copy_assets)

BIN
assets/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -53,3 +53,8 @@ void TranslatedCoordinates::setParent(std::shared_ptr<TranslatedCoordinates> par
this->parent = std::move(parent); this->parent = std::move(parent);
this->worldCoordinates = offset; this->worldCoordinates = offset;
} }
void TranslatedCoordinates::set(GridCoordinates newGridCoordinates)
{
this->worldCoordinates = {newGridCoordinates.x / worldToGridFactor, newGridCoordinates.y / worldToGridFactor, 0};
}

View file

@ -28,6 +28,8 @@ public:
void set(IsometricCoordinates newIsometricCoordinates); void set(IsometricCoordinates newIsometricCoordinates);
void set(GridCoordinates newGridCoordinates);
void move(WorldCoordinates deltaWorldCoordinates); void move(WorldCoordinates deltaWorldCoordinates);
void move(sf::Vector2f deltaWorldCoordinates); void move(sf::Vector2f deltaWorldCoordinates);

View file

@ -0,0 +1,11 @@
#include "environment_collectable.hpp"
EnvironmentCollectable::EnvironmentCollectable(GridCoordinates position)
{
coordinates->set(position);
}
void EnvironmentCollectable::draw(sf::RenderWindow *window) const
{
}

View file

@ -0,0 +1,16 @@
#ifndef HOLESOME_ENVIRONMENT_COLLECTABLE_HPP
#define HOLESOME_ENVIRONMENT_COLLECTABLE_HPP
#include "../game_object.h"
class EnvironmentCollectable : public GameObject
{
public:
EnvironmentCollectable(GridCoordinates position);
void draw(sf::RenderWindow *window) const override;
};
#endif //HOLESOME_ENVIRONMENT_COLLECTABLE_HPP

View file

@ -22,3 +22,27 @@ void GameObject::setActive(bool active)
child->setActive(active); child->setActive(active);
} }
} }
void GameObject::draw(sf::RenderWindow *window) const
{
for (auto &child: children)
{
child->draw(window);
}
}
void GameObject::update()
{
for (auto &child: children)
{
child->update();
}
}
void GameObject::lateUpdate()
{
for (auto &child: children)
{
child->lateUpdate();
}
}

View file

@ -12,14 +12,11 @@ class GameObject
public: public:
GameObject(); GameObject();
virtual void draw(sf::RenderWindow *window) const virtual void draw(sf::RenderWindow *window) const;
{}
virtual void update() virtual void update();
{}
virtual void lateUpdate() virtual void lateUpdate();
{}
void setActive(bool active); void setActive(bool active);
bool getActive() const { return isActive; } bool getActive() const { return isActive; }

View file

@ -1,7 +1,19 @@
#include "player.hpp" #include "player.hpp"
#include "../../sprites/texture_manager.hpp"
#include "../../sprites/single_sprite.hpp"
#include <utility> #include <utility>
Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &image, WorldCoordinates initCoordinates)
{
coordinates->set(initCoordinates);
input = std::move(assignedInput);
auto sprite = std::make_shared<SingleSprite>(TextureManager::getInstance()->getTexture(image));
addChild(sprite);
}
sf::Vector2f Player::getTrackablePosition() const sf::Vector2f Player::getTrackablePosition() const
{ {
return coordinates->isometric().toScreen(); return coordinates->isometric().toScreen();
@ -10,7 +22,7 @@ sf::Vector2f Player::getTrackablePosition() const
sf::Vector2f Player::getTrackableSize() const sf::Vector2f Player::getTrackableSize() const
{ {
// TODO: Proper implementation // TODO: Proper implementation
return {circle->getRadius() * 2.f, circle->getRadius() * 2.f}; return {50, 50};
} }
void Player::update() void Player::update()
@ -26,26 +38,6 @@ void Player::update()
coordinates->move(moveDelta); coordinates->move(moveDelta);
} }
void Player::draw(sf::RenderWindow *window) const
{
circle->draw(window);
}
Player::~Player()
{
delete circle;
}
Player::Player(std::shared_ptr<InputIdentity> assignedInput, const sf::Color color, WorldCoordinates initCoordinates)
{
coordinates->set(initCoordinates);
input = std::move(assignedInput);
circle = new CircleObject(10, color);
circle->coordinates->setParent(coordinates);
}
TrackableState Player::getTrackableState() const TrackableState Player::getTrackableState() const
{ {
if (getActive()) if (getActive())

View file

@ -8,12 +8,10 @@
class Player : public GameObject, public ITrackable class Player : public GameObject, public ITrackable
{ {
public: public:
Player(std::shared_ptr<InputIdentity> assignedInput, sf::Color color, WorldCoordinates initCoordinates); Player(std::shared_ptr<InputIdentity> assignedInput, const std::string& image, WorldCoordinates initCoordinates);
~Player(); ~Player();
void draw(sf::RenderWindow *window) const override;
void update() override; void update() override;
sf::Vector2f getTrackablePosition() const override; sf::Vector2f getTrackablePosition() const override;
@ -25,7 +23,6 @@ public:
float speed = 30.0f; float speed = 30.0f;
private: private:
CircleObject *circle;
std::shared_ptr<InputIdentity> input; std::shared_ptr<InputIdentity> input;
}; };

View file

@ -1,12 +1,13 @@
#include "player_spawner.hpp" #include "player_spawner.hpp"
#include "player.hpp" #include "player.hpp"
#include "../../texture_config.h"
void PlayerSpawner::update() 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, sf::Color::Red, {0, 0}); auto player = new Player(inputIdentity, PLAYER_TEXTURE, {0, 0});
Game::getInstance()->addGameObject(player); Game::getInstance()->addGameObject(player);
Game::getInstance()->views[0]->addTrackable(player); Game::getInstance()->views[0]->addTrackable(player);
} }

View file

@ -4,6 +4,12 @@
#include "debug/grid_debug_layer.h" #include "debug/grid_debug_layer.h"
#include "game/camera/tracking_view.h" #include "game/camera/tracking_view.h"
#include "game/player/player_spawner.hpp" #include "game/player/player_spawner.hpp"
#include "sprites/texture_manager.hpp"
#include "texture_config.h"
void loadAllTextures();
void runGame();
INITIALIZE_EASYLOGGINGPP INITIALIZE_EASYLOGGINGPP
@ -11,6 +17,13 @@ int main(int argc, char *argv[])
{ {
START_EASYLOGGINGPP(argc, argv); START_EASYLOGGINGPP(argc, argv);
loadAllTextures();
runGame();
}
void runGame()
{
LOG(INFO) << "Starting game ...";
auto game = GameFactory::createWindowed("Holesome"); auto game = GameFactory::createWindowed("Holesome");
game->addGameObject(new GridDebugLayer(0, 50, 0, 50)); game->addGameObject(new GridDebugLayer(0, 50, 0, 50));
@ -22,3 +35,13 @@ int main(int argc, char *argv[])
InputMapper::getInstance().reset(); InputMapper::getInstance().reset();
game.reset(); game.reset();
} }
void loadAllTextures()
{
LOG(INFO) << "Loading textures...";
for (auto const &[key, path]: all_textures)
{
TextureManager::getInstance()->loadTexture(key, path);
}
LOG(INFO) << "Finished loading textures.";
}

View file

@ -0,0 +1,29 @@
#include "animated_sprite.hpp"
#include "../config.h"
AnimatedSprite::AnimatedSprite(const std::vector<sf::Sprite> &sprites)
{
this->sprites = sprites;
}
void AnimatedSprite::update()
{
timeSinceLastFrame += FRAME_TIME;
if (timeSinceLastFrame >= frameDuration)
{
timeSinceLastFrame -= frameDuration;
currentFrame++;
if (currentFrame >= sprites.size())
{
currentFrame = 0;
}
}
}
void AnimatedSprite::draw(sf::RenderWindow *window) const
{
auto currentSprite = sprites[currentFrame];
currentSprite.setPosition(coordinates->isometric().toScreen());
window->draw(currentSprite);
}

View file

@ -0,0 +1,25 @@
#ifndef HOLESOME_ANIMATED_SPRITE_HPP
#define HOLESOME_ANIMATED_SPRITE_HPP
#include <SFML/Graphics/Sprite.hpp>
#include "../game/game_object.h"
class AnimatedSprite : public GameObject
{
public:
AnimatedSprite(const std::vector<sf::Sprite>& sprites);
void update() override;
void draw(sf::RenderWindow *window) const override;
sf::Time frameDuration = sf::seconds(0.1f);
private:
int currentFrame = 0;
sf::Time timeSinceLastFrame = sf::Time::Zero;
std::vector<sf::Sprite> sprites;
};
#endif //HOLESOME_ANIMATED_SPRITE_HPP

View file

@ -0,0 +1,22 @@
#include "single_sprite.hpp"
SingleSprite::SingleSprite(const sf::Sprite &sprite)
{
this->sprite = sprite;
}
void SingleSprite::draw(sf::RenderWindow *window) const
{
window->draw(sprite);
}
void SingleSprite::lateUpdate()
{
sprite.setPosition(coordinates->isometric().toScreen());
}
SingleSprite::SingleSprite(const std::shared_ptr<sf::Texture>& texture)
{
sprite = sf::Sprite();
sprite.setTexture(*texture);
}

View file

@ -0,0 +1,23 @@
#ifndef HOLESOME_SINGLE_SPRITE_HPP
#define HOLESOME_SINGLE_SPRITE_HPP
#include <SFML/Graphics/Sprite.hpp>
#include "../game/game_object.h"
class SingleSprite : public GameObject
{
public:
SingleSprite(const sf::Sprite& sprite);
SingleSprite(const std::shared_ptr<sf::Texture>& texture);
void draw(sf::RenderWindow *window) const override;
void lateUpdate() override;
private:
sf::Sprite sprite;
};
#endif //HOLESOME_SINGLE_SPRITE_HPP

View file

@ -0,0 +1,47 @@
#include "sprite_sheet.hpp"
SpriteSheet::SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int columns, int rows)
{
// Extract sprites from texture
sprites = std::vector<sf::Sprite>();
int spriteWidth = texture->getSize().x / columns;
int spriteHeight = texture->getSize().y / rows;
for (int y = 0; y < rows; y++)
{
for (int x = 0; x < columns; x++)
{
sf::Sprite sprite;
sprite.setTexture(*texture);
sprite.setTextureRect(sf::IntRect(x * spriteWidth, y * spriteHeight, spriteWidth, spriteHeight));
sprites.push_back(sprite);
}
}
}
sf::Sprite SpriteSheet::getSprite(int sequenceIndex) const
{
if (sequenceIndex < 0 || sequenceIndex >= sprites.size())
{
throw std::runtime_error("Invalid sequence index");
}
return sprites[sequenceIndex];
}
std::shared_ptr<AnimatedSprite> SpriteSheet::getAnimation(int startingSequenceIndex, int numberOfFrames) const
{
if (startingSequenceIndex < 0 || startingSequenceIndex + numberOfFrames >= sprites.size())
{
throw std::runtime_error("Invalid starting sequence index");
}
if (numberOfFrames <= 0)
{
throw std::runtime_error("Invalid number of frames");
}
std::vector<sf::Sprite> animation = std::vector<sf::Sprite>();
for (int i = 0; i < numberOfFrames; i++)
{
animation.push_back(sprites[startingSequenceIndex + i]);
}
return std::make_shared<AnimatedSprite>(animation);
}

View file

@ -0,0 +1,24 @@
#ifndef HOLESOME_SPRITE_SHEET_HPP
#define HOLESOME_SPRITE_SHEET_HPP
#include <memory>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include "animated_sprite.hpp"
class SpriteSheet
{
public:
SpriteSheet(const std::shared_ptr<sf::Texture>& texture, int columns, int rows);
sf::Sprite getSprite(int sequenceIndex) const;
std::shared_ptr<AnimatedSprite> getAnimation(int startingSequenceIndex, int numberOfFrames) const;
private:
std::vector<sf::Sprite> sprites;
};
#endif //HOLESOME_SPRITE_SHEET_HPP

View file

@ -0,0 +1,54 @@
#include "texture_manager.hpp"
#include "../logging/easylogging++.h"
std::shared_ptr<TextureManager> TextureManager::getInstance()
{
if (TextureManager::singleton == nullptr)
{
TextureManager::singleton = std::make_shared<TextureManager>();
}
return TextureManager::singleton;
}
bool TextureManager::loadTexture(const std::string& textureName, const std::string& texturePath)
{
if (this->doesTextureExist(textureName))
{
LOG(WARNING) << "Texture " << textureName << " already loaded";
return false;
}
sf::Texture texture;
if (!texture.loadFromFile(texturePath))
{
LOG(ERROR) << "Could not load texture " << textureName << " from " << texturePath;
LOG(ERROR) << "Error: " << strerror(errno);
return false;
}
LOG(INFO) << "Loaded texture " << textureName << " from " << texturePath;
this->textures[textureName] = std::make_shared<sf::Texture>(texture);
return true;
}
bool TextureManager::doesTextureExist(const std::string& textureName)
{
return this->textures.find(textureName) != this->textures.end();
}
TextureManager::~TextureManager()
{
// Unload all textures
// Shared pointers will take care of the rest
textures.clear();
}
std::shared_ptr<sf::Texture> TextureManager::getTexture(const std::string &textureName)
{
if (!this->doesTextureExist(textureName))
{
return nullptr;
}
return this->textures[textureName];
}

View file

@ -0,0 +1,31 @@
#ifndef HOLESOME_TEXTURE_MANAGER_HPP
#define HOLESOME_TEXTURE_MANAGER_HPP
#include <memory>
#include <SFML/Graphics/Texture.hpp>
#include <map>
class TextureManager
{
public:
TextureManager() = default;
~TextureManager();
static std::shared_ptr<TextureManager> getInstance();
bool loadTexture(const std::string &textureName, const std::string &texturePath);
std::shared_ptr<sf::Texture> getTexture(const std::string &textureName);
bool doesTextureExist(const std::string &textureName);
private:
static inline std::shared_ptr<TextureManager> singleton = nullptr;
std::map<std::string, std::shared_ptr<sf::Texture>> textures;
};
#endif //HOLESOME_TEXTURE_MANAGER_HPP

13
src/texture_config.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef HOLESOME_TEXTURE_CONFIG_H
#define HOLESOME_TEXTURE_CONFIG_H
#include <string>
#include <map>
#define PLAYER_TEXTURE "player"
std::map<std::string, std::string> const all_textures = {
{PLAYER_TEXTURE, "assets/player.png"}
};
#endif //HOLESOME_TEXTURE_CONFIG_H