Magic_Game/src/kiwano/2d/action/ActionTween.h

924 lines
22 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 <kiwano/2d/action/Action.h>
#include <kiwano/utils/Logger.h>
namespace kiwano
{
/// \~chinese
/// @brief 缓动函数
using EaseFunc = Function<float(float)>;
/// \~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(ActionTweenEntity);
KGE_DECLARE_SMART_PTR(ActionMoveByEntity);
KGE_DECLARE_SMART_PTR(ActionMoveToEntity);
KGE_DECLARE_SMART_PTR(ActionJumpByEntity);
KGE_DECLARE_SMART_PTR(ActionJumpToEntity);
KGE_DECLARE_SMART_PTR(ActionScaleByEntity);
KGE_DECLARE_SMART_PTR(ActionScaleToEntity);
KGE_DECLARE_SMART_PTR(ActionFadeToEntity);
KGE_DECLARE_SMART_PTR(ActionRotateByEntity);
KGE_DECLARE_SMART_PTR(ActionRotateToEntity);
KGE_DECLARE_SMART_PTR(ActionCustomEntity);
/**
* \addtogroup Actions
* @{
*/
/// \~chinese
/// @brief 补间动画实体
class KGE_API ActionTweenEntity : public ActionEntity
{
public:
/// \~chinese
/// @brief 获取动画时长
Duration GetDuration() const;
/// \~chinese
/// @brief 设置动画时长
void SetDuration(Duration duration);
/// \~chinese
/// @brief 获取动画速度缓动函数
const EaseFunc& GetEaseFunc() const;
/// \~chinese
/// @brief 设置动画速度缓动函数
void SetEaseFunc(const EaseFunc& func);
protected:
ActionTweenEntity();
/// \~chinese
/// @brief 补间动画
/// @param duration 动画时长
/// @param func 动画速度缓动函数
ActionTweenEntity(Duration duration);
void Update(Actor* target, Duration dt) override;
virtual void UpdateTween(Actor* target, float percent) = 0;
void DoClone(ActionTweenEntity* to) const;
private:
Duration dur_;
EaseFunc ease_func_;
};
/// \~chinese
/// @brief 补间动画
class ActionTween : public Action
{
public:
ActionTween() = default;
inline ActionTween(ActionTweenEntityPtr ptr)
{
SetEntity(ptr);
}
/// \~chinese
/// @brief 设置缓动函数
inline ActionTween& Ease(EaseFunc ease)
{
auto tween_ptr = Get();
if (tween_ptr)
tween_ptr->SetEaseFunc(ease);
return (*this);
}
/// \~chinese
/// @brief 获取指针
inline ActionTweenEntity* Get() const
{
return static_cast<ActionTweenEntity*>(Action::Get());
}
/// \~chinese
/// @brief 设置动画实体
inline void SetEntity(ActionTweenEntityPtr tween_ptr)
{
Action::SetEntity(tween_ptr.Get());
}
inline ActionTweenEntity* operator->() const
{
return Get();
}
};
/// \~chinese
/// @brief 相对位移动画
class KGE_API ActionMoveBy : public ActionTween
{
public:
/// \~chinese
/// @brief 创建相对位移动画
/// @param duration 动画时长
/// @param displacement 位移向量
ActionMoveBy(Duration duration, const Vec2& displacement);
};
/// \~chinese
/// @brief 相对位移动画实体
class KGE_API ActionMoveByEntity : public ActionTweenEntity
{
public:
/// \~chinese
/// @brief 创建相对位移动画
/// @param duration 动画时长
/// @param displacement 位移向量
ActionMoveByEntity(Duration duration, const Vec2& displacement);
/// \~chinese
/// @brief 获取位移向量
Vec2 GetDisplacement() const;
/// \~chinese
/// @brief 设置位移向量
void SetDisplacement(const Vec2& displacement);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionMoveByEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionMoveByEntity* 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 ActionTween
{
public:
/// \~chinese
/// @brief 创建位移动画
/// @param duration 动画时长
/// @param distination 目的坐标
ActionMoveTo(Duration duration, const Point& distination);
};
/// \~chinese
/// @brief 位移动画实体
class KGE_API ActionMoveToEntity : public ActionMoveByEntity
{
public:
/// \~chinese
/// @brief 创建位移动画
/// @param duration 动画时长
/// @param distination 目的坐标
ActionMoveToEntity(Duration duration, const Point& distination);
/// \~chinese
/// @brief 获取目的坐标
Point GetDistination() const;
/// \~chinese
/// @brief 设置目的坐标
void SetDistination(const Point& distination);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionMoveToEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionMoveToEntity* Reverse() const override
{
KGE_ERRORF("Reverse() not supported in ActionMoveToEntity");
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 跳跃次数
ActionJumpBy(Duration duration, const Vec2& displacement, float height, int count = 1);
};
/// \~chinese
/// @brief 相对跳跃动画实体
class KGE_API ActionJumpByEntity : public ActionTweenEntity
{
public:
/// \~chinese
/// @brief 创建相对跳跃动画
/// @param duration 动画时长
/// @param displacement 跳跃位移向量
/// @param height 跳跃高度
/// @param count 跳跃次数
ActionJumpByEntity(Duration duration, const Vec2& displacement, float height, int count = 1);
/// \~chinese
/// @brief 获取跳跃位移
Vec2 GetDisplacement() const;
/// \~chinese
/// @brief 获取跳跃高度
float GetJumpHeight() const;
/// \~chinese
/// @brief 获取跳跃次数
int GetJumpCount() const;
/// \~chinese
/// @brief 设置跳跃位移
void SetDisplacement(const Vec2& displacement);
/// \~chinese
/// @brief 设置跳跃高度
void SetJumpHeight(float height);
/// \~chinese
/// @brief 设置跳跃次数
void SetJumpCount(int count);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionJumpByEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionJumpByEntity* 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 ActionTween
{
public:
/// \~chinese
/// @brief 创建跳跃动画
/// @param duration 动画时长
/// @param distination 目的坐标
/// @param height 跳跃高度
/// @param count 跳跃次数
ActionJumpTo(Duration duration, const Point& distination, float height, int count = 1);
};
/// \~chinese
/// @brief 跳跃动画实体
class KGE_API ActionJumpToEntity : public ActionJumpByEntity
{
public:
/// \~chinese
/// @brief 创建跳跃动画
/// @param duration 动画时长
/// @param distination 目的坐标
/// @param height 跳跃高度
/// @param count 跳跃次数
ActionJumpToEntity(Duration duration, const Point& distination, float height, int count = 1);
/// \~chinese
/// @brief 获取目的坐标
Point GetDistination() const;
/// \~chinese
/// @brief 设置目的坐标
void SetDistination(const Point& distination);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionJumpToEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionJumpToEntity* Reverse() const override
{
KGE_ERRORF("Reverse() not supported in ActionJumpToEntity");
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 纵向缩放相对变化值
ActionScaleBy(Duration duration, float scale_x, float scale_y);
/// \~chinese
/// @brief 创建相对缩放动画
/// @param duration 动画时长
/// @param scale 缩放相对变化值
ActionScaleBy(Duration duration, Vec2 scale);
};
/// \~chinese
/// @brief 相对缩放动画实体
class KGE_API ActionScaleByEntity : public ActionTweenEntity
{
public:
/// \~chinese
/// @brief 创建相对缩放动画
/// @param duration 动画时长
/// @param scale_x 横向缩放相对变化值
/// @param scale_y 纵向缩放相对变化值
ActionScaleByEntity(Duration duration, float scale_x, float scale_y);
/// \~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 获取该动画的拷贝对象
ActionScaleByEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionScaleByEntity* 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 ActionTween
{
public:
/// \~chinese
/// @brief 创建缩放动画
/// @param duration 动画时长
/// @param scale_x 横向缩放目标值
/// @param scale_y 纵向缩放目标值
ActionScaleTo(Duration duration, float scale_x, float scale_y);
/// \~chinese
/// @brief 创建缩放动画
/// @param duration 动画时长
/// @param scale 缩放目标值
ActionScaleTo(Duration duration, Vec2 scale);
};
/// \~chinese
/// @brief 缩放动画实体
class KGE_API ActionScaleToEntity : public ActionScaleByEntity
{
public:
/// \~chinese
/// @brief 创建缩放动画
/// @param duration 动画时长
/// @param scale_x 横向缩放目标值
/// @param scale_y 纵向缩放目标值
ActionScaleToEntity(Duration duration, float scale_x, float scale_y);
/// \~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 获取该动画的拷贝对象
ActionScaleToEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionScaleToEntity* Reverse() const override
{
KGE_ERRORF("Reverse() not supported in ActionScaleToEntity");
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 目标透明度
ActionFadeTo(Duration duration, float opacity);
};
/// \~chinese
/// @brief 淡入动画
class KGE_API ActionFadeIn : public ActionTween
{
public:
/// \~chinese
/// @brief 创建淡入动画
/// @param duration 动画时长
ActionFadeIn(Duration duration);
};
/// \~chinese
/// @brief 淡出动画
class KGE_API ActionFadeOut : public ActionTween
{
public:
/// \~chinese
/// @brief 创建淡出动画
/// @param duration 动画时长
ActionFadeOut(Duration duration);
};
/// \~chinese
/// @brief 透明度渐变动画实体
class KGE_API ActionFadeToEntity : public ActionTweenEntity
{
public:
/// \~chinese
/// @brief 创建透明度渐变动画
/// @param duration 动画时长
/// @param opacity 目标透明度
ActionFadeToEntity(Duration duration, float opacity);
/// \~chinese
/// @brief 获取目标透明度
float GetTargetOpacity() const;
/// \~chinese
/// @brief 设置目标透明度
void SetTargetOpacity(float opacity);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionFadeToEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionFadeToEntity* Reverse() const override
{
KGE_ERRORF("Reverse() not supported in ActionFadeToEntity");
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 ActionRotateBy : public ActionTween
{
public:
/// \~chinese
/// @brief 创建相对旋转动画
/// @param duration 动画时长
/// @param rotation 角度相对变化值
ActionRotateBy(Duration duration, float rotation);
};
/// \~chinese
/// @brief 相对旋转动画实体
class KGE_API ActionRotateByEntity : public ActionTweenEntity
{
public:
/// \~chinese
/// @brief 创建相对旋转动画
/// @param duration 动画时长
/// @param rotation 角度相对变化值
ActionRotateByEntity(Duration duration, float rotation);
/// \~chinese
/// @brief 获取角度相对变化值
float GetRotation() const;
/// \~chinese
/// @brief 设置角度相对变化值
void SetRotation(float rotation);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionRotateByEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionRotateByEntity* 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 ActionTween
{
public:
/// \~chinese
/// @brief 创建旋转动画
/// @param duration 动画时长
/// @param rotation 目标角度
ActionRotateTo(Duration duration, float rotation);
};
/// \~chinese
/// @brief 旋转动画实体
class KGE_API ActionRotateToEntity : public ActionRotateByEntity
{
public:
/// \~chinese
/// @brief 创建旋转动画
/// @param duration 动画时长
/// @param rotation 目标角度
ActionRotateToEntity(Duration duration, float rotation);
/// \~chinese
/// @brief 获取目标角度
float GetTargetRotation() const;
/// \~chinese
/// @brief 设置目标角度
void SetTargetRotation(float rotation);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionRotateToEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionRotateToEntity* Reverse() const override
{
KGE_ERRORF("Reverse() not supported in ActionRotateToEntity");
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<void(Actor* /* target */, float /* percent */)>;
/// \~chinese
/// @brief 创建自定义动画
/// @param duration 动画时长
/// @param tween_func 动画回调函数
ActionCustom(Duration duration, TweenFunc tween_func);
};
/// \~chinese
/// @brief 自定义动画实体
class KGE_API ActionCustomEntity : public ActionTweenEntity
{
public:
/// \~chinese
/// @brief 创建自定义动画
/// @param duration 动画时长
/// @param tween_func 动画回调函数
ActionCustomEntity(Duration duration, ActionCustom::TweenFunc tween_func);
/// \~chinese
/// @brief 获取动画回调函数
ActionCustom::TweenFunc GetTweenFunc() const;
/// \~chinese
/// @brief 设置动画回调函数
void SetTweenFunc(const ActionCustom::TweenFunc& tween_func);
/// \~chinese
/// @brief 获取该动画的拷贝对象
ActionCustomEntity* Clone() const override;
/// \~chinese
/// @brief 获取该动画的倒转
ActionCustomEntity* Reverse() const override
{
KGE_ERRORF("Reverse() not supported in ActionCustomEntity");
return nullptr;
}
protected:
void Init(Actor* target) override;
void UpdateTween(Actor* target, float percent) override;
private:
ActionCustom::TweenFunc tween_func_;
};
/** @} */
inline const EaseFunc& ActionTweenEntity::GetEaseFunc() const
{
return ease_func_;
}
inline Duration ActionTweenEntity::GetDuration() const
{
return dur_;
}
inline void ActionTweenEntity::SetDuration(Duration duration)
{
dur_ = duration;
}
inline void ActionTweenEntity::SetEaseFunc(const EaseFunc& func)
{
ease_func_ = func;
}
inline Vec2 ActionMoveByEntity::GetDisplacement() const
{
return displacement_;
}
inline void ActionMoveByEntity::SetDisplacement(const Vec2& displacement)
{
displacement_ = displacement;
}
inline Point ActionMoveToEntity::GetDistination() const
{
return distination_;
}
inline void ActionMoveToEntity::SetDistination(const Point& distination)
{
distination_ = distination;
}
inline Vec2 ActionJumpByEntity::GetDisplacement() const
{
return displacement_;
}
inline float ActionJumpByEntity::GetJumpHeight() const
{
return height_;
}
inline int ActionJumpByEntity::GetJumpCount() const
{
return jump_count_;
}
inline void ActionJumpByEntity::SetDisplacement(const Vec2& displacement)
{
displacement_ = displacement;
}
inline void ActionJumpByEntity::SetJumpHeight(float height)
{
height_ = height;
}
inline void ActionJumpByEntity::SetJumpCount(int count)
{
jump_count_ = count;
}
inline Point ActionJumpToEntity::GetDistination() const
{
return distination_;
}
inline void ActionJumpToEntity::SetDistination(const Point& distination)
{
distination_ = distination;
}
inline float ActionScaleByEntity::GetScaleX() const
{
return delta_x_;
}
inline float ActionScaleByEntity::GetScaleY() const
{
return delta_y_;
}
inline void ActionScaleByEntity::SetScaleX(float scale_x)
{
delta_x_ = scale_x;
}
inline void ActionScaleByEntity::SetScaleY(float scale_y)
{
delta_y_ = scale_y;
}
inline float ActionScaleToEntity::GetTargetScaleX() const
{
return end_scale_x_;
}
inline float ActionScaleToEntity::GetTargetScaleY() const
{
return end_scale_y_;
}
inline void ActionScaleToEntity::SetTargetScaleX(float scale_x)
{
end_scale_x_ = scale_x;
}
inline void ActionScaleToEntity::SetTargetScaleY(float scale_y)
{
end_scale_y_ = scale_y;
}
inline float ActionFadeToEntity::GetTargetOpacity() const
{
return end_val_;
}
inline void ActionFadeToEntity::SetTargetOpacity(float opacity)
{
end_val_ = opacity;
}
inline float ActionRotateByEntity::GetRotation() const
{
return delta_val_;
}
inline void ActionRotateByEntity::SetRotation(float rotation)
{
delta_val_ = rotation;
}
inline float ActionRotateToEntity::GetTargetRotation() const
{
return end_val_;
}
inline void ActionRotateToEntity::SetTargetRotation(float rotation)
{
end_val_ = rotation;
}
inline ActionCustom::TweenFunc ActionCustomEntity::GetTweenFunc() const
{
return tween_func_;
}
inline void ActionCustomEntity::SetTweenFunc(const ActionCustom::TweenFunc& tween_func)
{
tween_func_ = tween_func;
}
} // namespace kiwano