From 50825ba00d44c6d713944c221df6463e7edcb31d Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Thu, 10 May 2018 14:03:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0JumpBy=E5=92=8CJumpTo?= =?UTF-8?q?=E5=8A=A8=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Action/Action.cpp | 2 +- core/Action/ActionGradual.cpp | 6 +- core/Action/Animate.cpp | 38 ++++++--- core/Action/CallFunc.cpp | 2 +- core/Action/Delay.cpp | 4 +- core/Action/JumpBy.cpp | 52 ++++++++++++ core/Action/JumpTo.cpp | 18 +++++ core/Action/Loop.cpp | 51 ++++++++---- core/Action/MoveBy.cpp | 8 +- core/Action/MoveTo.cpp | 6 +- core/Action/OpacityBy.cpp | 8 +- core/Action/OpacityTo.cpp | 6 +- core/Action/RotateBy.cpp | 8 +- core/Action/RotateTo.cpp | 6 +- core/Action/ScaleBy.cpp | 4 +- core/Action/ScaleTo.cpp | 2 +- core/Action/Sequence.cpp | 25 +++--- core/Action/Spawn.cpp | 25 +++--- core/e2daction.h | 110 ++++++++++++++++++++------ project/vs2017/Easy2D.vcxproj | 2 + project/vs2017/Easy2D.vcxproj.filters | 6 ++ 21 files changed, 287 insertions(+), 102 deletions(-) create mode 100644 core/Action/JumpBy.cpp create mode 100644 core/Action/JumpTo.cpp diff --git a/core/Action/Action.cpp b/core/Action/Action.cpp index 0692d64e..a7d0c36b 100644 --- a/core/Action/Action.cpp +++ b/core/Action/Action.cpp @@ -60,7 +60,7 @@ void e2d::Action::setName(const String& name) e2d::Action * e2d::Action::reverse() const { - WARN_IF(true, "Action cannot be reversed!"); + ASSERT(false, "Action cannot be reversed!"); return nullptr; } diff --git a/core/Action/ActionGradual.cpp b/core/Action/ActionGradual.cpp index 872ebede..f86eef70 100644 --- a/core/Action/ActionGradual.cpp +++ b/core/Action/ActionGradual.cpp @@ -14,16 +14,16 @@ void e2d::ActionGradual::_init() void e2d::ActionGradual::_update() { Action::_update(); - // 判断时间间隔是否足够 + if (_duration == 0) { _delta = 1; this->stop(); return; } - // 计算动作进度 + _delta = min((Time::getTotalTime() - _last) / _duration, 1); - // 判断动作是否结束 + if (_delta >= 1) { this->stop(); diff --git a/core/Action/Animate.cpp b/core/Action/Animate.cpp index 1de48a19..adb4368c 100644 --- a/core/Action/Animate.cpp +++ b/core/Action/Animate.cpp @@ -89,26 +89,40 @@ void e2d::Animate::onDestroy() e2d::Animate * e2d::Animate::clone() const { - return new (std::nothrow) Animate(_animation); + if (_animation) + { + return new (std::nothrow) Animate(_animation); + } + else + { + return nullptr; + } } e2d::Animate * e2d::Animate::reverse() const { - auto& oldFrames = _animation->getFrames(); - std::vector frames(oldFrames.size()); - - if (!oldFrames.empty()) + if (_animation) { - for (auto iter = oldFrames.crbegin(), iterCrend = oldFrames.crend(); iter != iterCrend; ++iter) + auto& oldFrames = _animation->getFrames(); + std::vector frames(oldFrames.size()); + + if (!oldFrames.empty()) { - Image* frame = *iter; - if (frame) + for (auto iter = oldFrames.crbegin(), iterCrend = oldFrames.crend(); iter != iterCrend; ++iter) { - frames.push_back(frame); + Image* frame = *iter; + if (frame) + { + frames.push_back(frame); + } } } - } - auto animation = new (std::nothrow) Animation(_animation->getInterval(), frames); - return new (std::nothrow) Animate(animation); + auto animation = new (std::nothrow) Animation(_animation->getInterval(), frames); + return new (std::nothrow) Animate(animation); + } + else + { + return nullptr; + } } diff --git a/core/Action/CallFunc.cpp b/core/Action/CallFunc.cpp index a706e737..4b6f7c6f 100644 --- a/core/Action/CallFunc.cpp +++ b/core/Action/CallFunc.cpp @@ -7,7 +7,7 @@ e2d::CallFunc::CallFunc(const Function& func) : e2d::CallFunc * e2d::CallFunc::clone() const { - return new CallFunc(_func); + return new (std::nothrow) CallFunc(_func); } void e2d::CallFunc::_init() diff --git a/core/Action/Delay.cpp b/core/Action/Delay.cpp index 30ed120b..7afbd0fc 100644 --- a/core/Action/Delay.cpp +++ b/core/Action/Delay.cpp @@ -7,7 +7,7 @@ e2d::Delay::Delay(double duration) e2d::Delay * e2d::Delay::clone() const { - return new Delay(_delay); + return new (std::nothrow) Delay(_delay); } void e2d::Delay::_init() @@ -18,7 +18,7 @@ void e2d::Delay::_init() void e2d::Delay::_update() { Action::_update(); - // 判断时间间隔是否足够 + if ((Time::getTotalTime() - _last) >= _delay) { this->stop(); diff --git a/core/Action/JumpBy.cpp b/core/Action/JumpBy.cpp new file mode 100644 index 00000000..c010fbe6 --- /dev/null +++ b/core/Action/JumpBy.cpp @@ -0,0 +1,52 @@ +#include "..\e2daction.h" + +e2d::JumpBy::JumpBy(double duration, const Vector & vec, double height, int jumps) + : ActionGradual(duration) + , _deltaPos(vec) + , _height(height) + , _jumps(jumps) +{ +} + +e2d::JumpBy * e2d::JumpBy::clone() const +{ + return new (std::nothrow) JumpBy(_duration, _deltaPos, _height, _jumps); +} + +e2d::JumpBy * e2d::JumpBy::reverse() const +{ + return new (std::nothrow) JumpBy(_duration, -_deltaPos, _height, _jumps); +} + +void e2d::JumpBy::_init() +{ + ActionGradual::_init(); + + if (_target) + { + _prevPos = _startPos = _target->getPos(); + } +} + +void e2d::JumpBy::_update() +{ + ActionGradual::_update(); + + if (_target) + { + double frac = fmod(_delta * _jumps, 1.0); + double x = _deltaPos.x * _delta; + double y = _height * 4 * frac * (1 - frac); + y += _deltaPos.y * _delta; + + Point currentPos = _target->getPos(); + + Vector diff = currentPos - _prevPos; + _startPos = diff + _startPos; + + Point newPos = _startPos + Vector(x, y); + _target->setPos(newPos); + + _prevPos = newPos; + } +} diff --git a/core/Action/JumpTo.cpp b/core/Action/JumpTo.cpp new file mode 100644 index 00000000..431b5b01 --- /dev/null +++ b/core/Action/JumpTo.cpp @@ -0,0 +1,18 @@ +#include "..\e2daction.h" + +e2d::JumpTo::JumpTo(double duration, const Point & pos, double height, int jumps) + : JumpBy(duration, Point(), height, jumps) + , _endPos(pos) +{ +} + +e2d::JumpTo * e2d::JumpTo::clone() const +{ + return new (std::nothrow) JumpTo(_duration, _endPos, _height, _jumps); +} + +void e2d::JumpTo::_init() +{ + JumpBy::_init(); + _deltaPos = _endPos - _startPos; +} diff --git a/core/Action/Loop.cpp b/core/Action/Loop.cpp index 4f616de8..e5a6cd59 100644 --- a/core/Action/Loop.cpp +++ b/core/Action/Loop.cpp @@ -6,8 +6,13 @@ e2d::Loop::Loop(Action * action, int times /* = -1 */) , _times(0) , _totalTimes(times) { - ASSERT(_action, "Loop NULL pointer exception!"); - _action->retain(); + ASSERT(action, "Loop NULL pointer exception!"); + + if (action) + { + _action = action; + _action->retain(); + } } e2d::Loop::~Loop() @@ -16,14 +21,25 @@ e2d::Loop::~Loop() e2d::Loop * e2d::Loop::clone() const { - return new Loop(_action->clone()); + if (_action) + { + return new (std::nothrow) Loop(_action->clone()); + } + else + { + return nullptr; + } } void e2d::Loop::_init() { Action::_init(); - _action->_target = _target; - _action->_init(); + + if (_action) + { + _action->_target = _target; + _action->_init(); + } } void e2d::Loop::_update() @@ -36,14 +52,21 @@ void e2d::Loop::_update() return; } - _action->_update(); - - if (_action->_isDone()) + if (_action) { - _times++; - - Action::reset(); - _action->reset(); + _action->_update(); + + if (_action->_isDone()) + { + _times++; + + Action::reset(); + _action->reset(); + } + } + else + { + this->stop(); } } @@ -51,7 +74,7 @@ void e2d::Loop::reset() { Action::reset(); - _action->reset(); + if (_action) _action->reset(); _times = 0; } @@ -63,5 +86,5 @@ void e2d::Loop::onDestroy() void e2d::Loop::_resetTime() { - _action->_resetTime(); + if (_action) _action->_resetTime(); } diff --git a/core/Action/MoveBy.cpp b/core/Action/MoveBy.cpp index 003d8667..916605f4 100644 --- a/core/Action/MoveBy.cpp +++ b/core/Action/MoveBy.cpp @@ -1,8 +1,8 @@ #include "..\e2daction.h" -e2d::MoveBy::MoveBy(double duration, Vector vector) : - ActionGradual(duration) +e2d::MoveBy::MoveBy(double duration, Vector vector) + : ActionGradual(duration) { _deltaPos = vector; } @@ -29,10 +29,10 @@ void e2d::MoveBy::_update() e2d::MoveBy * e2d::MoveBy::clone() const { - return new MoveBy(_duration, _deltaPos); + return new (std::nothrow) MoveBy(_duration, _deltaPos); } e2d::MoveBy * e2d::MoveBy::reverse() const { - return new MoveBy(_duration, -_deltaPos); + return new (std::nothrow) MoveBy(_duration, -_deltaPos); } \ No newline at end of file diff --git a/core/Action/MoveTo.cpp b/core/Action/MoveTo.cpp index 8bff9037..24dc4530 100644 --- a/core/Action/MoveTo.cpp +++ b/core/Action/MoveTo.cpp @@ -1,14 +1,14 @@ #include "..\e2daction.h" -e2d::MoveTo::MoveTo(double duration, Point pos) : - MoveBy(duration, Vector()) +e2d::MoveTo::MoveTo(double duration, Point pos) + : MoveBy(duration, Vector()) { _endPos = pos; } e2d::MoveTo * e2d::MoveTo::clone() const { - return new MoveTo(_duration, _endPos); + return new (std::nothrow) MoveTo(_duration, _endPos); } void e2d::MoveTo::_init() diff --git a/core/Action/OpacityBy.cpp b/core/Action/OpacityBy.cpp index d633f0d7..014ff06c 100644 --- a/core/Action/OpacityBy.cpp +++ b/core/Action/OpacityBy.cpp @@ -1,8 +1,8 @@ #include "..\e2daction.h" -e2d::OpacityBy::OpacityBy(double duration, double opacity) : - ActionGradual(duration) +e2d::OpacityBy::OpacityBy(double duration, double opacity) + : ActionGradual(duration) { _deltaVal = opacity; } @@ -29,10 +29,10 @@ void e2d::OpacityBy::_update() e2d::OpacityBy * e2d::OpacityBy::clone() const { - return new OpacityBy(_duration, _deltaVal); + return new (std::nothrow) OpacityBy(_duration, _deltaVal); } e2d::OpacityBy * e2d::OpacityBy::reverse() const { - return new OpacityBy(_duration, -_deltaVal); + return new (std::nothrow) OpacityBy(_duration, -_deltaVal); } \ No newline at end of file diff --git a/core/Action/OpacityTo.cpp b/core/Action/OpacityTo.cpp index e70bd77e..673f7345 100644 --- a/core/Action/OpacityTo.cpp +++ b/core/Action/OpacityTo.cpp @@ -1,15 +1,15 @@ #include "..\e2daction.h" -e2d::OpacityTo::OpacityTo(double duration, double opacity) : - OpacityBy(duration, 0) +e2d::OpacityTo::OpacityTo(double duration, double opacity) + : OpacityBy(duration, 0) { _endVal = opacity; } e2d::OpacityTo * e2d::OpacityTo::clone() const { - return new OpacityTo(_duration, _endVal); + return new (std::nothrow) OpacityTo(_duration, _endVal); } void e2d::OpacityTo::_init() diff --git a/core/Action/RotateBy.cpp b/core/Action/RotateBy.cpp index c40f0e8c..eb294ffe 100644 --- a/core/Action/RotateBy.cpp +++ b/core/Action/RotateBy.cpp @@ -1,8 +1,8 @@ #include "..\e2daction.h" -e2d::RotateBy::RotateBy(double duration, double rotation) : - ActionGradual(duration) +e2d::RotateBy::RotateBy(double duration, double rotation) + : ActionGradual(duration) { _deltaVal = rotation; } @@ -29,10 +29,10 @@ void e2d::RotateBy::_update() e2d::RotateBy * e2d::RotateBy::clone() const { - return new RotateBy(_duration, _deltaVal); + return new (std::nothrow) RotateBy(_duration, _deltaVal); } e2d::RotateBy * e2d::RotateBy::reverse() const { - return new RotateBy(_duration, -_deltaVal); + return new (std::nothrow) RotateBy(_duration, -_deltaVal); } \ No newline at end of file diff --git a/core/Action/RotateTo.cpp b/core/Action/RotateTo.cpp index 60dfd09e..3726cd0c 100644 --- a/core/Action/RotateTo.cpp +++ b/core/Action/RotateTo.cpp @@ -1,15 +1,15 @@ #include "..\e2daction.h" -e2d::RotateTo::RotateTo(double duration, double rotation) : - RotateBy(duration, 0) +e2d::RotateTo::RotateTo(double duration, double rotation) + : RotateBy(duration, 0) { _endVal = rotation; } e2d::RotateTo * e2d::RotateTo::clone() const { - return new RotateTo(_duration, _endVal); + return new (std::nothrow) RotateTo(_duration, _endVal); } void e2d::RotateTo::_init() diff --git a/core/Action/ScaleBy.cpp b/core/Action/ScaleBy.cpp index fe703372..88e42c0e 100644 --- a/core/Action/ScaleBy.cpp +++ b/core/Action/ScaleBy.cpp @@ -38,10 +38,10 @@ void e2d::ScaleBy::_update() e2d::ScaleBy * e2d::ScaleBy::clone() const { - return new ScaleBy(_duration, _deltaX, _deltaY); + return new (std::nothrow) ScaleBy(_duration, _deltaX, _deltaY); } e2d::ScaleBy * e2d::ScaleBy::reverse() const { - return new ScaleBy(_duration, -_deltaX, -_deltaY); + return new (std::nothrow) ScaleBy(_duration, -_deltaX, -_deltaY); } \ No newline at end of file diff --git a/core/Action/ScaleTo.cpp b/core/Action/ScaleTo.cpp index b4d4df23..0c004efb 100644 --- a/core/Action/ScaleTo.cpp +++ b/core/Action/ScaleTo.cpp @@ -16,7 +16,7 @@ e2d::ScaleTo::ScaleTo(double duration, double scaleX, double scaleY) e2d::ScaleTo * e2d::ScaleTo::clone() const { - return new ScaleTo(_duration, _endScaleX, _endScaleY); + return new (std::nothrow) ScaleTo(_duration, _endScaleX, _endScaleY); } void e2d::ScaleTo::_init() diff --git a/core/Action/Sequence.cpp b/core/Action/Sequence.cpp index f677b63c..cecdd440 100644 --- a/core/Action/Sequence.cpp +++ b/core/Action/Sequence.cpp @@ -130,22 +130,27 @@ void e2d::Sequence::add(const std::initializer_list& actions) e2d::Sequence * e2d::Sequence::clone() const { - auto a = new Sequence(); - for (auto action : _actions) + auto sequence = new (std::nothrow) Sequence(); + for (const auto& action : _actions) { - a->add(action->clone()); + if (action) + { + sequence->add(action->clone()); + } } - return a; + return sequence; } e2d::Sequence * e2d::Sequence::reverse() const { - auto a = new Sequence(); - for (auto action : _actions) + auto sequence = new (std::nothrow) Sequence(); + for (const auto& action : _actions) { - a->add(action->reverse()); + if (action) + { + sequence->add(action->reverse()); + } } - // 将动作顺序逆序排列 - a->_actions.reserve(_actions.size()); - return a; + sequence->_actions.reserve(_actions.size()); + return sequence; } \ No newline at end of file diff --git a/core/Action/Spawn.cpp b/core/Action/Spawn.cpp index 5c888d9e..0e3b2c2a 100644 --- a/core/Action/Spawn.cpp +++ b/core/Action/Spawn.cpp @@ -127,22 +127,27 @@ void e2d::Spawn::add(const std::initializer_list& actions) e2d::Spawn * e2d::Spawn::clone() const { - auto a = new Spawn(); - for (auto action : _actions) + auto spawn = new (std::nothrow) Spawn(); + for (const auto& action : _actions) { - a->add(action->clone()); + if (action) + { + spawn->add(action->clone()); + } } - return a; + return spawn; } e2d::Spawn * e2d::Spawn::reverse() const { - auto a = new Spawn(); - for (auto action : _actions) + auto spawn = new (std::nothrow) Spawn(); + for (const auto& action : _actions) { - a->add(action->reverse()); + if (action) + { + spawn->add(action->reverse()); + } } - // 将动作顺序逆序排列 - a->_actions.reserve(_actions.size()); - return a; + spawn->_actions.reserve(_actions.size()); + return spawn; } \ No newline at end of file diff --git a/core/e2daction.h b/core/e2daction.h index d6bc1019..5206db66 100644 --- a/core/e2daction.h +++ b/core/e2daction.h @@ -64,7 +64,7 @@ protected: // 初始化动作 virtual void _init(); - // 执行动作 + // 更新动作 virtual void _update(); // 获取动作结束状态 @@ -118,8 +118,8 @@ class MoveBy : public: // 创建相对位移动作 MoveBy( - double duration, /* 动作持续时长 */ - Vector vector /* 位移向量 */ + double duration, /* 持续时长 */ + Vector vector /* 移动距离 */ ); // 获取该动作的拷贝对象 @@ -132,7 +132,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: @@ -148,8 +148,8 @@ class MoveTo : public: // 创建位移动作 MoveTo( - double duration, /* 动作持续时长 */ - Point pos /* 位移至目标点的坐标 */ + double duration, /* 持续时长 */ + Point pos /* 目的坐标 */ ); // 获取该动作的拷贝对象 @@ -164,6 +164,66 @@ protected: }; +// 相对跳跃动作 +class JumpBy : + public ActionGradual +{ +public: + // 创建相对跳跃动作 + JumpBy( + double duration, /* 持续时长 */ + const Vector& vec, /* 跳跃距离 */ + double height, /* 跳跃高度 */ + int jumps /* 跳跃次数 */ + ); + + // 获取该动作的拷贝对象 + virtual JumpBy * clone() const override; + + // 获取该动作的倒转 + virtual JumpBy * reverse() const override; + +protected: + // 初始化动作 + virtual void _init() override; + + // 更新动作 + virtual void _update() override; + +protected: + Point _startPos; + Vector _deltaPos; + double _height; + int _jumps; + Point _prevPos; +}; + + +// 跳跃动作 +class JumpTo : + public JumpBy +{ +public: + // 创建位移动作 + JumpTo( + double duration, /* 持续时长 */ + const Point& pos, /* 目的坐标 */ + double height, /* 跳跃高度 */ + int jumps /* 跳跃次数 */ + ); + + // 获取该动作的拷贝对象 + virtual JumpTo * clone() const override; + +protected: + // 初始化动作 + virtual void _init() override; + +protected: + Point _endPos; +}; + + // 相对缩放动作 class ScaleBy : public ActionGradual @@ -171,13 +231,13 @@ class ScaleBy : public: // 创建相对缩放动作 ScaleBy( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double scale /* 缩放比例变化 */ ); // 创建相对缩放动作 ScaleBy( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double scaleX, /* 横向缩放比例变化 */ double scaleY /* 纵向缩放比例变化 */ ); @@ -192,7 +252,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: @@ -210,13 +270,13 @@ class ScaleTo : public: // 创建缩放动作 ScaleTo( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double scale /* 缩放至目标比例 */ ); // 创建缩放动作 ScaleTo( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double scaleX, /* 横向缩放至目标比例 */ double scaleY /* 纵向缩放至目标比例 */ ); @@ -241,7 +301,7 @@ class OpacityBy : public: // 创建透明度相对渐变动作 OpacityBy( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double opacity /* 透明度相对变化值 */ ); @@ -255,7 +315,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: @@ -271,7 +331,7 @@ class OpacityTo : public: // 创建透明度渐变动作 OpacityTo( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double opacity /* 透明度渐变至目标值 */ ); @@ -294,7 +354,7 @@ class FadeIn : public: // 创建淡入动作 FadeIn( - double duration /* 动作持续时长 */ + double duration /* 持续时长 */ ) : OpacityTo(duration, 1) { @@ -309,7 +369,7 @@ class FadeOut : public: // 创建淡出动作 FadeOut( - double duration /* 动作持续时长 */ + double duration /* 持续时长 */ ) : OpacityTo(duration, 0) { @@ -324,7 +384,7 @@ class RotateBy : public: // 创建相对旋转动作 RotateBy( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double rotation /* 旋转角度变化值 */ ); @@ -338,7 +398,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: @@ -354,7 +414,7 @@ class RotateTo : public: // 创建旋转动作 RotateTo( - double duration, /* 动作持续时长 */ + double duration, /* 持续时长 */ double rotation /* 旋转角度至目标值 */ ); @@ -387,7 +447,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: @@ -421,7 +481,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; // 重置动作时间 @@ -451,7 +511,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: @@ -518,7 +578,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; // 重置动作时间 @@ -589,7 +649,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; // 重置动作时间 @@ -639,7 +699,7 @@ protected: // 初始化动作 virtual void _init() override; - // 执行动作 + // 更新动作 virtual void _update() override; protected: diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index 53fd96a5..e7723655 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -199,6 +199,8 @@ + + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 6469e08a..ace9416f 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -216,6 +216,12 @@ Common + + Action + + + Action +