22 :
EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
35 setAnimation(path, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
41 setAnimation(spritesheet, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
45 :
EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
51 :
EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
53 setAnimation(path, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
57 :
EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
59 setAnimation(spritesheet, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
73 _readReverse = reverse;
78 if (frameDuration < 0) {
81 <<
", min: 0, max: <unknown>" << std::endl;
83 std::to_string(frameDuration),
88 _frameDelay = frameDuration;
93 if (frameIndex > _totalFrames || frameIndex < 0) {
100 _frameInitial = frameIndex;
106 _totalFrames = rects.size();
111 _baseTexture.setFilePath(path);
112 _processAnimation(frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
117 _baseTexture.update(spritesheet);
118 _processAnimation(frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
123 if (_clock.getElapsedTime() >= _frameDelay) {
215 PRETTY_INFO <<
"Processing getFrames" << std::endl;
218 PRETTY_INFO <<
"Processing getLooped" << std::endl;
221 PRETTY_INFO <<
"Processing getPaused" << std::endl;
224 PRETTY_INFO <<
"Processing getFrames" << std::endl;
227 PRETTY_INFO <<
"Processing getPlaying" << std::endl;
230 PRETTY_INFO <<
"Processing getStopped" << std::endl;
233 PRETTY_INFO <<
"Processing getTicked" << std::endl;
239 PRETTY_INFO <<
"Processing getFramesCount" << std::endl;
242 PRETTY_INFO <<
"Processing getBaseTexture" << std::endl;
245 PRETTY_INFO <<
"Processing getReadReverse" << std::endl;
248 PRETTY_INFO <<
"Processing getInitialFrame" << std::endl;
251 PRETTY_INFO <<
"Processing getCurrentFrameIndex" << std::endl;
254 PRETTY_INFO <<
"Processing getCurrentFrame" << std::endl;
306 return _frameInitial;
311 PRETTY_INFO <<
"Getting the current frame index" << std::endl;
312 if (_frames.size() <= 0) {
314 <<
"No frames available" << std::endl;
317 return _currentFrameIndex;
322 PRETTY_INFO <<
"Getting the current frame" << std::endl;
323 if (_frames.size() <= 0) {
325 <<
"No frames available" << std::endl;
328 std::uint32_t frame = getCurrentFrameIndex();
329 std::uint32_t frameSize = _frames.size() - 1;
330 if (frame > frameSize || frame < 0) {
332 <<
"Frame index out of bounds" << std::endl;
335 PRETTY_SUCCESS <<
"Getting the current frame frame list." << std::endl;
336 return _frames[frame];
346 PRETTY_INFO <<
"Getting the frame dimension" << std::endl;
347 if (_frames.size() <= 0) {
349 <<
"No frames available" << std::endl;
352 PRETTY_SUCCESS <<
"Getting the frame dimensions from the first frame." << std::endl;
353 return _frames[0].size;
358 return getCurrentFrame();
368 std::string indentation =
"";
369 for (
unsigned int i = 0; i < indent; ++i) {
372 std::string result = indentation +
"AnimationComponent:\n";
383 result += indentation +
"- Current Frame: " +
Recoded::myToString(_currentFrameIndex) +
"\n";
385 result += indentation +
"- Base texture: {\n" + _baseTexture.getInfo(indent + 1) + indentation +
"}\n";
386 result += indentation +
"- Frames: {\n";
387 for (
unsigned int i = 0; i < _frames.size(); i++) {
390 result += indentation +
"}\n";
391 result += indentation +
"Current Rectangle: " +
Recoded::myToString(_currentRectangle) +
"\n";
392 result += indentation +
"Clock: {\n" + _clock.getInfo(indent + 1) + indentation +
"}\n";
404 PRETTY_DEBUG <<
"The animation component class is different from the current, updating" << std::endl;
413 PRETTY_INFO <<
"The animation ticking is paused." << std::endl;
417 if (_frames.empty()) {
419 <<
"There are no frames to render." << std::endl;
421 "<There are no frames>",
422 "<Have you thought of adding frames to the class?>",
423 "<If not use the setAnimation function>"
427 if (_frameInitial > _totalFrames) {
429 <<
"The default frame is greater than "
430 <<
" the total amount of frames, frame initial: "
431 << std::to_string(_frameInitial)
432 <<
"minimum frames: 0"
433 <<
"maximum frames:" << std::to_string(_totalFrames)
448 std::uint32_t nextFrame = _currentFrameIndex - 1;
451 if (nextFrame == std::numeric_limits<std::uint32_t>::max() && _readReverse) {
452 PRETTY_INFO <<
"The next frame is negative, resetting counter to the maximum available frames." << std::endl;
454 PRETTY_INFO <<
"Looping is enabled, the sprite will thus return to the last frame." << std::endl;
455 nextFrame = _totalFrames - 1;
457 if (_frameInitial > _totalFrames) {
459 <<
"The default frame is greater than "
460 <<
" the total amount of frames, frame initial: "
461 << std::to_string(_frameInitial)
462 <<
"minimum frames: 0"
463 <<
"maximum frames:" << std::to_string(_totalFrames)
467 _currentFrameIndex = _frameInitial;
470 _currentFrameIndex = nextFrame;
472 _currentRectangle = _frames[_currentFrameIndex];
478 std::uint32_t nextFrame = _currentFrameIndex + 1;
481 if (nextFrame >= _totalFrames && !_readReverse) {
482 PRETTY_INFO <<
"The next frame is positive, resetting counter to the maximum available frames." << std::endl;
484 PRETTY_INFO <<
"Looping is enabled, the sprite will thus return to the last frame." << std::endl;
487 if (_frameInitial > _totalFrames) {
489 <<
"The default frame is greater than "
490 <<
" the total amount of frames, frame initial: "
491 << std::to_string(_frameInitial)
492 <<
"minimum frames: 0"
493 <<
"maximum frames:" << std::to_string(_totalFrames)
497 _currentFrameIndex = _frameInitial;
500 _currentFrameIndex = nextFrame;
502 _currentRectangle = _frames[_currentFrameIndex];
516 PRETTY_INFO <<
"Reseting the frame index to initial frame" << std::endl;
517 _currentFrameIndex = initialFrame;
518 PRETTY_INFO <<
"Setting the _frame initial to the correct value" << std::endl;
519 _frameInitial = initialFrame;
522 std::any textureCapsule = _baseTexture.getTexture();
523 if (!textureCapsule.has_value()) {
525 <<
"Texture is not set." << std::endl;
530 if (!OptionalTexture.has_value()) {
531 PRETTY_ERROR <<
"BaseId: '" <<
Recoded::myToString(getEntityNodeId()) <<
"' " <<
"The decasting has failed, skipping the rest of the function" << std::endl;
535 std::shared_ptr<sf::Texture> texture = OptionalTexture.value();
536 PRETTY_DEBUG <<
"Getting the texture size" << std::endl;
537 sf::Vector2u textureDim = texture->getSize();
538 PRETTY_DEBUG <<
"Texture size gathered ( width: " << textureDim.x
539 <<
" height: " << textureDim.y <<
")" << std::endl;
540 spritesheetSize.
setDimension({ textureDim.x, textureDim.y });
541 PRETTY_INFO <<
"Checking if the texture width and height can contain"
542 <<
" the required frameWidth (" << frameWidth
543 <<
") and fameHeight (" << frameHeight <<
")"
545 if (frameWidth <= 0) {
547 <<
"Frame width must be greater than zero." << std::endl;
549 std::to_string(frameWidth),
551 std::to_string(spritesheetSize.
getWidth())
554 if (frameHeight <= 0) {
556 <<
"Frame height must be greater than zero." << std::endl;
558 std::to_string(frameHeight),
560 std::to_string(spritesheetSize.
getHeight())
563 if (frameWidth > spritesheetSize.
getWidth()) {
565 <<
"The frame width is greater than the texture width, "
566 <<
"frame width: " << frameWidth
567 <<
"texture width: " << spritesheetSize.
getWidth()
575 if (frameHeight > spritesheetSize.
getHeight()) {
577 <<
"The frame height is greater than the texture height, "
578 <<
"frame height: " << frameHeight
579 <<
"texture height: " << spritesheetSize.
getHeight()
587 PRETTY_INFO <<
"Cutting the texture into frames (Mathing some final elements)" << std::endl;
588 const int columns = spritesheetSize.
getWidth() / frameWidth;
589 const int rows = spritesheetSize.
getHeight() / frameHeight;
591 _totalFrames = (columns * rows);
597 <<
"', spritesheet height: '"
599 <<
"', spritesheet width: '"
601 <<
"', frame height: '" << frameHeight
602 <<
"', frame width: '" << frameWidth <<
"'"
605 if (initialFrame < 0 || initialFrame > _totalFrames) {
607 <<
"Initial frame is out of range, expected at maximum: "
614 if (endFrame != (-1) && (endFrame < 0 || endFrame > _totalFrames)) {
616 <<
"Initial frame is out of range, expected at maximum: "
623 const short int columUpdater = _getIndexUpdater(startLeft);
624 const short int rowUpdater = _getIndexUpdater(startTop);
626 unsigned int posx = 0;
627 unsigned int posy = 0;
628 unsigned int frameCounter = 0;
631 PRETTY_INFO <<
"The texture is set to be cut from the top." << std::endl;
634 PRETTY_INFO <<
"The texture is set to be cut from the bottom." << std::endl;
638 PRETTY_INFO <<
"There are : " << _totalFrames <<
" in total" << std::endl;
648 <<
", _continueLoop(startTop, posy, rows): " <<
Recoded::myToString(_continueLoop(startTop, posy, rows))
649 <<
", _continueLoop(startLeft, posx, columns): " <<
Recoded::myToString(_continueLoop(startLeft, posx, columns))
651 std::pair<int, int> pos{ posy, posx };
652 for (; _continueLoop(startTop, posy, rows); posy += rowUpdater) {
653 posx = (columns - 1);
655 PRETTY_INFO <<
"The texture is set to be cut from the left." << std::endl;
667 <<
", _continueLoop(startTop, posy, rows): " <<
Recoded::myToString(_continueLoop(startTop, posy, rows))
668 <<
", _continueLoop(startLeft, posx, columns): " <<
Recoded::myToString(_continueLoop(startLeft, posx, columns))
670 for (; _continueLoop(startLeft, posx, columns); posx += columUpdater) {
680 <<
", _continueLoop(startTop, posy, rows): " <<
Recoded::myToString(_continueLoop(startTop, posy, rows))
681 <<
", _continueLoop(startLeft, posx, columns): " <<
Recoded::myToString(_continueLoop(startLeft, posx, columns))
687 std::pair<int, int> position = {
691 std::pair<int, int> dimension = {
696 if (frameCounter >= initialFrame && (frameCounter <= endFrame || endFrame == (-1))) {
697 _frames.push_back(viewField);
714 <<
", _continueLoop(startTop, posy, rows): " <<
Recoded::myToString(_continueLoop(startTop, posy, rows))
715 <<
", _continueLoop(startLeft, posx, columns): " <<
Recoded::myToString(_continueLoop(startLeft, posx, columns))
717 if (_frames.size() > 0) {
719 _currentFrameIndex = 0;
720 _currentRectangle = _frames[_currentFrameIndex];
721 _totalFrames = _frames.size();
737 return (position < maxValue);
739 return (position > 0);
This is the file that contains the class in charge of tracking sprite animations.
#define PRETTY_ERROR
Error log with details and colour.
#define PRETTY_DEBUG
Debug log with details and colour.
#define PRETTY_INFO
Info log with details and colour.
#define PRETTY_CRITICAL
Critical log with details and colour.
#define PRETTY_SUCCESS
Success log with details and colour.
This is the class in charge of informing the user that the duration they provided is invalid.
This is the class in charge of raising the invalid height error informing the user that the height th...
This is the class in charge of informing the user that the index they provided is invalid.
This is the class in charge of raising the invalid width error informing the user that the width they...
This is the class in charge of informing the user that there are no frames for the animation.
This is the class in charge of informing the user that they tried to access a non-existant texture in...
const std::vector< Recoded::IntRect > getFrames() const
Get all the frames loaded in the animation component.
void stop()
A function to stop the animation, and reset the index to the default frame.
const std::uint32_t getCurrentFrameIndex() const
Get the index of the frame that is currently in use.
const Recoded::IntRect getCurrentRectangle() const
Get the Rectangle that is currently in use.
const std::string getInfo(const unsigned int indent=0) const
This is a function meant for debugging purposes It will dump the current state of the variables upon ...
void _tick()
Main function to process the ticking of the animation.
const bool isLooping() const
Get the information about if the component is set to loop the animation.
void _tickReverse()
Advances the animation by one frame in reverse.
const GUI::ECS::Components::TextureComponent getBaseTexture() const
Get the Base Texture object.
void start()
Start the playing of the animation from the current index in memory.
const bool isStopped() const
Get the information about the state of the animation (stopped)
const bool isPlaying() const
Get the information about the state of the animation (playing)
void _tickRegular()
Advances the animation by one frame in regular (forward) order.
void setAnimation(const std::vector< Recoded::IntRect > &rects)
Set the Animation object.
const bool getTicked() const
A function to check if the frame has changed.
AnimationComponent & operator=(const GUI::ECS::Components::AnimationComponent ©)
void resume()
Resume the playing of the animation (has no effect if already playing)
const bool _continueLoop(const bool startBegining, const unsigned int position, const unsigned int maxValue) const
const std::pair< int, int > getFrameDimensions() const
Get the dimension of the first frame under an std::pair<int, int> instance.
const float getDelay() const
Get the Delay object that is used before changing frames.
void checkTick()
Check if it is time to change the frame of the animation.
void forceTick()
Force the animation to tick regardless of the delay.
void update(const GUI::ECS::Components::AnimationComponent ©)
Update the current Animation component with another Animation class.
const bool getLoop() const
Get the info about if the animation is being read in a loop or not (once at the end,...
void pause()
Pause the playing of the animation but does not reset the index to the default frame.
const bool isPaused() const
Get the information about the state of the animation (paused)
AnimationComponent()
Construct a new Animation Component object.
const GUI::ECS::Systems::Clock getClock() const
Get the Clock object.
~AnimationComponent()
Destroy the Animation Component object.
const bool getLooped() const
Get the information about if the animation has completed a loop (valid for the 1rst frame of the new ...
void setLoop(bool loop)
Set the Loop object.
const bool getReadReverse() const
Get the info about if the order of the frames are being read from right to left instead of left to ri...
void setInitialFrame(std::uint32_t frameIndex)
Set the Initial Frame object.
void _processAnimation(const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame=0, const int endFrame=(-1))
Function in charge of generating the animation frames based on the provided information.
const bool hasTicked()
A function to check if the frame has changed.
void setReadReverse(bool reverse)
Set the Read Reverse object.
void setDelay(float frameDuration)
Set the Delay object.
const std::uint32_t getInitialFrame() const
Get the index of the frame considered as the first in the series of the animation.
const bool hasLooped() const
A function to check if the animation has looped around (valid for the 1rst frame of the new loop)
const short int _getIndexUpdater(const bool startBegining=true) const
const std::uint32_t getFrameCount() const
Get the total number of frames contained in the animation.
const bool getStopped() const
Get the information about the state of the animation (paused/playing)
const bool getPaused() const
Get the information about the state of the animation (paused/playing)
const Recoded::IntRect getCurrentFrame() const
Get the index of the frame that is currently in use.
const bool getPlaying() const
Get the information about the state of the animation (paused/playing)
Represents a texture component used in an entity component system.
A class for managing time tracking within the ECS system.
Represents a rectangular component that can detect collisions and mouse interactions,...
const float getWidth() const
Gets the width of the component.
void setDimension(const std::pair< float, float > &dimension)
Set the dimension of the object.
const float getHeight() const
Gets the height of the component.
A generic 2D rectangle class that holds position and size as pairs.
std::ostream & operator<<(std::ostream &os, const AnimationComponent &item)
Outputs the animation's info to a stream.
const std::string myToString(const Rect< RectType > &rectangle)
Converts a Rect<T> object to its string representation.
std::optional< T > unCast(const std::any &classNode, const bool raiseOnError=true, const std::string customErrorMessage="")
Casts the content of a std::any back to its original type.