Implemented rotation for sprites, among other things
This commit is contained in:
parent
24963b2d0a
commit
e8319fd6b9
20 changed files with 301 additions and 76 deletions
|
@ -137,6 +137,9 @@ set(COORDINATES_00_SOURCES
|
|||
src/coordinates/translated_coordinates.h
|
||||
src/coordinates/translated_coordinates.cpp)
|
||||
|
||||
set(MINIMAP_00_SOURCES
|
||||
src/prototypes/minimap_00.cpp)
|
||||
|
||||
# Add an executable target
|
||||
add_executable(Holesome ${SOURCES})
|
||||
add_executable(Physics_00 ${PHYSICS_00_SOURCES})
|
||||
|
@ -145,6 +148,8 @@ add_executable(Math_00 ${MATH_00_SOURCES})
|
|||
|
||||
add_executable(Coordinates_00 ${COORDINATES_00_SOURCES})
|
||||
|
||||
add_executable(Minimap_00 ${MINIMAP_00_SOURCES})
|
||||
|
||||
# Link SFML and other libraries to your executable target
|
||||
target_link_libraries(Holesome sfml-graphics sfml-audio)
|
||||
target_link_libraries(Holesome Eigen3::Eigen)
|
||||
|
@ -156,6 +161,8 @@ target_link_libraries(Math_00 Eigen3::Eigen)
|
|||
|
||||
target_link_libraries(Coordinates_00 Eigen3::Eigen)
|
||||
|
||||
target_link_libraries(Minimap_00 sfml-graphics sfml-audio)
|
||||
|
||||
# Assets
|
||||
add_custom_target(copy_assets
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#define PLAYER_RADIUS_PER_LEVEL 0.25f
|
||||
|
||||
// World
|
||||
#define WORLD_GRAVITY b2Vec2(0.f, 0.f)
|
||||
#define WORLD_GRAVITY b2Vec2(0.f, -9.8f)
|
||||
#define SKY_HEIGHT_SCALE 2.f
|
||||
|
||||
// FPS
|
||||
|
|
|
@ -101,3 +101,11 @@ TranslatedCoordinates::TranslatedCoordinates(DiagonalWorldCoordinates diagonalWo
|
|||
{
|
||||
setDiagonal(diagonalWorldCoordinates);
|
||||
}
|
||||
|
||||
void TranslatedCoordinates::removeParent()
|
||||
{
|
||||
// Uncomment, if global position should be preserved
|
||||
// auto globalWorldCoordinates = this->world();
|
||||
// this->worldCoordinates = globalWorldCoordinates;
|
||||
this->parent = nullptr;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
void setParent(std::shared_ptr<TranslatedCoordinates> parent, WorldCoordinates offset = {0, 0});
|
||||
|
||||
void removeParent();
|
||||
|
||||
void setWorldOffset(WorldCoordinates offset);
|
||||
|
||||
void setScreenOffset(IsometricCoordinates offset);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "collectable.hpp"
|
||||
#include "../../sprites/versatile_sprite.hpp"
|
||||
#include "../../config.h"
|
||||
#include "../input/input_mapper.h"
|
||||
|
||||
Collectable::Collectable()
|
||||
{
|
||||
|
@ -10,7 +11,9 @@ Collectable::Collectable()
|
|||
|
||||
void Collectable::setRotation(float angle)
|
||||
{
|
||||
|
||||
// Assume that the sprite is the first child
|
||||
auto sprite = std::dynamic_pointer_cast<VersatileSprite>(getChildren()[0]);
|
||||
sprite->setRotation(angle);
|
||||
}
|
||||
|
||||
float Collectable::getDepth() const
|
||||
|
@ -29,3 +32,28 @@ void Collectable::setSprite(const std::string &spriteName)
|
|||
// Set half size offset of coordinates
|
||||
coordinates->move(IsometricCoordinates(0, -sizeWidth / 2.f, 0));
|
||||
}
|
||||
|
||||
void Collectable::update()
|
||||
{
|
||||
GameObject::update();
|
||||
|
||||
// TODO: Remove this
|
||||
if (InputMapper::getInstance()->getInputIdentities().empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<InputIdentity> inputIdentity = InputMapper::getInstance()->getInputIdentity(
|
||||
InputDeviceGroup::KEYBOARD_WASD);
|
||||
|
||||
// Rotate based on grow/shrink input
|
||||
if (inputIdentity->isPerformingAction(GameAction::GROW))
|
||||
{
|
||||
angle += 10.f;
|
||||
} else if (inputIdentity->isPerformingAction(GameAction::SHRINK))
|
||||
{
|
||||
angle -= 10.f;
|
||||
}
|
||||
|
||||
setRotation(angle);
|
||||
}
|
||||
|
|
|
@ -13,16 +13,20 @@ public:
|
|||
|
||||
void setRotation(float angle);
|
||||
|
||||
void update() override;
|
||||
|
||||
float getDepth() const;
|
||||
|
||||
int getId() const
|
||||
{
|
||||
return collectableId;
|
||||
}
|
||||
|
||||
private:
|
||||
int collectableId = 0;
|
||||
static inline int collectableCount = 0;
|
||||
|
||||
float angle = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -30,17 +30,18 @@ void CollectablesCollection::createEmpty(int maxDepth)
|
|||
void CollectablesCollection::remove(const std::shared_ptr<Collectable> &collectable)
|
||||
{
|
||||
depthCollections[collectable->getDepth()]->remove(collectable);
|
||||
|
||||
removeChild(collectable);
|
||||
}
|
||||
|
||||
void CollectablesCollection::add(const std::shared_ptr<Collectable> &collectable)
|
||||
{
|
||||
depthCollections[collectable->getDepth()]->add(collectable);
|
||||
addDetachedChild(collectable);
|
||||
}
|
||||
|
||||
void CollectablesCollection::update()
|
||||
{
|
||||
updateCollectables();
|
||||
GameObject::update();
|
||||
|
||||
// Move collectables to new depth collections if necessary
|
||||
|
||||
|
@ -57,22 +58,27 @@ void CollectablesCollection::update()
|
|||
for (auto &collectable: collectables)
|
||||
{
|
||||
int newDepth = std::floor(collectable->getDepth());
|
||||
if (newDepth != depth)
|
||||
if (newDepth == depth)
|
||||
{
|
||||
if (newDepth < 0 || newDepth >= (int) depthCollections.size())
|
||||
{
|
||||
LOG(ERROR) << "Collectable " << collectable->getId() << " has invalid depth " << newDepth
|
||||
<< "! Keeping it at previous depth " << depth << " ...";
|
||||
continue;
|
||||
}
|
||||
|
||||
depthCollection->remove(collectable);
|
||||
depthCollections[newDepth]->add(collectable);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isValidDepth(newDepth))
|
||||
{
|
||||
LOG(ERROR) << "Collectable " << collectable->getId() << " has invalid depth " << newDepth
|
||||
<< "! Keeping it at previous depth " << depth << " ...";
|
||||
continue;
|
||||
}
|
||||
|
||||
depthCollection->remove(collectable);
|
||||
depthCollections[newDepth]->add(collectable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CollectablesCollection::isValidDepth(int desiredDepth) const
|
||||
{ return desiredDepth >= 0 && desiredDepth < (int) depthCollections.size(); }
|
||||
|
||||
void CollectablesCollection::draw(sf::RenderWindow *window)
|
||||
{
|
||||
// Render collectables in reverse order of depth
|
||||
|
@ -86,25 +92,3 @@ void CollectablesCollection::draw(sf::RenderWindow *window)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CollectablesCollection::updateCollectables()
|
||||
{
|
||||
for (auto &[depth, depthCollection]: depthCollections)
|
||||
{
|
||||
for (auto &collectable: depthCollection->collectables)
|
||||
{
|
||||
collectable->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -23,14 +23,12 @@ 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;
|
||||
|
||||
std::map<int, std::shared_ptr<CollectablesDepthCollection>> depthCollections = {};
|
||||
|
||||
void updateCollectables();
|
||||
bool isValidDepth(int desiredDepth) const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -99,6 +99,14 @@ void Game::update()
|
|||
}
|
||||
|
||||
InputMapper::getInstance()->updateIdentities();
|
||||
|
||||
for (const auto &gameObject: gameObjects)
|
||||
{
|
||||
if (gameObject->getActive())
|
||||
{
|
||||
gameObject->preRenderUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Game> Game::getInstance()
|
||||
|
|
|
@ -64,6 +64,7 @@ void GameObject::removeChild(const std::shared_ptr<GameObject> &child)
|
|||
if (it != children.end())
|
||||
{
|
||||
children.erase(it);
|
||||
child->coordinates->removeParent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,3 +85,11 @@ void GameObject::addDetachedChild(const std::shared_ptr<GameObject> &child)
|
|||
{
|
||||
children.push_back(child);
|
||||
}
|
||||
|
||||
void GameObject::preRenderUpdate()
|
||||
{
|
||||
for (auto &child: children)
|
||||
{
|
||||
child->preRenderUpdate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ public:
|
|||
|
||||
virtual void physicsUpdate();
|
||||
|
||||
virtual void preRenderUpdate();
|
||||
|
||||
void setActive(bool active);
|
||||
bool getActive() const { return isActive; }
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ void CollectableSimulation::physicsUpdate()
|
|||
{
|
||||
updateGroundHole();
|
||||
|
||||
// world->Step(FRAME_TIME.asSeconds(), COLLECTABLES_SIM_VELOCITY_ITERATIONS, COLLECTABLES_SIM_POSITION_ITERATIONS);
|
||||
world->Step(FRAME_TIME.asSeconds(), COLLECTABLES_SIM_VELOCITY_ITERATIONS, COLLECTABLES_SIM_POSITION_ITERATIONS);
|
||||
|
||||
updateCollectable();
|
||||
}
|
||||
|
|
72
src/prototypes/minimap_00.cpp
Normal file
72
src/prototypes/minimap_00.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <SFML/Window/Event.hpp>
|
||||
#include <SFML/Graphics/CircleShape.hpp>
|
||||
#include <SFML/Graphics/RectangleShape.hpp>
|
||||
|
||||
void drawMainContent(sf::RenderWindow *window)
|
||||
{
|
||||
sf::RectangleShape rectangle(sf::Vector2f(800, 600));
|
||||
rectangle.setFillColor(sf::Color::Green);
|
||||
rectangle.setPosition(0, 0);
|
||||
window->draw(rectangle);
|
||||
|
||||
sf::CircleShape circle(50);
|
||||
circle.setFillColor(sf::Color::Red);
|
||||
circle.setPosition(150, 150);
|
||||
window->draw(circle);
|
||||
}
|
||||
|
||||
void drawMiniMapContent(sf::RenderWindow *window)
|
||||
{
|
||||
sf::RectangleShape rectangle(sf::Vector2f(196, 196));
|
||||
rectangle.setFillColor(sf::Color::White);
|
||||
rectangle.setPosition(2, 2);
|
||||
rectangle.setOutlineColor(sf::Color::Black);
|
||||
rectangle.setOutlineThickness(2);
|
||||
window->draw(rectangle);
|
||||
|
||||
sf::CircleShape circle(20);
|
||||
circle.setFillColor(sf::Color::Blue);
|
||||
circle.setPosition(80, 80);
|
||||
window->draw(circle);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Create simple window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "Minimap example");
|
||||
|
||||
// Create minimap view
|
||||
sf::View minimapView(sf::FloatRect(0, 0, 200, 200));
|
||||
// Set viewport to the top right corner
|
||||
minimapView.setViewport(sf::FloatRect(0.75f, 0, 0.25f, 0.25f));
|
||||
|
||||
while (window.isOpen()) {
|
||||
window.clear(sf::Color::Black);
|
||||
|
||||
// Draw main content
|
||||
auto fullView = window.getDefaultView();
|
||||
window.setView(fullView);
|
||||
|
||||
drawMainContent(&window);
|
||||
|
||||
|
||||
// Draw minimap
|
||||
window.setView(minimapView);
|
||||
|
||||
drawMiniMapContent(&window);
|
||||
|
||||
|
||||
// Finished
|
||||
window.display();
|
||||
|
||||
// Handle close event
|
||||
sf::Event event{};
|
||||
while (window.pollEvent(event)) {
|
||||
if (event.type == sf::Event::Closed) {
|
||||
window.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,12 @@
|
|||
|
||||
AnimatedSprite::AnimatedSprite(const std::vector<sf::Sprite> &sprites, const sf::Vector2f &size)
|
||||
{
|
||||
this->sprites = sprites;
|
||||
// Create a copy of the sprites as pointers
|
||||
for (auto &sprite: sprites)
|
||||
{
|
||||
this->sprites.push_back(std::make_shared<sf::Sprite>(sprite));
|
||||
}
|
||||
|
||||
setSize(size);
|
||||
}
|
||||
|
||||
|
@ -25,27 +30,50 @@ void AnimatedSprite::update()
|
|||
void AnimatedSprite::draw(sf::RenderWindow *window)
|
||||
{
|
||||
auto currentSprite = sprites[currentFrame];
|
||||
currentSprite.setPosition(coordinates->isometric().toScreen());
|
||||
currentSprite->setPosition(renderPosition);
|
||||
|
||||
window->draw(currentSprite);
|
||||
window->draw(*currentSprite);
|
||||
}
|
||||
|
||||
void AnimatedSprite::setSize(const sf::Vector2f &size)
|
||||
{
|
||||
for (auto &sprite: sprites)
|
||||
{
|
||||
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();
|
||||
auto scale = sprites[currentFrame]->getScale();
|
||||
auto textureSize = sprites[currentFrame]->getTextureRect();
|
||||
return {textureSize.width * scale.x, textureSize.height * scale.y};
|
||||
}
|
||||
|
||||
sf::Sprite AnimatedSprite::getSprite() const
|
||||
{
|
||||
return sprites[currentFrame];
|
||||
return *sprites[currentFrame];
|
||||
}
|
||||
|
||||
void AnimatedSprite::setRotation(float angle)
|
||||
{
|
||||
this->angle = restrictAngle(angle);
|
||||
|
||||
for (auto &sprite: sprites)
|
||||
{
|
||||
sprite->setRotation(angle);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimatedSprite::preRenderUpdate()
|
||||
{
|
||||
if (angle == 0)
|
||||
{
|
||||
renderPosition = coordinates->isometric().toScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
auto position = coordinates->isometric().toScreen();
|
||||
|
||||
renderPosition = calculateRotatedCornerPosition(position, angle);
|
||||
}
|
||||
|
|
|
@ -23,10 +23,17 @@ public:
|
|||
|
||||
sf::Sprite getSprite() const override;
|
||||
|
||||
void preRenderUpdate() override;
|
||||
|
||||
void setRotation(float angle) override;
|
||||
|
||||
private:
|
||||
int currentFrame = 0;
|
||||
sf::Time timeSinceLastFrame = sf::Time::Zero;
|
||||
std::vector<sf::Sprite> sprites;
|
||||
std::vector<std::shared_ptr<sf::Sprite>> sprites;
|
||||
|
||||
sf::Vector2f renderPosition;
|
||||
float angle = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ SingleSprite::SingleSprite(const std::shared_ptr<sf::Texture> &texture, const sf
|
|||
|
||||
void SingleSprite::draw(sf::RenderWindow *window)
|
||||
{
|
||||
sprite.setPosition(coordinates->isometric().toScreen());
|
||||
sprite.setPosition(renderPosition);
|
||||
window->draw(sprite);
|
||||
}
|
||||
|
||||
|
@ -42,3 +42,22 @@ sf::Sprite SingleSprite::getSprite() const
|
|||
{
|
||||
return sprite;
|
||||
}
|
||||
|
||||
void SingleSprite::setRotation(float angle)
|
||||
{
|
||||
this->angle = restrictAngle(angle);
|
||||
sprite.setRotation(angle);
|
||||
}
|
||||
|
||||
void SingleSprite::preRenderUpdate()
|
||||
{
|
||||
if (angle == 0)
|
||||
{
|
||||
renderPosition = coordinates->isometric().toScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
auto position = coordinates->isometric().toScreen();
|
||||
|
||||
renderPosition = calculateRotatedCornerPosition(position, angle);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
class SingleSprite : public GameObject, public Sprite
|
||||
{
|
||||
public:
|
||||
SingleSprite(const sf::Sprite &sprite, const sf::Vector2f &size = sf::Vector2f(0, 0));
|
||||
explicit 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));
|
||||
explicit SingleSprite(const std::shared_ptr<sf::Texture> &texture, const sf::Vector2f &size = sf::Vector2f(0, 0));
|
||||
|
||||
void draw(sf::RenderWindow *window) override;
|
||||
|
||||
|
@ -21,8 +21,14 @@ public:
|
|||
|
||||
sf::Sprite getSprite() const override;
|
||||
|
||||
void setRotation(float angle) override;
|
||||
|
||||
void preRenderUpdate() override;
|
||||
|
||||
private:
|
||||
sf::Sprite sprite;
|
||||
float angle = 0;
|
||||
sf::Vector2f renderPosition;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <vector>
|
||||
#include <memory>
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
#include <cmath>
|
||||
|
||||
class Sprite
|
||||
{
|
||||
|
@ -23,6 +24,52 @@ public:
|
|||
{
|
||||
throw std::runtime_error("Sprite::getSprite() not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates a sprite around its center.
|
||||
* @param angle [0, 360]
|
||||
*/
|
||||
virtual void setRotation(float angle)
|
||||
{
|
||||
throw std::runtime_error("Sprite::setRotation() not implemented");
|
||||
}
|
||||
|
||||
protected:
|
||||
static float restrictAngle(float angle)
|
||||
{
|
||||
float const MAX_ANGLE = 360.f;
|
||||
angle = std::fmod(angle, MAX_ANGLE); // Get the remainder after dividing by 360
|
||||
|
||||
if (angle < 0.0f)
|
||||
{
|
||||
float numberOfTimes = std::ceil(std::abs(angle) / MAX_ANGLE);
|
||||
angle += MAX_ANGLE * numberOfTimes; // Convert negative angles to positive
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
[[nodiscard]] sf::Vector2f
|
||||
calculateRotatedCornerPosition(sf::Vector2f spriteScreenPosition, float angle) const
|
||||
{
|
||||
angle = restrictAngle(angle);
|
||||
|
||||
auto spriteSize = getSize();
|
||||
|
||||
// Calculate the center point of the sprite
|
||||
sf::Vector2f center(spriteScreenPosition.x + spriteSize.x / 2, spriteScreenPosition.y + spriteSize.y / 2);
|
||||
|
||||
// Convert the angle to radians
|
||||
float angle_rad = angle * (M_PI / 180.0f);
|
||||
|
||||
// Calculate the rotated coordinates of the top left corner
|
||||
float new_x = center.x + (spriteScreenPosition.x - center.x) * std::cos(angle_rad) -
|
||||
(spriteScreenPosition.y - center.y) * std::sin(angle_rad);
|
||||
float new_y = center.y + (spriteScreenPosition.x - center.x) * std::sin(angle_rad) +
|
||||
(spriteScreenPosition.y - center.y) * std::cos(angle_rad);
|
||||
|
||||
return {new_x, new_y};
|
||||
}
|
||||
};
|
||||
|
||||
#endif //HOLESOME_SPRITE_HPP
|
||||
|
|
|
@ -22,42 +22,34 @@ VersatileSprite::VersatileSprite(const std::string &name, sf::Vector2f size)
|
|||
|
||||
void VersatileSprite::setSize(const sf::Vector2f &size)
|
||||
{
|
||||
if (singleSprite != nullptr)
|
||||
{
|
||||
singleSprite->setSize(size);
|
||||
} else if (animatedSprite != nullptr)
|
||||
{
|
||||
animatedSprite->setSize(size);
|
||||
} else
|
||||
{
|
||||
Sprite::setSize(size);
|
||||
}
|
||||
getUsedSpritePtr()->setSize(size);
|
||||
}
|
||||
|
||||
sf::Vector2f VersatileSprite::getSize() const
|
||||
{
|
||||
if (singleSprite != nullptr)
|
||||
{
|
||||
return singleSprite->getSize();
|
||||
} else if (animatedSprite != nullptr)
|
||||
{
|
||||
return animatedSprite->getSize();
|
||||
} else
|
||||
{
|
||||
return Sprite::getSize();
|
||||
}
|
||||
return getUsedSpritePtr()->getSize();
|
||||
}
|
||||
|
||||
sf::Sprite VersatileSprite::getSprite() const
|
||||
{
|
||||
return getUsedSpritePtr()->getSprite();
|
||||
}
|
||||
|
||||
void VersatileSprite::setRotation(float angle)
|
||||
{
|
||||
getUsedSpritePtr()->setRotation(angle);
|
||||
}
|
||||
|
||||
std::shared_ptr<Sprite> VersatileSprite::getUsedSpritePtr() const
|
||||
{
|
||||
if (singleSprite != nullptr)
|
||||
{
|
||||
return singleSprite->getSprite();
|
||||
return singleSprite;
|
||||
} else if (animatedSprite != nullptr)
|
||||
{
|
||||
return animatedSprite->getSprite();
|
||||
return animatedSprite;
|
||||
} else
|
||||
{
|
||||
return {};
|
||||
throw std::runtime_error("Versatile sprite has no sprite");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,15 @@ public:
|
|||
|
||||
[[nodiscard]] sf::Vector2f getSize() const override;
|
||||
|
||||
sf::Sprite getSprite() const override;
|
||||
[[nodiscard]] sf::Sprite getSprite() const override;
|
||||
|
||||
void setRotation(float angle) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<SingleSprite> singleSprite = nullptr;
|
||||
std::shared_ptr<AnimatedSprite> animatedSprite = nullptr;
|
||||
|
||||
std::shared_ptr<Sprite> getUsedSpritePtr() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue