diff --git a/core/base/ActionFiniteTime.cpp b/core/base/ActionInterval.cpp similarity index 81% rename from core/base/ActionFiniteTime.cpp rename to core/base/ActionInterval.cpp index 2e9ae017..be3a2988 100644 --- a/core/base/ActionFiniteTime.cpp +++ b/core/base/ActionInterval.cpp @@ -18,7 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "ActionFiniteTime.h" +#include "ActionInterval.h" +#include "Geometry.h" #include "base.hpp" #include "Node.h" #include @@ -26,27 +27,27 @@ namespace easy2d { //------------------------------------------------------- - // FiniteTimeAction + // IntervalAction //------------------------------------------------------- - FiniteTimeAction::FiniteTimeAction(Duration const& duration) + IntervalAction::IntervalAction(Duration const& duration) : process_(0) , duration_(duration) { } - void FiniteTimeAction::Reset() + void IntervalAction::Reset() { Action::Reset(); process_ = 0; } - void FiniteTimeAction::Init(Node* target) + void IntervalAction::Init(Node* target) { Action::Init(target); } - void FiniteTimeAction::Update(Node* target, Duration const& dt) + void IntervalAction::Update(Node* target, Duration const& dt) { Action::Update(target, dt); @@ -73,14 +74,14 @@ namespace easy2d //------------------------------------------------------- MoveBy::MoveBy(Duration const& duration, Point const& vector) - : FiniteTimeAction(duration) + : IntervalAction(duration) { delta_pos_ = vector; } void MoveBy::Init(Node* target) { - FiniteTimeAction::Init(target); + IntervalAction::Init(target); if (target) { @@ -90,7 +91,7 @@ namespace easy2d void MoveBy::Update(Node* target, Duration const& dt) { - FiniteTimeAction::Update(target, dt); + IntervalAction::Update(target, dt); if (target) { @@ -137,7 +138,7 @@ namespace easy2d //------------------------------------------------------- JumpBy::JumpBy(Duration const& duration, Point const& vec, float height, int jumps) - : FiniteTimeAction(duration) + : IntervalAction(duration) , delta_pos_(vec) , height_(height) , jumps_(jumps) @@ -156,7 +157,7 @@ namespace easy2d void JumpBy::Init(Node* target) { - FiniteTimeAction::Init(target); + IntervalAction::Init(target); if (target) { @@ -166,7 +167,7 @@ namespace easy2d void JumpBy::Update(Node* target, Duration const& dt) { - FiniteTimeAction::Update(target, dt); + IntervalAction::Update(target, dt); if (target) { @@ -208,14 +209,14 @@ namespace easy2d //------------------------------------------------------- ScaleBy::ScaleBy(Duration const& duration, float scale) - : FiniteTimeAction(duration) + : IntervalAction(duration) { delta_x_ = scale; delta_y_ = scale; } ScaleBy::ScaleBy(Duration const& duration, float scale_x, float scale_y) - : FiniteTimeAction(duration) + : IntervalAction(duration) { delta_x_ = scale_x; delta_y_ = scale_y; @@ -223,7 +224,7 @@ namespace easy2d void ScaleBy::Init(Node* target) { - FiniteTimeAction::Init(target); + IntervalAction::Init(target); if (target) { @@ -234,7 +235,7 @@ namespace easy2d void ScaleBy::Update(Node* target, Duration const& dt) { - FiniteTimeAction::Update(target, dt); + IntervalAction::Update(target, dt); if (target) { @@ -284,14 +285,14 @@ namespace easy2d //------------------------------------------------------- OpacityBy::OpacityBy(Duration const& duration, float opacity) - : FiniteTimeAction(duration) + : IntervalAction(duration) { delta_val_ = opacity; } void OpacityBy::Init(Node* target) { - FiniteTimeAction::Init(target); + IntervalAction::Init(target); if (target) { @@ -301,7 +302,7 @@ namespace easy2d void OpacityBy::Update(Node* target, Duration const& dt) { - FiniteTimeAction::Update(target, dt); + IntervalAction::Update(target, dt); if (target) { @@ -352,14 +353,14 @@ namespace easy2d //------------------------------------------------------- RotateBy::RotateBy(Duration const& duration, float rotation) - : FiniteTimeAction(duration) + : IntervalAction(duration) , delta_val_(rotation) { } void RotateBy::Init(Node* target) { - FiniteTimeAction::Init(target); + IntervalAction::Init(target); if (target) { @@ -369,7 +370,7 @@ namespace easy2d void RotateBy::Update(Node* target, Duration const& dt) { - FiniteTimeAction::Update(target, dt); + IntervalAction::Update(target, dt); if (target) { @@ -405,6 +406,53 @@ namespace easy2d } + //------------------------------------------------------- + // PathAction + //------------------------------------------------------- + + PathAction::PathAction(Duration const & duration, spGeometry const& geo, bool rotating, float start, float end) + : IntervalAction(duration) + , start_(start) + , end_(end) + , geo_(geo) + , rotating_(rotating) + { + } + + spAction PathAction::Clone() const + { + return new PathAction(duration_, geo_, rotating_, start_, end_); + } + + spAction PathAction::Reverse() const + { + return new PathAction(duration_, geo_, rotating_, end_, start_); + } + + void PathAction::Update(Node * target, Duration const & dt) + { + IntervalAction::Update(target, dt); + + if (target) + { + float percent = std::min(std::max((end_ - start_) * process_ + start_, 0.f), 1.f); + float length = geo_->GetLength() * percent; + Point point, tangent; + if (geo_->ComputePointAt(length, &point, &tangent)) + { + target->SetPosition(point); + + if (rotating_) + { + float ac = math::Acos(tangent.x); + float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; + target->SetRotation(rotation); + } + } + } + } + + //------------------------------------------------------- // Delay //------------------------------------------------------- @@ -447,4 +495,5 @@ namespace easy2d { return new (std::nothrow) Delay(delay_); } + } diff --git a/core/base/ActionFiniteTime.h b/core/base/ActionInterval.h similarity index 90% rename from core/base/ActionFiniteTime.h rename to core/base/ActionInterval.h index 3678b2d2..a8ed619d 100644 --- a/core/base/ActionFiniteTime.h +++ b/core/base/ActionInterval.h @@ -24,24 +24,19 @@ namespace easy2d { - // 持续动作 - class FiniteTimeAction + class IntervalAction : public Action { public: - // 创建特定时长的持续动作 - explicit FiniteTimeAction( + explicit IntervalAction( Duration const& duration ); - // 重置动作 virtual void Reset() override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: @@ -52,7 +47,7 @@ namespace easy2d // 相对位移动作 class MoveBy - : public FiniteTimeAction + : public IntervalAction { public: explicit MoveBy( @@ -67,10 +62,8 @@ namespace easy2d virtual spAction Reverse() const override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: @@ -101,7 +94,6 @@ namespace easy2d } protected: - // 初始化动作 virtual void Init(Node* target) override; protected: @@ -111,7 +103,7 @@ namespace easy2d // 相对跳跃动作 class JumpBy - : public FiniteTimeAction + : public IntervalAction { public: explicit JumpBy( @@ -128,10 +120,8 @@ namespace easy2d virtual spAction Reverse() const override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: @@ -166,7 +156,6 @@ namespace easy2d } protected: - // 初始化动作 virtual void Init(Node* target) override; protected: @@ -176,7 +165,7 @@ namespace easy2d // 相对缩放动作 class ScaleBy - : public FiniteTimeAction + : public IntervalAction { public: explicit ScaleBy( @@ -197,10 +186,8 @@ namespace easy2d virtual spAction Reverse() const override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: @@ -238,7 +225,6 @@ namespace easy2d } protected: - // 初始化动作 virtual void Init(Node* target) override; protected: @@ -249,7 +235,7 @@ namespace easy2d // 透明度相对渐变动作 class OpacityBy - : public FiniteTimeAction + : public IntervalAction { public: explicit OpacityBy( @@ -264,10 +250,8 @@ namespace easy2d virtual spAction Reverse() const override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: @@ -297,7 +281,6 @@ namespace easy2d } protected: - // 初始化动作 virtual void Init(Node* target) override; protected: @@ -331,7 +314,7 @@ namespace easy2d // 相对旋转动作 class RotateBy - : public FiniteTimeAction + : public IntervalAction { public: explicit RotateBy( @@ -346,10 +329,8 @@ namespace easy2d virtual spAction Reverse() const override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: @@ -379,7 +360,6 @@ namespace easy2d } protected: - // 初始化动作 virtual void Init(Node* target) override; protected: @@ -387,6 +367,36 @@ namespace easy2d }; + // 路径动作 + class PathAction + : public IntervalAction + { + public: + explicit PathAction( + Duration const& duration, /* 持续时长 */ + spGeometry const& geo, /* 几何图形 */ + bool rotating = false, /* 沿路径切线方向旋转 */ + float start = 0.f, /* 起点 */ + float end = 1.f /* 终点 */ + ); + + // 获取该动作的拷贝对象 + virtual spAction Clone() const override; + + // 获取该动作的倒转 + virtual spAction Reverse() const override; + + protected: + virtual void Update(Node* target, Duration const& dt) override; + + protected: + bool rotating_; + float start_; + float end_; + spGeometry geo_; + }; + + // 延时动作 class Delay : public Action @@ -406,10 +416,8 @@ namespace easy2d virtual void Reset() override; protected: - // 初始化动作 virtual void Init(Node* target) override; - // 更新动作 virtual void Update(Node* target, Duration const& dt) override; protected: diff --git a/core/base/Geometry.h b/core/base/Geometry.h index e557e892..7ff04aa8 100644 --- a/core/base/Geometry.h +++ b/core/base/Geometry.h @@ -44,16 +44,6 @@ namespace easy2d virtual ~Geometry(); - cpGeometry const& GetD2DGeometry() const { return geo_; } - - float GetLength(); - - bool ComputePointAt( - float length, - Point* point, - Point* tangent - ); - // 判断图形是否包含点 bool ContainsPoint( Point const& point @@ -64,6 +54,18 @@ namespace easy2d spGeometry const& other ); + // 获取图形展开成一条直线的长度 + float GetLength(); + + // 计算图形路径上点的位置和切线向量 + bool ComputePointAt( + float length, + Point* point, + Point* tangent + ); + + cpGeometry const& GetD2DGeometry() const { return geo_; } + protected: cpGeometry geo_; }; diff --git a/core/base/base.hpp b/core/base/base.hpp index bfac55ee..1fa21264 100644 --- a/core/base/base.hpp +++ b/core/base/base.hpp @@ -70,6 +70,7 @@ namespace easy2d E2D_DECLARE_SMART_PTR(FadeOut); E2D_DECLARE_SMART_PTR(RotateBy); E2D_DECLARE_SMART_PTR(RotateTo); + E2D_DECLARE_SMART_PTR(PathAction); E2D_DECLARE_SMART_PTR(Delay); E2D_DECLARE_SMART_PTR(Animation); E2D_DECLARE_SMART_PTR(Animate); diff --git a/core/easy2d.h b/core/easy2d.h index 1c69739d..540b83b3 100644 --- a/core/easy2d.h +++ b/core/easy2d.h @@ -68,7 +68,7 @@ #include "base/Task.h" #include "base/Action.hpp" #include "base/ActionCombined.h" -#include "base/ActionFiniteTime.h" +#include "base/ActionInterval.h" #include "base/Animation.h" #include "base/CallFunc.h" #include "base/Transition.h" diff --git a/core/math/scalar.hpp b/core/math/scalar.hpp index feaf8a82..9ac788cc 100644 --- a/core/math/scalar.hpp +++ b/core/math/scalar.hpp @@ -66,6 +66,18 @@ namespace easy2d inline double Tan(double val) { return ::tan(val * constants::PId / 180.0); } + inline float Asin(float val) { return ::asinf(val) * 180.f / constants::PIf; } + + inline double Asin(double val) { return ::asin(val) * 180.f / constants::PIf; } + + inline float Acos(float val) { return ::acosf(val) * 180.f / constants::PIf; } + + inline double Acos(double val) { return ::acos(val) * 180.f / constants::PIf; } + + inline float Atan(float val) { return ::atanf(val) * 180.f / constants::PIf; } + + inline double Atan(double val) { return ::atan(val) * 180.f / constants::PIf; } + inline float Ceil(float val) { return ::ceil(val); } inline double Ceil(double val) { return ::ceil(val); } diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 26fc37cb..558262b4 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -21,7 +21,7 @@ - + @@ -84,7 +84,7 @@ - + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index af750553..ce4f1897 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -5,9 +5,6 @@ base - - base - base @@ -185,6 +182,9 @@ base + + base + @@ -207,9 +207,6 @@ base - - base - base @@ -330,5 +327,8 @@ base + + base + \ No newline at end of file diff --git a/project/vs2015/Easy2D.vcxproj b/project/vs2015/Easy2D.vcxproj index e1ac5c75..6eb2eb27 100644 --- a/project/vs2015/Easy2D.vcxproj +++ b/project/vs2015/Easy2D.vcxproj @@ -21,7 +21,7 @@ - + @@ -84,7 +84,7 @@ - + diff --git a/project/vs2015/Easy2D.vcxproj.filters b/project/vs2015/Easy2D.vcxproj.filters index af750553..ce4f1897 100644 --- a/project/vs2015/Easy2D.vcxproj.filters +++ b/project/vs2015/Easy2D.vcxproj.filters @@ -5,9 +5,6 @@ base - - base - base @@ -185,6 +182,9 @@ base + + base + @@ -207,9 +207,6 @@ base - - base - base @@ -330,5 +327,8 @@ base + + base + \ No newline at end of file diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 88e98062..4a9c0982 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -21,7 +21,7 @@ - + @@ -84,7 +84,7 @@ - + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index af750553..ce4f1897 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -5,9 +5,6 @@ base - - base - base @@ -185,6 +182,9 @@ base + + base + @@ -207,9 +207,6 @@ base - - base - base @@ -330,5 +327,8 @@ base + + base + \ No newline at end of file