#pragma once #include #include #include #include #include #include #include #include #include namespace extra2d { class Node; struct TweenOptions { TweenEasing easing = TweenEasing::Linear; std::function onStart = nullptr; std::function onUpdate = nullptr; std::function onComplete = nullptr; }; struct TweenProperty { std::optional position; std::optional scale; std::optional rotation; std::optional opacity; std::optional color; }; class TweenAction { public: enum class Type : uint8_t { Interval, Delay, Call, Parallel, }; virtual ~TweenAction() = default; virtual void update(float dt) = 0; virtual bool isFinished() const = 0; virtual float getDuration() const = 0; virtual float getElapsed() const = 0; virtual void reset() = 0; Type getType() const { return type_; } protected: TweenAction(Type type) : type_(type) {} Type type_; }; class Tween { public: using Ptr = std::shared_ptr; using Callback = std::function; explicit Tween(Node *target); Tween(Node *target, const std::string &name); ~Tween(); Tween(const Tween &) = delete; Tween &operator=(const Tween &) = delete; Tween(Tween &&) = default; Tween &operator=(Tween &&) = default; static Tween create(Node *target); static Tween create(Node *target, const std::string &name); Tween &to(float duration, const TweenProperty &props, const TweenOptions &options = {}); Tween &by(float duration, const TweenProperty &props, const TweenOptions &options = {}); Tween &set(const TweenProperty &props); Tween &delay(float seconds); Tween &call(Callback callback); Tween ¶llel(); Tween &endParallel(); Tween &union_(); Tween &repeat(int times); Tween &repeatForever(); Tween &yoyo(bool enabled = true); void start(); void stop(); void pause(); void resume(); void update(float dt); bool isFinished() const; bool isPlaying() const; bool isPaused() const; float getTotalDuration() const; void setName(const std::string &name) { name_ = name; } const std::string &name() const { return name_; } private: Node *target_ = nullptr; std::string name_; std::vector> actions_; size_t currentActionIndex_ = 0; bool playing_ = false; bool paused_ = false; bool finished_ = false; int repeatCount_ = 1; int currentRepeat_ = 0; bool yoyo_ = false; bool reverse_ = false; bool repeatForever_ = false; bool inParallel_ = false; std::vector> parallelActions_; void addAction(std::unique_ptr action); void advanceToNextAction(); void resetAllActions(); }; namespace tween { inline TweenProperty pos(const Vec2 &p) { TweenProperty props; props.position = p; return props; } inline TweenProperty pos(float x, float y) { return pos(Vec2(x, y)); } inline TweenProperty scl(const Vec2 &s) { TweenProperty props; props.scale = s; return props; } inline TweenProperty scl(float s) { return scl(Vec2(s, s)); } inline TweenProperty rot(float degrees) { TweenProperty props; props.rotation = degrees; return props; } inline TweenProperty opa(float opacity) { TweenProperty props; props.opacity = opacity; return props; } inline TweenProperty col(const Color &c) { TweenProperty props; props.color = c; return props; } TweenProperty combine(std::initializer_list props); } // namespace tween } // namespace extra2d