Concept with texture cutout

This commit is contained in:
Maximilian Giller 2023-06-10 20:46:52 +02:00
parent b3d793cb9f
commit 7b69993881
24 changed files with 242 additions and 85 deletions

View file

@ -58,23 +58,23 @@ set(SOURCES
src/game/camera/tracking_view_options.hpp
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/sprites/basic/texture_manager.cpp
src/sprites/basic/texture_manager.hpp
src/sprites/basic/sprite_sheet.cpp
src/sprites/basic/sprite_sheet.hpp
src/sprites/basic/animated_sprite.cpp
src/sprites/basic/animated_sprite.hpp
src/sprites/basic/single_sprite.cpp
src/sprites/basic/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
src/sprites/basic/versatile_sprite.cpp
src/sprites/basic/versatile_sprite.hpp
src/sprites/basic/sprite.hpp
src/sprites/basic/sprite_factory.cpp
src/sprites/basic/sprite_factory.hpp
src/input_config.h
src/game/input/button_config.hpp
src/game/input/game_action.hpp
@ -88,7 +88,9 @@ set(SOURCES
src/game/level/level_config.hpp
src/game/level/level_loader.cpp
src/game/level/level_loader.hpp
src/levels.hpp)
src/levels.hpp
src/sprites/ground_sprite.cpp
src/sprites/ground_sprite.hpp src/sprites/basic/texture_cutout.hpp)
set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp)

BIN
assets/grass_plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -20,7 +20,7 @@
// Graphic settings
#define ISOMETRIC_SKEW 0.3f
#define MOVEMENT_SKEW sf::Vector2f(1.f, 1/ISOMETRIC_SKEW/2.f)
#define WORLD_TO_ISO_SCALE 50.0f // 50.f
#define WORLD_TO_ISO_SCALE 10.0f // 50.f
// Tracking view defaults
#define DEF_TV_FREE_MOVE_THRESHOLD 0.f

View file

@ -4,24 +4,29 @@
#include "../../debug/grid_debug_layer.h"
#include "../player/player_spawner.hpp"
#include "../../levels.hpp"
#include "../../sprites/ground_sprite.hpp"
#include "../../texture_config.h"
void LevelLoader::loadLevel(LevelConfig levelConfig)
void LevelLoader::loadLevel(const LevelConfig& levelConfig)
{
Game::getInstance()->clearGameObjects();
auto game = Game::getInstance();
game->clearGameObjects();
LOG(INFO) << "Loading level '" << levelConfig.name << "' ...";
Game::getInstance()->setLevel(levelConfig);
game->setLevel(levelConfig);
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
// Add basic game objects
game->addGameObject(new GroundSprite(GROUND_SKIN, levelConfig.worldMapSize));
game->addGameObject(new TrackingView());
game->addGameObject(new PlayerSpawner(levelConfig.playerSpawnPoints));
if (DEVELOPER_MODE)
{
Game::getInstance()->addGameObject(new GridDebugLayer(0, 50, 0, 50));
game->addGameObject(new GridDebugLayer(0, 50, 0, 50));
}
Game::getInstance()->addGameObject(new TrackingView());
Game::getInstance()->addGameObject(new PlayerSpawner(levelConfig.playerSpawnPoints));
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
}

View file

@ -8,7 +8,7 @@
class LevelLoader
{
public:
static void loadLevel(LevelConfig levelConfig);
static void loadLevel(const LevelConfig& levelConfig);
static void loadLevel(const std::string &levelName);
};

View file

@ -3,7 +3,7 @@
#include "../game_object.h"
#include "../camera/ITrackable.h"
#include "../../sprites/versatile_sprite.hpp"
#include "../../sprites/basic/versatile_sprite.hpp"
#include "../input/input_identity.h"
#include "../../config.h"

View file

@ -4,7 +4,7 @@
#include "debug/grid_debug_layer.h"
#include "game/camera/tracking_view.h"
#include "game/player/player_spawner.hpp"
#include "sprites/texture_manager.hpp"
#include "sprites/basic/texture_manager.hpp"
#include "texture_config.h"
#include "game/level/level_loader.hpp"
#include "levels.hpp"

