R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
AnimationSystem.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** RTYPE
4** File description:
5** AnimationSystem
6*/
7
8#include "AnimationSystem.hpp"
9
10namespace ecs {
14 void AnimationSystem::update(Registry &registry, float deltaTime) {
15 auto entities = registry.getEntitiesWithMask(this->getComponentMask());
16
17 for (auto entityId : entities) {
18 // Check if entity still has all required components
19 // (entity might have been destroyed/modified by another system)
20 if (!registry.hasComponent<Animation>(entityId) ||
21 !registry.hasComponent<AnimationSet>(entityId) || !registry.hasComponent<Sprite>(entityId)) {
22 continue;
23 }
24
25 // Use try-catch to handle race conditions where entity is destroyed
26 // between the hasComponent check and getComponent call
27 Animation *animation = nullptr;
28 AnimationSet *animationSet = nullptr;
29 Sprite *sprite = nullptr;
30
31 try {
32 animation = &registry.getComponent<Animation>(entityId);
33 animationSet = &registry.getComponent<AnimationSet>(entityId);
34 sprite = &registry.getComponent<Sprite>(entityId);
35 } catch (const std::exception &) {
36 // Entity was destroyed/modified between check and access
37 continue;
38 }
39
40 // Skip if animation is not playing
41 if (!animation->isPlaying()) {
42 continue;
43 }
44
45 // Get the current animation clip
46 const std::string &currentClipName = animation->getCurrentClipName();
47 if (!animationSet->hasClip(currentClipName)) {
48 continue; // Invalid clip name
49 }
50
51 const AnimationClip &clip = *animationSet->getClip(currentClipName);
52 if (clip.frames.empty()) {
53 continue; // No frames in clip
54 }
55
56 // Advance timer
57 float newTimer = animation->getTimer() + deltaTime;
58 animation->setTimer(newTimer);
59
60 // Check if it's time to advance to next frame
61 if (newTimer >= clip.frameDuration) {
62 animation->setTimer(0.0f); // Reset timer
63
64 // Advance to next frame
65 int nextFrame = animation->getCurrentFrameIndex() + 1;
66
67 // Check if we've reached the end of the animation
68 if (nextFrame >= static_cast<int>(clip.frames.size())) {
69 if (clip.loop) {
70 // Loop back to first frame
71 nextFrame = 0;
72 } else {
73 // Stop on last frame
74 nextFrame = static_cast<int>(clip.frames.size()) - 1;
75 animation->setPlaying(false);
76
77 // Transition to next clip if specified
78 if (!clip.nextClip.empty() && animationSet->hasClip(clip.nextClip)) {
79 animation->setCurrentClipName(clip.nextClip);
80 animation->setCurrentFrameIndex(0);
81 animation->setTimer(0.0f);
82 animation->setPlaying(true);
83 continue; // Skip sprite update, will be handled next frame
84 }
85 }
86 }
87
88 animation->setCurrentFrameIndex(nextFrame);
89 }
90
91 // Update sprite to display current frame
92 int frameIndex = animation->getCurrentFrameIndex();
93 if (frameIndex >= 0 && frameIndex < static_cast<int>(clip.frames.size())) {
94 sprite->setSourceRect(clip.frames[frameIndex]);
95 }
96 }
97 }
98
100 return (1ULL << getComponentType<Animation>()) | (1ULL << getComponentType<AnimationSet>()) |
101 (1ULL << getComponentType<Sprite>());
102 }
103} // namespace ecs
Component containing all available animations for an entity.
bool hasClip(const std::string &clipName) const
Check if a clip exists.
const AnimationClip * getClip(const std::string &clipName) const
Get a specific animation clip.
ComponentMask getComponentMask() const override
Gets the component mask for this system.
void update(Registry &registry, float deltaTime) override
Updates all entity animations.
Component managing current animation playback state.
Definition Animation.hpp:21
void setCurrentFrameIndex(int frameIndex)
Set the current frame index.
Definition Animation.hpp:84
std::string getCurrentClipName() const
Get the current animation clip name.
Definition Animation.hpp:42
bool isPlaying() const
Check if animation is playing.
Definition Animation.hpp:60
int getCurrentFrameIndex() const
Get the current frame index.
Definition Animation.hpp:54
void setCurrentClipName(const std::string &clipName)
Set the current animation clip name.
Definition Animation.hpp:72
float getTimer() const
Get the playback timer.
Definition Animation.hpp:48
void setPlaying(bool playing)
Set the playing state.
Definition Animation.hpp:90
void setTimer(float timer)
Set the playback timer.
Definition Animation.hpp:78
Manages entities, their signatures and component type registrations.
Definition Registry.hpp:68
std::vector< Address > getEntitiesWithMask(Signature requiredMask)
Get all entities matching a specific component mask.
Definition Registry.cpp:79
T & getComponent(Address address)
Get a component from an entity.
bool hasComponent(Address address)
Check if an entity has a specific component.
Component representing a visual sprite from a texture.
Definition Sprite.hpp:32
void setSourceRect(Rectangle sourceRect)
Set the source rectangle.
Definition Sprite.hpp:108
Maximum number of distinct component types supported by the Registry.
Definition GameLogic.hpp:26
std::uint64_t ComponentMask
Type alias for component bitmask.
Definition ISystem.hpp:24
Defines a sequence of frames for an animation.
std::string nextClip
Next clip name after completion (optional)
bool loop
Whether animation loops.
float frameDuration
Duration per frame in seconds.
std::vector< Rectangle > frames
Frame rectangles in the texture.