R-Type  2
Doom but in better
Loading...
Searching...
No Matches
AnimationComponent.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2024
3** rtype (Workspace)
4** File description:
5** AnimationComponent.cpp
6*/
7
15
17 : EntityNode(0), _baseTexture(0), _clock(0)
18{
19};
20
22 : EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
23{
24};
25
26GUI::ECS::Components::AnimationComponent::AnimationComponent(const std::vector<Recoded::IntRect> &textures)
27 : EntityNode(0), _baseTexture(0), _clock(0)
28{
29 setAnimation(textures);
30};
31
32GUI::ECS::Components::AnimationComponent::AnimationComponent(const std::string &path, const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
33 : EntityNode(0), _baseTexture(0), _clock(0)
34{
35 setAnimation(path, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
36};
37
38GUI::ECS::Components::AnimationComponent::AnimationComponent(const GUI::ECS::Components::TextureComponent &spritesheet, const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
39 : EntityNode(0), _baseTexture(0), _clock(0)
40{
41 setAnimation(spritesheet, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
42};
43
44GUI::ECS::Components::AnimationComponent::AnimationComponent(const std::uint32_t entityId, const std::vector<Recoded::IntRect> &rects)
45 : EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
46{
47 setAnimation(rects);
48};
49
50GUI::ECS::Components::AnimationComponent::AnimationComponent(const std::uint32_t entityId, const std::string &path, const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
51 : EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
52{
53 setAnimation(path, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
54};
55
56GUI::ECS::Components::AnimationComponent::AnimationComponent(const std::uint32_t entityId, const GUI::ECS::Components::TextureComponent &spritesheet, const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
57 : EntityNode(entityId), _baseTexture(entityId), _clock(entityId)
58{
59 setAnimation(spritesheet, frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
60};
61
62
63
65
67{
68 _loop = loop;
69}
70
72{
73 _readReverse = reverse;
74}
75
77{
78 if (frameDuration < 0) {
79 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
80 << "Invalid duration, current: " << Recoded::myToString(frameDuration)
81 << ", min: 0, max: <unknown>" << std::endl;
83 std::to_string(frameDuration),
84 "0",
85 ""
86 );
87 }
88 _frameDelay = frameDuration;
89}
90
92{
93 if (frameIndex > _totalFrames || frameIndex < 0) {
94 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
95 << "Invalid duration, current: " << Recoded::myToString(frameIndex)
96 << ", min: 0, max: " << Recoded::myToString(_totalFrames)
97 << std::endl;
98 throw CustomExceptions::InvalidIndex(std::to_string(frameIndex), "0", std::to_string(_totalFrames));
99 }
100 _frameInitial = frameIndex;
101}
102
103void GUI::ECS::Components::AnimationComponent::setAnimation(const std::vector<Recoded::IntRect> &rects)
104{
105 _frames = rects;
106 _totalFrames = rects.size();
107}
108
109void GUI::ECS::Components::AnimationComponent::setAnimation(const std::string &path, const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
110{
111 _baseTexture.setFilePath(path);
112 _processAnimation(frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
113}
114
115void GUI::ECS::Components::AnimationComponent::setAnimation(const GUI::ECS::Components::TextureComponent &spritesheet, const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
116{
117 _baseTexture.update(spritesheet);
118 _processAnimation(frameWidth, frameHeight, startLeft, startTop, initialFrame, endFrame);
119}
120
122{
123 if (_clock.getElapsedTime() >= _frameDelay) {
124 _tick();
125 _hasTicked = true;
126 _clock.reset();
127 }
128}
129
131{
132 _tick();
133 _hasTicked = true;
134 _clock.reset();
135}
136
138{
139 _clock.start();
140 _hasTicked = false;
141 _playing = true;
142 _paused = false;
143 _stopped = false;
144}
145
147{
148 _clock.stop();
149 _hasTicked = false;
150 _playing = false;
151 _paused = true;
152 _stopped = false;
153}
154
156{
157 _clock.start();
158 _hasTicked = false;
159 _playing = true;
160 _paused = false;
161 _stopped = false;
162}
163
165{
166 _clock.reset();
167 _hasTicked = false;
168 _playing = false;
169 _paused = false;
170 _stopped = true;
171}
172
174{
175 if (_hasTicked) {
176 _hasTicked = false;
177 return true;
178 }
179 return false;
180}
181
183{
184 return _looped;
185}
186
188{
189 return _loop;
190}
191
193{
194 return _paused;
195}
196
198{
199 return _playing;
200}
201
203{
204 return _stopped;
205}
206
208{
209 PRETTY_INFO << "Processing getLoop" << std::endl;
210 _loop = copy.getLoop();
211 PRETTY_SUCCESS << "Processed getLoop" << std::endl;
212 PRETTY_INFO << "Processing getCLock" << std::endl;
213 _clock = copy.getClock();
214 PRETTY_SUCCESS << "Processed getCLock" << std::endl;
215 PRETTY_INFO << "Processing getFrames" << std::endl;
216 _frames = copy.getFrames();
217 PRETTY_SUCCESS << "Processed getFrames" << std::endl;
218 PRETTY_INFO << "Processing getLooped" << std::endl;
219 _looped = copy.getLooped();
220 PRETTY_SUCCESS << "Processed getLooped" << std::endl;
221 PRETTY_INFO << "Processing getPaused" << std::endl;
222 _paused = copy.getPaused();
223 PRETTY_SUCCESS << "Processed getPaused" << std::endl;
224 PRETTY_INFO << "Processing getFrames" << std::endl;
225 _frames = copy.getFrames();
226 PRETTY_SUCCESS << "Processed getFrames" << std::endl;
227 PRETTY_INFO << "Processing getPlaying" << std::endl;
228 _playing = copy.getPlaying();
229 PRETTY_SUCCESS << "Processed getPlaying" << std::endl;
230 PRETTY_INFO << "Processing getStopped" << std::endl;
231 _stopped = copy.getStopped();
232 PRETTY_SUCCESS << "Processed getStopped" << std::endl;
233 PRETTY_INFO << "Processing getTicked" << std::endl;
234 _hasTicked = copy.getTicked();
235 PRETTY_SUCCESS << "Processed getTicked" << std::endl;
236 PRETTY_INFO << "Processing getDelay" << std::endl;
237 _frameDelay = copy.getDelay();
238 PRETTY_SUCCESS << "Processed getDelay" << std::endl;
239 PRETTY_INFO << "Processing getFramesCount" << std::endl;
240 _totalFrames = copy.getFrameCount();
241 PRETTY_SUCCESS << "Processed getFramesCount" << std::endl;
242 PRETTY_INFO << "Processing getBaseTexture" << std::endl;
243 _baseTexture = copy.getBaseTexture();
244 PRETTY_SUCCESS << "Processed getBaseTexture" << std::endl;
245 PRETTY_INFO << "Processing getReadReverse" << std::endl;
246 _readReverse = copy.getReadReverse();
247 PRETTY_SUCCESS << "Processed getReadReverse" << std::endl;
248 PRETTY_INFO << "Processing getInitialFrame" << std::endl;
249 _frameInitial = copy.getInitialFrame();
250 PRETTY_SUCCESS << "Processed getInitialFrame" << std::endl;
251 PRETTY_INFO << "Processing getCurrentFrameIndex" << std::endl;
252 _currentFrameIndex = copy.getCurrentFrameIndex();
253 PRETTY_SUCCESS << "Processed getCurrentFrameIndex" << std::endl;
254 PRETTY_INFO << "Processing getCurrentFrame" << std::endl;
255 _currentRectangle = copy.getCurrentFrame();
256 PRETTY_SUCCESS << "Processed getCurrentFrame" << std::endl;
257}
258
260{
261 return _hasTicked;
262}
263
265{
266 return isPaused();
267}
268
270{
271 return isPlaying();
272}
273
275{
276 return isStopped();
277}
278
280{
281 return _looped;
282}
283
285{
286 return _loop;
287}
288
290{
291 return _readReverse;
292}
293
295{
296 return _frameDelay;
297}
298
300{
301 return _totalFrames;
302}
303
305{
306 return _frameInitial;
307}
308
310{
311 PRETTY_INFO << "Getting the current frame index" << std::endl;
312 if (_frames.size() <= 0) {
313 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
314 << "No frames available" << std::endl;
316 }
317 return _currentFrameIndex;
318}
319
321{
322 PRETTY_INFO << "Getting the current frame" << std::endl;
323 if (_frames.size() <= 0) {
324 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
325 << "No frames available" << std::endl;
327 }
328 std::uint32_t frame = getCurrentFrameIndex();
329 std::uint32_t frameSize = _frames.size() - 1;
330 if (frame > frameSize || frame < 0) {
331 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
332 << "Frame index out of bounds" << std::endl;
333 throw CustomExceptions::InvalidIndex(std::to_string(frame), "0", std::to_string(frameSize));
334 }
335 PRETTY_SUCCESS << "Getting the current frame frame list." << std::endl;
336 return _frames[frame];
337}
338
343
345{
346 PRETTY_INFO << "Getting the frame dimension" << std::endl;
347 if (_frames.size() <= 0) {
348 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
349 << "No frames available" << std::endl;
351 }
352 PRETTY_SUCCESS << "Getting the frame dimensions from the first frame." << std::endl;
353 return _frames[0].size;
354}
355
357{
358 return getCurrentFrame();
359}
360
361const std::vector<Recoded::IntRect> GUI::ECS::Components::AnimationComponent::getFrames() const
362{
363 return _frames;
364}
365
366const std::string GUI::ECS::Components::AnimationComponent::getInfo(const unsigned int indent) const
367{
368 std::string indentation = "";
369 for (unsigned int i = 0; i < indent; ++i) {
370 indentation += "\t";
371 }
372 std::string result = indentation + "AnimationComponent:\n";
373 result += indentation + "- Entity Id: " + Recoded::myToString(getEntityNodeId()) + "\n";
374 result += indentation + "- Looped: " + Recoded::myToString(_looped) + "\n";
375 result += indentation + "- Loop: " + Recoded::myToString(_loop) + "\n";
376 result += indentation + "- Paused: " + Recoded::myToString(_paused) + "\n";
377 result += indentation + "- Playing: " + Recoded::myToString(_playing) + "\n";
378 result += indentation + "- Stopped: " + Recoded::myToString(_stopped) + "\n";
379 result += indentation + "- Has Ticked: " + Recoded::myToString(_hasTicked) + "\n";
380 result += indentation + "- Read Reverse: " + Recoded::myToString(_readReverse) + "\n";
381 result += indentation + "- Frame Delay: " + Recoded::myToString(_frameDelay) + "\n";
382 result += indentation + "- Frame Initial: " + Recoded::myToString(_frameInitial) + "\n";
383 result += indentation + "- Current Frame: " + Recoded::myToString(_currentFrameIndex) + "\n";
384 result += indentation + "- Total Frames: " + Recoded::myToString(_totalFrames) + "\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++) {
388 result += indentation + "\t- " + Recoded::myToString(i) + ": " + Recoded::myToString(_frames[i]) + "\n";
389 }
390 result += indentation + "}\n";
391 result += indentation + "Current Rectangle: " + Recoded::myToString(_currentRectangle) + "\n";
392 result += indentation + "Clock: {\n" + _clock.getInfo(indent + 1) + indentation + "}\n";
393 return result;
394}
395
400
402{
403 if (this != &copy) {
404 PRETTY_DEBUG << "The animation component class is different from the current, updating" << std::endl;
405 update(copy);
406 }
407 return *this;
408};
409
411{
412 if (_paused) {
413 PRETTY_INFO << "The animation ticking is paused." << std::endl;
414 return;
415 }
416
417 if (_frames.empty()) {
418 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
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>"
424 );
425 }
426
427 if (_frameInitial > _totalFrames) {
428 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
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)
434 << std::endl;
435 throw CustomExceptions::InvalidIndex(std::to_string(_frameInitial), "0", std::to_string(_totalFrames));
436 }
437
438 if (!_readReverse) {
439 _tickRegular();
440 } else {
441 _tickReverse();
442 }
443}
444
446{
447
448 std::uint32_t nextFrame = _currentFrameIndex - 1;
449
450
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;
453 if (_loop) {
454 PRETTY_INFO << "Looping is enabled, the sprite will thus return to the last frame." << std::endl;
455 nextFrame = _totalFrames - 1;
456 } else {
457 if (_frameInitial > _totalFrames) {
458 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
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)
464 << std::endl;
465 throw CustomExceptions::InvalidIndex(std::to_string(_frameInitial), "0", std::to_string(_totalFrames));
466 }
467 _currentFrameIndex = _frameInitial;
468 }
469 } else {
470 _currentFrameIndex = nextFrame;
471 }
472 _currentRectangle = _frames[_currentFrameIndex];
473
474};
475
477{
478 std::uint32_t nextFrame = _currentFrameIndex + 1;
479
480
481 if (nextFrame >= _totalFrames && !_readReverse) {
482 PRETTY_INFO << "The next frame is positive, resetting counter to the maximum available frames." << std::endl;
483 if (_loop) {
484 PRETTY_INFO << "Looping is enabled, the sprite will thus return to the last frame." << std::endl;
485 nextFrame = 0;
486 } else {
487 if (_frameInitial > _totalFrames) {
488 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
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)
494 << std::endl;
495 throw CustomExceptions::InvalidIndex(std::to_string(_frameInitial), "0", std::to_string(_totalFrames));
496 }
497 _currentFrameIndex = _frameInitial;
498 }
499 } else {
500 _currentFrameIndex = nextFrame;
501 }
502 _currentRectangle = _frames[_currentFrameIndex];
503};
504
505void GUI::ECS::Components::AnimationComponent::_processAnimation(const unsigned int frameWidth, const unsigned int frameHeight, const bool startLeft, const bool startTop, const unsigned int initialFrame, const int endFrame)
506{
507 PRETTY_DEBUG << "User provided values: frameWidth: "
508 << Recoded::myToString(frameWidth)
509 << ", frameHeight: " << Recoded::myToString(frameHeight)
510 << ", starLeft: " << Recoded::myToString(startLeft)
511 << ", startTop: " << Recoded::myToString(startTop)
512 << ", initialFrame: " << Recoded::myToString(initialFrame)
513 << ", endFrame: " << Recoded::myToString(endFrame)
514 << std::endl;
515
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;
520
521 GUI::ECS::Systems::Collision spritesheetSize;
522 std::any textureCapsule = _baseTexture.getTexture();
523 if (!textureCapsule.has_value()) {
524 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
525 << "Texture is not set." << std::endl;
526 throw CustomExceptions::NoTexture("Base texture for the spritesheet animation");
527 }
528 PRETTY_DEBUG << "Getting the texture" << std::endl;
529 std::optional<std::shared_ptr<sf::Texture>> OptionalTexture = Utilities::unCast<std::shared_ptr<sf::Texture>, CustomExceptions::NoTexture>(textureCapsule, true, "Base texture for the spritesheet animation, <std::any , bad cast error>, system error: ");
530 if (!OptionalTexture.has_value()) {
531 PRETTY_ERROR << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' " << "The decasting has failed, skipping the rest of the function" << std::endl;
532 return;
533 }
534 PRETTY_INFO << "Texture Fetched" << 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 << ")"
544 << std::endl;
545 if (frameWidth <= 0) {
546 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
547 << "Frame width must be greater than zero." << std::endl;
549 std::to_string(frameWidth),
550 "1",
551 std::to_string(spritesheetSize.getWidth())
552 );
553 }
554 if (frameHeight <= 0) {
555 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
556 << "Frame height must be greater than zero." << std::endl;
558 std::to_string(frameHeight),
559 "1",
560 std::to_string(spritesheetSize.getHeight())
561 );
562 }
563 if (frameWidth > spritesheetSize.getWidth()) {
564 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
565 << "The frame width is greater than the texture width, "
566 << "frame width: " << frameWidth
567 << "texture width: " << spritesheetSize.getWidth()
568 << std::endl;
570 Recoded::myToString(frameWidth),
571 "0",
572 Recoded::myToString(textureDim.x)
573 );
574 }
575 if (frameHeight > spritesheetSize.getHeight()) {
576 PRETTY_CRITICAL << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
577 << "The frame height is greater than the texture height, "
578 << "frame height: " << frameHeight
579 << "texture height: " << spritesheetSize.getHeight()
580 << std::endl;
582 Recoded::myToString(frameHeight),
583 "0",
584 Recoded::myToString(textureDim.y)
585 );
586 }
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;
590
591 _totalFrames = (columns * rows);
592 PRETTY_DEBUG << "Entity id: '" << Recoded::myToString(getEntityNodeId())
593 << "' "
594 << "Calculated number of frames: '" << Recoded::myToString(_totalFrames)
595 << "', columns: '" << Recoded::myToString(columns)
596 << "', rows: '" << Recoded::myToString(rows)
597 << "', spritesheet height: '"
598 << Recoded::myToString(spritesheetSize.getHeight())
599 << "', spritesheet width: '"
600 << Recoded::myToString(spritesheetSize.getWidth())
601 << "', frame height: '" << frameHeight
602 << "', frame width: '" << frameWidth << "'"
603 << std::endl;
604
605 if (initialFrame < 0 || initialFrame > _totalFrames) {
606 PRETTY_ERROR << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
607 << "Initial frame is out of range, expected at maximum: "
608 << Recoded::myToString(_totalFrames)
609 << ", at minimum: 0, but got: " << Recoded::myToString(initialFrame)
610 << std::endl;
611 throw CustomExceptions::InvalidIndex(std::to_string(initialFrame), "0", std::to_string(_totalFrames - 1));
612 }
613
614 if (endFrame != (-1) && (endFrame < 0 || endFrame > _totalFrames)) {
615 PRETTY_ERROR << "BaseId: '" << Recoded::myToString(getEntityNodeId()) << "' "
616 << "Initial frame is out of range, expected at maximum: "
617 << Recoded::myToString(_totalFrames)
618 << ", at minimum: 0 (or -1), but got: " << Recoded::myToString(endFrame)
619 << std::endl;
620 throw CustomExceptions::InvalidIndex(std::to_string(endFrame), "0 (or -1)", std::to_string(_totalFrames - 1));
621 }
622
623 const short int columUpdater = _getIndexUpdater(startLeft);
624 const short int rowUpdater = _getIndexUpdater(startTop);
625
626 unsigned int posx = 0;
627 unsigned int posy = 0;
628 unsigned int frameCounter = 0;
629
630 if (startTop) {
631 PRETTY_INFO << "The texture is set to be cut from the top." << std::endl;
632 posy = 0;
633 } else {
634 PRETTY_INFO << "The texture is set to be cut from the bottom." << std::endl;
635 posy = rows - 1;
636 }
637
638 PRETTY_INFO << "There are : " << _totalFrames << " in total" << std::endl;
639 PRETTY_DEBUG << "Loop info (begin): startTop: " << Recoded::myToString(startTop)
640 << ", posy: " << Recoded::myToString(posy)
641 << ", rows: " << Recoded::myToString(rows)
642 << ", startLeft: " << Recoded::myToString(startLeft)
643 << ", rowUpdater: " << Recoded::myToString(rowUpdater)
644 << ", posx: " << Recoded::myToString(posx)
645 << ", columns: " << Recoded::myToString(columns)
646 << ", columUpdater: " << Recoded::myToString(columUpdater)
647 << ", frameCounter: " << Recoded::myToString(frameCounter)
648 << ", _continueLoop(startTop, posy, rows): " << Recoded::myToString(_continueLoop(startTop, posy, rows))
649 << ", _continueLoop(startLeft, posx, columns): " << Recoded::myToString(_continueLoop(startLeft, posx, columns))
650 << std::endl;
651 std::pair<int, int> pos{ posy, posx };
652 for (; _continueLoop(startTop, posy, rows); posy += rowUpdater) {
653 posx = (columns - 1);
654 if (startLeft) {
655 PRETTY_INFO << "The texture is set to be cut from the left." << std::endl;
656 posx = 0;
657 }
658 PRETTY_DEBUG << "Loop info (o1): startTop: " << Recoded::myToString(startTop)
659 << ", posy: " << Recoded::myToString(posy)
660 << ", rows: " << Recoded::myToString(rows)
661 << ", startLeft: " << Recoded::myToString(startLeft)
662 << ", rowUpdater: " << Recoded::myToString(rowUpdater)
663 << ", posx: " << Recoded::myToString(posx)
664 << ", columns: " << Recoded::myToString(columns)
665 << ", columUpdater: " << Recoded::myToString(columUpdater)
666 << ", frameCounter: " << Recoded::myToString(frameCounter)
667 << ", _continueLoop(startTop, posy, rows): " << Recoded::myToString(_continueLoop(startTop, posy, rows))
668 << ", _continueLoop(startLeft, posx, columns): " << Recoded::myToString(_continueLoop(startLeft, posx, columns))
669 << std::endl;
670 for (; _continueLoop(startLeft, posx, columns); posx += columUpdater) {
671 PRETTY_DEBUG << "Loop info (o2): startTop: " << Recoded::myToString(startTop)
672 << ", posy: " << Recoded::myToString(posy)
673 << ", rows: " << Recoded::myToString(rows)
674 << ", startLeft: " << Recoded::myToString(startLeft)
675 << ", rowUpdater: " << Recoded::myToString(rowUpdater)
676 << ", posx: " << Recoded::myToString(posx)
677 << ", columns: " << Recoded::myToString(columns)
678 << ", columUpdater: " << Recoded::myToString(columUpdater)
679 << ", frameCounter: " << Recoded::myToString(frameCounter)
680 << ", _continueLoop(startTop, posy, rows): " << Recoded::myToString(_continueLoop(startTop, posy, rows))
681 << ", _continueLoop(startLeft, posx, columns): " << Recoded::myToString(_continueLoop(startLeft, posx, columns))
682 << std::endl;
683 PRETTY_DEBUG << "Processing frame: "
684 << Recoded::myToString(std::pair<unsigned int, unsigned int>({ posx, posy }))
685 << ", index: " << Recoded::myToString(frameCounter)
686 << std::endl;
687 std::pair<int, int> position = {
688 (posx * frameWidth),
689 (posy * frameHeight)
690 };
691 std::pair<int, int> dimension = {
692 frameWidth,
693 frameHeight
694 };
695 Recoded::IntRect viewField(position, dimension);
696 if (frameCounter >= initialFrame && (frameCounter <= endFrame || endFrame == (-1))) {
697 _frames.push_back(viewField);
698 PRETTY_DEBUG << "Adding a new frame : " << Recoded::myToString(viewField) << std::endl;
699 } else {
700 PRETTY_DEBUG << "Skipping frame : " << Recoded::myToString(viewField) << std::endl;
701 }
702 frameCounter++;
703 }
704 }
705 PRETTY_DEBUG << "Loop info (end): startTop: " << Recoded::myToString(startTop)
706 << ", posy: " << Recoded::myToString(posy)
707 << ", rows: " << Recoded::myToString(rows)
708 << ", startLeft: " << Recoded::myToString(startLeft)
709 << ", rowUpdater: " << Recoded::myToString(rowUpdater)
710 << ", posx: " << Recoded::myToString(posx)
711 << ", columns: " << Recoded::myToString(columns)
712 << ", columUpdater: " << Recoded::myToString(columUpdater)
713 << ", frameCounter: " << Recoded::myToString(frameCounter)
714 << ", _continueLoop(startTop, posy, rows): " << Recoded::myToString(_continueLoop(startTop, posy, rows))
715 << ", _continueLoop(startLeft, posx, columns): " << Recoded::myToString(_continueLoop(startLeft, posx, columns))
716 << std::endl;
717 if (_frames.size() > 0) {
718 _frameInitial = 0;
719 _currentFrameIndex = 0;
720 _currentRectangle = _frames[_currentFrameIndex];
721 _totalFrames = _frames.size();
722 }
723 PRETTY_SUCCESS << "The frames have been processed." << std::endl;
724}
725
726const short int GUI::ECS::Components::AnimationComponent::_getIndexUpdater(const bool startBegining) const
727{
728 if (startBegining) {
729 return 1;
730 }
731 return (-1);
732}
733
734const bool GUI::ECS::Components::AnimationComponent::_continueLoop(const bool startBegining, const unsigned int position, const unsigned int maxValue) const
735{
736 if (startBegining) {
737 return (position < maxValue);
738 }
739 return (position > 0);
740}
741
743{
744 os << item.getInfo();
745 return os;
746}
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.
Definition Invalid.hpp:577
This is the class in charge of raising the invalid height error informing the user that the height th...
Definition Invalid.hpp:427
This is the class in charge of informing the user that the index they provided is invalid.
Definition Invalid.hpp:546
This is the class in charge of raising the invalid width error informing the user that the width they...
Definition Invalid.hpp:394
This is the class in charge of informing the user that there are no frames for the animation.
Definition No.hpp:268
This is the class in charge of informing the user that they tried to access a non-existant texture in...
Definition No.hpp:446
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 &copy)
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 &copy)
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.
Definition Clock.hpp:36
Represents a rectangular component that can detect collisions and mouse interactions,...
Definition Collision.hpp:39
const float getWidth() const
Gets the width of the component.
void setDimension(const std::pair< float, float > &dimension)
Set the dimension of the object.
Definition Collision.cpp:95
const float getHeight() const
Gets the height of the component.
A generic 2D rectangle class that holds position and size as pairs.
Definition Rect.hpp:38
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.
Definition Rect.hpp:223
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.
Definition UnCast.hpp:65