diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index c1e30927..15b16ac8 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -1,20 +1,19 @@  - - - - - - - - - - - + + + + + + + + + + @@ -93,8 +92,6 @@ - - @@ -121,18 +118,18 @@ - - - - - - - - - + + + + + + + + + @@ -179,8 +176,6 @@ - - diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index b7a6e769..d8d8d42d 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -16,9 +16,6 @@ {2e18d99a-e906-499a-9e29-4e0783202644} - - {9314f30d-5742-48b6-94e5-e3b4284106f6} - {e84dcf9a-e650-473e-8c9c-193804ab9e76} @@ -38,7 +35,7 @@ {d15f4de1-7c2c-40d6-a3ce-68860b95a61e} - {254c8f6b-8a27-4241-bae1-39cee771ccde} + {9314f30d-5742-48b6-94e5-e3b4284106f6} @@ -75,15 +72,6 @@ 2d - - 2d\action - - - 2d\action - - - 2d\action - utils @@ -93,12 +81,6 @@ 2d - - 2d\action - - - 2d\action - utils @@ -258,12 +240,6 @@ core - - render - - - render - utils @@ -285,9 +261,6 @@ utils - - 2d\action - render\DirectX @@ -345,9 +318,6 @@ core - - 2d\action - base @@ -372,24 +342,42 @@ core - - 2d\animation - 2d\animation 2d\animation - + 2d\animation - + + 2d\animation + + + 2d\animation + + 2d\animation 2d\animation + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + @@ -413,15 +401,6 @@ 2d - - 2d\action - - - 2d\action - - - 2d\action - utils @@ -431,12 +410,6 @@ 2d - - 2d\action - - - 2d\action - utils @@ -539,12 +512,6 @@ core - - render - - - render - utils @@ -560,9 +527,6 @@ utils - - 2d\action - utils @@ -608,9 +572,6 @@ utils - - 2d\action - base @@ -626,18 +587,39 @@ core - - 2d\animation - 2d\animation 2d\animation + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + 2d\animation + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index e1ded17a..ebdfb9ee 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -70,7 +70,7 @@ Actor::~Actor() void Actor::Update(Duration dt) { - ActionScheduler::Update(this, dt); + Animator::Update(this, dt); TaskScheduler::Update(dt); ComponentManager::Update(dt); diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index 3a81048d..a06619b4 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include namespace kiwano { @@ -62,8 +62,8 @@ typedef IntrusiveList ActorList; */ class KGE_API Actor : public ObjectBase + , public Animator , public TaskScheduler - , public ActionScheduler , public EventDispatcher , public ComponentManager , protected IntrusiveListValue diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index bcdda931..145eed49 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -20,7 +20,7 @@ #pragma once #include -#include +#include #include #include @@ -150,17 +150,19 @@ public: void FillRoundedRect(const Rect& rect, const Vec2& radius); /// \~chinese - /// @brief »æÖÆÍ¼ÏñÖ¡ - /// @param frame ͼÏñÖ¡ - /// @param pos »æÖÆÍ¼ÏñµÄλÖà - void DrawFrame(FramePtr frame, const Point& pos); + /// @brief »æÖÆÎÆÀí + /// @param texture ÎÆÀí + /// @param pos »æÖƵÄÄ¿±êλÖà + /// @param crop_rect ÎÆÀí²Ã¼ô¾ØÐÎ + void DrawTexture(TexturePtr texture, const Point& pos, const Rect* crop_rect = nullptr); /// \~chinese - /// @brief »æÖÆÍ¼ÏñÖ¡ - /// @param frame ͼÏñÖ¡ - /// @param pos »æÖÆÍ¼ÏñµÄλÖà - /// @param size äÖȾµÄͼÏñ´óС - void DrawFrame(FramePtr frame, const Point& pos, const Size& size); + /// @brief »æÖÆÎÆÀí + /// @param texture ÎÆÀí + /// @param pos »æÖƵÄÄ¿±êλÖà + /// @param size »æÖƵÄÄ¿±ê´óС + /// @param crop_rect ÎÆÀí²Ã¼ô¾ØÐÎ + void DrawTexture(TexturePtr texture, const Point& pos, const Size& size, const Rect* crop_rect = nullptr); /// \~chinese /// @brief »æÖÆÎÄ×Ö²¼¾Ö @@ -381,22 +383,22 @@ inline void CanvasRenderContext::FillRoundedRect(const Rect& rect, const Vec2& r ctx_->FillRoundedRectangle(rect, radius); } -inline void CanvasRenderContext::DrawFrame(FramePtr frame, const Point& pos) +inline void CanvasRenderContext::DrawTexture(TexturePtr texture, const Point& pos, const Rect* crop_rect) { - if (frame) + if (texture) { - Size frame_size = frame->GetSize(); - this->DrawFrame(frame, pos, frame_size); + this->DrawTexture(texture, pos, texture->GetSize(), crop_rect); } } -inline void CanvasRenderContext::DrawFrame(FramePtr frame, const Point& pos, const Size& size) +inline void CanvasRenderContext::DrawTexture(TexturePtr texture, const Point& pos, const Size& size, + const Rect* crop_rect) { KGE_ASSERT(ctx_); - if (frame) + if (texture) { - ctx_->DrawFrame(frame, Rect(pos, size)); + ctx_->DrawTexture(*texture, crop_rect, &Rect(pos, size)); } } diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h index cc575b5e..6fa6bf15 100644 --- a/src/kiwano/2d/GifSprite.h +++ b/src/kiwano/2d/GifSprite.h @@ -130,7 +130,7 @@ private: void ComposeNextFrame(); /// \~chinese - /// @brief ½âÎöµ±Ç°Í¼ÏñÖ¡ + /// @brief ½âÎöµ±Ç°¹Ø¼üÖ¡ void DisposeCurrentFrame(); /// \~chinese @@ -138,11 +138,11 @@ private: void OverlayNextFrame(); /// \~chinese - /// @brief ±£´æºÏ³ÉºóµÄͼÏñÖ¡ + /// @brief ±£´æºÏ³ÉºóµÄ¹Ø¼üÖ¡ void SaveComposedFrame(); /// \~chinese - /// @brief »Ö¸´Òѱ£´æµÄͼÏñÖ¡ + /// @brief »Ö¸´Òѱ£´æµÄ¹Ø¼üÖ¡ void RestoreSavedFrame(); /// \~chinese diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index 5e643bd7..0ffd0a45 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -36,9 +36,9 @@ Sprite::Sprite(const Resource& res) Load(res); } -Sprite::Sprite(FramePtr frame) +Sprite::Sprite(TexturePtr texture) { - SetFrame(frame); + SetTexture(texture); } Sprite::Sprite(const String& file_path, const Rect& crop_rect) @@ -53,110 +53,61 @@ Sprite::Sprite(const Resource& res, const Rect& crop_rect) SetCropRect(crop_rect); } +Sprite::Sprite(TexturePtr texture, const Rect& crop_rect) +{ + SetTexture(texture); + SetCropRect(crop_rect); +} + Sprite::~Sprite() {} -bool Sprite::Load(const String& file_path, bool autoresize) +bool Sprite::Load(const String& file_path) { - FramePtr frame = MakePtr(file_path); - if (frame && frame->IsValid()) + TexturePtr texture = MakePtr(file_path); + if (texture && texture->IsValid()) { - SetFrame(frame, autoresize); + SetTexture(texture); return true; } Fail("Sprite::Load failed"); return false; } -bool Sprite::Load(const Resource& res, bool autoresize) +bool Sprite::Load(const Resource& res) { - FramePtr frame = MakePtr(res); - if (frame) + TexturePtr texture = MakePtr(res); + if (texture && texture->IsValid()) { - SetFrame(frame, autoresize); + SetTexture(texture); return true; } Fail("Sprite::Load failed"); return false; } -float Sprite::GetSourceWidth() const +void Sprite::SetTexture(TexturePtr texture) { - if (frame_) - { - return frame_->GetSourceWidth(); - } - return 0.0f; -} + texture_ = texture; -float Sprite::GetSourceHeight() const -{ - if (frame_) + Size texture_size; + if (texture_) { - return frame_->GetSourceHeight(); - } - return 0.0f; -} - -Size Sprite::GetSourceSize() const -{ - if (frame_) - { - return frame_->GetSourceSize(); - } - return Size(); -} - -Rect Sprite::GetCropRect() const -{ - if (frame_) - { - return frame_->GetCropRect(); - } - return Rect(); -} - -void Sprite::SetCropRect(const Rect& crop_rect) -{ - if (frame_) - { - frame_->SetCropRect(crop_rect); - } -} - -void Sprite::SetFrame(FramePtr frame, bool autoresize) -{ - if (frame_ != frame) - { - frame_ = frame; - if (autoresize) - { - ResetSize(); - } - } -} - -void Sprite::ResetSize() -{ - if (frame_) - { - SetSize(frame_->GetSize()); - } - else - { - SetSize(Size()); + texture_size = texture_->GetSize(); } + // ÖØÖòüô¾ØÐÎ + SetCropRect(Rect(Point(), texture_size)); } void Sprite::OnRender(RenderContext& ctx) { - if (frame_ && frame_->IsValid()) + if (texture_ && texture_->IsValid()) { - ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds()); + ctx.DrawTexture(*texture_, &crop_rect_, &GetBounds()); } } bool Sprite::CheckVisibility(RenderContext& ctx) const { - return frame_ && frame_->IsValid() && Actor::CheckVisibility(ctx); + return texture_ && texture_->IsValid() && Actor::CheckVisibility(ctx); } } // namespace kiwano diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h index 9a30f601..2a729f8e 100644 --- a/src/kiwano/2d/Sprite.h +++ b/src/kiwano/2d/Sprite.h @@ -20,7 +20,7 @@ #pragma once #include -#include +#include namespace kiwano { @@ -53,8 +53,8 @@ public: /// \~chinese /// @brief ´´½¨¾«Áé - /// @param frame ͼÏñÖ¡ - Sprite(FramePtr frame); + /// @param texture ͼÏñ + Sprite(TexturePtr texture); /// \~chinese /// @brief ´´½¨¾«Áé @@ -68,61 +68,46 @@ public: /// @param crop_rect ²Ã¼ô¾ØÐÎ Sprite(const Resource& res, const Rect& crop_rect); + /// \~chinese + /// @brief ´´½¨¾«Áé + /// @param texture ͼÏñ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + Sprite(TexturePtr texture, const Rect& crop_rect); + virtual ~Sprite(); /// \~chinese - /// @brief ¼ÓÔØ±¾µØÍ¼Æ¬ + /// @brief ¼ÓÔØ±¾µØÍ¼Æ¬²¢ÖØÖòüô¾ØÐÎ /// @param file_path ±¾µØÍ¼Æ¬Â·¾¶ - /// @param autoresize ÊÇ·ñ×Ô¶¯µ÷Õû×ÔÉí´óСΪͼÏñ´óС - bool Load(const String& file_path, bool autoresize = true); + bool Load(const String& file_path); /// \~chinese - /// @brief ¼ÓÔØÍ¼Ïñ×ÊÔ´ + /// @brief ¼ÓÔØÍ¼Ïñ×ÊÔ´²¢ÖØÖòüô¾ØÐÎ /// @param res ͼƬ×ÊÔ´ - /// @param autoresize ÊÇ·ñ×Ô¶¯µ÷Õû×ÔÉí´óСΪͼÏñ´óС - bool Load(const Resource& res, bool autoresize = true); + bool Load(const Resource& res); /// \~chinese - /// @brief »ñȡͼÏñÔ­¿í¶È - float GetSourceWidth() const; - - /// \~chinese - /// @brief »ñȡͼÏñÔ­¸ß¶È - float GetSourceHeight() const; - - /// \~chinese - /// @brief »ñȡͼÏñÔ­´óС - Size GetSourceSize() const; + /// @brief »ñȡͼÏñ + TexturePtr GetTexture() const; /// \~chinese /// @brief »ñÈ¡²Ã¼ô¾ØÐÎ Rect GetCropRect() const; + /// \~chinese + /// @brief ÉèÖÃͼÏñ²¢ÖØÖòüô¾ØÐÎ + /// @param[in] texture ͼÏñ + void SetTexture(TexturePtr texture); + /// \~chinese /// @brief ʹÓþØÐÎÇøÓò²Ã¼ô¾«Áé /// @param crop_rect ²Ã¼ô¾ØÐÎ void SetCropRect(const Rect& crop_rect); /// \~chinese - /// @brief »ñȡ֡ͼÏñ - FramePtr GetFrame() const; - - /// \~chinese - /// @brief ÉèÖÃͼÏñÖ¡ - /// @param[in] frame ͼÏñÖ¡ - /// @param autoresize ÊÇ·ñ×Ô¶¯µ÷Õû×ÔÉí´óСΪͼÏñ´óС - void SetFrame(FramePtr frame, bool autoresize = true); - - /// \~chinese - /// @brief ÖØÖþ«Áé´óСΪͼÏñÖ¡´óС - void ResetSize(); - - /// \~chinese - /// @brief »ñȡͼÏñÖ¡ÊôÐÔ - inline Value> FrameProperty() - { - return Value>(frame_, Closure(this, &Sprite::ResetSize)); - } + /// @brief ÉèÖùؼüÖ¡ + /// @param[in] frame ¹Ø¼üÖ¡ + void SetKeyFrame(KeyFramePtr frame); void OnRender(RenderContext& ctx) override; @@ -130,13 +115,35 @@ protected: bool CheckVisibility(RenderContext& ctx) const override; private: - FramePtr frame_; + TexturePtr texture_; + Rect crop_rect_; }; /** @} */ -inline FramePtr Sprite::GetFrame() const +inline TexturePtr Sprite::GetTexture() const { - return frame_; + return texture_; } + +inline Rect Sprite::GetCropRect() const +{ + return crop_rect_; +} + +inline void Sprite::SetCropRect(const Rect& crop_rect) +{ + crop_rect_ = crop_rect; + SetSize(crop_rect.GetSize()); +} + +inline void Sprite::SetKeyFrame(KeyFramePtr frame) +{ + if (frame) + { + SetTexture(frame->GetTexture()); + SetCropRect(frame->GetCropRect()); + } +} + } // namespace kiwano diff --git a/src/kiwano/2d/action/Action.cpp b/src/kiwano/2d/action/Action.cpp deleted file mode 100644 index abdf00e5..00000000 --- a/src/kiwano/2d/action/Action.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// 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. - -#include -#include - -namespace kiwano -{ -ActionEntity::ActionEntity() - : running_(true) - , detach_target_(false) - , loops_done_(0) - , loops_(0) - , status_(Status::NotStarted) -{ -} - -ActionEntity::~ActionEntity() {} - -void ActionEntity::Init(Actor* target) {} - -void ActionEntity::Update(Actor* target, Duration dt) -{ - Complete(target); -} - -void ActionEntity::UpdateStep(Actor* target, Duration dt) -{ - KGE_ASSERT(target != nullptr && "ActionEntity target should NOT be nullptr!"); - - elapsed_ += dt; - - if (status_ == Status::NotStarted) - { - status_ = delay_.IsZero() ? Status::Started : Status::Delayed; - Init(target); - } - - switch (status_) - { - case Status::Delayed: - if (elapsed_ >= delay_) - { - status_ = Status::Started; - } - break; - - case Status::Started: - Update(target, dt); - break; - - default: - break; - } - - if (status_ == Status::Done) - { - if (cb_done_) - cb_done_(target); - - if (detach_target_) - target->RemoveFromParent(); - - status_ = Status::Removeable; - } -} - -void ActionEntity::Complete(Actor* target) -{ - if (cb_loop_done_) - cb_loop_done_(target); - - if (loops_ >= 0 && loops_done_ >= loops_) - { - Done(); - } - else - { - Init(target); // reinit when a loop is done - } - - ++loops_done_; -} - -void ActionEntity::Reset() -{ - status_ = Status::NotStarted; - elapsed_ = 0; - loops_done_ = 0; -} - -void ActionEntity::DoClone(ActionEntity* to) const -{ - if (to) - { - to->SetDelay(this->GetDelay()); - to->SetDoneCallback(this->GetDoneCallback()); - to->SetLoopDoneCallback(this->GetLoopDoneCallback()); - to->SetLoops(this->GetLoops()); - to->SetName(this->GetName()); - } -} - -} // namespace kiwano diff --git a/src/kiwano/2d/action/Action.h b/src/kiwano/2d/action/Action.h deleted file mode 100644 index e3c6cf87..00000000 --- a/src/kiwano/2d/action/Action.h +++ /dev/null @@ -1,417 +0,0 @@ -// 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 -#include -#include -#include -#include - -namespace kiwano -{ -class Actor; -class ActionScheduler; - -KGE_DECLARE_SMART_PTR(ActionEntity); - -/** - * \~chinese - * \defgroup Actions ¶¯»­ - */ - -/** - * \addtogroup Actions - * @{ - */ - -/// \~chinese -/// @brief ¶¯»­Áбí -typedef IntrusiveList ActionList; - -/// \~chinese -/// @brief ¶¯»­½áÊøÊ±µÄ»Øµ÷º¯Êý -typedef Function ActionDoneCallback; - -/// \~chinese -/// @brief ¶¯»­ÊµÌå -class KGE_API ActionEntity - : public ObjectBase - , public Cloneable - , protected IntrusiveListValue -{ - friend class ActionScheduler; - friend class ActionGroupEntity; - friend IntrusiveList; - -public: - ActionEntity(); - - virtual ~ActionEntity(); - - /// \~chinese - /// @brief ¼ÌÐø¶¯»­ - void Resume(); - - /// \~chinese - /// @brief ÔÝÍ£¶¯»­ - void Pause(); - - /// \~chinese - /// @brief Í£Ö¹¶¯»­ - void Stop(); - - /// \~chinese - /// @brief ÉèÖö¯»­ÑÓʱ - void SetDelay(Duration delay); - - /// \~chinese - /// @brief ÉèÖÃÑ­»·´ÎÊý - /// @param loops Ñ­»·´ÎÊý£¬-1 ΪÓÀ¾ÃÑ­»· - void SetLoops(int loops); - - /// \~chinese - /// @brief ¶¯»­½áÊøÊ±ÒÆ³ýÄ¿±ê½ÇÉ« - void RemoveTargetWhenDone(); - - /// \~chinese - /// @brief ÉèÖö¯»­½áÊøÊ±µÄ»Øµ÷º¯Êý - void SetDoneCallback(const ActionDoneCallback& cb); - - /// \~chinese - /// @brief ÉèÖö¯»­Ñ­»·½áÊøÊ±µÄ»Øµ÷º¯Êý - void SetLoopDoneCallback(const ActionDoneCallback& cb); - - /// \~chinese - /// @brief »ñÈ¡¶¯»­µÄµ¹×ª - virtual ActionEntity* Reverse() const = 0; - - /// \~chinese - /// @brief »ñÈ¡¶¯»­µÄÔËÐÐ״̬ - bool IsRunning() const; - - /// \~chinese - /// @brief »ñÈ¡¶¯»­µÄÑ­»·´ÎÊý - int GetLoops() const; - - /// \~chinese - /// @brief »ñÈ¡¶¯»­µÄÑÓʱ - Duration GetDelay() const; - - /// \~chinese - /// @brief »ñÈ¡¶¯»­½áÊøÊ±µÄ»Øµ÷º¯Êý - ActionDoneCallback GetDoneCallback() const; - - /// \~chinese - /// @brief »ñÈ¡¶¯»­Ñ­»·½áÊøÊ±µÄ»Øµ÷º¯Êý - ActionDoneCallback GetLoopDoneCallback() const; - -protected: - /// \~chinese - /// @brief ³õʼ»¯¶¯»­ - virtual void Init(Actor* target); - - /// \~chinese - /// @brief ¸üж¯»­ - virtual void Update(Actor* target, Duration dt); - - /// \~chinese - /// @brief ¸üÐÂÒ»¸öʱ¼ä²½ - void UpdateStep(Actor* target, Duration dt); - - /// \~chinese - /// @brief Íê³É¶¯»­ - void Complete(Actor* target); - - /// \~chinese - /// @brief ÖØÖö¯»­ - void Reset(); - - /// \~chinese - /// @brief ¶¯»­×´Ì¬ - enum class Status - { - NotStarted, ///< δ¿ªÊ¼ - Delayed, ///< µÈ´ýÑÓʱ - Started, ///< ÒÑ¿ªÊ¼ - Done, ///< ÒѽáÊø - Removeable ///< ¿ÉÒÆ³ý - }; - - /// \~chinese - /// @brief »ñÈ¡¶¯»­×´Ì¬ - Status GetStatus() const; - - /// \~chinese - /// @brief »ñÈ¡ÏûÊÅʱ¼ä - Duration GetElapsed() const; - - /// \~chinese - /// @brief »ñÈ¡Íê³ÉµÄÑ­»·´ÎÊý - int GetLoopsDone() const; - - /// \~chinese - /// @brief ½áÊø¶¯»­ - void Done(); - - /// \~chinese - /// @brief ÊÇ·ñÒѽáÊø - bool IsDone() const; - - /// \~chinese - /// @brief ÊÇ·ñ¿ÉÒÆ³ý - bool IsRemoveable() const; - - /// \~chinese - /// @brief Ö´ÐпË¡ - void DoClone(ActionEntity* to) const; - -private: - Status status_; - bool running_; - bool detach_target_; - int loops_; - int loops_done_; - Duration delay_; - Duration elapsed_; - ActionDoneCallback cb_done_; - ActionDoneCallback cb_loop_done_; -}; - -/// \~chinese -/// @brief ¶¯»­ -class KGE_API Action -{ -public: - Action() = default; - - inline Action(ActionEntityPtr ptr) - : ptr(ptr) - { - } - - /// \~chinese - /// @brief ÉèÖÃÑ­»·´ÎÊý - inline Action& Loops(int loops) - { - if (ptr) - ptr->SetLoops(loops); - return (*this); - } - - /// \~chinese - /// @brief ÉèÖö¯»­ÑÓ³Ù - inline Action& Delay(Duration delay) - { - if (ptr) - ptr->SetDelay(delay); - return (*this); - } - - /// \~chinese - /// @brief ÉèÖö¯»­½áÊø»Øµ÷º¯Êý - inline Action& DoneCallback(const ActionDoneCallback& cb) - { - if (ptr) - ptr->SetDoneCallback(cb); - return (*this); - } - - /// \~chinese - /// @brief ÉèÖö¯»­Ñ­»·½áÊøÊ±µÄ»Øµ÷º¯Êý - inline Action& LoopDoneCallback(const ActionDoneCallback& cb) - { - if (ptr) - ptr->SetLoopDoneCallback(cb); - return (*this); - } - - /// \~chinese - /// @brief ¶¯»­½áÊøÊ±ÒÆ³ýÄ¿±ê½ÇÉ« - inline Action& RemoveTargetWhenDone() - { - if (ptr) - ptr->RemoveTargetWhenDone(); - return (*this); - } - - /// \~chinese - /// @brief ÉèÖÃÃû³Æ - inline Action& Name(const String& name) - { - if (ptr) - ptr->SetName(name); - return (*this); - } - - /// \~chinese - /// @brief ¿Ë¡¶¯»­ - inline Action Clone() const - { - if (ptr) - return Action(ptr->Clone()); - return Action(); - } - - /// \~chinese - /// @brief »ñÈ¡·´Ïò¶¯»­ - inline Action Reverse() const - { - if (ptr) - return Action(ptr->Reverse()); - return Action(); - } - - /// \~chinese - /// @brief »ñȡָÕë - inline ActionEntity* Get() const - { - return const_cast(ptr.Get()); - } - - /// \~chinese - /// @brief ÉèÖö¯»­ÊµÌå - inline void SetEntity(ActionEntityPtr ptr) - { - this->ptr = ptr; - } - - inline ActionEntity* operator->() const - { - return Get(); - } - - inline operator ActionEntity*() const - { - return Get(); - } - - inline operator ActionEntityPtr() const - { - return ptr; - } - - inline operator bool() const - { - return ptr != nullptr; - } - -protected: - ActionEntityPtr ptr; -}; - -/** @} */ - -inline void ActionEntity::Resume() -{ - running_ = true; -} - -inline void ActionEntity::Pause() -{ - running_ = false; -} - -inline void ActionEntity::Stop() -{ - Done(); -} - -inline void ActionEntity::SetDelay(Duration delay) -{ - delay_ = delay; -} - -inline void ActionEntity::SetLoops(int loops) -{ - loops_ = loops; -} - -inline void ActionEntity::RemoveTargetWhenDone() -{ - detach_target_ = true; -} - -inline void ActionEntity::SetDoneCallback(const ActionDoneCallback& cb) -{ - cb_done_ = cb; -} - -inline void ActionEntity::SetLoopDoneCallback(const ActionDoneCallback& cb) -{ - cb_loop_done_ = cb; -} - -inline void ActionEntity::Done() -{ - status_ = Status::Done; -} - -inline ActionEntity::Status ActionEntity::GetStatus() const -{ - return status_; -} - -inline bool ActionEntity::IsRunning() const -{ - return running_; -} - -inline bool ActionEntity::IsDone() const -{ - return status_ == Status::Done || status_ == Status::Removeable; -} - -inline bool ActionEntity::IsRemoveable() const -{ - return status_ == Status::Removeable; -} - -inline int ActionEntity::GetLoops() const -{ - return loops_; -} - -inline Duration ActionEntity::GetDelay() const -{ - return delay_; -} - -inline Duration ActionEntity::GetElapsed() const -{ - return elapsed_; -} - -inline int ActionEntity::GetLoopsDone() const -{ - return loops_done_; -} - -inline ActionDoneCallback ActionEntity::GetDoneCallback() const -{ - return cb_done_; -} - -inline ActionDoneCallback ActionEntity::GetLoopDoneCallback() const -{ - return cb_loop_done_; -} -} // namespace kiwano diff --git a/src/kiwano/2d/action/ActionTween.cpp b/src/kiwano/2d/action/ActionTween.cpp deleted file mode 100644 index 421ff940..00000000 --- a/src/kiwano/2d/action/ActionTween.cpp +++ /dev/null @@ -1,528 +0,0 @@ -// 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. - -#include -#include -#include - -namespace kiwano -{ -//------------------------------------------------------- -// Ease Functions -//------------------------------------------------------- - -inline EaseFunc MakeEaseIn(float rate) -{ - return std::bind(math::EaseIn, std::placeholders::_1, rate); -} -inline EaseFunc MakeEaseOut(float rate) -{ - return std::bind(math::EaseOut, std::placeholders::_1, rate); -} -inline EaseFunc MakeEaseInOut(float rate) -{ - return std::bind(math::EaseInOut, std::placeholders::_1, rate); -} -inline EaseFunc MakeEaseElasticIn(float period) -{ - return std::bind(math::EaseElasticIn, std::placeholders::_1, period); -} -inline EaseFunc MakeEaseElasticOut(float period) -{ - return std::bind(math::EaseElasticOut, std::placeholders::_1, period); -} -inline EaseFunc MakeEaseElasticInOut(float period) -{ - return std::bind(math::EaseElasticInOut, std::placeholders::_1, period); -} - -KGE_API EaseFunc Ease::Linear = math::Linear; -KGE_API EaseFunc Ease::EaseIn = MakeEaseIn(2.f); -KGE_API EaseFunc Ease::EaseOut = MakeEaseOut(2.f); -KGE_API EaseFunc Ease::EaseInOut = MakeEaseInOut(2.f); -KGE_API EaseFunc Ease::ExpoIn = math::EaseExponentialIn; -KGE_API EaseFunc Ease::ExpoOut = math::EaseExponentialOut; -KGE_API EaseFunc Ease::ExpoInOut = math::EaseExponentialInOut; -KGE_API EaseFunc Ease::BounceIn = math::EaseBounceIn; -KGE_API EaseFunc Ease::BounceOut = math::EaseBounceOut; -KGE_API EaseFunc Ease::BounceInOut = math::EaseBounceInOut; -KGE_API EaseFunc Ease::ElasticIn = MakeEaseElasticIn(0.3f); -KGE_API EaseFunc Ease::ElasticOut = MakeEaseElasticOut(0.3f); -KGE_API EaseFunc Ease::ElasticInOut = MakeEaseElasticInOut(0.3f); -KGE_API EaseFunc Ease::SineIn = math::EaseSineIn; -KGE_API EaseFunc Ease::SineOut = math::EaseSineOut; -KGE_API EaseFunc Ease::SineInOut = math::EaseSineInOut; -KGE_API EaseFunc Ease::BackIn = math::EaseBackIn; -KGE_API EaseFunc Ease::BackOut = math::EaseBackOut; -KGE_API EaseFunc Ease::BackInOut = math::EaseBackInOut; -KGE_API EaseFunc Ease::QuadIn = math::EaseQuadIn; -KGE_API EaseFunc Ease::QuadOut = math::EaseQuadOut; -KGE_API EaseFunc Ease::QuadInOut = math::EaseQuadInOut; -KGE_API EaseFunc Ease::CubicIn = math::EaseCubicIn; -KGE_API EaseFunc Ease::CubicOut = math::EaseCubicOut; -KGE_API EaseFunc Ease::CubicInOut = math::EaseCubicInOut; -KGE_API EaseFunc Ease::QuartIn = math::EaseQuartIn; -KGE_API EaseFunc Ease::QuartOut = math::EaseQuartOut; -KGE_API EaseFunc Ease::QuartInOut = math::EaseQuartInOut; -KGE_API EaseFunc Ease::QuintIn = math::EaseQuintIn; -KGE_API EaseFunc Ease::QuintOut = math::EaseQuintOut; -KGE_API EaseFunc Ease::QuintInOut = math::EaseQuintInOut; - -//------------------------------------------------------- -// ActionTweenEntity -//------------------------------------------------------- - -ActionTweenEntity::ActionTweenEntity() - : dur_() - , ease_func_(nullptr) -{ -} - -ActionTweenEntity::ActionTweenEntity(Duration duration) - : dur_(duration) - , ease_func_(nullptr) -{ -} - -void ActionTweenEntity::Update(Actor* target, Duration dt) -{ - float percent; - - if (dur_.IsZero()) - { - percent = 1.f; - Complete(target); - } - else - { - Duration elapsed = GetElapsed() - GetDelay(); - float loops_done = elapsed / dur_; - - while (GetLoopsDone() < static_cast(loops_done)) - { - Complete(target); // loops_done_++ - } - - percent = (GetStatus() == Status::Done) ? 1.f : (loops_done - static_cast(GetLoopsDone())); - } - - if (ease_func_) - percent = ease_func_(percent); - - UpdateTween(target, percent); -} - -void ActionTweenEntity::DoClone(ActionTweenEntity* to) const -{ - if (to) - { - ActionEntity::DoClone(to); - to->SetDuration(this->GetDuration()); - to->SetEaseFunc(this->GetEaseFunc()); - } -} - -//------------------------------------------------------- -// Move Action -//------------------------------------------------------- - -ActionMoveByEntity::ActionMoveByEntity(Duration duration, const Vec2& displacement) - : ActionTweenEntity(duration) - , displacement_(displacement) -{ -} - -void ActionMoveByEntity::Init(Actor* target) -{ - if (target) - { - prev_pos_ = start_pos_ = target->GetPosition(); - } -} - -void ActionMoveByEntity::UpdateTween(Actor* target, float percent) -{ - Point diff = target->GetPosition() - prev_pos_; - start_pos_ = start_pos_ + diff; - - Point new_pos = start_pos_ + (displacement_ * percent); - target->SetPosition(new_pos); - - prev_pos_ = new_pos; -} - -ActionMoveByEntity* ActionMoveByEntity::Clone() const -{ - ActionMoveByEntity* ptr = new ActionMoveByEntity(GetDuration(), displacement_); - DoClone(ptr); - return ptr; -} - -ActionMoveByEntity* ActionMoveByEntity::Reverse() const -{ - ActionMoveByEntity* ptr = new ActionMoveByEntity(GetDuration(), -displacement_); - DoClone(ptr); - return ptr; -} - -ActionMoveToEntity::ActionMoveToEntity(Duration duration, const Point& distination) - : ActionMoveByEntity(duration, Vec2()) - , distination_(distination) -{ -} - -ActionMoveToEntity* ActionMoveToEntity::Clone() const -{ - ActionMoveToEntity* ptr = new ActionMoveToEntity(GetDuration(), distination_); - DoClone(ptr); - return ptr; -} - -void ActionMoveToEntity::Init(Actor* target) -{ - ActionMoveByEntity::Init(target); - displacement_ = distination_ - start_pos_; -} - -//------------------------------------------------------- -// Jump Action -//------------------------------------------------------- - -ActionJumpByEntity::ActionJumpByEntity(Duration duration, const Vec2& displacement, float height, int count) - : ActionTweenEntity(duration) - , height_(height) - , jump_count_(count) - , displacement_(displacement) -{ -} - -ActionJumpByEntity* ActionJumpByEntity::Clone() const -{ - ActionJumpByEntity* ptr = new ActionJumpByEntity(GetDuration(), displacement_, height_, jump_count_); - DoClone(ptr); - return ptr; -} - -ActionJumpByEntity* ActionJumpByEntity::Reverse() const -{ - ActionJumpByEntity* ptr = new ActionJumpByEntity(GetDuration(), -displacement_, height_, jump_count_); - DoClone(ptr); - return ptr; -} - -void ActionJumpByEntity::Init(Actor* target) -{ - if (target) - { - prev_pos_ = start_pos_ = target->GetPosition(); - } -} - -void ActionJumpByEntity::UpdateTween(Actor* target, float percent) -{ - float frac = fmod(percent * jump_count_, 1.f); - float x = displacement_.x * percent; - float y = height_ * 4 * frac * (1 - frac); - y += displacement_.y * percent; - - Point diff = target->GetPosition() - prev_pos_; - start_pos_ = diff + start_pos_; - - Point new_pos = start_pos_ + Point(x, y); - target->SetPosition(new_pos); - - prev_pos_ = new_pos; -} - -ActionJumpToEntity::ActionJumpToEntity(Duration duration, const Point& distination, float height, int count) - : ActionJumpByEntity(duration, Vec2(), height, count) - , distination_(distination) -{ -} - -ActionJumpToEntity* ActionJumpToEntity::Clone() const -{ - ActionJumpToEntity* ptr = new ActionJumpToEntity(GetDuration(), distination_, height_, jump_count_); - DoClone(ptr); - return ptr; -} - -void ActionJumpToEntity::Init(Actor* target) -{ - ActionJumpByEntity::Init(target); - displacement_ = distination_ - start_pos_; -} - -//------------------------------------------------------- -// Scale Action -//------------------------------------------------------- - -ActionScaleByEntity::ActionScaleByEntity(Duration duration, float scale_x, float scale_y) - : ActionTweenEntity(duration) - , delta_x_(scale_x) - , delta_y_(scale_y) - , start_scale_x_(0.f) - , start_scale_y_(0.f) -{ -} - -void ActionScaleByEntity::Init(Actor* target) -{ - if (target) - { - start_scale_x_ = target->GetScaleX(); - start_scale_y_ = target->GetScaleY(); - } -} - -void ActionScaleByEntity::UpdateTween(Actor* target, float percent) -{ - target->SetScale(Vec2{ start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent }); -} - -ActionScaleByEntity* ActionScaleByEntity::Clone() const -{ - ActionScaleByEntity* ptr = new ActionScaleByEntity(GetDuration(), delta_x_, delta_y_); - DoClone(ptr); - return ptr; -} - -ActionScaleByEntity* ActionScaleByEntity::Reverse() const -{ - ActionScaleByEntity* ptr = new ActionScaleByEntity(GetDuration(), -delta_x_, -delta_y_); - DoClone(ptr); - return ptr; -} - -ActionScaleToEntity::ActionScaleToEntity(Duration duration, float scale_x, float scale_y) - : ActionScaleByEntity(duration, 0, 0) - , end_scale_x_(scale_x) - , end_scale_y_(scale_y) -{ -} - -ActionScaleToEntity* ActionScaleToEntity::Clone() const -{ - ActionScaleToEntity* ptr = new ActionScaleToEntity(GetDuration(), end_scale_x_, end_scale_y_); - DoClone(ptr); - return ptr; -} - -void ActionScaleToEntity::Init(Actor* target) -{ - ActionScaleByEntity::Init(target); - delta_x_ = end_scale_x_ - start_scale_x_; - delta_y_ = end_scale_y_ - start_scale_y_; -} - -//------------------------------------------------------- -// Opacity Action -//------------------------------------------------------- - -ActionFadeToEntity::ActionFadeToEntity(Duration duration, float opacity) - : ActionTweenEntity(duration) - , delta_val_(0.0f) - , start_val_(0.f) - , end_val_(opacity) -{ -} - -void ActionFadeToEntity::Init(Actor* target) -{ - if (target) - { - start_val_ = target->GetOpacity(); - delta_val_ = end_val_ - start_val_; - } -} - -void ActionFadeToEntity::UpdateTween(Actor* target, float percent) -{ - target->SetOpacity(start_val_ + delta_val_ * percent); -} - -ActionFadeToEntity* ActionFadeToEntity::Clone() const -{ - ActionFadeToEntity* ptr = new ActionFadeToEntity(GetDuration(), end_val_); - DoClone(ptr); - return ptr; -} - -//------------------------------------------------------- -// Rotate Action -//------------------------------------------------------- - -ActionRotateByEntity::ActionRotateByEntity(Duration duration, float rotation) - : ActionTweenEntity(duration) - , delta_val_(rotation) - , start_val_(0.0f) -{ -} - -void ActionRotateByEntity::Init(Actor* target) -{ - if (target) - { - start_val_ = target->GetRotation(); - } -} - -void ActionRotateByEntity::UpdateTween(Actor* target, float percent) -{ - float rotation = start_val_ + delta_val_ * percent; - if (rotation > 360.f) - rotation -= 360.f; - - target->SetRotation(rotation); -} - -ActionRotateByEntity* ActionRotateByEntity::Clone() const -{ - ActionRotateByEntity* ptr = new ActionRotateByEntity(GetDuration(), delta_val_); - DoClone(ptr); - return ptr; -} - -ActionRotateByEntity* ActionRotateByEntity::Reverse() const -{ - ActionRotateByEntity* ptr = new ActionRotateByEntity(GetDuration(), -delta_val_); - DoClone(ptr); - return ptr; -} - -ActionRotateToEntity::ActionRotateToEntity(Duration duration, float rotation) - : ActionRotateByEntity(duration, 0) - , end_val_(rotation) -{ -} - -ActionRotateToEntity* ActionRotateToEntity::Clone() const -{ - ActionRotateToEntity* ptr = new ActionRotateToEntity(GetDuration(), end_val_); - DoClone(ptr); - return ptr; -} - -void ActionRotateToEntity::Init(Actor* target) -{ - ActionRotateByEntity::Init(target); - delta_val_ = end_val_ - start_val_; -} - -//------------------------------------------------------- -// ActionCustomEntity -//------------------------------------------------------- - -ActionCustomEntity::ActionCustomEntity(Duration duration, ActionCustom::TweenFunc tween_func) - : ActionTweenEntity(duration) - , tween_func_(tween_func) -{ -} - -ActionCustomEntity* ActionCustomEntity::Clone() const -{ - ActionCustomEntity* ptr = new ActionCustomEntity(GetDuration(), tween_func_); - DoClone(ptr); - return ptr; -} - -void ActionCustomEntity::Init(Actor* target) -{ - if (!tween_func_) - this->Done(); -} - -void ActionCustomEntity::UpdateTween(Actor* target, float percent) -{ - if (tween_func_) - tween_func_(target, percent); -} - -ActionMoveBy::ActionMoveBy(Duration duration, const Vec2& displacement) -{ - SetEntity(MakePtr(duration, displacement)); -} - -ActionMoveTo::ActionMoveTo(Duration duration, const Point& distination) -{ - SetEntity(MakePtr(duration, distination)); -} - -ActionJumpBy::ActionJumpBy(Duration duration, const Vec2& displacement, float height, int count) -{ - SetEntity(MakePtr(duration, displacement, height, count)); -} - -ActionJumpTo::ActionJumpTo(Duration duration, const Point& distination, float height, int count) -{ - SetEntity(MakePtr(duration, distination, height, count)); -} - -ActionScaleBy::ActionScaleBy(Duration duration, float scale_x, float scale_y) -{ - SetEntity(MakePtr(duration, scale_x, scale_y)); -} - -ActionScaleBy::ActionScaleBy(Duration duration, Vec2 scale) -{ - SetEntity(MakePtr(duration, scale.x, scale.y)); -} - -ActionScaleTo::ActionScaleTo(Duration duration, float scale_x, float scale_y) -{ - SetEntity(MakePtr(duration, scale_x, scale_y)); -} - -ActionScaleTo::ActionScaleTo(Duration duration, Vec2 scale) -{ - SetEntity(MakePtr(duration, scale.x, scale.y)); -} - -ActionFadeTo::ActionFadeTo(Duration duration, float opacity) -{ - SetEntity(MakePtr(duration, opacity)); -} - -ActionFadeIn::ActionFadeIn(Duration duration) -{ - SetEntity(MakePtr(duration, 1.0f)); -} - -ActionFadeOut::ActionFadeOut(Duration duration) -{ - SetEntity(MakePtr(duration, 0.0f)); -} - -ActionRotateBy::ActionRotateBy(Duration duration, float rotation) -{ - SetEntity(MakePtr(duration, rotation)); -} - -ActionRotateTo::ActionRotateTo(Duration duration, float rotation) -{ - SetEntity(MakePtr(duration, rotation)); -} - -ActionCustom::ActionCustom(Duration duration, TweenFunc tween_func) -{ - SetEntity(MakePtr(duration, tween_func)); -} - -} // namespace kiwano diff --git a/src/kiwano/2d/action/ActionTween.h b/src/kiwano/2d/action/ActionTween.h deleted file mode 100644 index 53d1608a..00000000 --- a/src/kiwano/2d/action/ActionTween.h +++ /dev/null @@ -1,923 +0,0 @@ -// 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(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(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; - - /// \~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 diff --git a/src/kiwano/2d/action/Animation.cpp b/src/kiwano/2d/action/Animation.cpp deleted file mode 100644 index 2ac98c25..00000000 --- a/src/kiwano/2d/action/Animation.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// 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. - -#include -#include -#include - -namespace kiwano -{ - -Animation::Animation(Duration dur, FrameSequencePtr frame_seq) -{ - SetEntity(MakePtr(dur, frame_seq)); -} - -AnimationEntity::AnimationEntity() - : frame_seq_(nullptr) -{ -} - -AnimationEntity::AnimationEntity(Duration dur, FrameSequencePtr frame_seq) - : ActionTweenEntity(dur) - , frame_seq_(frame_seq) -{ -} - -AnimationEntity::~AnimationEntity() {} - -FrameSequencePtr AnimationEntity::GetFrameSequence() const -{ - return frame_seq_; -} - -void AnimationEntity::SetFrameSequence(FrameSequencePtr frame_seq) -{ - frame_seq_ = frame_seq; -} - -void AnimationEntity::Init(Actor* target) -{ - KGE_ASSERT(frame_seq_ && "AnimationEntity::Init() failed: FrameSequence is NULL!"); - if (!frame_seq_ || frame_seq_->GetFrames().empty()) - { - Done(); - return; - } - - auto sprite_target = dynamic_cast(target); - KGE_ASSERT(sprite_target && "AnimationEntity only supports Sprites!"); - - if (sprite_target && frame_seq_) - { - sprite_target->SetFrame(frame_seq_->GetFrames()[0]); - } -} - -void AnimationEntity::UpdateTween(Actor* target, float percent) -{ - auto sprite_target = dynamic_cast(target); - - if (sprite_target && frame_seq_) - { - const auto& frames = frame_seq_->GetFrames(); - auto size = frames.size(); - auto index = std::min(static_cast(math::Floor(size * percent)), size - 1); - - sprite_target->SetFrame(frames[index]); - } -} - -AnimationEntity* AnimationEntity::Clone() const -{ - AnimationEntity* ptr = new AnimationEntity(GetDuration(), frame_seq_); - DoClone(ptr); - return ptr; -} - -AnimationEntity* AnimationEntity::Reverse() const -{ - AnimationEntity* ptr = new AnimationEntity(GetDuration(), nullptr); - DoClone(ptr); - - if (frame_seq_) - { - FrameSequencePtr frames = frame_seq_->Reverse(); - ptr->SetFrameSequence(frames); - } - return ptr; -} - -} // namespace kiwano diff --git a/src/kiwano/2d/animation/Animation.cpp b/src/kiwano/2d/animation/Animation.cpp index c7b1420a..ece08e9e 100644 --- a/src/kiwano/2d/animation/Animation.cpp +++ b/src/kiwano/2d/animation/Animation.cpp @@ -18,9 +18,110 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include #include namespace kiwano { - +Animation::Animation() + : running_(true) + , detach_target_(false) + , loops_done_(0) + , loops_(0) + , status_(Status::NotStarted) +{ } + +Animation::~Animation() {} + +void Animation::Init(Actor* target) {} + +void Animation::Update(Actor* target, Duration dt) +{ + Complete(target); +} + +void Animation::UpdateStep(Actor* target, Duration dt) +{ + KGE_ASSERT(target != nullptr && "Animation target should NOT be nullptr!"); + + elapsed_ += dt; + + if (status_ == Status::NotStarted) + { + if (delay_.IsZero()) + { + status_ = Status::Started; + EmitEvent(target, AnimationEvent::Started); + } + else + { + status_ = Status::Delayed; + } + Init(target); + } + + switch (status_) + { + case Status::Delayed: + if (elapsed_ >= delay_) + { + status_ = Status::Started; + EmitEvent(target, AnimationEvent::Started); + } + break; + + case Status::Started: + Update(target, dt); + break; + + default: + break; + } + + if (status_ == Status::Done) + { + EmitEvent(target, AnimationEvent::Done); + + if (detach_target_) + target->RemoveFromParent(); + + status_ = Status::Removeable; + } +} + +void Animation::Complete(Actor* target) +{ + EmitEvent(target, AnimationEvent::LoopDone); + + if (loops_ >= 0 && loops_done_ >= loops_) + { + Done(); + } + else + { + Init(target); // reinit when a loop is done + } + + ++loops_done_; +} + +void Animation::Reset() +{ + status_ = Status::NotStarted; + elapsed_ = 0; + loops_done_ = 0; +} + +void Animation::DoClone(Animation* to) const +{ + if (to) + { + to->SetDelay(this->GetDelay()); + to->SetHandler(this->GetHandler()); + to->SetLoops(this->GetLoops()); + to->SetName(this->GetName()); + } +} + +} // namespace kiwano diff --git a/src/kiwano/2d/animation/Animation.h b/src/kiwano/2d/animation/Animation.h index dba82b5f..85cab7d0 100644 --- a/src/kiwano/2d/animation/Animation.h +++ b/src/kiwano/2d/animation/Animation.h @@ -20,10 +20,291 @@ #pragma once #include +#include +#include +#include +#include +#include namespace kiwano { +class Actor; +class Animator; +KGE_DECLARE_SMART_PTR(Animation); +KGE_DECLARE_SMART_PTR(AnimationEventHandler); +/** + * \~chinese + * \defgroup Animation ¶¯»­ + */ +/** + * \addtogroup Animation + * @{ + */ + +/// \~chinese +/// @brief ¶¯»­Ê¼þ +enum class AnimationEvent +{ + Started, ///< ¶¯»­¿ªÊ¼ + LoopDone, ///< ¶¯»­Ò»´ÎÑ­»·½áÊø + Done, ///< ¶¯»­½áÊø + Removed, ///< ¶¯»­±»ÒƳý +}; + +/// \~chinese +/// @brief ¶¯»­Ê¼þ´¦ÀíÆ÷ +class KGE_API AnimationEventHandler : public ObjectBase +{ +public: + /// \~chinese + /// @brief ´¦Àí¶¯»­Ê¼þ + /// @param anim ¶¯»­¶ÔÏó + /// @param target Ö´Ðж¯»­µÄ¶ÔÏó + /// @param evt ¶¯»­Ê¼þ + virtual void Handle(Animation* anim, Actor* target, AnimationEvent evt) = 0; +}; + +/// \~chinese +/// @brief ¶¯»­Áбí +typedef IntrusiveList AnimationList; + +/// \~chinese +/// @brief ¶¯»­ +class KGE_API Animation + : public ObjectBase + , public Cloneable + , protected IntrusiveListValue +{ + friend class Animator; + friend class AnimationGroup; + friend IntrusiveList; + +public: + Animation(); + + virtual ~Animation(); + + /// \~chinese + /// @brief ¼ÌÐø¶¯»­ + void Resume(); + + /// \~chinese + /// @brief ÔÝÍ£¶¯»­ + void Pause(); + + /// \~chinese + /// @brief Í£Ö¹¶¯»­ + void Stop(); + + /// \~chinese + /// @brief ÉèÖö¯»­ÑÓʱ + void SetDelay(Duration delay); + + /// \~chinese + /// @brief ÉèÖÃÑ­»·´ÎÊý + /// @param loops Ñ­»·´ÎÊý£¬-1 ΪÓÀ¾ÃÑ­»· + void SetLoops(int loops); + + /// \~chinese + /// @brief ¶¯»­½áÊøÊ±ÒÆ³ýÄ¿±ê½ÇÉ« + void RemoveTargetWhenDone(); + + /// \~chinese + /// @brief »ñÈ¡¶¯»­µÄµ¹×ª + virtual Animation* Reverse() const = 0; + + /// \~chinese + /// @brief »ñÈ¡¶¯»­µÄÔËÐÐ״̬ + bool IsRunning() const; + + /// \~chinese + /// @brief »ñÈ¡¶¯»­µÄÑ­»·´ÎÊý + int GetLoops() const; + + /// \~chinese + /// @brief »ñÈ¡¶¯»­µÄÑÓʱ + Duration GetDelay() const; + + /// \~chinese + /// @brief ÉèÖö¯»­Ê¼þ´¦Àí + void SetHandler(AnimationEventHandlerPtr handler); + + /// \~chinese + /// @brief »ñÈ¡¶¯»­Ê¼þ´¦Àí + AnimationEventHandlerPtr GetHandler() const; + +protected: + /// \~chinese + /// @brief ³õʼ»¯¶¯»­ + virtual void Init(Actor* target); + + /// \~chinese + /// @brief ¸üж¯»­ + virtual void Update(Actor* target, Duration dt); + + /// \~chinese + /// @brief ¸üÐÂÒ»¸öʱ¼ä²½ + void UpdateStep(Actor* target, Duration dt); + + /// \~chinese + /// @brief Íê³É¶¯»­ + void Complete(Actor* target); + + /// \~chinese + /// @brief ÖØÖö¯»­ + void Reset(); + + /// \~chinese + /// @brief ¶¯»­×´Ì¬ + enum class Status + { + NotStarted, ///< δ¿ªÊ¼ + Delayed, ///< µÈ´ýÑÓʱ + Started, ///< ÒÑ¿ªÊ¼ + Done, ///< ÒѽáÊø + Removeable ///< ¿ÉÒÆ³ý + }; + + /// \~chinese + /// @brief »ñÈ¡¶¯»­×´Ì¬ + Status GetStatus() const; + + /// \~chinese + /// @brief »ñÈ¡ÏûÊÅʱ¼ä + Duration GetElapsed() const; + + /// \~chinese + /// @brief »ñÈ¡Íê³ÉµÄÑ­»·´ÎÊý + int GetLoopsDone() const; + + /// \~chinese + /// @brief ½áÊø¶¯»­ + void Done(); + + /// \~chinese + /// @brief ÊÇ·ñÒѽáÊø + bool IsDone() const; + + /// \~chinese + /// @brief ÊÇ·ñ¿ÉÒÆ³ý + bool IsRemoveable() const; + + /// \~chinese + /// @brief ·¢³ö¶¯»­Ê¼þ + void EmitEvent(Actor* target, AnimationEvent evt); + + /// \~chinese + /// @brief Ö´ÐпË¡ + void DoClone(Animation* to) const; + +private: + Status status_; + bool running_; + bool detach_target_; + int loops_; + int loops_done_; + Duration delay_; + Duration elapsed_; + + AnimationEventHandlerPtr handler_; +}; + +/** @} */ + +inline void Animation::Resume() +{ + running_ = true; } + +inline void Animation::Pause() +{ + running_ = false; +} + +inline void Animation::Stop() +{ + Done(); +} + +inline void Animation::SetDelay(Duration delay) +{ + delay_ = delay; +} + +inline void Animation::SetLoops(int loops) +{ + loops_ = loops; +} + +inline void Animation::RemoveTargetWhenDone() +{ + detach_target_ = true; +} + +inline void Animation::Done() +{ + status_ = Status::Done; +} + +inline Animation::Status Animation::GetStatus() const +{ + return status_; +} + +inline bool Animation::IsRunning() const +{ + return running_; +} + +inline bool Animation::IsDone() const +{ + return status_ == Status::Done || status_ == Status::Removeable; +} + +inline bool Animation::IsRemoveable() const +{ + return status_ == Status::Removeable; +} + +inline void Animation::EmitEvent(Actor* target, AnimationEvent evt) +{ + if (handler_) + { + handler_->Handle(this, target, evt); + } +} + +inline int Animation::GetLoops() const +{ + return loops_; +} + +inline Duration Animation::GetDelay() const +{ + return delay_; +} + +inline void Animation::SetHandler(AnimationEventHandlerPtr handler) +{ + handler_ = handler; +} + +inline AnimationEventHandlerPtr Animation::GetHandler() const +{ + return handler_; +} + +inline Duration Animation::GetElapsed() const +{ + return elapsed_; +} + +inline int Animation::GetLoopsDone() const +{ + return loops_done_; +} + +} // namespace kiwano diff --git a/src/kiwano/2d/action/ActionGroup.cpp b/src/kiwano/2d/animation/AnimationGroup.cpp similarity index 55% rename from src/kiwano/2d/action/ActionGroup.cpp rename to src/kiwano/2d/animation/AnimationGroup.cpp index 7dd6292f..c1f8d33f 100644 --- a/src/kiwano/2d/action/ActionGroup.cpp +++ b/src/kiwano/2d/animation/AnimationGroup.cpp @@ -18,52 +18,45 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include -#include -#include +#include namespace kiwano { -ActionGroup::ActionGroup(const Vector& actions, bool parallel) -{ - SetEntity(MakePtr(actions, parallel)); -} - -ActionGroupEntity::ActionGroupEntity() +AnimationGroup::AnimationGroup() : parallel_(false) { } -ActionGroupEntity::ActionGroupEntity(const Vector& actions, bool parallel) +AnimationGroup::AnimationGroup(const Vector& animations, bool parallel) : parallel_(parallel) { - AddActions(actions); + AddAnimation(animations); } -ActionGroupEntity::~ActionGroupEntity() {} +AnimationGroup::~AnimationGroup() {} -void ActionGroupEntity::Init(Actor* target) +void AnimationGroup::Init(Actor* target) { - if (actions_.IsEmpty()) + if (animations_.IsEmpty()) { Done(); return; } - // reset all actions - for (current_ = actions_.GetFirst(); current_; current_ = current_->GetNext()) + // reset all animations + for (current_ = animations_.GetFirst(); current_; current_ = current_->GetNext()) { current_->Reset(); } if (!parallel_) { - current_ = actions_.GetFirst(); + current_ = animations_.GetFirst(); } } -void ActionGroupEntity::Update(Actor* target, Duration dt) +void AnimationGroup::Update(Actor* target, Duration dt) { if (!parallel_) { @@ -83,7 +76,7 @@ void ActionGroupEntity::Update(Actor* target, Duration dt) else { bool done = true; - for (current_ = actions_.GetFirst(); current_; current_ = current_->GetNext()) + for (current_ = animations_.GetFirst(); current_; current_ = current_->GetNext()) { if (!current_->IsDone()) { @@ -99,46 +92,46 @@ void ActionGroupEntity::Update(Actor* target, Duration dt) } } -void ActionGroupEntity::AddAction(ActionEntityPtr action) +void AnimationGroup::AddAnimation(AnimationPtr animation) { - if (action) + if (animation) { - actions_.PushBack(action); + animations_.PushBack(animation); } } -void ActionGroupEntity::AddActions(const Vector& actions) +void AnimationGroup::AddAnimation(const Vector& animations) { - for (const auto& action : actions) - AddAction(action); + for (const auto& animation : animations) + AddAnimation(animation); } -ActionGroupEntity* ActionGroupEntity::Clone() const +AnimationGroup* AnimationGroup::Clone() const { - Vector actions; - if (!actions_.IsEmpty()) + Vector animations; + if (!animations_.IsEmpty()) { - for (auto action = actions_.GetFirst(); action; action = action->GetNext()) + for (auto animation = animations_.GetFirst(); animation; animation = animation->GetNext()) { - actions.push_back(action->Clone()); + animations.push_back(animation->Clone()); } } - ActionGroupEntity* ptr = new ActionGroupEntity(actions, parallel_); + AnimationGroup* ptr = new AnimationGroup(animations, parallel_); DoClone(ptr); return ptr; } -ActionGroupEntity* ActionGroupEntity::Reverse() const +AnimationGroup* AnimationGroup::Reverse() const { - Vector actions; - if (!actions_.IsEmpty()) + Vector animations; + if (!animations_.IsEmpty()) { - for (auto action = actions_.GetLast(); action; action = action->GetPrev()) + for (auto animation = animations_.GetLast(); animation; animation = animation->GetPrev()) { - actions.push_back(action->Reverse()); + animations.push_back(animation->Reverse()); } } - ActionGroupEntity* ptr = new ActionGroupEntity(actions, parallel_); + AnimationGroup* ptr = new AnimationGroup(animations, parallel_); DoClone(ptr); return ptr; } diff --git a/src/kiwano/2d/action/ActionGroup.h b/src/kiwano/2d/animation/AnimationGroup.h similarity index 61% rename from src/kiwano/2d/action/ActionGroup.h rename to src/kiwano/2d/animation/AnimationGroup.h index 341f3904..81ce5348 100644 --- a/src/kiwano/2d/action/ActionGroup.h +++ b/src/kiwano/2d/animation/AnimationGroup.h @@ -19,65 +19,54 @@ // THE SOFTWARE. #pragma once -#include +#include namespace kiwano { -KGE_DECLARE_SMART_PTR(ActionGroupEntity); +KGE_DECLARE_SMART_PTR(AnimationGroup); /** - * \addtogroup Actions + * \addtogroup Animation * @{ */ + /// \~chinese /// @brief ¶¯»­×éºÏ -class KGE_API ActionGroup : public Action +class KGE_API AnimationGroup : public Animation { public: - /// \~chinese - /// @brief ´´½¨¶¯»­×éºÏ - /// @param actions ¶¯»­¼¯ºÏ - /// @param parallel ͬ²½Ö´ÐÐ - ActionGroup(const Vector& actions, bool parallel = false); -}; - -/// \~chinese -/// @brief ¶¯»­×éºÏʵÌå -class KGE_API ActionGroupEntity : public ActionEntity -{ -public: - ActionGroupEntity(); + AnimationGroup(); /// \~chinese /// @brief ´´½¨¶¯»­×éºÏ - /// @param actions ¶¯»­¼¯ºÏ + /// @param animations ¶¯»­¼¯ºÏ /// @param parallel ͬ²½Ö´ÐÐ - ActionGroupEntity(const Vector& actions, bool parallel = false); + AnimationGroup(const Vector& animations, bool parallel = false); - virtual ~ActionGroupEntity(); + virtual ~AnimationGroup(); /// \~chinese /// @brief Ìí¼Ó¶¯»­ - /// @param action ¶¯»­ - void AddAction(ActionEntityPtr action); + /// @param animation ¶¯»­ + void AddAnimation(AnimationPtr animation); /// \~chinese /// @brief Ìí¼Ó¶à¸ö¶¯»­ - /// @param actions ¶¯»­¼¯ºÏ - void AddActions(const Vector& actions); + /// @param animations ¶¯»­¼¯ºÏ + void AddAnimation(const Vector& animations); /// \~chinese /// @brief »ñÈ¡ËùÓж¯»­ - const ActionList& GetActions() const; + const AnimationList& GetAnimations() const; /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó - ActionGroupEntity* Clone() const override; + AnimationGroup* Clone() const override; /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª - ActionGroupEntity* Reverse() const override; + AnimationGroup* Reverse() const override; protected: void Init(Actor* target) override; @@ -86,15 +75,15 @@ protected: private: bool parallel_; - ActionEntityPtr current_; - ActionList actions_; + AnimationPtr current_; + AnimationList animations_; }; /** @} */ -inline const ActionList& ActionGroupEntity::GetActions() const +inline const AnimationList& AnimationGroup::GetAnimations() const { - return actions_; + return animations_; } } // namespace kiwano diff --git a/src/kiwano/2d/animation/AnimationWrapper.h b/src/kiwano/2d/animation/AnimationWrapper.h new file mode 100644 index 00000000..8deb8c65 --- /dev/null +++ b/src/kiwano/2d/animation/AnimationWrapper.h @@ -0,0 +1,311 @@ +// Copyright (c) 2020-2021 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 +#include +#include +#include +#include +#include + +namespace kiwano +{ + +/// \~chinese +/// @brief ¶¯»­°ü×°Æ÷ +class KGE_API AnimationWrapper +{ +public: + AnimationWrapper() = default; + + inline AnimationWrapper(AnimationPtr ptr) + : ptr(ptr) + { + } + + /// \~chinese + /// @brief ÉèÖÃÑ­»·´ÎÊý + inline AnimationWrapper& Loops(int loops) + { + if (ptr) + ptr->SetLoops(loops); + return (*this); + } + + /// \~chinese + /// @brief ÉèÖö¯»­ÑÓ³Ù + inline AnimationWrapper& Delay(Duration delay) + { + if (ptr) + ptr->SetDelay(delay); + return (*this); + } + + /// \~chinese + /// @brief ÉèÖö¯»­½áÊø»Øµ÷º¯Êý + inline AnimationWrapper& Handler(AnimationEventHandlerPtr handler) + { + if (ptr) + ptr->SetHandler(handler); + return (*this); + } + + /// \~chinese + /// @brief ¶¯»­½áÊøÊ±ÒÆ³ýÄ¿±ê½ÇÉ« + inline AnimationWrapper& RemoveTargetWhenDone() + { + if (ptr) + ptr->RemoveTargetWhenDone(); + return (*this); + } + + /// \~chinese + /// @brief ÉèÖÃÃû³Æ + inline AnimationWrapper& Name(const String& name) + { + if (ptr) + ptr->SetName(name); + return (*this); + } + + /// \~chinese + /// @brief ÉèÖûº¶¯º¯Êý + inline AnimationWrapper& Ease(const EaseFunc& ease) + { + auto tween = dynamic_cast(ptr.Get()); + if (tween) + { + tween->SetEaseFunc(ease); + } + return (*this); + } + + /// \~chinese + /// @brief ¿Ë¡¶¯»­ + inline AnimationWrapper Clone() const + { + if (ptr) + return AnimationWrapper(ptr->Clone()); + return AnimationWrapper(); + } + + /// \~chinese + /// @brief »ñÈ¡·´Ïò¶¯»­ + inline AnimationWrapper Reverse() const + { + if (ptr) + return AnimationWrapper(ptr->Reverse()); + return AnimationWrapper(); + } + + /// \~chinese + /// @brief »ñȡָÕë + inline Animation* Get() const + { + return const_cast(ptr.Get()); + } + + /// \~chinese + /// @brief ÉèÖö¯»­ + inline void SetEntity(AnimationPtr ptr) + { + this->ptr = ptr; + } + + inline Animation* operator->() const + { + return Get(); + } + + inline operator Animation*() const + { + return Get(); + } + + inline operator AnimationPtr() const + { + return ptr; + } + + inline operator bool() const + { + return ptr != nullptr; + } + +protected: + AnimationPtr ptr; +}; + +namespace animation +{ + +/// \~chinese +/// @brief ´´½¨Ïà¶ÔÎ»ÒÆ¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param displacement Î»ÒÆÏòÁ¿ +inline AnimationWrapper MoveBy(kiwano::Duration duration, const Vec2& displacement) +{ + return AnimationWrapper(new MoveByAnimation(duration, displacement)); +} + +/// \~chinese +/// @brief ´´½¨Î»Òƶ¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param distination Ä¿µÄ×ø±ê +inline AnimationWrapper MoveTo(kiwano::Duration duration, const Point& distination) +{ + return AnimationWrapper(new MoveToAnimation(duration, distination)); +} + +/// \~chinese +/// @brief ´´½¨Ïà¶ÔÌøÔ¾¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param displacement ÌøÔ¾Î»ÒÆÏòÁ¿ +/// @param height ÌøÔ¾¸ß¶È +/// @param count ÌøÔ¾´ÎÊý +inline AnimationWrapper JumpBy(kiwano::Duration duration, const Vec2& displacement, float height, int count = 1) +{ + return AnimationWrapper(new JumpByAnimation(duration, displacement, height, count)); +} + +/// \~chinese +/// @brief ´´½¨ÌøÔ¾¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param distination Ä¿µÄ×ø±ê +/// @param height ÌøÔ¾¸ß¶È +/// @param count ÌøÔ¾´ÎÊý +inline AnimationWrapper JumpTo(kiwano::Duration duration, const Point& distination, float height, int count = 1) +{ + return AnimationWrapper(new JumpToAnimation(duration, distination, height, count)); +} + +/// \~chinese +/// @brief ´´½¨Ïà¶ÔËõ·Å¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param scale Ëõ·ÅÏà¶Ô±ä»¯Öµ +inline AnimationWrapper ScaleBy(kiwano::Duration duration, Vec2 scale) +{ + return AnimationWrapper(new ScaleByAnimation(duration, scale)); +} + +/// \~chinese +/// @brief ´´½¨Ëõ·Å¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param scale Ëõ·ÅÄ¿±êÖµ +inline AnimationWrapper ScaleTo(kiwano::Duration duration, Vec2 scale) +{ + return AnimationWrapper(new ScaleToAnimation(duration, scale)); +} + +/// \~chinese +/// @brief ´´½¨Í¸Ã÷¶È½¥±ä¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param opacity Ä¿±ê͸Ã÷¶È +inline AnimationWrapper FadeTo(kiwano::Duration duration, float opacity) +{ + return AnimationWrapper(new FadeToAnimation(duration, opacity)); +} + +/// \~chinese +/// @brief ´´½¨µ­È붯»­ +/// @param duration ¶¯»­Ê±³¤ +inline AnimationWrapper FadeIn(kiwano::Duration duration) +{ + return AnimationWrapper(new FadeToAnimation(duration, 1.0f)); +} + +/// \~chinese +/// @brief ´´½¨µ­³ö¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +inline AnimationWrapper FadeOut(kiwano::Duration duration) +{ + return AnimationWrapper(new FadeToAnimation(duration, 0.0f)); +} + +/// \~chinese +/// @brief ´´½¨Ïà¶ÔÐýת¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param rotation ½Ç¶ÈÏà¶Ô±ä»¯Öµ +inline AnimationWrapper RotateBy(kiwano::Duration duration, float rotation) +{ + return AnimationWrapper(new RotateByAnimation(duration, rotation)); +} + +/// \~chinese +/// @brief ´´½¨Ðýת¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param rotation Ä¿±ê½Ç¶È +inline AnimationWrapper RotateTo(kiwano::Duration duration, float rotation) +{ + return AnimationWrapper(new RotateToAnimation(duration, rotation)); +} + +/// \~chinese +/// @brief ´´½¨×Ô¶¨Ò嶯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param tween_func ¶¯»­»Øµ÷º¯Êý +inline AnimationWrapper Custom(kiwano::Duration duration, TweenFunc tween_func) +{ + return AnimationWrapper(new CustomAnimation(duration, tween_func)); +} + +/// \~chinese +/// @brief ´´½¨Â·¾¶ÐÐ×ß¶¯»­ +/// @param duration ³ÖÐøÊ±³¤ +/// @param path ·¾¶ÐÎ×´ +/// @param rotating ÊÇ·ñÑØÂ·¾¶ÇÐÏß·½ÏòÐýת +/// @param start ·¾¶Æðµã£¨°Ù·Ö±È£© +/// @param end ·¾¶Öյ㣨°Ù·Ö±È£© +inline AnimationWrapper Path(kiwano::Duration duration, ShapePtr path, bool rotating = false, float start = 0.f, + float end = 1.f) +{ + return AnimationWrapper(new PathAnimation(duration, path, rotating, start, end)); +} + +/// \~chinese +/// @brief ´´½¨ÑÓʱ¶¯»­ +/// @param delay ÑÓʱʱ³¤ +inline AnimationWrapper Delay(kiwano::Duration delay) +{ + return AnimationWrapper(new DelayAnimation(delay)); +} + +/// \~chinese +/// @brief ´´½¨Ö¡¶¯»­ +/// @param duration ¶¯»­Ê±³¤ +/// @param frame_seq ÐòÁÐÖ¡ +inline AnimationWrapper Frames(kiwano::Duration duration, FrameSequencePtr frame_seq) +{ + return AnimationWrapper(new FrameAnimation(duration, frame_seq)); +} + +/// \~chinese +/// @brief ´´½¨¶¯»­×éºÏ +/// @param actions ¶¯»­¼¯ºÏ +/// @param parallel ͬ²½Ö´ÐÐ +inline AnimationWrapper Group(const Vector& animations, bool parallel = false) +{ + return AnimationWrapper(new AnimationGroup(animations, parallel)); +} + +} // namespace animation +} // namespace kiwano diff --git a/src/kiwano/2d/action/ActionScheduler.cpp b/src/kiwano/2d/animation/Animator.cpp similarity index 51% rename from src/kiwano/2d/action/ActionScheduler.cpp rename to src/kiwano/2d/animation/Animator.cpp index e1ff9f77..c2ab51f9 100644 --- a/src/kiwano/2d/action/ActionScheduler.cpp +++ b/src/kiwano/2d/animation/Animator.cpp @@ -19,87 +19,87 @@ // THE SOFTWARE. #include -#include +#include #include namespace kiwano { -void ActionScheduler::Update(Actor* target, Duration dt) +void Animator::Update(Actor* target, Duration dt) { - if (actions_.IsEmpty() || !target) + if (animations_.IsEmpty() || !target) return; - ActionEntityPtr next; - for (auto action = actions_.GetFirst(); action; action = next) + AnimationPtr next; + for (auto animation = animations_.GetFirst(); animation; animation = next) { - next = action->GetNext(); + next = animation->GetNext(); - if (action->IsRunning()) - action->UpdateStep(target, dt); + if (animation->IsRunning()) + animation->UpdateStep(target, dt); - if (action->IsRemoveable()) - actions_.Remove(action); + if (animation->IsRemoveable()) + animations_.Remove(animation); } } -ActionEntity* ActionScheduler::AddAction(ActionEntityPtr action) +Animation* Animator::AddAnimation(AnimationPtr animation) { - KGE_ASSERT(action && "AddAction failed, NULL pointer exception"); + KGE_ASSERT(animation && "AddAnimation failed, NULL pointer exception"); - if (action) + if (animation) { - actions_.PushBack(action); + animations_.PushBack(animation); } - return action.Get(); + return animation.Get(); } -void ActionScheduler::ResumeAllActions() +void Animator::ResumeAllAnimations() { - if (actions_.IsEmpty()) + if (animations_.IsEmpty()) return; - for (auto& action : actions_) + for (auto& animation : animations_) { - action->Resume(); + animation->Resume(); } } -void ActionScheduler::PauseAllActions() +void Animator::PauseAllAnimations() { - if (actions_.IsEmpty()) + if (animations_.IsEmpty()) return; - for (auto& action : actions_) + for (auto& animation : animations_) { - action->Pause(); + animation->Pause(); } } -void ActionScheduler::StopAllActions() +void Animator::StopAllAnimations() { - if (actions_.IsEmpty()) + if (animations_.IsEmpty()) return; - for (auto& action : actions_) + for (auto& animation : animations_) { - action->Stop(); + animation->Stop(); } } -ActionEntity* ActionScheduler::GetAction(const String& name) +Animation* Animator::GetAnimation(const String& name) { - if (actions_.IsEmpty()) + if (animations_.IsEmpty()) return nullptr; - for (auto& action : actions_) - if (action->IsName(name)) - return action.Get(); + for (auto& animation : animations_) + if (animation->IsName(name)) + return animation.Get(); return nullptr; } -const ActionList& ActionScheduler::GetAllActions() const +const AnimationList& Animator::GetAllAnimations() const { - return actions_; + return animations_; } } // namespace kiwano diff --git a/src/kiwano/2d/action/ActionScheduler.h b/src/kiwano/2d/animation/Animator.h similarity index 76% rename from src/kiwano/2d/action/ActionScheduler.h rename to src/kiwano/2d/animation/Animator.h index 60a6dc20..2a458ffe 100644 --- a/src/kiwano/2d/action/ActionScheduler.h +++ b/src/kiwano/2d/animation/Animator.h @@ -19,13 +19,13 @@ // THE SOFTWARE. #pragma once -#include +#include namespace kiwano { /** - * \addtogroup Actions + * \addtogroup Animation * @{ */ @@ -33,40 +33,47 @@ namespace kiwano * \~chinese * @brief ¶¯»­µ÷¶ÈÆ÷ */ -class KGE_API ActionScheduler +class KGE_API Animator { public: /// \~chinese /// @brief Ìí¼Ó¶¯»­ - ActionEntity* AddAction(ActionEntityPtr action); + Animation* AddAnimation(AnimationPtr animation); + + /// \~chinese + /// @brief ¿ªÊ¼¶¯»­ + inline Animation* StartAnimation(AnimationPtr animation) + { + return AddAnimation(animation); + } /// \~chinese /// @brief ¼ÌÐøËùÓÐÔÝÍ£¶¯»­ - void ResumeAllActions(); + void ResumeAllAnimations(); /// \~chinese /// @brief ÔÝÍ£ËùÓж¯»­ - void PauseAllActions(); + void PauseAllAnimations(); /// \~chinese /// @brief Í£Ö¹ËùÓж¯»­ - void StopAllActions(); + void StopAllAnimations(); /// \~chinese /// @brief »ñȡָ¶¨Ãû³ÆµÄ¶¯»­ /// @param name ¶¯»­Ãû³Æ - ActionEntity* GetAction(const String& name); + Animation* GetAnimation(const String& name); /// \~chinese /// @brief »ñÈ¡ËùÓж¯»­ - const ActionList& GetAllActions() const; + const AnimationList& GetAllAnimations() const; /// \~chinese /// @brief ¸üж¯»­ void Update(Actor* target, Duration dt); private: - ActionList actions_; + AnimationList animations_; }; /** @} */ diff --git a/src/kiwano/2d/animation/Key.h b/src/kiwano/2d/animation/CustomAnimation.cpp similarity index 52% rename from src/kiwano/2d/animation/Key.h rename to src/kiwano/2d/animation/CustomAnimation.cpp index 2e5f241a..3656eef3 100644 --- a/src/kiwano/2d/animation/Key.h +++ b/src/kiwano/2d/animation/CustomAnimation.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2020 Kiwano - Nomango +// 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 @@ -18,52 +18,34 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#pragma once -#include +#include namespace kiwano { -template -class KeyValue +CustomAnimation::CustomAnimation(Duration duration, TweenFunc tween_func) + : TweenAnimation(duration) + , tween_func_(tween_func) { -public: - typedef _Ty value_type; - typedef Value<_Ty, _NotifierTy> property_type; - - inline KeyValue(const property_type& prop, value_type end_value) - : end_value_(end_value) - , prop_(prop) - , interpolator_() - { - } - - inline KeyValue(const property_type& prop, value_type end_value, const EaseFunc& ease_func) - : end_value_(end_value) - , prop_(prop) - , interpolator_(ease_func) - { - } - - inline property_type GetProperty() const - { - return prop_; - } - - inline value_type GetEndValue() const - { - return end_value_; - } - - inline const Interpolator& GetInterpolator() const - { - return interpolator_; - } - -private: - property_type prop_; - value_type end_value_; - Interpolator interpolator_; -}; - } + +CustomAnimation* CustomAnimation::Clone() const +{ + CustomAnimation* ptr = new CustomAnimation(GetDuration(), tween_func_); + DoClone(ptr); + return ptr; +} + +void CustomAnimation::Init(Actor* target) +{ + if (!tween_func_) + this->Done(); +} + +void CustomAnimation::UpdateTween(Actor* target, float frac) +{ + if (tween_func_) + tween_func_(target, frac); +} + +} // namespace kiwano diff --git a/src/kiwano/2d/action/Animation.h b/src/kiwano/2d/animation/CustomAnimation.h similarity index 55% rename from src/kiwano/2d/action/Animation.h rename to src/kiwano/2d/animation/CustomAnimation.h index 714529ad..3c41c745 100644 --- a/src/kiwano/2d/action/Animation.h +++ b/src/kiwano/2d/animation/CustomAnimation.h @@ -19,72 +19,75 @@ // THE SOFTWARE. #pragma once -#include -#include +#include namespace kiwano { - -KGE_DECLARE_SMART_PTR(AnimationEntity); +KGE_DECLARE_SMART_PTR(CustomAnimation); /** - * \addtogroup Actions + * \addtogroup Animation * @{ */ + /// \~chinese -/// @brief Ö¡¶¯»­ -class KGE_API Animation : public ActionTween +/// @brief ²¹¼ä¶¯»­»Øµ÷º¯Êý +/// @details ÔÚ¶¯»­¸üÐÂʱ»Øµ÷¸Ãº¯Êý£¬µÚÒ»¸ö²ÎÊýÊÇÖ´Ðж¯»­µÄÄ¿±ê£¬µÚ¶þ¸ö²ÎÊýÊǶ¯»­½ø¶È£¨0.0 - 1.0£© +using TweenFunc = Function; + +/// \~chinese +/// @brief ×Ô¶¨Ò嶯»­ +class KGE_API CustomAnimation : public TweenAnimation { public: /// \~chinese - /// @brief ´´½¨Ö¡¶¯»­ - /// @param dur ¶¯»­Ê±³¤ - /// @param frame_seq ÐòÁÐÖ¡ - Animation(Duration dur, FrameSequencePtr frame_seq); -}; - -/// \~chinese -/// @brief Ö¡¶¯»­ÊµÌå -class KGE_API AnimationEntity : public ActionTweenEntity -{ -public: - AnimationEntity(); + /// @brief ´´½¨×Ô¶¨Ò嶯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param tween_func ¶¯»­»Øµ÷º¯Êý + CustomAnimation(Duration duration, TweenFunc tween_func); /// \~chinese - /// @brief ´´½¨Ö¡¶¯»­ - /// @param dur ¶¯»­Ê±³¤ - /// @param frame_seq ÐòÁÐÖ¡ - AnimationEntity(Duration dur, FrameSequencePtr frame_seq); - - virtual ~AnimationEntity(); + /// @brief »ñÈ¡¶¯»­»Øµ÷º¯Êý + TweenFunc GetTweenFunc() const; /// \~chinese - /// @brief »ñÈ¡ÐòÁÐÖ¡ - FrameSequencePtr GetFrameSequence() const; - - /// \~chinese - /// @brief ÉèÖÃÐòÁÐÖ¡ - /// @param[in] frame_seq ÐòÁÐÖ¡ - void SetFrameSequence(FrameSequencePtr frame_seq); + /// @brief ÉèÖö¯»­»Øµ÷º¯Êý + void SetTweenFunc(const TweenFunc& tween_func); /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó - AnimationEntity* Clone() const override; + CustomAnimation* Clone() const override; /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª - AnimationEntity* Reverse() const override; + CustomAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in CustomAnimation"); + return nullptr; + } protected: void Init(Actor* target) override; - void UpdateTween(Actor* target, float percent) override; + void UpdateTween(Actor* target, float frac) override; private: - FrameSequencePtr frame_seq_; + TweenFunc tween_func_; }; /** @} */ + + +inline TweenFunc CustomAnimation::GetTweenFunc() const +{ + return tween_func_; +} + +inline void CustomAnimation::SetTweenFunc(const TweenFunc& tween_func) +{ + tween_func_ = tween_func; +} + } // namespace kiwano diff --git a/src/kiwano/2d/action/ActionDelay.cpp b/src/kiwano/2d/animation/DelayAnimation.cpp similarity index 77% rename from src/kiwano/2d/action/ActionDelay.cpp rename to src/kiwano/2d/animation/DelayAnimation.cpp index 1a9017e8..19be3ccc 100644 --- a/src/kiwano/2d/action/ActionDelay.cpp +++ b/src/kiwano/2d/animation/DelayAnimation.cpp @@ -18,29 +18,24 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include namespace kiwano { -ActionDelay::ActionDelay(Duration delay) -{ - SetEntity(MakePtr(delay)); -} - -ActionDelayEntity::ActionDelayEntity(Duration delay) +DelayAnimation::DelayAnimation(Duration delay) { this->SetDelay(delay); } -ActionDelayEntity* ActionDelayEntity::Clone() const +DelayAnimation* DelayAnimation::Clone() const { - ActionDelayEntity* ptr = new ActionDelayEntity(GetDelay()); + DelayAnimation* ptr = new DelayAnimation(GetDelay()); DoClone(ptr); return ptr; } -ActionDelayEntity* ActionDelayEntity::Reverse() const +DelayAnimation* DelayAnimation::Reverse() const { return Clone(); } diff --git a/src/kiwano/2d/action/ActionDelay.h b/src/kiwano/2d/animation/DelayAnimation.h similarity index 74% rename from src/kiwano/2d/action/ActionDelay.h rename to src/kiwano/2d/animation/DelayAnimation.h index 51b39681..f882ff58 100644 --- a/src/kiwano/2d/action/ActionDelay.h +++ b/src/kiwano/2d/animation/DelayAnimation.h @@ -19,46 +19,36 @@ // THE SOFTWARE. #pragma once -#include +#include namespace kiwano { -KGE_DECLARE_SMART_PTR(ActionDelayEntity); +KGE_DECLARE_SMART_PTR(DelayAnimation); /** - * \addtogroup Actions + * \addtogroup Animation * @{ */ -/// \~chinese -/// @brief ÑÓʱ¶¯»­ -class KGE_API ActionDelay : public Action -{ -public: - /// \~chinese - /// @brief ´´½¨ÑÓʱ¶¯»­ - /// @param delay ÑÓʱʱ³¤ - ActionDelay(Duration delay); -}; /// \~chinese -/// @brief ÑÓʱ¶¯»­ÊµÌå -class KGE_API ActionDelayEntity : public ActionEntity +/// @brief ÑÓʱ¶¯»­ +class KGE_API DelayAnimation : public Animation { public: /// \~chinese /// @brief ´´½¨ÑÓʱ¶¯»­ /// @param delay ÑÓʱʱ³¤ - ActionDelayEntity(Duration delay); + DelayAnimation(Duration delay); /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó - ActionDelayEntity* Clone() const override; + DelayAnimation* Clone() const override; /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª - ActionDelayEntity* Reverse() const override; + DelayAnimation* Reverse() const override; }; /** @} */ diff --git a/src/kiwano/2d/animation/FrameAnimation.cpp b/src/kiwano/2d/animation/FrameAnimation.cpp index c7b1420a..966724d8 100644 --- a/src/kiwano/2d/animation/FrameAnimation.cpp +++ b/src/kiwano/2d/animation/FrameAnimation.cpp @@ -18,9 +18,90 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include +#include namespace kiwano { +FrameAnimation::FrameAnimation() + : frame_seq_(nullptr) +{ } + +FrameAnimation::FrameAnimation(Duration dur, FrameSequencePtr frame_seq) + : TweenAnimation(dur) + , frame_seq_(frame_seq) +{ +} + +FrameAnimation::~FrameAnimation() {} + +FrameSequencePtr FrameAnimation::GetFrameSequence() const +{ + return frame_seq_; +} + +void FrameAnimation::SetFrameSequence(FrameSequencePtr frame_seq) +{ + frame_seq_ = frame_seq; +} + +void FrameAnimation::Init(Actor* target) +{ + KGE_ASSERT(frame_seq_ && "FrameAnimation::Init() failed: FrameSequence is NULL!"); + if (!frame_seq_ || frame_seq_->GetFrames().empty()) + { + Done(); + return; + } + + auto sprite_target = dynamic_cast(target); + KGE_ASSERT(sprite_target && "FrameAnimation only supports Sprites!"); + + if (sprite_target && frame_seq_) + { + sprite_target->SetKeyFrame(frame_seq_->GetFrames()[0]); + current_index_ = 0; + } +} + +void FrameAnimation::UpdateTween(Actor* target, float percent) +{ + auto sprite_target = dynamic_cast(target); + + if (sprite_target && frame_seq_) + { + const auto& frames = frame_seq_->GetFrames(); + auto size = frames.size(); + auto index = std::min(static_cast(math::Floor(size * percent)), size - 1); + + if (index != current_index_) + { + current_index_ = index; + sprite_target->SetKeyFrame(frames[index]); + } + } +} + +FrameAnimation* FrameAnimation::Clone() const +{ + FrameAnimation* ptr = new FrameAnimation(GetDuration(), frame_seq_); + DoClone(ptr); + return ptr; +} + +FrameAnimation* FrameAnimation::Reverse() const +{ + FrameAnimation* ptr = new FrameAnimation(GetDuration(), nullptr); + DoClone(ptr); + + if (frame_seq_) + { + FrameSequencePtr frames = frame_seq_->Reverse(); + ptr->SetFrameSequence(frames); + } + return ptr; +} + +} // namespace kiwano diff --git a/src/kiwano/2d/animation/FrameAnimation.h b/src/kiwano/2d/animation/FrameAnimation.h index dba82b5f..4fb25441 100644 --- a/src/kiwano/2d/animation/FrameAnimation.h +++ b/src/kiwano/2d/animation/FrameAnimation.h @@ -19,11 +19,61 @@ // THE SOFTWARE. #pragma once -#include +#include +#include namespace kiwano { +KGE_DECLARE_SMART_PTR(FrameAnimation); +/** + * \addtogroup Animation + * @{ + */ -} +/// \~chinese +/// @brief Ö¡¶¯»­ +class KGE_API FrameAnimation : public TweenAnimation +{ +public: + FrameAnimation(); + + /// \~chinese + /// @brief ´´½¨Ö¡¶¯»­ + /// @param dur ¶¯»­Ê±³¤ + /// @param frame_seq ÐòÁÐÖ¡ + FrameAnimation(Duration dur, FrameSequencePtr frame_seq); + + virtual ~FrameAnimation(); + + /// \~chinese + /// @brief »ñÈ¡ÐòÁÐÖ¡ + FrameSequencePtr GetFrameSequence() const; + + /// \~chinese + /// @brief ÉèÖÃÐòÁÐÖ¡ + /// @param[in] frame_seq ÐòÁÐÖ¡ + void SetFrameSequence(FrameSequencePtr frame_seq); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + FrameAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + FrameAnimation* Reverse() const override; + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float percent) override; + +private: + size_t current_index_; + FrameSequencePtr frame_seq_; +}; + +/** @} */ + +} // namespace kiwano diff --git a/src/kiwano/render/FrameSequence.cpp b/src/kiwano/2d/animation/FrameSequence.cpp similarity index 73% rename from src/kiwano/render/FrameSequence.cpp rename to src/kiwano/2d/animation/FrameSequence.cpp index 8a8add29..4b271395 100644 --- a/src/kiwano/render/FrameSequence.cpp +++ b/src/kiwano/2d/animation/FrameSequence.cpp @@ -18,28 +18,22 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include #include namespace kiwano { -FrameSequence::FrameSequence(const Vector& frames) -{ - AddFrames(frames); -} - -FrameSequence::FrameSequence(FramePtr frame, int cols, int rows, int max_num, float padding_x, - float padding_y) -{ - AddFrames(frame, cols, rows, max_num, padding_x, padding_y); -} - FrameSequence::FrameSequence() {} FrameSequence::~FrameSequence() {} -void FrameSequence::AddFrame(FramePtr frame) +FrameSequence::FrameSequence(const Vector& frames) +{ + AddFrames(frames); +} + +void FrameSequence::AddFrame(KeyFramePtr frame) { if (frame) { @@ -51,7 +45,7 @@ void FrameSequence::AddFrame(FramePtr frame) } } -void FrameSequence::AddFrames(const Vector& frames) +void FrameSequence::AddFrames(const Vector& frames) { if (frames_.empty()) frames_ = frames; @@ -63,58 +57,13 @@ void FrameSequence::AddFrames(const Vector& frames) } } -void FrameSequence::AddFrames(FramePtr frame, int cols, int rows, int max_num, float padding_x, float padding_y) -{ - if (cols <= 0 || rows <= 0 || max_num == 0) - return; - - if (!frame) - return; - - Rect src_rect = frame->GetCropRect(); - float raw_width = src_rect.GetWidth(); - float raw_height = src_rect.GetHeight(); - float width = (raw_width - (cols - 1) * padding_x) / cols; - float height = (raw_height - (rows - 1) * padding_y) / rows; - - Vector frames; - frames.reserve((max_num > 0) ? max_num : (rows * cols)); - - int current_num = 0; - - float dty = src_rect.GetTop(); - for (int i = 0; i < rows; i++) - { - float dtx = src_rect.GetLeft(); - - for (int j = 0; j < cols; j++) - { - FramePtr ptr = MakePtr(); - if (ptr) - { - ptr->SetTexture(frame->GetTexture()); - ptr->SetCropRect(Rect{ dtx, dty, dtx + width, dty + height }); - frames.push_back(ptr); - ++current_num; - } - dtx += (width + padding_x); - } - dty += (height + padding_y); - - if (max_num > 0 && current_num == max_num) - break; - } - - AddFrames(frames); -} - -FramePtr FrameSequence::GetFrame(size_t index) const +KeyFramePtr FrameSequence::GetFrame(size_t index) const { KGE_ASSERT(index < frames_.size()); return frames_[index]; } -const Vector& FrameSequence::GetFrames() const +const Vector& FrameSequence::GetFrames() const { return frames_; } @@ -147,4 +96,62 @@ FrameSequencePtr FrameSequence::Reverse() const return frame_seq; } +KeyFrameSpliter::KeyFrameSpliter(TexturePtr texture) + : texture(texture) +{ + if (texture) + { + crop_rect = Rect(Point(), texture->GetSize()); + } +} + +KeyFrameSpliter::KeyFrameSpliter(TexturePtr texture, const Rect& crop_rect) + : texture(texture) + , crop_rect(crop_rect) +{ +} + +Vector KeyFrameSpliter::Split(int cols, int rows, int max_num, float padding_x, float padding_y) +{ + if (cols <= 0 || rows <= 0 || max_num == 0) + return {}; + + if (!texture) + return {}; + + float raw_width = crop_rect.GetWidth(); + float raw_height = crop_rect.GetHeight(); + float width = (raw_width - (cols - 1) * padding_x) / cols; + float height = (raw_height - (rows - 1) * padding_y) / rows; + + Vector frames; + frames.reserve((max_num > 0) ? max_num : (rows * cols)); + + int current_num = 0; + + float dty = crop_rect.GetTop(); + for (int i = 0; i < rows; i++) + { + float dtx = crop_rect.GetLeft(); + + for (int j = 0; j < cols; j++) + { + KeyFramePtr ptr = MakePtr(); + if (ptr) + { + ptr->SetTexture(texture); + ptr->SetCropRect(Rect{ dtx, dty, dtx + width, dty + height }); + frames.push_back(ptr); + ++current_num; + } + dtx += (width + padding_x); + } + dty += (height + padding_y); + + if (max_num > 0 && current_num == max_num) + break; + } + return frames; +} + } // namespace kiwano diff --git a/src/kiwano/render/FrameSequence.h b/src/kiwano/2d/animation/FrameSequence.h similarity index 69% rename from src/kiwano/render/FrameSequence.h rename to src/kiwano/2d/animation/FrameSequence.h index ab54b5a2..ba0234f6 100644 --- a/src/kiwano/render/FrameSequence.h +++ b/src/kiwano/2d/animation/FrameSequence.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include #include @@ -36,19 +36,8 @@ class KGE_API FrameSequence : public ObjectBase public: /// \~chinese /// @brief ´´½¨ÐòÁÐÖ¡ - /// @param frames ͼÏñÖ¡¼¯ºÏ - FrameSequence(const Vector& frames); - - /// \~chinese - /// @brief °´ÐÐÁзָîͼÏñ²¢´´½¨ÐòÁÐÖ¡ - /// @param frame ͼÏñÖ¡ - /// @param cols ÁÐÊý - /// @param rows ÐÐÊý - /// @param max_num ×î´óÖ¡ÊýÁ¿£¬Éè-1Ϊ½«·Ö¸îºóµÄͼÏñÈ«²¿×÷ΪÐòÁÐÖ¡ - /// @param padding_x X·½Ïò¼ä¸ô - /// @param padding_y Y·½Ïò¼ä¸ô - FrameSequence(FramePtr frame, int cols, int rows = 1, int max_num = -1, float padding_x = 0, - float padding_y = 0); + /// @param frames ¹Ø¼üÖ¡¼¯ºÏ + FrameSequence(const Vector& frames); /// \~chinese /// @brief ¹¹½¨¿ÕÐòÁÐÖ¡ @@ -58,32 +47,22 @@ public: /// \~chinese /// @brief Ìí¼Ó¹Ø¼üÖ¡ - /// @param frame ͼÏñÖ¡ - void AddFrame(FramePtr frame); + /// @param frame ¹Ø¼üÖ¡ + void AddFrame(KeyFramePtr frame); /// \~chinese /// @brief Ìí¼Ó¶à¸ö¹Ø¼üÖ¡ - /// @param frames ͼÏñÖ¡¼¯ºÏ - void AddFrames(const Vector& frames); - - /// \~chinese - /// @brief °´ÐÐÁзָîͼÏñ²¢Ìí¼ÓÐòÁÐÖ¡ - /// @param frame ͼÏñÖ¡ - /// @param cols ÁÐÊý - /// @param rows ÐÐÊý - /// @param max_num ×î´óÖ¡ÊýÁ¿£¬Éè-1Ϊ½«·Ö¸îºóµÄͼÏñÈ«²¿×÷ΪÐòÁÐÖ¡ - /// @param padding_x X·½Ïò¼ä¸ô - /// @param padding_y Y·½Ïò¼ä¸ô - void AddFrames(FramePtr frame, int cols, int rows = 1, int max_num = -1, float padding_x = 0, float padding_y = 0); + /// @param frames ¹Ø¼üÖ¡¼¯ºÏ + void AddFrames(const Vector& frames); /// \~chinese /// @brief »ñÈ¡¹Ø¼üÖ¡ - /// @param index ͼÏñ֡ϱê - FramePtr GetFrame(size_t index) const; + /// @param index ¹Ø¼ü֡ϱê + KeyFramePtr GetFrame(size_t index) const; /// \~chinese /// @brief »ñÈ¡ËùÓйؼüÖ¡ - const Vector& GetFrames() const; + const Vector& GetFrames() const; /// \~chinese /// @brief »ñÈ¡¹Ø¼üÖ¡ÊýÁ¿ @@ -98,6 +77,37 @@ public: FrameSequencePtr Reverse() const; private: - Vector frames_; + Vector frames_; }; + +/// \~chinese +/// @brief ÐòÁÐ֡ͼÏñ·Ö¸îÆ÷ +struct KGE_API KeyFrameSpliter +{ + TexturePtr texture; + Rect crop_rect; + + KeyFrameSpliter() = default; + + /// \~chinese + /// @brief ´´½¨ÐòÁÐ֡ͼÏñ·Ö¸îÆ÷ + /// @param texture ͼÏñ + KeyFrameSpliter(TexturePtr texture); + + /// \~chinese + /// @brief ´´½¨ÐòÁÐ֡ͼÏñ·Ö¸îÆ÷ + /// @param texture ͼÏñ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + KeyFrameSpliter(TexturePtr texture, const Rect& crop_rect); + + /// \~chinese + /// @brief °´ÐÐÁзָîͼÏñ²¢´´½¨ÐòÁÐÖ¡ + /// @param cols ÁÐÊý + /// @param rows ÐÐÊý + /// @param max_num ×î´óÖ¡ÊýÁ¿£¬Éè-1Ϊ½«·Ö¸îºóµÄͼÏñÈ«²¿×÷ΪÐòÁÐÖ¡ + /// @param padding_x X·½Ïò¼ä¸ô + /// @param padding_y Y·½Ïò¼ä¸ô + Vector Split(int cols, int rows = 1, int max_num = -1, float padding_x = 0, float padding_y = 0); +}; + } // namespace kiwano diff --git a/src/kiwano/2d/animation/Interpolator.h b/src/kiwano/2d/animation/Interpolator.h deleted file mode 100644 index 1ee64a70..00000000 --- a/src/kiwano/2d/animation/Interpolator.h +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2019-2020 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 -#include - -namespace kiwano -{ - -#define KGE_INTERPOLATOR_NUMRIC_INTERPOLATE_IMPL(TYPE) \ - inline TYPE Interpolate(TYPE start, TYPE end, float frac) \ - { \ - return NumricInterpolate(start, end, Fraction(frac)); \ - } - -class KGE_API Interpolator -{ -public: - inline Interpolator() {} - - inline Interpolator(const EaseFunc& ease_func) - : ease_func_(ease_func) - { - } - - KGE_INTERPOLATOR_NUMRIC_INTERPOLATE_IMPL(int) - KGE_INTERPOLATOR_NUMRIC_INTERPOLATE_IMPL(unsigned) - KGE_INTERPOLATOR_NUMRIC_INTERPOLATE_IMPL(float) - KGE_INTERPOLATOR_NUMRIC_INTERPOLATE_IMPL(double) - - template - inline _Ty Interpolate(_Ty start, _Ty end, float frac) - { - if (NumricInterpolate(0, 1, Fraction(frac)) == 1) - return end; - return start; - } - -private: - inline float Fraction(float frac) - { - if (ease_func_) - { - return ease_func_(frac); - } - return frac; - } - - template - inline _Ty NumricInterpolate(_Ty start, _Ty end, float frac) - { - return start + static_cast<_Ty>(math::Floor(static_cast(end - start) * frac)); - } - -private: - EaseFunc ease_func_; -}; - -} diff --git a/src/kiwano/render/Frame.cpp b/src/kiwano/2d/animation/KeyFrame.cpp similarity index 76% rename from src/kiwano/render/Frame.cpp rename to src/kiwano/2d/animation/KeyFrame.cpp index 54185929..d2779a35 100644 --- a/src/kiwano/render/Frame.cpp +++ b/src/kiwano/2d/animation/KeyFrame.cpp @@ -18,29 +18,47 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include namespace kiwano { -Frame::Frame(const String& file_path) +KeyFrame::KeyFrame() {} + +KeyFrame::KeyFrame(const String& file_path) { Load(file_path); } -Frame::Frame(const Resource& res) +KeyFrame::KeyFrame(const Resource& res) { Load(res); } -Frame::Frame(TexturePtr texture) +KeyFrame::KeyFrame(TexturePtr texture) { SetTexture(texture); } -Frame::Frame() {} +KeyFrame::KeyFrame(const String& file_path, const Rect& crop_rect) + : KeyFrame(file_path) +{ + SetCropRect(crop_rect); +} -bool Frame::Load(const String& file_path) +KeyFrame::KeyFrame(const Resource& res, const Rect& crop_rect) + : KeyFrame(res) +{ + SetCropRect(crop_rect); +} + +KeyFrame::KeyFrame(TexturePtr texture, const Rect& crop_rect) + : KeyFrame(texture) +{ + SetCropRect(crop_rect); +} + +bool KeyFrame::Load(const String& file_path) { TexturePtr texture = Texture::Preload(file_path); if (texture->IsValid()) @@ -51,7 +69,7 @@ bool Frame::Load(const String& file_path) return false; } -bool Frame::Load(const Resource& res) +bool KeyFrame::Load(const Resource& res) { TexturePtr texture = Texture::Preload(res); if (texture->IsValid()) @@ -62,7 +80,7 @@ bool Frame::Load(const Resource& res) return false; } -void Frame::SetCropRect(const Rect& crop_rect) +void KeyFrame::SetCropRect(const Rect& crop_rect) { if (texture_->IsValid()) { @@ -74,7 +92,7 @@ void Frame::SetCropRect(const Rect& crop_rect) } } -void Frame::SetTexture(TexturePtr texture) +void KeyFrame::SetTexture(TexturePtr texture) { texture_ = texture; if (texture_->IsValid()) diff --git a/src/kiwano/render/Frame.h b/src/kiwano/2d/animation/KeyFrame.h similarity index 56% rename from src/kiwano/render/Frame.h rename to src/kiwano/2d/animation/KeyFrame.h index 96e45b60..2fb40457 100644 --- a/src/kiwano/render/Frame.h +++ b/src/kiwano/2d/animation/KeyFrame.h @@ -19,38 +19,53 @@ // THE SOFTWARE. #pragma once -#include #include namespace kiwano { -KGE_DECLARE_SMART_PTR(Frame); +KGE_DECLARE_SMART_PTR(KeyFrame); /** * \~chinese - * @brief ͼÏñÖ¡ + * @brief ¹Ø¼üÖ¡ */ -class KGE_API Frame : public ObjectBase +class KGE_API KeyFrame : public ObjectBase { public: + KeyFrame(); + /// \~chinese - /// @brief ´´½¨Í¼ÏñÖ¡ + /// @brief ´´½¨¹Ø¼üÖ¡ /// @param file_path ͼÏñ·¾¶ - Frame(const String& file_path); + KeyFrame(const String& file_path); /// \~chinese - /// @brief ´´½¨Í¼ÏñÖ¡ + /// @brief ´´½¨¹Ø¼üÖ¡ /// @param res ͼÏñ×ÊÔ´ - Frame(const Resource& res); + KeyFrame(const Resource& res); /// \~chinese - /// @brief ´´½¨Í¼ÏñÖ¡ + /// @brief ´´½¨¹Ø¼üÖ¡ /// @param texture ÎÆÀí - Frame(TexturePtr texture); + KeyFrame(TexturePtr texture); /// \~chinese - /// @brief ¹¹½¨¿ÕͼÏñÖ¡ - Frame(); + /// @brief ´´½¨¹Ø¼üÖ¡ + /// @param file_path ͼÏñ·¾¶ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + KeyFrame(const String& file_path, const Rect& crop_rect); + + /// \~chinese + /// @brief ´´½¨¹Ø¼üÖ¡ + /// @param res ͼÏñ×ÊÔ´ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + KeyFrame(const Resource& res, const Rect& crop_rect); + + /// \~chinese + /// @brief ´´½¨¹Ø¼üÖ¡ + /// @param texture ÎÆÀí + /// @param crop_rect ²Ã¼ô¾ØÐÎ + KeyFrame(TexturePtr texture, const Rect& crop_rect); /// \~chinese /// @brief ¼ÓÔØÍ¼Ïñ @@ -63,8 +78,12 @@ public: bool Load(const Resource& res); /// \~chinese - /// @brief ²Ã¼ôͼÏñ֡Ϊ¾ØÐÎ - /// @param crop_rect ²Ã¼ô¾ØÐζ¨Òå + /// @brief ÊÇ·ñÓÐЧ + bool IsValid() const; + + /// \~chinese + /// @brief ²Ã¼ô¹Ø¼ü֡Ϊ¾ØÐÎ + /// @param crop_rect ²Ã¼ô¾ØÐÎ void SetCropRect(const Rect& crop_rect); /// \~chinese @@ -72,42 +91,10 @@ public: /// @param texture ÎÆÀí void SetTexture(TexturePtr texture); - /// \~chinese - /// @brief ÊÇ·ñÓÐЧ - bool IsValid() const; - - /// \~chinese - /// @brief »ñÈ¡¿í¶È - float GetWidth() const; - - /// \~chinese - /// @brief »ñÈ¡¸ß¶È - float GetHeight() const; - - /// \~chinese - /// @brief »ñÈ¡´óС - Size GetSize() const; - - /// \~chinese - /// @brief »ñÈ¡²Ã¼ôλÖà - Point GetCropPoint() const; - /// \~chinese /// @brief »ñÈ¡²Ã¼ô¾ØÐÎ const Rect& GetCropRect() const; - /// \~chinese - /// @brief »ñȡͼÏñÔ­¿í¶È - float GetSourceWidth() const; - - /// \~chinese - /// @brief »ñȡͼÏñÔ­¸ß¶È - float GetSourceHeight() const; - - /// \~chinese - /// @brief »ñȡͼÏñÔ­´óС - Size GetSourceSize() const; - /// \~chinese /// @brief »ñÈ¡ÎÆÀí TexturePtr GetTexture() const; @@ -117,64 +104,17 @@ private: Rect crop_rect_; }; -inline bool Frame::IsValid() const +inline bool KeyFrame::IsValid() const { return texture_ && texture_->IsValid(); } -inline float Frame::GetWidth() const -{ - return crop_rect_.GetWidth(); -} - -inline float Frame::GetHeight() const -{ - return crop_rect_.GetHeight(); -} - -inline Size Frame::GetSize() const -{ - return crop_rect_.GetSize(); -} - -inline Point Frame::GetCropPoint() const -{ - return crop_rect_.GetLeftTop(); -} - -inline const Rect& Frame::GetCropRect() const +inline const Rect& KeyFrame::GetCropRect() const { return crop_rect_; } -inline float Frame::GetSourceWidth() const -{ - if (texture_) - { - return texture_->GetWidth(); - } - return 0.0f; -} - -inline float Frame::GetSourceHeight() const -{ - if (texture_) - { - return texture_->GetHeight(); - } - return 0.0f; -} - -inline Size Frame::GetSourceSize() const -{ - if (texture_) - { - return texture_->GetSize(); - } - return Size(); -} - -inline TexturePtr Frame::GetTexture() const +inline TexturePtr KeyFrame::GetTexture() const { return texture_; } diff --git a/src/kiwano/2d/action/ActionWalk.cpp b/src/kiwano/2d/animation/PathAnimation.cpp similarity index 72% rename from src/kiwano/2d/action/ActionWalk.cpp rename to src/kiwano/2d/animation/PathAnimation.cpp index 71d1c3d7..d0e49481 100644 --- a/src/kiwano/2d/action/ActionWalk.cpp +++ b/src/kiwano/2d/animation/PathAnimation.cpp @@ -18,19 +18,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include #include -#include namespace kiwano { -ActionWalk::ActionWalk(Duration duration, ShapePtr path, bool rotating, float start, float end) -{ - SetEntity(MakePtr(duration, path, rotating, start, end)); -} - -ActionWalkEntity::ActionWalkEntity(Duration duration, ShapePtr path, bool rotating, float start, float end) - : ActionTweenEntity(duration) +PathAnimation::PathAnimation(Duration duration, ShapePtr path, bool rotating, float start, float end) + : TweenAnimation(duration) , start_(start) , end_(end) , rotating_(rotating) @@ -39,21 +34,21 @@ ActionWalkEntity::ActionWalkEntity(Duration duration, ShapePtr path, bool rotati { } -ActionWalkEntity* ActionWalkEntity::Clone() const +PathAnimation* PathAnimation::Clone() const { - ActionWalkEntity* ptr = new ActionWalkEntity(GetDuration(), path_, rotating_, start_, end_); + PathAnimation* ptr = new PathAnimation(GetDuration(), path_, rotating_, start_, end_); DoClone(ptr); return ptr; } -ActionWalkEntity* ActionWalkEntity::Reverse() const +PathAnimation* PathAnimation::Reverse() const { - ActionWalkEntity* ptr = new ActionWalkEntity(GetDuration(), path_, rotating_, end_, start_); + PathAnimation* ptr = new PathAnimation(GetDuration(), path_, rotating_, end_, start_); DoClone(ptr); return ptr; } -void ActionWalkEntity::Init(Actor* target) +void PathAnimation::Init(Actor* target) { if (!path_ || !path_->IsValid()) { @@ -65,7 +60,7 @@ void ActionWalkEntity::Init(Actor* target) length_ = path_->GetLength(); } -void ActionWalkEntity::UpdateTween(Actor* target, float percent) +void PathAnimation::UpdateTween(Actor* target, float percent) { float distance = length_ * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); diff --git a/src/kiwano/2d/action/ActionWalk.h b/src/kiwano/2d/animation/PathAnimation.h similarity index 68% rename from src/kiwano/2d/action/ActionWalk.h rename to src/kiwano/2d/animation/PathAnimation.h index 9a11873c..556b1704 100644 --- a/src/kiwano/2d/action/ActionWalk.h +++ b/src/kiwano/2d/animation/PathAnimation.h @@ -19,37 +19,22 @@ // THE SOFTWARE. #pragma once -#include +#include #include -#include namespace kiwano { -KGE_DECLARE_SMART_PTR(ActionWalkEntity); +KGE_DECLARE_SMART_PTR(PathAnimation); /** - * \addtogroup Actions + * \addtogroup Animation * @{ */ -/// \~chinese -/// @brief ·¾¶ÐÐ×ß¶¯»­ -class KGE_API ActionWalk : public ActionTween -{ -public: - /// \~chinese - /// @brief ´´½¨Â·¾¶ÐÐ×ß¶¯»­ - /// @param duration ³ÖÐøÊ±³¤ - /// @param path ·¾¶ÐÎ×´ - /// @param rotating ÊÇ·ñÑØÂ·¾¶ÇÐÏß·½ÏòÐýת - /// @param start ·¾¶Æðµã£¨°Ù·Ö±È£© - /// @param end ·¾¶Öյ㣨°Ù·Ö±È£© - ActionWalk(Duration duration, ShapePtr path, bool rotating = false, float start = 0.f, float end = 1.f); -}; /// \~chinese -/// @brief ·¾¶ÐÐ×ß¶¯»­ÊµÌå -class KGE_API ActionWalkEntity : public ActionTweenEntity +/// @brief ·¾¶ÐÐ×ß¶¯»­ +class KGE_API PathAnimation : public TweenAnimation { public: /// \~chinese @@ -59,7 +44,7 @@ public: /// @param rotating ÊÇ·ñÑØÂ·¾¶ÇÐÏß·½ÏòÐýת /// @param start ·¾¶Æðµã£¨°Ù·Ö±È£© /// @param end ·¾¶Öյ㣨°Ù·Ö±È£© - ActionWalkEntity(Duration duration, ShapePtr path, bool rotating = false, float start = 0.f, float end = 1.f); + PathAnimation(Duration duration, ShapePtr path, bool rotating = false, float start = 0.f, float end = 1.f); /// \~chinese /// @brief »ñȡ·Ïß @@ -95,11 +80,11 @@ public: /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó - ActionWalkEntity* Clone() const override; + PathAnimation* Clone() const override; /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª - ActionWalkEntity* Reverse() const override; + PathAnimation* Reverse() const override; protected: void Init(Actor* target) override; @@ -117,42 +102,42 @@ private: /** @} */ -inline ShapePtr ActionWalkEntity::GetPath() const +inline ShapePtr PathAnimation::GetPath() const { return path_; } -inline bool ActionWalkEntity::IsRotating() const +inline bool PathAnimation::IsRotating() const { return rotating_; } -inline float ActionWalkEntity::GetStartValue() const +inline float PathAnimation::GetStartValue() const { return start_; } -inline float ActionWalkEntity::GetEndValue() const +inline float PathAnimation::GetEndValue() const { return end_; } -inline void ActionWalkEntity::SetPath(ShapePtr path) +inline void PathAnimation::SetPath(ShapePtr path) { path_ = path; } -inline void ActionWalkEntity::SetRotating(bool rotating) +inline void PathAnimation::SetRotating(bool rotating) { rotating_ = rotating; } -inline void ActionWalkEntity::SetStartValue(float start) +inline void PathAnimation::SetStartValue(float start) { start_ = start; } -inline void ActionWalkEntity::SetEndValue(float end) +inline void PathAnimation::SetEndValue(float end) { end_ = end; } diff --git a/src/kiwano/2d/animation/TweenAnimation.cpp b/src/kiwano/2d/animation/TweenAnimation.cpp index c7b1420a..d3498b80 100644 --- a/src/kiwano/2d/animation/TweenAnimation.cpp +++ b/src/kiwano/2d/animation/TweenAnimation.cpp @@ -18,9 +18,352 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include +#include namespace kiwano { +//------------------------------------------------------- +// TweenAnimation +//------------------------------------------------------- + +TweenAnimation::TweenAnimation() + : dur_() + , ease_func_(nullptr) +{ } + +TweenAnimation::TweenAnimation(Duration duration) + : dur_(duration) + , ease_func_(nullptr) +{ +} + +float TweenAnimation::Interpolate(float frac) +{ + if (ease_func_) + frac = ease_func_(frac); + return frac; +} + +void TweenAnimation::Update(Actor* target, Duration dt) +{ + float frac; + + if (dur_.IsZero()) + { + frac = 1.f; + Complete(target); + } + else + { + Duration elapsed = GetElapsed() - GetDelay(); + float loops_done = elapsed / dur_; + + while (GetLoopsDone() < static_cast(loops_done)) + { + Complete(target); // loops_done_++ + } + + frac = (GetStatus() == Status::Done) ? 1.f : (loops_done - static_cast(GetLoopsDone())); + } + + frac = Interpolate(frac); + + UpdateTween(target, frac); +} + +void TweenAnimation::DoClone(TweenAnimation* to) const +{ + if (to) + { + Animation::DoClone(to); + to->SetDuration(this->GetDuration()); + to->SetEaseFunc(this->GetEaseFunc()); + } +} + +//------------------------------------------------------- +// Move Animation +//------------------------------------------------------- + +MoveByAnimation::MoveByAnimation(Duration duration, const Vec2& displacement) + : TweenAnimation(duration) + , displacement_(displacement) +{ +} + +void MoveByAnimation::Init(Actor* target) +{ + if (target) + { + prev_pos_ = start_pos_ = target->GetPosition(); + } +} + +void MoveByAnimation::UpdateTween(Actor* target, float frac) +{ + Point diff = target->GetPosition() - prev_pos_; + start_pos_ = start_pos_ + diff; + + Point new_pos = start_pos_ + (displacement_ * frac); + target->SetPosition(new_pos); + + prev_pos_ = new_pos; +} + +MoveByAnimation* MoveByAnimation::Clone() const +{ + MoveByAnimation* ptr = new MoveByAnimation(GetDuration(), displacement_); + DoClone(ptr); + return ptr; +} + +MoveByAnimation* MoveByAnimation::Reverse() const +{ + MoveByAnimation* ptr = new MoveByAnimation(GetDuration(), -displacement_); + DoClone(ptr); + return ptr; +} + +MoveToAnimation::MoveToAnimation(Duration duration, const Point& distination) + : MoveByAnimation(duration, Vec2()) + , distination_(distination) +{ +} + +MoveToAnimation* MoveToAnimation::Clone() const +{ + MoveToAnimation* ptr = new MoveToAnimation(GetDuration(), distination_); + DoClone(ptr); + return ptr; +} + +void MoveToAnimation::Init(Actor* target) +{ + MoveByAnimation::Init(target); + displacement_ = distination_ - start_pos_; +} + +//------------------------------------------------------- +// Jump Animation +//------------------------------------------------------- + +JumpByAnimation::JumpByAnimation(Duration duration, const Vec2& displacement, float height, int count) + : TweenAnimation(duration) + , height_(height) + , jump_count_(count) + , displacement_(displacement) +{ +} + +JumpByAnimation* JumpByAnimation::Clone() const +{ + JumpByAnimation* ptr = new JumpByAnimation(GetDuration(), displacement_, height_, jump_count_); + DoClone(ptr); + return ptr; +} + +JumpByAnimation* JumpByAnimation::Reverse() const +{ + JumpByAnimation* ptr = new JumpByAnimation(GetDuration(), -displacement_, height_, jump_count_); + DoClone(ptr); + return ptr; +} + +void JumpByAnimation::Init(Actor* target) +{ + if (target) + { + prev_pos_ = start_pos_ = target->GetPosition(); + } +} + +void JumpByAnimation::UpdateTween(Actor* target, float frac) +{ + float f = ::fmod(frac * jump_count_, 1.f); + float x = displacement_.x * frac; + float y = height_ * 4 * f * (1 - f); + y += displacement_.y * frac; + + Point diff = target->GetPosition() - prev_pos_; + start_pos_ = diff + start_pos_; + + Point new_pos = start_pos_ + Point(x, y); + target->SetPosition(new_pos); + + prev_pos_ = new_pos; +} + +JumpToAnimation::JumpToAnimation(Duration duration, const Point& distination, float height, int count) + : JumpByAnimation(duration, Vec2(), height, count) + , distination_(distination) +{ +} + +JumpToAnimation* JumpToAnimation::Clone() const +{ + JumpToAnimation* ptr = new JumpToAnimation(GetDuration(), distination_, height_, jump_count_); + DoClone(ptr); + return ptr; +} + +void JumpToAnimation::Init(Actor* target) +{ + JumpByAnimation::Init(target); + displacement_ = distination_ - start_pos_; +} + +//------------------------------------------------------- +// Scale Animation +//------------------------------------------------------- + +ScaleByAnimation::ScaleByAnimation(Duration duration, const Vec2& scale) + : TweenAnimation(duration) + , delta_(scale) + , start_val_() +{ +} + +void ScaleByAnimation::Init(Actor* target) +{ + if (target) + { + start_val_ = target->GetScale(); + } +} + +void ScaleByAnimation::UpdateTween(Actor* target, float frac) +{ + target->SetScale(Vec2{ start_val_.x + delta_.x * frac, start_val_.y + delta_.y * frac }); +} + +ScaleByAnimation* ScaleByAnimation::Clone() const +{ + ScaleByAnimation* ptr = new ScaleByAnimation(GetDuration(), delta_); + DoClone(ptr); + return ptr; +} + +ScaleByAnimation* ScaleByAnimation::Reverse() const +{ + ScaleByAnimation* ptr = new ScaleByAnimation(GetDuration(), -delta_); + DoClone(ptr); + return ptr; +} + +ScaleToAnimation::ScaleToAnimation(Duration duration, const Vec2& scale) + : ScaleByAnimation(duration, Vec2()) + , end_val_(scale) +{ +} + +ScaleToAnimation* ScaleToAnimation::Clone() const +{ + ScaleToAnimation* ptr = new ScaleToAnimation(GetDuration(), end_val_); + DoClone(ptr); + return ptr; +} + +void ScaleToAnimation::Init(Actor* target) +{ + ScaleByAnimation::Init(target); + delta_ = end_val_ - start_val_; +} + +//------------------------------------------------------- +// Opacity Animation +//------------------------------------------------------- + +FadeToAnimation::FadeToAnimation(Duration duration, float opacity) + : TweenAnimation(duration) + , delta_val_(0.0f) + , start_val_(0.f) + , end_val_(opacity) +{ +} + +void FadeToAnimation::Init(Actor* target) +{ + if (target) + { + start_val_ = target->GetOpacity(); + delta_val_ = end_val_ - start_val_; + } +} + +void FadeToAnimation::UpdateTween(Actor* target, float frac) +{ + target->SetOpacity(start_val_ + delta_val_ * frac); +} + +FadeToAnimation* FadeToAnimation::Clone() const +{ + FadeToAnimation* ptr = new FadeToAnimation(GetDuration(), end_val_); + DoClone(ptr); + return ptr; +} + +//------------------------------------------------------- +// Rotate Animation +//------------------------------------------------------- + +RotateByAnimation::RotateByAnimation(Duration duration, float rotation) + : TweenAnimation(duration) + , delta_val_(rotation) + , start_val_(0.0f) +{ +} + +void RotateByAnimation::Init(Actor* target) +{ + if (target) + { + start_val_ = target->GetRotation(); + } +} + +void RotateByAnimation::UpdateTween(Actor* target, float frac) +{ + float rotation = start_val_ + delta_val_ * frac; + if (rotation > 360.f) + rotation -= 360.f; + + target->SetRotation(rotation); +} + +RotateByAnimation* RotateByAnimation::Clone() const +{ + RotateByAnimation* ptr = new RotateByAnimation(GetDuration(), delta_val_); + DoClone(ptr); + return ptr; +} + +RotateByAnimation* RotateByAnimation::Reverse() const +{ + RotateByAnimation* ptr = new RotateByAnimation(GetDuration(), -delta_val_); + DoClone(ptr); + return ptr; +} + +RotateToAnimation::RotateToAnimation(Duration duration, float rotation) + : RotateByAnimation(duration, 0) + , end_val_(rotation) +{ +} + +RotateToAnimation* RotateToAnimation::Clone() const +{ + RotateToAnimation* ptr = new RotateToAnimation(GetDuration(), end_val_); + DoClone(ptr); + return ptr; +} + +void RotateToAnimation::Init(Actor* target) +{ + RotateByAnimation::Init(target); + delta_val_ = end_val_ - start_val_; +} + +} // namespace kiwano diff --git a/src/kiwano/2d/animation/TweenAnimation.h b/src/kiwano/2d/animation/TweenAnimation.h index dba82b5f..5750b46b 100644 --- a/src/kiwano/2d/animation/TweenAnimation.h +++ b/src/kiwano/2d/animation/TweenAnimation.h @@ -19,11 +19,609 @@ // THE SOFTWARE. #pragma once -#include +#include +#include +#include namespace kiwano { +KGE_DECLARE_SMART_PTR(TweenAnimation); +KGE_DECLARE_SMART_PTR(MoveByAnimation); +KGE_DECLARE_SMART_PTR(MoveToAnimation); +KGE_DECLARE_SMART_PTR(JumpByAnimation); +KGE_DECLARE_SMART_PTR(JumpToAnimation); +KGE_DECLARE_SMART_PTR(ScaleByAnimation); +KGE_DECLARE_SMART_PTR(ScaleToAnimation); +KGE_DECLARE_SMART_PTR(FadeToAnimation); +KGE_DECLARE_SMART_PTR(RotateByAnimation); +KGE_DECLARE_SMART_PTR(RotateToAnimation); + +/** + * \addtogroup Animation + * @{ + */ + +/// \~chinese +/// @brief ²¹¼ä¶¯»­ +class KGE_API TweenAnimation : public Animation +{ +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: + TweenAnimation(); + + TweenAnimation(Duration duration); + + float Interpolate(float frac); + + void Update(Actor* target, Duration dt) override; + + virtual void UpdateTween(Actor* target, float frac) = 0; + + void DoClone(TweenAnimation* to) const; + +private: + Duration dur_; + EaseFunc ease_func_; +}; +/// \~chinese +/// @brief Ïà¶ÔÎ»ÒÆ¶¯»­ +class KGE_API MoveByAnimation : public TweenAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Ïà¶ÔÎ»ÒÆ¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param displacement Î»ÒÆÏòÁ¿ + MoveByAnimation(Duration duration, const Vec2& displacement); + + /// \~chinese + /// @brief »ñÈ¡Î»ÒÆÏòÁ¿ + Vec2 GetDisplacement() const; + + /// \~chinese + /// @brief ÉèÖÃÎ»ÒÆÏòÁ¿ + void SetDisplacement(const Vec2& displacement); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + MoveByAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + MoveByAnimation* Reverse() const override; + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float frac) override; + +protected: + Point start_pos_; + Point prev_pos_; + Vec2 displacement_; +}; + + +/// \~chinese +/// @brief Î»ÒÆ¶¯»­ +class KGE_API MoveToAnimation : public MoveByAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Î»Òƶ¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param distination Ä¿µÄ×ø±ê + MoveToAnimation(Duration duration, const Point& distination); + + /// \~chinese + /// @brief »ñȡĿµÄ×ø±ê + Point GetDistination() const; + + /// \~chinese + /// @brief ÉèÖÃÄ¿µÄ×ø±ê + void SetDistination(const Point& distination); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + MoveToAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + MoveToAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in MoveToAnimation"); + return nullptr; + } + +protected: + void Init(Actor* target) override; + +private: + Point distination_; +}; + + +/// \~chinese +/// @brief Ïà¶ÔÌøÔ¾¶¯»­ +class KGE_API JumpByAnimation : public TweenAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Ïà¶ÔÌøÔ¾¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param displacement ÌøÔ¾Î»ÒÆÏòÁ¿ + /// @param height ÌøÔ¾¸ß¶È + /// @param count ÌøÔ¾´ÎÊý + JumpByAnimation(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 »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + JumpByAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + JumpByAnimation* Reverse() const override; + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float frac) override; + +protected: + float height_; + int jump_count_; + Point start_pos_; + Point displacement_; + Point prev_pos_; +}; + + +/// \~chinese +/// @brief ÌøÔ¾¶¯»­ +class KGE_API JumpToAnimation : public JumpByAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨ÌøÔ¾¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param distination Ä¿µÄ×ø±ê + /// @param height ÌøÔ¾¸ß¶È + /// @param count ÌøÔ¾´ÎÊý + JumpToAnimation(Duration duration, const Point& distination, float height, int count = 1); + + /// \~chinese + /// @brief »ñȡĿµÄ×ø±ê + Point GetDistination() const; + + /// \~chinese + /// @brief ÉèÖÃÄ¿µÄ×ø±ê + void SetDistination(const Point& distination); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + JumpToAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + JumpToAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in JumpToAnimation"); + return nullptr; + } + +protected: + void Init(Actor* target) override; + +private: + Point distination_; +}; + + +/// \~chinese +/// @brief Ïà¶ÔËõ·Å¶¯»­ +class KGE_API ScaleByAnimation : public TweenAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Ïà¶ÔËõ·Å¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param scale Ëõ·ÅÏà¶Ô±ä»¯Öµ + ScaleByAnimation(Duration duration, const Vec2& scale); + + /// \~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 »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + ScaleByAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + ScaleByAnimation* Reverse() const override; + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float frac) override; + +protected: + Vec2 start_val_; + Vec2 delta_; +}; + + +/// \~chinese +/// @brief Ëõ·Å¶¯»­ +class KGE_API ScaleToAnimation : public ScaleByAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Ëõ·Å¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param scale Ëõ·ÅÄ¿±êÖµ + ScaleToAnimation(Duration duration, const Vec2& scale); + + /// \~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 »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + ScaleToAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + ScaleToAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in ScaleToAnimation"); + return nullptr; + } + +protected: + void Init(Actor* target) override; + +private: + Vec2 end_val_; +}; + + +/// \~chinese +/// @brief ͸Ã÷¶È½¥±ä¶¯»­ +class KGE_API FadeToAnimation : public TweenAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Í¸Ã÷¶È½¥±ä¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param opacity Ä¿±ê͸Ã÷¶È + FadeToAnimation(Duration duration, float opacity); + + /// \~chinese + /// @brief »ñȡĿ±ê͸Ã÷¶È + float GetTargetOpacity() const; + + /// \~chinese + /// @brief ÉèÖÃÄ¿±ê͸Ã÷¶È + void SetTargetOpacity(float opacity); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + FadeToAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + FadeToAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in FadeToAnimation"); + return nullptr; + } + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float frac) override; + +private: + float start_val_; + float delta_val_; + float end_val_; +}; + + +/// \~chinese +/// @brief Ïà¶ÔÐýת¶¯»­ +class KGE_API RotateByAnimation : public TweenAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Ïà¶ÔÐýת¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param rotation ½Ç¶ÈÏà¶Ô±ä»¯Öµ + RotateByAnimation(Duration duration, float rotation); + + /// \~chinese + /// @brief »ñÈ¡½Ç¶ÈÏà¶Ô±ä»¯Öµ + float GetRotation() const; + + /// \~chinese + /// @brief ÉèÖýǶÈÏà¶Ô±ä»¯Öµ + void SetRotation(float rotation); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + RotateByAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + RotateByAnimation* Reverse() const override; + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float frac) override; + +protected: + float start_val_; + float delta_val_; +}; + + +/// \~chinese +/// @brief Ðýת¶¯»­ +class KGE_API RotateToAnimation : public RotateByAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨Ðýת¶¯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param rotation Ä¿±ê½Ç¶È + RotateToAnimation(Duration duration, float rotation); + + /// \~chinese + /// @brief »ñȡĿ±ê½Ç¶È + float GetTargetRotation() const; + + /// \~chinese + /// @brief ÉèÖÃÄ¿±ê½Ç¶È + void SetTargetRotation(float rotation); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + RotateToAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + RotateToAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in RotateToAnimation"); + return nullptr; + } + +protected: + void Init(Actor* target) override; + +private: + float end_val_; +}; + +/** @} */ + +inline const EaseFunc& TweenAnimation::GetEaseFunc() const +{ + return ease_func_; } + +inline Duration TweenAnimation::GetDuration() const +{ + return dur_; +} + +inline void TweenAnimation::SetDuration(Duration duration) +{ + dur_ = duration; +} + +inline void TweenAnimation::SetEaseFunc(const EaseFunc& func) +{ + ease_func_ = func; +} + +inline Vec2 MoveByAnimation::GetDisplacement() const +{ + return displacement_; +} + +inline void MoveByAnimation::SetDisplacement(const Vec2& displacement) +{ + displacement_ = displacement; +} + +inline Point MoveToAnimation::GetDistination() const +{ + return distination_; +} + +inline void MoveToAnimation::SetDistination(const Point& distination) +{ + distination_ = distination; +} + +inline Vec2 JumpByAnimation::GetDisplacement() const +{ + return displacement_; +} + +inline float JumpByAnimation::GetJumpHeight() const +{ + return height_; +} + +inline int JumpByAnimation::GetJumpCount() const +{ + return jump_count_; +} + +inline void JumpByAnimation::SetDisplacement(const Vec2& displacement) +{ + displacement_ = displacement; +} + +inline void JumpByAnimation::SetJumpHeight(float height) +{ + height_ = height; +} + +inline void JumpByAnimation::SetJumpCount(int count) +{ + jump_count_ = count; +} + +inline Point JumpToAnimation::GetDistination() const +{ + return distination_; +} + +inline void JumpToAnimation::SetDistination(const Point& distination) +{ + distination_ = distination; +} + +inline float ScaleByAnimation::GetScaleX() const +{ + return delta_.x; +} + +inline float ScaleByAnimation::GetScaleY() const +{ + return delta_.y; +} + +inline void ScaleByAnimation::SetScaleX(float scale_x) +{ + delta_.x = scale_x; +} + +inline void ScaleByAnimation::SetScaleY(float scale_y) +{ + delta_.y = scale_y; +} + +inline float ScaleToAnimation::GetTargetScaleX() const +{ + return end_val_.x; +} + +inline float ScaleToAnimation::GetTargetScaleY() const +{ + return end_val_.y; +} + +inline void ScaleToAnimation::SetTargetScaleX(float scale_x) +{ + end_val_.x = scale_x; +} + +inline void ScaleToAnimation::SetTargetScaleY(float scale_y) +{ + end_val_.y = scale_y; +} + +inline float FadeToAnimation::GetTargetOpacity() const +{ + return end_val_; +} + +inline void FadeToAnimation::SetTargetOpacity(float opacity) +{ + end_val_ = opacity; +} + +inline float RotateByAnimation::GetRotation() const +{ + return delta_val_; +} + +inline void RotateByAnimation::SetRotation(float rotation) +{ + delta_val_ = rotation; +} + +inline float RotateToAnimation::GetTargetRotation() const +{ + return end_val_; +} + +inline void RotateToAnimation::SetTargetRotation(float rotation) +{ + end_val_ = rotation; +} + +} // namespace kiwano diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index a01e941f..83b5171b 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -82,8 +82,6 @@ #include #include #include -#include -#include #include #include #include @@ -104,13 +102,21 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include + +// +// animation +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // // platform diff --git a/src/kiwano/render/RenderContext.cpp b/src/kiwano/render/RenderContext.cpp index 0bd36a47..a305c6c3 100644 --- a/src/kiwano/render/RenderContext.cpp +++ b/src/kiwano/render/RenderContext.cpp @@ -60,22 +60,6 @@ void RenderContext::EndDraw() } } -void RenderContext::DrawFrame(FramePtr frame, const Point& dest_pos) -{ - if (frame) - { - this->DrawTexture(*frame->GetTexture(), &frame->GetCropRect(), &Rect(dest_pos, frame->GetSize())); - } -} - -void RenderContext::DrawFrame(FramePtr frame, const Rect& dest_rect) -{ - if (frame) - { - this->DrawTexture(*frame->GetTexture(), &frame->GetCropRect(), &dest_rect); - } -} - void RenderContext::SetGlobalTransform(const Matrix3x2* matrix) { if (matrix) diff --git a/src/kiwano/render/RenderContext.h b/src/kiwano/render/RenderContext.h index 6f2199a0..0ca0e94c 100644 --- a/src/kiwano/render/RenderContext.h +++ b/src/kiwano/render/RenderContext.h @@ -25,7 +25,6 @@ #include #include #include -#include namespace kiwano { @@ -80,18 +79,6 @@ public: virtual void DrawTexture(const Texture& texture, const Rect* src_rect = nullptr, const Rect* dest_rect = nullptr) = 0; - /// \~chinese - /// @brief »æÖÆÍ¼ÏñÖ¡ - /// @param frame ͼÏñÖ¡ - /// @param dest_pos »æÖÆÍ¼ÏñµÄλÖà - virtual void DrawFrame(FramePtr frame, const Point& dest_pos); - - /// \~chinese - /// @brief »æÖÆÍ¼ÏñÖ¡ - /// @param frame ͼÏñÖ¡ - /// @param dest_rect »æÖƵÄÄ¿±êÇøÓò - virtual void DrawFrame(FramePtr frame, const Rect& dest_rect); - /// \~chinese /// @brief »æÖÆÎı¾²¼¾Ö /// @param layout Îı¾²¼¾Ö diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h index dd1956d4..e32eb1fb 100644 --- a/src/kiwano/render/Renderer.h +++ b/src/kiwano/render/Renderer.h @@ -104,8 +104,8 @@ public: virtual void CreateGifImage(GifImage& gif, const Resource& resource) = 0; /// \~chinese - /// @brief ´´½¨GIFͼÏñÖ¡ÄÚ²¿×ÊÔ´ - /// @param[out] frame GIFͼÏñÖ¡ + /// @brief ´´½¨GIF¹Ø¼üÖ¡ÄÚ²¿×ÊÔ´ + /// @param[out] frame GIF¹Ø¼üÖ¡ /// @param[in] gif GIFͼÏñ /// @param[in] frame_index ֡ϱê virtual void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) = 0; diff --git a/src/kiwano/utils/ResourceCache.h b/src/kiwano/utils/ResourceCache.h index d9b80158..d8adaa88 100644 --- a/src/kiwano/utils/ResourceCache.h +++ b/src/kiwano/utils/ResourceCache.h @@ -20,10 +20,7 @@ #pragma once #include -#include -#include -#include -#include +#include namespace kiwano { diff --git a/src/kiwano/utils/ResourceLoader.cpp b/src/kiwano/utils/ResourceLoader.cpp index 59ccc770..3ef352b8 100644 --- a/src/kiwano/utils/ResourceLoader.cpp +++ b/src/kiwano/utils/ResourceLoader.cpp @@ -24,6 +24,11 @@ #include #include +#include +#include +#include +#include + namespace kiwano { namespace resource_cache_01 @@ -195,7 +200,7 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& else if (!file.empty()) { // Simple image - FramePtr frame = MakePtr(); + KeyFramePtr frame = MakePtr(); if (frame && frame->Load(gdata->path + file)) { cache->AddObject(id, frame); @@ -212,11 +217,11 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& return; // Frames - Vector frames; + Vector frames; frames.reserve(files.size()); for (const auto& file : files) { - FramePtr frame = MakePtr(); + KeyFramePtr frame = MakePtr(); if (frame->Load(gdata->path + file)) { frames.push_back(frame); @@ -243,14 +248,17 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& { if (rows || cols) { - // Frame slices - FramePtr frame = MakePtr(); - if (frame && frame->Load(gdata->path + file)) + // KeyFrame slices + TexturePtr texture = MakePtr(); + if (texture && texture->Load(gdata->path + file)) { FrameSequencePtr frame_seq = MakePtr(); if (frame_seq) { - frame_seq->AddFrames(frame, cols, rows, max_num, padding_x, padding_y); + KeyFrameSpliter spliter(texture); + + auto frames = spliter.Split(cols, rows, max_num, padding_x, padding_y); + frame_seq->AddFrames(frames); cache->AddObject(id, frame_seq); return; } @@ -259,7 +267,7 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& else { // Simple image - FramePtr frame = MakePtr(); + KeyFramePtr frame = MakePtr(); if (frame && frame->Load(gdata->path + file)) { cache->AddObject(id, frame);