// Copyright (c) 2016-2018 Kiwano - Nomango // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #pragma once #include #include namespace kiwano { /// \~chinese /// @brief 缓动函数 using EaseFunc = Function; /// \~chinese /// @brief 缓动函数枚举 /// @details 查看 https://easings.net 获取更多信息 struct Ease { static KGE_API EaseFunc Linear; ///< 线性 static KGE_API EaseFunc EaseIn; ///< 由慢变快 static KGE_API EaseFunc EaseOut; ///< 由快变慢 static KGE_API EaseFunc EaseInOut; ///< 由慢变快, 再由快变慢 static KGE_API EaseFunc ExpoIn; ///< 由慢变极快 static KGE_API EaseFunc ExpoOut; ///< 由极快变慢 static KGE_API EaseFunc ExpoInOut; ///< 由慢至极快, 再由极快边慢 static KGE_API EaseFunc ElasticIn; ///< 自起点赋予弹性 static KGE_API EaseFunc ElasticOut; ///< 自终点赋予弹性 static KGE_API EaseFunc ElasticInOut; ///< 再起点和终点赋予弹性 static KGE_API EaseFunc BounceIn; ///< 自起点赋予反弹力 static KGE_API EaseFunc BounceOut; ///< 自终点赋予反弹力 static KGE_API EaseFunc BounceInOut; ///< 在起点和终点赋予反弹力 static KGE_API EaseFunc BackIn; static KGE_API EaseFunc BackOut; static KGE_API EaseFunc BackInOut; static KGE_API EaseFunc QuadIn; static KGE_API EaseFunc QuadOut; static KGE_API EaseFunc QuadInOut; static KGE_API EaseFunc CubicIn; static KGE_API EaseFunc CubicOut; static KGE_API EaseFunc CubicInOut; static KGE_API EaseFunc QuartIn; static KGE_API EaseFunc QuartOut; static KGE_API EaseFunc QuartInOut; static KGE_API EaseFunc QuintIn; static KGE_API EaseFunc QuintOut; static KGE_API EaseFunc QuintInOut; static KGE_API EaseFunc SineIn; static KGE_API EaseFunc SineOut; static KGE_API EaseFunc SineInOut; }; KGE_DECLARE_SMART_PTR(ActionTween); KGE_DECLARE_SMART_PTR(ActionMoveBy); KGE_DECLARE_SMART_PTR(ActionMoveTo); KGE_DECLARE_SMART_PTR(ActionJumpBy); KGE_DECLARE_SMART_PTR(ActionJumpTo); KGE_DECLARE_SMART_PTR(ActionScaleBy); KGE_DECLARE_SMART_PTR(ActionScaleTo); KGE_DECLARE_SMART_PTR(ActionFadeTo); KGE_DECLARE_SMART_PTR(ActionFadeIn); KGE_DECLARE_SMART_PTR(ActionFadeOut); KGE_DECLARE_SMART_PTR(ActionRotateBy); KGE_DECLARE_SMART_PTR(ActionRotateTo); KGE_DECLARE_SMART_PTR(ActionCustom); /** * \addtogroup Actions * @{ */ /// \~chinese /// @brief 补间动画 class KGE_API ActionTween : public Action { public: ActionTween(); /// \~chinese /// @brief 补间动画 /// @param duration 动画时长 /// @param func 动画速度缓动函数 ActionTween(Duration duration, EaseFunc ease); /// \~chinese /// @brief 获取动画时长 Duration GetDuration() const; /// \~chinese /// @brief 设置动画时长 void SetDuration(Duration duration); /// \~chinese /// @brief 获取动画速度缓动函数 EaseFunc const& GetEaseFunc() const; /// \~chinese /// @brief 设置动画速度缓动函数 void SetEaseFunc(EaseFunc const& func); protected: void Update(Actor* target, Duration dt) override; virtual void UpdateTween(Actor* target, float percent) = 0; private: Duration dur_; EaseFunc ease_func_; }; /// \~chinese /// @brief 相对位移动画 class KGE_API ActionMoveBy : public ActionTween { public: /// \~chinese /// @brief 创建相对位移动画 /// @param duration 动画时长 /// @param displacement 位移向量 static ActionMoveByPtr Create(Duration duration, Vec2 const& displacement); ActionMoveBy(); /// \~chinese /// @brief 获取位移向量 Vec2 GetDisplacement() const; /// \~chinese /// @brief 设置位移向量 void SetDisplacement(Vec2 const& displacement); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 ActionPtr Reverse() const override; protected: void Init(Actor* target) override; void UpdateTween(Actor* target, float percent) override; protected: Point start_pos_; Point prev_pos_; Vec2 displacement_; }; /// \~chinese /// @brief 位移动画 class KGE_API ActionMoveTo : public ActionMoveBy { public: /// \~chinese /// @brief 创建位移动画 /// @param duration 动画时长 /// @param distination 目的坐标 static ActionMoveToPtr Create(Duration duration, Point const& distination); ActionMoveTo(); /// \~chinese /// @brief 获取目的坐标 Point GetDistination() const; /// \~chinese /// @brief 设置目的坐标 void SetDistination(Point const& distination); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 virtual ActionPtr Reverse() const override { KGE_ERROR("Reverse() not supported in ActionMoveTo"); return nullptr; } protected: void Init(Actor* target) override; private: Point distination_; }; /// \~chinese /// @brief 相对跳跃动画 class KGE_API ActionJumpBy : public ActionTween { public: /// \~chinese /// @brief 创建相对跳跃动画 /// @param duration 动画时长 /// @param displacement 跳跃位移向量 /// @param height 跳跃高度 /// @param count 跳跃次数 static ActionJumpByPtr Create(Duration duration, Vec2 const& displacement, float height, int count = 1, EaseFunc ease = nullptr); ActionJumpBy(); /// \~chinese /// @brief 获取跳跃位移 Vec2 GetDisplacement() const; /// \~chinese /// @brief 获取跳跃高度 float GetJumpHeight() const; /// \~chinese /// @brief 获取跳跃次数 int GetJumpCount() const; /// \~chinese /// @brief 设置跳跃位移 void SetDisplacement(Vec2 const& displacement); /// \~chinese /// @brief 设置跳跃高度 void SetJumpHeight(float height); /// \~chinese /// @brief 设置跳跃次数 void SetJumpCount(int count); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 ActionPtr Reverse() const override; protected: void Init(Actor* target) override; void UpdateTween(Actor* target, float percent) override; protected: float height_; int jump_count_; Point start_pos_; Point displacement_; Point prev_pos_; }; /// \~chinese /// @brief 跳跃动画 class KGE_API ActionJumpTo : public ActionJumpBy { public: /// \~chinese /// @brief 创建跳跃动画 /// @param duration 动画时长 /// @param distination 目的坐标 /// @param height 跳跃高度 /// @param count 跳跃次数 static ActionJumpToPtr Create(Duration duration, Point const& distination, float height, int count = 1, EaseFunc ease = nullptr); ActionJumpTo(); /// \~chinese /// @brief 获取目的坐标 Point GetDistination() const; /// \~chinese /// @brief 设置目的坐标 void SetDistination(Point const& distination); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 virtual ActionPtr Reverse() const override { KGE_ERROR("Reverse() not supported in ActionJumpTo"); return nullptr; } protected: void Init(Actor* target) override; private: Point distination_; }; /// \~chinese /// @brief 相对缩放动画 class KGE_API ActionScaleBy : public ActionTween { public: /// \~chinese /// @brief 创建相对缩放动画 /// @param duration 动画时长 /// @param scale_x 横向缩放相对变化值 /// @param scale_y 纵向缩放相对变化值 static ActionScaleByPtr Create(Duration duration, float scale_x, float scale_y); ActionScaleBy(); /// \~chinese /// @brief 获取横向缩放相对变化值 float GetScaleX() const; /// \~chinese /// @brief 获取横向缩放相对变化值 float GetScaleY() const; /// \~chinese /// @brief 设置纵向缩放相对变化值 void SetScaleX(float scale_x); /// \~chinese /// @brief 设置纵向缩放相对变化值 void SetScaleY(float scale_y); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 ActionPtr Reverse() const override; protected: void Init(Actor* target) override; void UpdateTween(Actor* target, float percent) override; protected: float start_scale_x_; float start_scale_y_; float delta_x_; float delta_y_; }; /// \~chinese /// @brief 缩放动画 class KGE_API ActionScaleTo : public ActionScaleBy { public: /// \~chinese /// @brief 创建缩放动画 /// @param duration 动画时长 /// @param scale_x 横向缩放目标值 /// @param scale_y 纵向缩放目标值 static ActionScaleToPtr Create(Duration duration, float scale_x, float scale_y); ActionScaleTo(); /// \~chinese /// @brief 获取横向缩放目标值 float GetTargetScaleX() const; /// \~chinese /// @brief 获取横向缩放目标值 float GetTargetScaleY() const; /// \~chinese /// @brief 设置纵向缩放目标值 void SetTargetScaleX(float scale_x); /// \~chinese /// @brief 设置纵向缩放目标值 void SetTargetScaleY(float scale_y); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 virtual ActionPtr Reverse() const override { KGE_ERROR("Reverse() not supported in ActionScaleTo"); return nullptr; } protected: void Init(Actor* target) override; private: float end_scale_x_; float end_scale_y_; }; /// \~chinese /// @brief 透明度渐变动画 class KGE_API ActionFadeTo : public ActionTween { public: /// \~chinese /// @brief 创建透明度渐变动画 /// @param duration 动画时长 /// @param opacity 目标透明度 static ActionFadeToPtr Create(Duration duration, float opacity); ActionFadeTo(); /// \~chinese /// @brief 获取目标透明度 float GetTargetOpacity() const; /// \~chinese /// @brief 设置目标透明度 void SetTargetOpacity(float opacity); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 virtual ActionPtr Reverse() const override { KGE_ERROR("Reverse() not supported in ActionFadeTo"); return nullptr; } protected: void Init(Actor* target) override; void UpdateTween(Actor* target, float percent) override; private: float start_val_; float delta_val_; float end_val_; }; /// \~chinese /// @brief 淡入动画 class KGE_API ActionFadeIn : public ActionFadeTo { public: /// \~chinese /// @brief 创建淡入动画 /// @param duration 动画时长 static ActionFadeInPtr Create(Duration duration); }; /// \~chinese /// @brief 淡出动画 class KGE_API ActionFadeOut : public ActionFadeTo { public: /// \~chinese /// @brief 创建淡出动画 /// @param duration 动画时长 static ActionFadeOutPtr Create(Duration duration); }; /// \~chinese /// @brief 相对旋转动画 class KGE_API ActionRotateBy : public ActionTween { public: /// \~chinese /// @brief 创建相对旋转动画 /// @param duration 动画时长 /// @param rotation 角度相对变化值 static ActionRotateByPtr Create(Duration duration, float rotation); ActionRotateBy(); /// \~chinese /// @brief 获取角度相对变化值 float GetRotation() const; /// \~chinese /// @brief 设置角度相对变化值 void SetRotation(float rotation); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 ActionPtr Reverse() const override; protected: void Init(Actor* target) override; void UpdateTween(Actor* target, float percent) override; protected: float start_val_; float delta_val_; }; /// \~chinese /// @brief 旋转动画 class KGE_API ActionRotateTo : public ActionRotateBy { public: /// \~chinese /// @brief 创建旋转动画 /// @param duration 动画时长 /// @param rotation 目标角度 static ActionRotateToPtr Create(Duration duration, float rotation); ActionRotateTo(); /// \~chinese /// @brief 获取目标角度 float GetTargetRotation() const; /// \~chinese /// @brief 设置目标角度 void SetTargetRotation(float rotation); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 virtual ActionPtr Reverse() const override { KGE_ERROR("Reverse() not supported in ActionRotateTo"); return nullptr; } protected: void Init(Actor* target) override; private: float end_val_; }; /// \~chinese /// @brief 自定义动画 class KGE_API ActionCustom : public ActionTween { public: /// \~chinese /// @brief 动画回调函数 /// @details 在动画更新时回调该函数,第一个参数是执行动画的目标,第二个参数是动画进度(0.0 - 1.0) using TweenFunc = Function; /// \~chinese /// @brief 创建自定义动画 /// @param duration 动画时长 /// @param tween_func 动画回调函数 static ActionCustomPtr Create(Duration duration, TweenFunc tween_func); ActionCustom(); /// \~chinese /// @brief 获取动画回调函数 TweenFunc GetTweenFunc() const; /// \~chinese /// @brief 设置动画回调函数 void SetTweenFunc(TweenFunc const& tween_func); /// \~chinese /// @brief 获取该动画的拷贝对象 ActionPtr Clone() const override; /// \~chinese /// @brief 获取该动画的倒转 ActionPtr Reverse() const override { KGE_ERROR("Reverse() not supported in ActionCustom"); return nullptr; } protected: void Init(Actor* target) override; void UpdateTween(Actor* target, float percent) override; private: TweenFunc tween_func_; }; /** @} */ inline EaseFunc const& ActionTween::GetEaseFunc() const { return ease_func_; } inline Duration ActionTween::GetDuration() const { return dur_; } inline void ActionTween::SetDuration(Duration duration) { dur_ = duration; } inline void ActionTween::SetEaseFunc(EaseFunc const& func) { ease_func_ = func; } inline Vec2 ActionMoveBy::GetDisplacement() const { return displacement_; } inline void ActionMoveBy::SetDisplacement(Vec2 const& displacement) { displacement_ = displacement; } inline Point ActionMoveTo::GetDistination() const { return distination_; } inline void ActionMoveTo::SetDistination(Point const& distination) { distination_ = distination; } inline Vec2 ActionJumpBy::GetDisplacement() const { return displacement_; } inline float ActionJumpBy::GetJumpHeight() const { return height_; } inline int ActionJumpBy::GetJumpCount() const { return jump_count_; } inline void ActionJumpBy::SetDisplacement(Vec2 const& displacement) { displacement_ = displacement; } inline void ActionJumpBy::SetJumpHeight(float height) { height_ = height; } inline void ActionJumpBy::SetJumpCount(int count) { jump_count_ = count; } inline Point ActionJumpTo::GetDistination() const { return distination_; } inline void ActionJumpTo::SetDistination(Point const& distination) { distination_ = distination; } inline float ActionScaleBy::GetScaleX() const { return delta_x_; } inline float ActionScaleBy::GetScaleY() const { return delta_y_; } inline void ActionScaleBy::SetScaleX(float scale_x) { delta_x_ = scale_x; } inline void ActionScaleBy::SetScaleY(float scale_y) { delta_y_ = scale_y; } inline float ActionScaleTo::GetTargetScaleX() const { return end_scale_x_; } inline float ActionScaleTo::GetTargetScaleY() const { return end_scale_y_; } inline void ActionScaleTo::SetTargetScaleX(float scale_x) { end_scale_x_ = scale_x; } inline void ActionScaleTo::SetTargetScaleY(float scale_y) { end_scale_y_ = scale_y; } inline float ActionFadeTo::GetTargetOpacity() const { return end_val_; } inline void ActionFadeTo::SetTargetOpacity(float opacity) { end_val_ = opacity; } inline float ActionRotateBy::GetRotation() const { return delta_val_; } inline void ActionRotateBy::SetRotation(float rotation) { delta_val_ = rotation; } inline float ActionRotateTo::GetTargetRotation() const { return end_val_; } inline void ActionRotateTo::SetTargetRotation(float rotation) { end_val_ = rotation; } inline ActionCustom::TweenFunc ActionCustom::GetTweenFunc() const { return tween_func_; } inline void ActionCustom::SetTweenFunc(TweenFunc const& tween_func) { tween_func_ = tween_func; } } // namespace kiwano