View file

@ -1,6 +1,6 @@
#include "animated_sprite.hpp"
#include "../config.h"
#include "../logging/easylogging++.h"
#include "../../config.h"
#include "../../logging/easylogging++.h"
AnimatedSprite::AnimatedSprite(const std::vector<sf::Sprite> &sprites, const sf::Vector2f &size)
{

View file

@ -3,7 +3,7 @@
#include <SFML/Graphics/Sprite.hpp>
#include "../game/game_object.h"
#include "../../game/game_object.h"
#include "sprite.hpp"
class AnimatedSprite : public GameObject, public Sprite

View file

@ -15,6 +15,15 @@ SingleSprite::SingleSprite(const std::shared_ptr<sf::Texture> &texture, const sf
setSize(size);
}
SingleSprite::SingleSprite(const std::shared_ptr<TextureCutout> &texture, const sf::Vector2f &size)
{
sprite = sf::Sprite();
sprite.setTexture(*texture->texture);
sprite.setTextureRect(texture->cutout);
setSize(size);
}
void SingleSprite::draw(sf::RenderWindow *window)
{
sprite.setPosition(coordinates->isometric().toScreen());
@ -37,3 +46,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;
}

View file

@ -3,14 +3,16 @@
#include <SFML/Graphics/Sprite.hpp>
#include "../game/game_object.h"
#include "../../game/game_object.h"
#include "sprite.hpp"
#include "texture_cutout.hpp"
class SingleSprite : public GameObject, public Sprite
{
public:
SingleSprite(const sf::Sprite &sprite, const sf::Vector2f &size = sf::Vector2f(0, 0));
SingleSprite(const std::shared_ptr<TextureCutout> &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) override;
@ -19,6 +21,8 @@ public:
sf::Vector2f getSize() const override;
sf::Sprite getSprite() const;
private:
sf::Sprite sprite;
};

View file

@ -1,47 +1,17 @@
#include "sprite_factory.hpp"
#include "../texture_config.h"
#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);
auto texture = createTextureForSprite(name);
if (texture == nullptr)
{
LOG(ERROR) << "Texture " << config.resourceName << " not found. Could not create single sprite.";
LOG(ERROR) << "Texture for sprite " << name << " 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;
return std::make_shared<SingleSprite>(texture->texture, size);
}
std::shared_ptr<AnimatedSprite> SpriteFactory::createAnimatedSprite(const std::string& name, sf::Vector2f size)
@ -95,3 +65,42 @@ std::shared_ptr<SpriteSheet> SpriteFactory::createSheet(const std::string& name)
LOG(INFO) << "Creating sheet " << name;
return std::make_shared<SpriteSheet>(texture, config.columns, config.rows);
}
std::shared_ptr<TextureCutout> SpriteFactory::createTextureForSprite(const std::string &spriteName)
{
// Get sprite config
auto sprite_config = all_sprites.find(spriteName);
if (sprite_config == all_sprites.end())
{
LOG(ERROR) << "Sprite " << spriteName << " not found. Could not create sprite texture cutout.";
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 sprite texture cutout.";
return nullptr;
}
return std::make_shared<TextureCutout>(texture);
}
// Construct from sheet
auto sheet = createSheet(config.resourceName);
if (sheet == nullptr)
{
LOG(ERROR) << "Sheet " << config.resourceName << " not found. Could not create sprite texture cutout.";
return nullptr;
}
LOG(INFO) << "Creating sprite texture cutout from sheet " << config.resourceName;
return sheet->getTextureCutout(config.sheetIndex);
}

View file

@ -7,7 +7,8 @@
#include "single_sprite.hpp"
#include "animated_sprite.hpp"
#include "sprite_sheet.hpp"
#include "../logging/easylogging++.h"
#include "../../logging/easylogging++.h"
#include "texture_cutout.hpp"
class SpriteFactory
{
@ -15,6 +16,7 @@ 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<TextureCutout> createTextureForSprite(const std::string& spriteName);
};

View file

@ -1,37 +1,31 @@
#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)
{
// Extract sprites from texture
sprites = std::vector<sf::Sprite>();
textureCutouts = {};
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);
auto rect = sf::IntRect(x * spriteWidth, y * spriteHeight, spriteWidth, spriteHeight);
std::shared_ptr<TextureCutout> cutout = std::make_shared<TextureCutout>(texture, rect);
textureCutouts.push_back(cutout);
}
}
}
std::shared_ptr<SingleSprite> SpriteSheet::getSprite(int sequenceIndex) const
{
if (sequenceIndex < 0 || sequenceIndex >= sprites.size())
{
throw std::runtime_error("Invalid sequence index");
}
auto sprite = sprites[sequenceIndex];
return std::make_shared<SingleSprite>(sprite);
return std::make_shared<SingleSprite>(getTextureCutout(sequenceIndex));
}
std::shared_ptr<AnimatedSprite> SpriteSheet::getAnimation(int startingSequenceIndex, int numberOfFrames) const
{
if (startingSequenceIndex < 0 || startingSequenceIndex + numberOfFrames > sprites.size())
if (startingSequenceIndex < 0 || startingSequenceIndex + numberOfFrames > textureCutouts.size())
{
throw std::runtime_error("Invalid starting sequence index");
}
@ -43,7 +37,16 @@ std::shared_ptr<AnimatedSprite> SpriteSheet::getAnimation(int startingSequenceIn
std::vector<sf::Sprite> animation = std::vector<sf::Sprite>();
for (int i = 0; i < numberOfFrames; i++)
{
animation.push_back(sprites[startingSequenceIndex + i]);
animation.push_back(getSprite(startingSequenceIndex + i)->getSprite());
}
return std::make_shared<AnimatedSprite>(animation);
}
std::shared_ptr<TextureCutout> SpriteSheet::getTextureCutout(int sequenceIndex) const
{
if (sequenceIndex < 0 || sequenceIndex >= textureCutouts.size())
{
throw std::runtime_error("Invalid sequence index");
}
return textureCutouts[sequenceIndex];
}

View file

@ -7,6 +7,7 @@
#include <SFML/Graphics/Sprite.hpp>
#include "animated_sprite.hpp"
#include "single_sprite.hpp"
#include "texture_cutout.hpp"
class SpriteSheet
{
@ -17,8 +18,10 @@ public:
std::shared_ptr<AnimatedSprite> getAnimation(int startingSequenceIndex, int numberOfFrames) const;
std::shared_ptr<TextureCutout> getTextureCutout(int sequenceIndex) const;
private:
std::vector<sf::Sprite> sprites;
std::vector<std::shared_ptr<TextureCutout>> textureCutouts;
};

View file

@ -0,0 +1,15 @@
#ifndef HOLESOME_TEXTURE_CUTOUT_HPP
#define HOLESOME_TEXTURE_CUTOUT_HPP
#include <SFML/Graphics/Texture.hpp>
#include <memory>
#include <utility>
struct TextureCutout {
std::shared_ptr<sf::Texture> texture;
sf::IntRect cutout;
TextureCutout(std::shared_ptr<sf::Texture> texture, sf::IntRect cutout = {}) : texture(std::move(texture)), cutout(cutout) {}
};
#endif //HOLESOME_TEXTURE_CUTOUT_HPP

View file

@ -1,5 +1,5 @@
#include "texture_manager.hpp"
#include "../logging/easylogging++.h"
#include "../../logging/easylogging++.h"
std::shared_ptr<TextureManager> TextureManager::getInstance()
{

View file

@ -1,6 +1,6 @@
#include "versatile_sprite.hpp"
#include "sprite_factory.hpp"
#include "../texture_config.h"
#include "../../texture_config.h"
VersatileSprite::VersatileSprite(const std::string &name, sf::Vector2f size)
{

View file

@ -5,7 +5,7 @@
#include <SFML/System/Vector2.hpp>
#include <string>
#include "sprite.hpp"
#include "../game/game_object.h"
#include "../../game/game_object.h"
#include "single_sprite.hpp"
#include "animated_sprite.hpp"

View file

@ -0,0 +1,66 @@
#include <SFML/Graphics/ConvexShape.hpp>
#include "ground_sprite.hpp"
#include "basic/sprite_factory.hpp"
#include "../config.h"
GroundSprite::GroundSprite(const std::string &name, sf::Vector2f worldMapSize)
{
this->worldMapSize = worldMapSize;
constructGroundShape();
// Set Texture
auto texture = SpriteFactory::createTextureForSprite(name);
if (texture == nullptr)
{
LOG(ERROR) << "Texture " << name << " not found. Using simple fill color as fallback.";
groundShape.setFillColor(sf::Color::Green);
} else
{
setTexture(texture);
}
}
void GroundSprite::setSize(const sf::Vector2f &size)
{
worldMapSize = size;
}
sf::Vector2f GroundSprite::getSize() const
{
return worldMapSize;
}
void GroundSprite::constructGroundShape()
{
groundShape = sf::ConvexShape();
groundShape.setPointCount(4);
// Transform corners from world to iso space
sf::Vector2f left = CoordinateTransformer::worldToIsometric({0, worldMapSize.x}).toScreen();
sf::Vector2f top = CoordinateTransformer::worldToIsometric(worldMapSize).toScreen();
sf::Vector2f right = CoordinateTransformer::worldToIsometric({worldMapSize.y, 0}).toScreen();
groundShape.setPoint(0, {0, 0});
groundShape.setPoint(1, left);
groundShape.setPoint(2, top);
groundShape.setPoint(3, right);
}
void GroundSprite::draw(sf::RenderWindow *window)
{
window->draw(groundShape);
}
void GroundSprite::setTexture(const std::shared_ptr<TextureCutout> &textureCutout)
{
auto texture = textureCutout->texture.get();
texture->setRepeated(true);
groundShape.setTexture(texture);
groundShape.setTextureRect(textureCutout->cutout);
// Set scale
float scale = 1 / WORLD_TO_ISO_SCALE;
groundShape.scale(scale, scale / ISOMETRIC_SKEW);
}

View file

@ -0,0 +1,30 @@
#ifndef HOLESOME_GROUND_SPRITE_HPP
#define HOLESOME_GROUND_SPRITE_HPP
#include "basic/sprite.hpp"
#include "../game/game_object.h"
#include "basic/texture_cutout.hpp"
class GroundSprite : public Sprite, public GameObject
{
public:
GroundSprite(const std::string& name, sf::Vector2f worldMapSize);
void setSize(const sf::Vector2f &size) override;
sf::Vector2f getSize() const override;
void draw(sf::RenderWindow *window) override;
private:
sf::Vector2f worldMapSize;
sf::ConvexShape groundShape;
void constructGroundShape();
void setTexture(const std::shared_ptr<TextureCutout> &textureCutout);
};
#endif //HOLESOME_GROUND_SPRITE_HPP

View file

@ -8,6 +8,7 @@
#include "sprites/configs/sprite_config.hpp"
#define PLAYER_SKIN "ring"
#define GROUND_SKIN "simple_grass"
/**
* All textures used in the game.
@ -17,7 +18,8 @@ std::map<std::string, std::string> const all_textures = {
{"numbers", "assets/numbers.png"},
{"64", "assets/64.png"},
{"edge", "assets/edge.png"},
{"ring", "assets/ring.png"}
{"ring", "assets/ring.png"},
{"grasses", "assets/grass_plus.png"}
};
/**
@ -25,7 +27,8 @@ std::map<std::string, std::string> const all_textures = {
* 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)}
{"numbers", SheetConfig("numbers", 4, 2)},
{"grasses", SheetConfig("grasses", 25, 14)}
};
/**
@ -43,7 +46,8 @@ std::map<std::string, AnimationConfig> const all_animations = {
std::map<std::string, SpriteConfig> const all_sprites = {
{"64", SpriteConfig("64")},
{"edge", SpriteConfig("edge")},
{"ring", SpriteConfig("ring")}
{"ring", SpriteConfig("ring")},
{"simple_grass", SpriteConfig("grasses", 58)}
};
#endif //HOLESOME_TEXTURE_CONFIG_H