diff --git a/.gitignore b/.gitignore index 7c3945ca..b0f0dad1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ Release/ # Application folders .vs .idea +._Kiwano.sln # vs2010 ipch/ diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index 64816eec..7d53d52c 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -1,15 +1,25 @@  - - - - - - - + + + + + + + + + + + + + + + + + @@ -20,6 +30,7 @@ + @@ -29,7 +40,6 @@ - @@ -54,7 +64,6 @@ - @@ -69,6 +78,7 @@ + @@ -87,8 +97,6 @@ - - @@ -115,23 +123,31 @@ - - - - - - - + + + + + + + + + + + - + + + + + @@ -169,8 +185,6 @@ - - diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index 2717e40a..5b33f584 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} @@ -37,6 +34,12 @@ {d15f4de1-7c2c-40d6-a3ce-68860b95a61e} + + {9314f30d-5742-48b6-94e5-e3b4284106f6} + + + {f70cecd8-6d5b-405d-8466-d3ca2db9b806} + @@ -45,9 +48,6 @@ 2d - - 2d - core @@ -72,15 +72,6 @@ 2d - - 2d\action - - - 2d\action - - - 2d\action - utils @@ -90,12 +81,6 @@ 2d - - 2d\action - - - 2d\action - utils @@ -126,9 +111,6 @@ core - - core - core @@ -255,12 +237,6 @@ core - - render - - - render - utils @@ -282,9 +258,6 @@ utils - - 2d\action - render\DirectX @@ -342,9 +315,6 @@ core - - 2d\action - base @@ -369,6 +339,63 @@ core + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + core + + + 2d + + + platform + + + 2d\transition + + + 2d\transition + + + 2d\transition + + + 2d\transition + + + 2d\transition + @@ -377,9 +404,6 @@ 2d - - 2d - core @@ -392,15 +416,6 @@ 2d - - 2d\action - - - 2d\action - - - 2d\action - utils @@ -410,12 +425,6 @@ 2d - - 2d\action - - - 2d\action - utils @@ -518,12 +527,6 @@ core - - render - - - render - utils @@ -539,9 +542,6 @@ utils - - 2d\action - utils @@ -587,9 +587,6 @@ utils - - 2d\action - base @@ -605,6 +602,54 @@ core + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d\animation + + + 2d + + + 2d\transition + + + 2d\transition + + + 2d\transition + + + 2d\transition + + + 2d\transition + diff --git a/src/kiwano-audio/Transcoder.cpp b/src/kiwano-audio/Transcoder.cpp index f62d94fa..1a376816 100644 --- a/src/kiwano-audio/Transcoder.cpp +++ b/src/kiwano-audio/Transcoder.cpp @@ -94,7 +94,7 @@ HRESULT Transcoder::LoadMediaResource(const Resource& res) ComPtr byte_stream; ComPtr reader; - Resource::Data data = res.GetData(); + BinaryData data = res.GetData(); if (!data.IsValid()) { return E_FAIL; 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..ac212681 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,32 @@ 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 »æÖƾ«ÁéÖ¡ + /// @param frame ¾«ÁéÖ¡ + /// @param pos »æÖƵÄÄ¿±êλÖà + void DrawSpriteFrame(const SpriteFrame& frame, const Point& pos); + + /// \~chinese + /// @brief »æÖƾ«ÁéÖ¡ + /// @param frame ¾«ÁéÖ¡ + /// @param pos »æÖƵÄÄ¿±êλÖà + /// @param size »æÖƵÄÄ¿±ê´óС + void DrawSpriteFrame(const SpriteFrame& frame, const Point& pos, const Size& size); /// \~chinese /// @brief »æÖÆÎÄ×Ö²¼¾Ö @@ -381,25 +396,35 @@ 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)); } } +inline void CanvasRenderContext::DrawSpriteFrame(const SpriteFrame& frame, const Point& pos) +{ + this->DrawSpriteFrame(frame, pos, frame.GetCropRect().GetSize()); +} + +inline void CanvasRenderContext::DrawSpriteFrame(const SpriteFrame& frame, const Point& pos, const Size& size) +{ + this->DrawTexture(frame.GetTexture(), pos, size, &frame.GetCropRect()); +} + inline void CanvasRenderContext::DrawTextLayout(const String& text, const TextStyle& style, const Point& point) { TextLayoutPtr layout = MakePtr(text, style); 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..db2c7eea 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -36,127 +36,79 @@ Sprite::Sprite(const Resource& res) Load(res); } -Sprite::Sprite(FramePtr frame) +Sprite::Sprite(TexturePtr texture) +{ + SetFrame(SpriteFrame(texture)); +} + +Sprite::Sprite(const String& file_path, const Rect& crop_rect) +{ + SetFrame(SpriteFrame(file_path, crop_rect)); +} + +Sprite::Sprite(const Resource& res, const Rect& crop_rect) +{ + SetFrame(SpriteFrame(res, crop_rect)); +} + +Sprite::Sprite(TexturePtr texture, const Rect& crop_rect) +{ + SetFrame(SpriteFrame(texture, crop_rect)); +} + +Sprite::Sprite(const SpriteFrame& frame) { SetFrame(frame); } -Sprite::Sprite(const String& file_path, const Rect& crop_rect) - : Sprite(file_path) -{ - SetCropRect(crop_rect); -} - -Sprite::Sprite(const Resource& res, const Rect& crop_rect) - : Sprite(res) -{ - 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()) + SpriteFrame frame(file_path); + if (frame.IsValid()) { - SetFrame(frame, autoresize); + SetFrame(frame); 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) + SpriteFrame frame(res); + if (frame.IsValid()) { - SetFrame(frame, autoresize); + SetFrame(frame); return true; } Fail("Sprite::Load failed"); return false; } -float Sprite::GetSourceWidth() const +void Sprite::SetFrame(const SpriteFrame& frame) { - if (frame_) - { - return frame_->GetSourceWidth(); - } - return 0.0f; -} + frame_ = frame; + SetSize(frame_.GetSize()); -float Sprite::GetSourceHeight() const -{ - if (frame_) + if (!frame_.IsValid()) { - 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()); + Fail("Sprite::SetFrame failed"); } } void Sprite::OnRender(RenderContext& ctx) { - if (frame_ && frame_->IsValid()) + if (frame_.IsValid()) { - ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds()); + ctx.DrawTexture(*frame_.GetTexture(), &frame_.GetCropRect(), &GetBounds()); } } bool Sprite::CheckVisibility(RenderContext& ctx) const { - return frame_ && frame_->IsValid() && Actor::CheckVisibility(ctx); + return frame_.IsValid() && Actor::CheckVisibility(ctx); } + } // namespace kiwano diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h index 9a30f601..ced716ef 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,50 @@ 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); + + /// \~chinese + /// @brief ´´½¨¾«Áé + /// @param frame ¾«ÁéÖ¡ + Sprite(const SpriteFrame& frame); + 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 »ñÈ¡¾«ÁéÖ¡ + SpriteFrame GetFrame() const; + /// \~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 SetFrame(const SpriteFrame& frame); void OnRender(RenderContext& ctx) override; @@ -130,13 +119,29 @@ protected: bool CheckVisibility(RenderContext& ctx) const override; private: - FramePtr frame_; + SpriteFrame frame_; }; /** @} */ -inline FramePtr Sprite::GetFrame() const +inline TexturePtr Sprite::GetTexture() const +{ + return frame_.GetTexture(); +} + +inline Rect Sprite::GetCropRect() const +{ + return frame_.GetCropRect(); +} + +inline SpriteFrame Sprite::GetFrame() const { return frame_; } + +inline void Sprite::SetCropRect(const Rect& crop_rect) +{ + frame_.SetCropRect(crop_rect); +} + } // namespace kiwano diff --git a/src/kiwano/render/Frame.h b/src/kiwano/2d/SpriteFrame.h similarity index 58% rename from src/kiwano/render/Frame.h rename to src/kiwano/2d/SpriteFrame.h index 96e45b60..6369a433 100644 --- a/src/kiwano/render/Frame.h +++ b/src/kiwano/2d/SpriteFrame.h @@ -19,38 +19,54 @@ // THE SOFTWARE. #pragma once -#include +#include +#include #include namespace kiwano { -KGE_DECLARE_SMART_PTR(Frame); /** * \~chinese - * @brief ͼÏñÖ¡ + * @brief ¾«ÁéÖ¡ */ -class KGE_API Frame : public ObjectBase +class KGE_API SpriteFrame { public: + SpriteFrame(); + /// \~chinese - /// @brief ´´½¨Í¼ÏñÖ¡ + /// @brief ´´½¨¾«ÁéÖ¡ /// @param file_path ͼÏñ·¾¶ - Frame(const String& file_path); + SpriteFrame(const String& file_path); /// \~chinese - /// @brief ´´½¨Í¼ÏñÖ¡ + /// @brief ´´½¨¾«ÁéÖ¡ /// @param res ͼÏñ×ÊÔ´ - Frame(const Resource& res); + SpriteFrame(const Resource& res); /// \~chinese - /// @brief ´´½¨Í¼ÏñÖ¡ + /// @brief ´´½¨¾«ÁéÖ¡ /// @param texture ÎÆÀí - Frame(TexturePtr texture); + SpriteFrame(TexturePtr texture); /// \~chinese - /// @brief ¹¹½¨¿ÕͼÏñÖ¡ - Frame(); + /// @brief ´´½¨¾«ÁéÖ¡ + /// @param file_path ͼÏñ·¾¶ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + SpriteFrame(const String& file_path, const Rect& crop_rect); + + /// \~chinese + /// @brief ´´½¨¾«ÁéÖ¡ + /// @param res ͼÏñ×ÊÔ´ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + SpriteFrame(const Resource& res, const Rect& crop_rect); + + /// \~chinese + /// @brief ´´½¨¾«ÁéÖ¡ + /// @param texture ÎÆÀí + /// @param crop_rect ²Ã¼ô¾ØÐÎ + SpriteFrame(TexturePtr texture, const Rect& crop_rect); /// \~chinese /// @brief ¼ÓÔØÍ¼Ïñ @@ -62,121 +78,64 @@ public: /// @param res ͼÏñ×ÊÔ´ bool Load(const Resource& res); - /// \~chinese - /// @brief ²Ã¼ôͼÏñ֡Ϊ¾ØÐÎ - /// @param crop_rect ²Ã¼ô¾ØÐζ¨Òå - void SetCropRect(const Rect& crop_rect); - - /// \~chinese - /// @brief ÉèÖÃÎÆÀí - /// @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; + /// \~chinese + /// @brief »ñÈ¡¾«ÁéÖ¡´óС + Size GetSize() const; + + /// \~chinese + /// @brief ²Ã¼ô¾«Áé֡Ϊ¾ØÐÎ + /// @param crop_rect ²Ã¼ô¾ØÐÎ + void SetCropRect(const Rect& crop_rect); + + /// \~chinese + /// @brief ÉèÖÃÎÆÀí²¢ÖØÖòüô¾ØÐÎ + /// @param texture ÎÆÀí + void SetTexture(TexturePtr texture); + + /// \~chinese + /// @brief °´ÐÐÁзָÁéÖ¡ + /// @param cols ÁÐÊý + /// @param rows ÐÐÊý + /// @param max_num ×î´óÖ¡ÊýÁ¿£¬Éè-1Ϊ½«·Ö¸îºóµÄͼÏñÈ«²¿×÷ΪÐòÁÐÖ¡ + /// @param padding_x X·½Ïò¼ä¸ô + /// @param padding_y Y·½Ïò¼ä¸ô + Vector Split(int cols, int rows, int max_num = -1, float padding_x = 0, float padding_y = 0); + private: TexturePtr texture_; Rect crop_rect_; }; -inline bool Frame::IsValid() const +inline bool SpriteFrame::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& SpriteFrame::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 SpriteFrame::GetTexture() const { return texture_; } +inline Size SpriteFrame::GetSize() const +{ + return crop_rect_.GetSize(); +} + } // namespace kiwano diff --git a/src/kiwano/2d/SpriteFrame.h.cpp b/src/kiwano/2d/SpriteFrame.h.cpp new file mode 100644 index 00000000..1fb6716c --- /dev/null +++ b/src/kiwano/2d/SpriteFrame.h.cpp @@ -0,0 +1,138 @@ +// 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 + +namespace kiwano +{ + +SpriteFrame::SpriteFrame() {} + +SpriteFrame::SpriteFrame(const String& file_path) +{ + Load(file_path); +} + +SpriteFrame::SpriteFrame(const Resource& res) +{ + Load(res); +} + +SpriteFrame::SpriteFrame(TexturePtr texture) +{ + SetTexture(texture); +} + +SpriteFrame::SpriteFrame(const String& file_path, const Rect& crop_rect) + : SpriteFrame(file_path) +{ + SetCropRect(crop_rect); +} + +SpriteFrame::SpriteFrame(const Resource& res, const Rect& crop_rect) + : SpriteFrame(res) +{ + SetCropRect(crop_rect); +} + +SpriteFrame::SpriteFrame(TexturePtr texture, const Rect& crop_rect) + : SpriteFrame(texture) +{ + SetCropRect(crop_rect); +} + +bool SpriteFrame::Load(const String& file_path) +{ + TexturePtr texture = Texture::Preload(file_path); + if (texture->IsValid()) + { + SetTexture(texture); + return true; + } + return false; +} + +bool SpriteFrame::Load(const Resource& res) +{ + TexturePtr texture = Texture::Preload(res); + if (texture->IsValid()) + { + SetTexture(texture); + return true; + } + return false; +} + +void SpriteFrame::SetCropRect(const Rect& crop_rect) +{ + crop_rect_ = crop_rect; +} + +void SpriteFrame::SetTexture(TexturePtr texture) +{ + texture_ = texture; + + Size texture_size; + if (texture_) + { + texture_size = texture_->GetSize(); + } + SetCropRect(Rect(Point(), texture_size)); +} + +Vector SpriteFrame::Split(int cols, int rows, int max_num, float padding_x, float padding_y) +{ + if (cols <= 0 || rows <= 0 || max_num == 0) + return {}; + + if (!IsValid()) + 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++) + { + frames.emplace_back(texture_, Rect{ dtx, dty, dtx + width, dty + height }); + ++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/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp deleted file mode 100644 index b62167e3..00000000 --- a/src/kiwano/2d/Transition.cpp +++ /dev/null @@ -1,388 +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 -#include -#include -#include - -namespace kiwano -{ -//------------------------------------------------------- -// Transition -//------------------------------------------------------- - -Transition::Transition() - : done_(false) - , duration_() - , delta_() - , process_(0) - , window_size_() - , out_stage_(nullptr) - , in_stage_(nullptr) - , out_layer_() - , in_layer_() -{ -} - -Transition::~Transition() {} - -bool Transition::IsDone() -{ - return done_; -} - -void Transition::Init(Stage* prev, Stage* next) -{ - process_ = 0; - delta_ = Duration{}; - - out_stage_ = prev; - in_stage_ = next; - window_size_ = Renderer::GetInstance().GetOutputSize(); - - if (in_stage_) - { - in_layer_.SetClipRect(Rect{ Point(), window_size_ }); - } - - if (out_stage_) - { - out_layer_.SetClipRect(Rect{ Point(), window_size_ }); - } -} - -void Transition::Update(Duration dt) -{ - if (duration_.IsZero()) - { - process_ = 1; - } - else - { - delta_ += dt; - process_ = std::min(delta_ / duration_, 1.f); - } - - if (process_ >= 1) - { - this->Stop(); - } -} - -void Transition::Render(RenderContext& ctx) -{ - if (out_stage_) - { - out_stage_->PrepareToRender(ctx); - ctx.PushClipRect(Rect{ Point{}, window_size_ }); - ctx.PushLayer(out_layer_); - - out_stage_->Render(ctx); - - ctx.PopLayer(); - ctx.PopClipRect(); - } - - if (in_stage_) - { - in_stage_->PrepareToRender(ctx); - ctx.PushClipRect(Rect{ Point{}, window_size_ }); - ctx.PushLayer(in_layer_); - - in_stage_->Render(ctx); - - ctx.PopLayer(); - ctx.PopClipRect(); - } -} - -void Transition::Stop() -{ - done_ = true; - Reset(); -} - -//------------------------------------------------------- -// BoxTransition -//------------------------------------------------------- - -BoxTransition::BoxTransition(Duration duration) -{ - SetDuration(duration); -} - -BoxTransition::BoxTransition() {} - -void BoxTransition::Init(Stage* prev, Stage* next) -{ - Transition::Init(prev, next); - - in_layer_.SetOpacity(0.f); -} - -void BoxTransition::Update(Duration dt) -{ - Transition::Update(dt); - - if (process_ < .5f) - { - out_layer_.SetClipRect(Rect(window_size_.x * process_, window_size_.y * process_, - window_size_.x * (1 - process_), window_size_.y * (1 - process_))); - } - else - { - out_layer_.SetOpacity(0.f); - in_layer_.SetOpacity(1.f); - in_layer_.SetClipRect(Rect(window_size_.x * (1 - process_), window_size_.y * (1 - process_), - window_size_.x * process_, window_size_.y * process_)); - } -} - -//------------------------------------------------------- -// EmergeTransition -//------------------------------------------------------- - -EmergeTransition::EmergeTransition(Duration duration) -{ - SetDuration(duration); -} - -EmergeTransition::EmergeTransition() {} - -void EmergeTransition::Init(Stage* prev, Stage* next) -{ - Transition::Init(prev, next); - - out_layer_.SetOpacity(1.f); - in_layer_.SetOpacity(0.f); -} - -void EmergeTransition::Update(Duration dt) -{ - Transition::Update(dt); - - out_layer_.SetOpacity(1 - process_); - in_layer_.SetOpacity(process_); -} - -//------------------------------------------------------- -// FadeTransition -//------------------------------------------------------- - -FadeTransition::FadeTransition(Duration duration) -{ - SetDuration(duration); -} - -FadeTransition::FadeTransition() {} - -void FadeTransition::Init(Stage* prev, Stage* next) -{ - Transition::Init(prev, next); - - out_layer_.SetOpacity(1.f); - in_layer_.SetOpacity(0.f); -} - -void FadeTransition::Update(Duration dt) -{ - Transition::Update(dt); - - if (process_ < 0.5) - { - out_layer_.SetOpacity(1 - process_ * 2); - in_layer_.SetOpacity(0.f); - } - else - { - out_layer_.SetOpacity(0.f); - in_layer_.SetOpacity((process_ - 0.5f) * 2); - } -} - -//------------------------------------------------------- -// MoveTransition -//------------------------------------------------------- - -MoveTransition::MoveTransition(Duration duration, Type type) - : type_(type) -{ - SetDuration(duration); -} - -MoveTransition::MoveTransition() - : type_(Type::Left) -{ -} - -void MoveTransition::Init(Stage* prev, Stage* next) -{ - Transition::Init(prev, next); - - switch (type_) - { - case Type::Up: - pos_delta_ = Point(0, -window_size_.y); - start_pos_ = Point(0, window_size_.y); - break; - case Type::Down: - pos_delta_ = Point(0, window_size_.y); - start_pos_ = Point(0, -window_size_.y); - break; - case Type::Left: - pos_delta_ = Point(-window_size_.x, 0); - start_pos_ = Point(window_size_.x, 0); - break; - case Type::Right: - pos_delta_ = Point(window_size_.x, 0); - start_pos_ = Point(-window_size_.x, 0); - break; - } - - if (out_stage_) - { - out_stage_->SetTransform(Transform{}); - } - - if (in_stage_) - { - auto transform = Transform{}; - transform.position = start_pos_; - in_stage_->SetTransform(transform); - } -} - -void MoveTransition::Update(Duration dt) -{ - Transition::Update(dt); - - if (out_stage_) - { - auto transform = Transform{}; - transform.position = pos_delta_ * process_; - out_stage_->SetTransform(transform); - } - - if (in_stage_) - { - auto transform = Transform{}; - transform.position = start_pos_ + pos_delta_ * process_; - in_stage_->SetTransform(transform); - } -} - -void MoveTransition::Reset() -{ - if (out_stage_) - { - out_stage_->SetTransform(Transform{}); - } - - if (in_stage_) - { - in_stage_->SetTransform(Transform{}); - } -} - -//------------------------------------------------------- -// RotationTransition -//------------------------------------------------------- - -RotationTransition::RotationTransition(Duration duration, float rotation) - : rotation_(rotation) -{ - SetDuration(duration); -} - -RotationTransition::RotationTransition() - : rotation_(0.0f) -{ -} - -void RotationTransition::Init(Stage* prev, Stage* next) -{ - Transition::Init(prev, next); - - auto transform = Transform{}; - transform.position = Point{ window_size_.x / 2, window_size_.y / 2 }; - - if (out_stage_) - { - out_stage_->SetTransform(transform); - out_stage_->SetAnchor(Vec2{ 0.5f, 0.5f }); - } - - if (in_stage_) - { - in_stage_->SetTransform(transform); - in_stage_->SetAnchor(Vec2{ 0.5f, 0.5f }); - } - - in_layer_.SetOpacity(0.f); -} - -void RotationTransition::Update(Duration dt) -{ - Transition::Update(dt); - - if (process_ < .5f) - { - if (out_stage_) - { - auto transform = out_stage_->GetTransform(); - transform.scale = Point{ (.5f - process_) * 2, (.5f - process_) * 2 }; - transform.rotation = rotation_ * (.5f - process_) * 2; - out_stage_->SetTransform(transform); - } - } - else - { - if (in_stage_) - { - out_layer_.SetOpacity(0.f); - in_layer_.SetOpacity(1.f); - - auto transform = in_stage_->GetTransform(); - transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 }; - transform.rotation = rotation_ * (process_ - .5f) * 2; - - in_stage_->SetTransform(transform); - } - } -} - -void RotationTransition::Reset() -{ - if (out_stage_) - { - out_stage_->SetTransform(Transform{}); - out_stage_->SetAnchor(Vec2{ 0.f, 0.f }); - } - - if (in_stage_) - { - in_stage_->SetTransform(Transform{}); - in_stage_->SetAnchor(Vec2{ 0.f, 0.f }); - } -} -} // namespace kiwano diff --git a/src/kiwano/2d/Transition.h b/src/kiwano/2d/Transition.h deleted file mode 100644 index 86ced945..00000000 --- a/src/kiwano/2d/Transition.h +++ /dev/null @@ -1,256 +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 -{ -class Director; -class RenderContext; - -KGE_DECLARE_SMART_PTR(Transition); -KGE_DECLARE_SMART_PTR(FadeTransition); -KGE_DECLARE_SMART_PTR(EmergeTransition); -KGE_DECLARE_SMART_PTR(BoxTransition); -KGE_DECLARE_SMART_PTR(MoveTransition); -KGE_DECLARE_SMART_PTR(RotationTransition); - -/** - * \~chinese - * @brief Îę̀¹ý¶É¶¯»­ - */ -class KGE_API Transition : public ObjectBase -{ - friend class Director; - -public: - Transition(); - - virtual ~Transition(); - - /** - * \~chinese - * @brief ÉèÖö¯»­Ê±³¤ - */ - void SetDuration(Duration dt); - - /** - * \~chinese - * @brief ³¡¾°¹ý¶É¶¯»­ÊÇ·ñÒѽáÊø - */ - bool IsDone(); - -protected: - /** - * \~chinese - * @brief ³õʼ»¯³¡¾°¹ý¶É¶¯»­ - * @param[in] prev ת³ö³¡¾° - * @param[in] next תÈ볡¾° - */ - virtual void Init(Stage* prev, Stage* next); - - /** - * \~chinese - * @brief ¸üйý¶É¶¯»­ - * @param dt ¾àÉÏÒ»´Î¸üеÄʱ¼ä¼ä¸ô - */ - virtual void Update(Duration dt); - - /** - * \~chinese - * @brief äÖȾ¹ý¶È¶¯»­ - * @param[in] ctx äÖȾÉÏÏÂÎÄ - */ - virtual void Render(RenderContext& ctx); - - /** - * \~chinese - * @brief Í£Ö¹¶¯»­ - */ - virtual void Stop(); - - /** - * \~chinese - * @brief ÖØÖö¯»­ - */ - virtual void Reset() {} - -protected: - bool done_; - float process_; - Duration duration_; - Duration delta_; - Size window_size_; - StagePtr out_stage_; - StagePtr in_stage_; - Layer out_layer_; - Layer in_layer_; -}; - -/** - * \~chinese - * @brief µ­Èëµ­³ö¹ý¶É¶¯»­ - * @details ǰһ³¡¾°µ­³ö¶¯»­½áÊøºó£¬ºóÒ»³¡¾°µ­Èë - */ -class FadeTransition : public Transition -{ -public: - /** - * \~chinese - * @brief ´´½¨µ­Èëµ­³ö¹ý¶É¶¯»­ - * @param duration ¶¯»­Ê±³¤ - */ - FadeTransition(Duration duration); - - FadeTransition(); - -protected: - void Update(Duration dt) override; - - virtual void Init(Stage* prev, Stage* next) override; -}; - -/** - * \~chinese - * @brief ½¥±ä¹ý¶É¶¯»­ - * @details ǰһ³¡¾°µ­³ö¶¯»­µÄͬʱ£¬ºóÒ»³¡¾°µ­Èë - */ -class EmergeTransition : public Transition -{ -public: - /** - * \~chinese - * @brief ´´½¨½¥±ä¹ý¶É¶¯»­ - * @param duration ¶¯»­Ê±³¤ - */ - EmergeTransition(Duration duration); - - EmergeTransition(); - -protected: - void Update(Duration dt) override; - - virtual void Init(Stage* prev, Stage* next) override; -}; - -/** - * \~chinese - * @brief ºÐ×´¹ý¶É¶¯»­ - * @details ǰһ³¡¾°ÒÔºÐ×´ÊÕËõÖÁÏûʧ£¬ºóÒ»³¡¾°ÒÔºÐ×´À©´ó - */ -class BoxTransition : public Transition -{ -public: - /** - * \~chinese - * @brief ´´½¨ºÐ×´¹ý¶É¶¯»­ - * @param duration ¶¯»­Ê±³¤ - */ - BoxTransition(Duration duration); - - BoxTransition(); - -protected: - void Update(Duration dt) override; - - virtual void Init(Stage* prev, Stage* next) override; -}; - -/** - * \~chinese - * @brief Î»ÒÆ¹ý¶É¶¯»­ - * @details Á½³¡¾°ÒÔÎ»ÒÆµÄ·½Ê½Çл» - */ -class MoveTransition : public Transition -{ -public: - /** - * \~chinese - * @brief Î»ÒÆ·½Ê½ - */ - enum class Type : int - { - Up, ///< ÉÏÒÆ - Down, ///< ÏÂÒÆ - Left, ///< ×óÒÆ - Right ///< ÓÒÒÆ - }; - - /** - * \~chinese - * @brief ´´½¨Î»Òƹý¶É¶¯»­ - * @param duration ¶¯»­Ê±³¤ - * @param type Î»ÒÆ·½Ê½ - */ - MoveTransition(Duration duration, Type type); - - MoveTransition(); - -protected: - void Update(Duration dt) override; - - virtual void Init(Stage* prev, Stage* next) override; - - void Reset() override; - -private: - Type type_; - Point pos_delta_; - Point start_pos_; -}; - -/** - * \~chinese - * @brief Ðýת¹ý¶É¶¯»­ - * @details ǰһ³¡¾°ÒÔÐýת·½Ê½ÊÕËõÖÁÏûʧ£¬ºóÒ»³¡¾°ÒÔÐýת·½Ê½À©´ó - */ -class RotationTransition : public Transition -{ -public: - /** - * \~chinese - * @brief ´´½¨Ðýת¹ý¶É¶¯»­ - * @param duration ¶¯»­Ê±³¤ - * @param rotation Ðýת¶ÈÊý - */ - RotationTransition(Duration duration, float rotation = 360.0f); - - RotationTransition(); - -protected: - void Update(Duration dt) override; - - virtual void Init(Stage* prev, Stage* next) override; - - void Reset() override; - -private: - float rotation_; -}; - - -inline void Transition::SetDuration(Duration dt) -{ - duration_ = dt; -} - -} // 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/animation/Animation.cpp b/src/kiwano/2d/animation/Animation.cpp new file mode 100644 index 00000000..734f9775 --- /dev/null +++ b/src/kiwano/2d/animation/Animation.cpp @@ -0,0 +1,194 @@ +// 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 +{ +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()); + } +} + +AnimationEventHandlerPtr AnimationEventHandler::Create(const Function& handler) +{ + class CallbackAnimationEventHandler : public AnimationEventHandler + { + public: + typedef Function Callback; + + Callback handler; + + CallbackAnimationEventHandler(const Callback& handler) : handler(handler) {} + + void Handle(Animation* anim, Actor* target, AnimationEvent evt) override + { + if (handler) + { + handler(anim, target, evt); + } + } + }; + return AnimationEventHandlerPtr(new CallbackAnimationEventHandler(handler)); +} + +AnimationEventHandlerPtr AnimationEventHandler::Create(AnimationEvent evt, const Function& handler) +{ + class OneEventAnimationEventHandler : public AnimationEventHandler + { + public: + typedef Function Callback; + + AnimationEvent evt; + Callback handler; + + OneEventAnimationEventHandler(AnimationEvent evt, const Callback& handler) + : handler(handler) + , evt(evt) + { + } + + void Handle(Animation* anim, Actor* target, AnimationEvent evt) override + { + if (this->evt != evt) + return; + + if (handler) + { + handler(anim, target); + } + } + }; + return AnimationEventHandlerPtr(new OneEventAnimationEventHandler(evt, handler)); +} + +AnimationEventHandlerPtr AnimationEventHandler::HandleStarted(const Function& handler) +{ + return AnimationEventHandler::Create(AnimationEvent::Started, handler); +} + +AnimationEventHandlerPtr AnimationEventHandler::HandleLoopDone(const Function& handler) +{ + return AnimationEventHandler::Create(AnimationEvent::LoopDone, handler); +} + +AnimationEventHandlerPtr AnimationEventHandler::HandleDone(const Function& handler) +{ + return AnimationEventHandler::Create(AnimationEvent::Done, handler); +} + +} // namespace kiwano diff --git a/src/kiwano/2d/animation/Animation.h b/src/kiwano/2d/animation/Animation.h new file mode 100644 index 00000000..73025076 --- /dev/null +++ b/src/kiwano/2d/animation/Animation.h @@ -0,0 +1,335 @@ +// 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 Animator; + +KGE_DECLARE_SMART_PTR(Animation); +KGE_DECLARE_SMART_PTR(AnimationEventHandler); + +/** + * \~chinese + * \defgroup Animation ¶¯»­ + */ + +/** + * \addtogroup Animation + * @{ + */ + +/// \~chinese +/// @brief ¶¯»­Ê¼þ +enum class AnimationEvent +{ + Started, ///< ¶¯»­¿ªÊ¼ + LoopDone, ///< ¶¯»­Ò»´ÎÑ­»·½áÊø + Done, ///< ¶¯»­½áÊø +}; + +/// \~chinese +/// @brief ¶¯»­Ê¼þ´¦ÀíÆ÷ +class KGE_API AnimationEventHandler : public RefObject +{ +public: + /// \~chinese + /// @brief ´¦Àí¶¯»­Ê¼þ + /// @param anim ¶¯»­¶ÔÏó + /// @param target Ö´Ðж¯»­µÄ¶ÔÏó + /// @param evt ¶¯»­Ê¼þ + virtual void Handle(Animation* anim, Actor* target, AnimationEvent evt) = 0; + + /// \~chinese + /// @brief ´´½¨¶¯»­Ê¼þ´¦ÀíÆ÷ + /// @param handler ´¦Àí¶¯»­Ê¼þ»Øµ÷º¯Êý + static AnimationEventHandlerPtr Create(const Function& handler); + + /// \~chinese + /// @brief ´´½¨¶¯»­Ê¼þ´¦ÀíÆ÷ + /// @param evt ´¦ÀíµÄ¶¯»­Ê¼þ + /// @param handler ´¦Àí¶¯»­Ê¼þ»Øµ÷º¯Êý + static AnimationEventHandlerPtr Create(AnimationEvent evt, const Function& handler); + + /// \~chinese + /// @brief ´´½¨Started¶¯»­Ê¼þ´¦ÀíÆ÷ + /// @param handler ´¦Àí¶¯»­Ê¼þ»Øµ÷º¯Êý + static AnimationEventHandlerPtr HandleStarted(const Function& handler); + + /// \~chinese + /// @brief ´´½¨LoopDone¶¯»­Ê¼þ´¦ÀíÆ÷ + /// @param handler ´¦Àí¶¯»­Ê¼þ»Øµ÷º¯Êý + static AnimationEventHandlerPtr HandleLoopDone(const Function& handler); + + /// \~chinese + /// @brief ´´½¨Done¶¯»­Ê¼þ´¦ÀíÆ÷ + /// @param handler ´¦Àí¶¯»­Ê¼þ»Øµ÷º¯Êý + static AnimationEventHandlerPtr HandleDone(const Function& handler); +}; + +/// \~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/CustomAnimation.cpp b/src/kiwano/2d/animation/CustomAnimation.cpp new file mode 100644 index 00000000..3656eef3 --- /dev/null +++ b/src/kiwano/2d/animation/CustomAnimation.cpp @@ -0,0 +1,51 @@ +// 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 + +namespace kiwano +{ + +CustomAnimation::CustomAnimation(Duration duration, TweenFunc tween_func) + : TweenAnimation(duration) + , tween_func_(tween_func) +{ +} + +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/animation/CustomAnimation.h b/src/kiwano/2d/animation/CustomAnimation.h new file mode 100644 index 00000000..3c41c745 --- /dev/null +++ b/src/kiwano/2d/animation/CustomAnimation.h @@ -0,0 +1,93 @@ +// 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 + +namespace kiwano +{ +KGE_DECLARE_SMART_PTR(CustomAnimation); + +/** + * \addtogroup Animation + * @{ + */ + + +/// \~chinese +/// @brief ²¹¼ä¶¯»­»Øµ÷º¯Êý +/// @details ÔÚ¶¯»­¸üÐÂʱ»Øµ÷¸Ãº¯Êý£¬µÚÒ»¸ö²ÎÊýÊÇÖ´Ðж¯»­µÄÄ¿±ê£¬µÚ¶þ¸ö²ÎÊýÊǶ¯»­½ø¶È£¨0.0 - 1.0£© +using TweenFunc = Function; + +/// \~chinese +/// @brief ×Ô¶¨Ò嶯»­ +class KGE_API CustomAnimation : public TweenAnimation +{ +public: + /// \~chinese + /// @brief ´´½¨×Ô¶¨Ò嶯»­ + /// @param duration ¶¯»­Ê±³¤ + /// @param tween_func ¶¯»­»Øµ÷º¯Êý + CustomAnimation(Duration duration, TweenFunc tween_func); + + /// \~chinese + /// @brief »ñÈ¡¶¯»­»Øµ÷º¯Êý + TweenFunc GetTweenFunc() const; + + /// \~chinese + /// @brief ÉèÖö¯»­»Øµ÷º¯Êý + void SetTweenFunc(const TweenFunc& tween_func); + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó + CustomAnimation* Clone() const override; + + /// \~chinese + /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª + CustomAnimation* Reverse() const override + { + KGE_ERRORF("Reverse() not supported in CustomAnimation"); + return nullptr; + } + +protected: + void Init(Actor* target) override; + + void UpdateTween(Actor* target, float frac) override; + +private: + 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/EaseFunc.cpp b/src/kiwano/2d/animation/EaseFunc.cpp new file mode 100644 index 00000000..d2d373d4 --- /dev/null +++ b/src/kiwano/2d/animation/EaseFunc.cpp @@ -0,0 +1,84 @@ +// 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 +{ + +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; + +} diff --git a/src/kiwano/2d/animation/EaseFunc.h b/src/kiwano/2d/animation/EaseFunc.h new file mode 100644 index 00000000..96108df5 --- /dev/null +++ b/src/kiwano/2d/animation/EaseFunc.h @@ -0,0 +1,69 @@ +// 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 + +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; +}; + +} diff --git a/src/kiwano/2d/action/Animation.cpp b/src/kiwano/2d/animation/FrameAnimation.cpp similarity index 66% rename from src/kiwano/2d/action/Animation.cpp rename to src/kiwano/2d/animation/FrameAnimation.cpp index 2ac98c25..1351f6cd 100644 --- a/src/kiwano/2d/action/Animation.cpp +++ b/src/kiwano/2d/animation/FrameAnimation.cpp @@ -18,44 +18,40 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include #include -#include namespace kiwano { -Animation::Animation(Duration dur, FrameSequencePtr frame_seq) -{ - SetEntity(MakePtr(dur, frame_seq)); -} - -AnimationEntity::AnimationEntity() +FrameAnimation::FrameAnimation() : frame_seq_(nullptr) + , current_index_(0) { } -AnimationEntity::AnimationEntity(Duration dur, FrameSequencePtr frame_seq) - : ActionTweenEntity(dur) +FrameAnimation::FrameAnimation(Duration dur, FrameSequencePtr frame_seq) + : TweenAnimation(dur) , frame_seq_(frame_seq) + , current_index_(0) { } -AnimationEntity::~AnimationEntity() {} +FrameAnimation::~FrameAnimation() {} -FrameSequencePtr AnimationEntity::GetFrameSequence() const +FrameSequencePtr FrameAnimation::GetFrameSequence() const { return frame_seq_; } -void AnimationEntity::SetFrameSequence(FrameSequencePtr frame_seq) +void FrameAnimation::SetFrameSequence(FrameSequencePtr frame_seq) { frame_seq_ = frame_seq; } -void AnimationEntity::Init(Actor* target) +void FrameAnimation::Init(Actor* target) { - KGE_ASSERT(frame_seq_ && "AnimationEntity::Init() failed: FrameSequence is NULL!"); + KGE_ASSERT(frame_seq_ && "FrameAnimation::Init() failed: FrameSequence is NULL!"); if (!frame_seq_ || frame_seq_->GetFrames().empty()) { Done(); @@ -63,15 +59,16 @@ void AnimationEntity::Init(Actor* target) } auto sprite_target = dynamic_cast(target); - KGE_ASSERT(sprite_target && "AnimationEntity only supports Sprites!"); + KGE_ASSERT(sprite_target && "FrameAnimation only supports Sprites!"); if (sprite_target && frame_seq_) { sprite_target->SetFrame(frame_seq_->GetFrames()[0]); + current_index_ = 0; } } -void AnimationEntity::UpdateTween(Actor* target, float percent) +void FrameAnimation::UpdateTween(Actor* target, float percent) { auto sprite_target = dynamic_cast(target); @@ -81,20 +78,24 @@ void AnimationEntity::UpdateTween(Actor* target, float percent) auto size = frames.size(); auto index = std::min(static_cast(math::Floor(size * percent)), size - 1); - sprite_target->SetFrame(frames[index]); + if (index != current_index_) + { + current_index_ = index; + sprite_target->SetFrame(frames[index]); + } } } -AnimationEntity* AnimationEntity::Clone() const +FrameAnimation* FrameAnimation::Clone() const { - AnimationEntity* ptr = new AnimationEntity(GetDuration(), frame_seq_); + FrameAnimation* ptr = new FrameAnimation(GetDuration(), frame_seq_); DoClone(ptr); return ptr; } -AnimationEntity* AnimationEntity::Reverse() const +FrameAnimation* FrameAnimation::Reverse() const { - AnimationEntity* ptr = new AnimationEntity(GetDuration(), nullptr); + FrameAnimation* ptr = new FrameAnimation(GetDuration(), nullptr); DoClone(ptr); if (frame_seq_) diff --git a/src/kiwano/2d/action/Animation.h b/src/kiwano/2d/animation/FrameAnimation.h similarity index 73% rename from src/kiwano/2d/action/Animation.h rename to src/kiwano/2d/animation/FrameAnimation.h index 714529ad..4fb25441 100644 --- a/src/kiwano/2d/action/Animation.h +++ b/src/kiwano/2d/animation/FrameAnimation.h @@ -19,45 +19,33 @@ // THE SOFTWARE. #pragma once -#include -#include +#include +#include namespace kiwano { -KGE_DECLARE_SMART_PTR(AnimationEntity); +KGE_DECLARE_SMART_PTR(FrameAnimation); /** - * \addtogroup Actions + * \addtogroup Animation * @{ */ /// \~chinese /// @brief Ö¡¶¯»­ -class KGE_API Animation : public ActionTween +class KGE_API FrameAnimation : 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(); + FrameAnimation(); /// \~chinese /// @brief ´´½¨Ö¡¶¯»­ /// @param dur ¶¯»­Ê±³¤ /// @param frame_seq ÐòÁÐÖ¡ - AnimationEntity(Duration dur, FrameSequencePtr frame_seq); + FrameAnimation(Duration dur, FrameSequencePtr frame_seq); - virtual ~AnimationEntity(); + virtual ~FrameAnimation(); /// \~chinese /// @brief »ñÈ¡ÐòÁÐÖ¡ @@ -70,11 +58,11 @@ public: /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄ¿½±´¶ÔÏó - AnimationEntity* Clone() const override; + FrameAnimation* Clone() const override; /// \~chinese /// @brief »ñÈ¡¸Ã¶¯»­µÄµ¹×ª - AnimationEntity* Reverse() const override; + FrameAnimation* Reverse() const override; protected: void Init(Actor* target) override; @@ -82,6 +70,7 @@ protected: void UpdateTween(Actor* target, float percent) override; private: + size_t current_index_; FrameSequencePtr frame_seq_; }; diff --git a/src/kiwano/render/FrameSequence.cpp b/src/kiwano/2d/animation/FrameSequence.cpp similarity index 54% rename from src/kiwano/render/FrameSequence.cpp rename to src/kiwano/2d/animation/FrameSequence.cpp index 8a8add29..8b82f085 100644 --- a/src/kiwano/render/FrameSequence.cpp +++ b/src/kiwano/2d/animation/FrameSequence.cpp @@ -18,40 +18,34 @@ // 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) { - if (frame) + AddFrames(frames); +} + +void FrameSequence::AddFrame(const SpriteFrame& frame) +{ + if (frame.IsValid()) { frames_.push_back(frame); } else { - Fail("FrameSequence::Add failed, NULL pointer exception"); + Fail("FrameSequence::AddFrame failed, frame is invalid"); } } -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 +const SpriteFrame& 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_; } diff --git a/src/kiwano/render/FrameSequence.h b/src/kiwano/2d/animation/FrameSequence.h similarity index 56% rename from src/kiwano/render/FrameSequence.h rename to src/kiwano/2d/animation/FrameSequence.h index ab54b5a2..da128f44 100644 --- a/src/kiwano/render/FrameSequence.h +++ b/src/kiwano/2d/animation/FrameSequence.h @@ -19,9 +19,9 @@ // THE SOFTWARE. #pragma once -#include #include #include +#include namespace kiwano { @@ -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 ¹¹½¨¿ÕÐòÁÐÖ¡ @@ -57,36 +46,26 @@ public: virtual ~FrameSequence(); /// \~chinese - /// @brief Ìí¼Ó¹Ø¼üÖ¡ - /// @param frame ͼÏñÖ¡ - void AddFrame(FramePtr frame); + /// @brief Ìí¼Ó¾«ÁéÖ¡ + /// @param frame ¾«ÁéÖ¡ + void AddFrame(const SpriteFrame& frame); /// \~chinese - /// @brief Ìí¼Ó¶à¸ö¹Ø¼üÖ¡ - /// @param frames ͼÏñÖ¡¼¯ºÏ - void AddFrames(const Vector& frames); + /// @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); + /// @brief »ñÈ¡¾«ÁéÖ¡ + /// @param index ¾«Áé֡ϱê + const SpriteFrame& GetFrame(size_t index) const; /// \~chinese - /// @brief »ñÈ¡¹Ø¼üÖ¡ - /// @param index ͼÏñ֡ϱê - FramePtr GetFrame(size_t index) const; + /// @brief »ñÈ¡ËùÓо«ÁéÖ¡ + const Vector& GetFrames() const; /// \~chinese - /// @brief »ñÈ¡ËùÓйؼüÖ¡ - const Vector& GetFrames() const; - - /// \~chinese - /// @brief »ñÈ¡¹Ø¼üÖ¡ÊýÁ¿ + /// @brief »ñÈ¡¾«ÁéÖ¡ÊýÁ¿ size_t GetFramesCount() const; /// \~chinese @@ -98,6 +77,7 @@ public: FrameSequencePtr Reverse() const; private: - Vector frames_; + Vector frames_; }; + } // namespace kiwano 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 new file mode 100644 index 00000000..d3498b80 --- /dev/null +++ b/src/kiwano/2d/animation/TweenAnimation.cpp @@ -0,0 +1,369 @@ +// 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 +{ + +//------------------------------------------------------- +// 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 new file mode 100644 index 00000000..5750b46b --- /dev/null +++ b/src/kiwano/2d/animation/TweenAnimation.h @@ -0,0 +1,627 @@ +// 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 + +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/2d/transition/BoxTransition.cpp b/src/kiwano/2d/transition/BoxTransition.cpp new file mode 100644 index 00000000..24438541 --- /dev/null +++ b/src/kiwano/2d/transition/BoxTransition.cpp @@ -0,0 +1,58 @@ +// 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 + +namespace kiwano +{ + +BoxTransition::BoxTransition(Duration duration) +{ + SetDuration(duration); +} + +BoxTransition::BoxTransition() {} + +void BoxTransition::Init(Stage* prev, Stage* next) +{ + Transition::Init(prev, next); + + in_layer_.SetOpacity(0.f); +} + +void BoxTransition::Update(Duration dt) +{ + Transition::Update(dt); + + if (process_ < .5f) + { + out_layer_.SetClipRect(Rect(window_size_.x * process_, window_size_.y * process_, + window_size_.x * (1 - process_), window_size_.y * (1 - process_))); + } + else + { + out_layer_.SetOpacity(0.f); + in_layer_.SetOpacity(1.f); + in_layer_.SetClipRect(Rect(window_size_.x * (1 - process_), window_size_.y * (1 - process_), + window_size_.x * process_, window_size_.y * process_)); + } +} + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/BoxTransition.h b/src/kiwano/2d/transition/BoxTransition.h new file mode 100644 index 00000000..54020f23 --- /dev/null +++ b/src/kiwano/2d/transition/BoxTransition.h @@ -0,0 +1,52 @@ +// 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 + +namespace kiwano +{ + +KGE_DECLARE_SMART_PTR(BoxTransition); + +/** + * \~chinese + * @brief ºÐ×´¹ý¶É¶¯»­ + * @details ǰһ³¡¾°ÒÔºÐ×´ÊÕËõÖÁÏûʧ£¬ºóÒ»³¡¾°ÒÔºÐ×´À©´ó + */ +class BoxTransition : public Transition +{ +public: + /** + * \~chinese + * @brief ´´½¨ºÐ×´¹ý¶É¶¯»­ + * @param duration ¶¯»­Ê±³¤ + */ + BoxTransition(Duration duration); + + BoxTransition(); + +protected: + void Update(Duration dt) override; + + virtual void Init(Stage* prev, Stage* next) override; +}; + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/FadeTransition.cpp b/src/kiwano/2d/transition/FadeTransition.cpp new file mode 100644 index 00000000..06353e62 --- /dev/null +++ b/src/kiwano/2d/transition/FadeTransition.cpp @@ -0,0 +1,66 @@ +// 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 + +namespace kiwano +{ + +FadeTransition::FadeTransition(Duration duration, bool parallel) + : parallel_(parallel) +{ + SetDuration(duration); +} + +FadeTransition::FadeTransition() {} + +void FadeTransition::Init(Stage* prev, Stage* next) +{ + Transition::Init(prev, next); + + out_layer_.SetOpacity(1.f); + in_layer_.SetOpacity(0.f); +} + +void FadeTransition::Update(Duration dt) +{ + Transition::Update(dt); + + if (parallel_) + { + out_layer_.SetOpacity(1 - process_); + in_layer_.SetOpacity(process_); + } + else + { + if (process_ < 0.5) + { + out_layer_.SetOpacity(1 - process_ * 2); + in_layer_.SetOpacity(0.f); + } + else + { + out_layer_.SetOpacity(0.f); + in_layer_.SetOpacity((process_ - 0.5f) * 2); + } + } +} + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/FadeTransition.h b/src/kiwano/2d/transition/FadeTransition.h new file mode 100644 index 00000000..983e7a18 --- /dev/null +++ b/src/kiwano/2d/transition/FadeTransition.h @@ -0,0 +1,56 @@ +// 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 + +namespace kiwano +{ + +KGE_DECLARE_SMART_PTR(FadeTransition); + +/** + * \~chinese + * @brief µ­Èëµ­³ö¹ý¶É¶¯»­ + * @details ǰһ³¡¾°µ­³ö¶¯»­½áÊøºó£¬ºóÒ»³¡¾°µ­Èë + */ +class FadeTransition : public Transition +{ +public: + /** + * \~chinese + * @brief ´´½¨µ­Èëµ­³ö¹ý¶É¶¯»­ + * @param duration ¶¯»­Ê±³¤ + * @param parallel µ­ÈëºÍµ­³öͬʱ½øÐÐ + */ + FadeTransition(Duration duration, bool parallel = false); + + FadeTransition(); + +protected: + void Update(Duration dt) override; + + virtual void Init(Stage* prev, Stage* next) override; + +private: + bool parallel_; +}; + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/MoveTransition.cpp b/src/kiwano/2d/transition/MoveTransition.cpp new file mode 100644 index 00000000..34275cc8 --- /dev/null +++ b/src/kiwano/2d/transition/MoveTransition.cpp @@ -0,0 +1,106 @@ +// 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 + +namespace kiwano +{ + +MoveTransition::MoveTransition(Duration duration, Type type) + : type_(type) +{ + SetDuration(duration); +} + +MoveTransition::MoveTransition() + : type_(Type::Left) +{ +} + +void MoveTransition::Init(Stage* prev, Stage* next) +{ + Transition::Init(prev, next); + + switch (type_) + { + case Type::Up: + pos_delta_ = Point(0, -window_size_.y); + start_pos_ = Point(0, window_size_.y); + break; + case Type::Down: + pos_delta_ = Point(0, window_size_.y); + start_pos_ = Point(0, -window_size_.y); + break; + case Type::Left: + pos_delta_ = Point(-window_size_.x, 0); + start_pos_ = Point(window_size_.x, 0); + break; + case Type::Right: + pos_delta_ = Point(window_size_.x, 0); + start_pos_ = Point(-window_size_.x, 0); + break; + } + + if (out_stage_) + { + out_stage_->SetTransform(Transform{}); + } + + if (in_stage_) + { + auto transform = Transform{}; + transform.position = start_pos_; + in_stage_->SetTransform(transform); + } +} + +void MoveTransition::Update(Duration dt) +{ + Transition::Update(dt); + + if (out_stage_) + { + auto transform = Transform{}; + transform.position = pos_delta_ * process_; + out_stage_->SetTransform(transform); + } + + if (in_stage_) + { + auto transform = Transform{}; + transform.position = start_pos_ + pos_delta_ * process_; + in_stage_->SetTransform(transform); + } +} + +void MoveTransition::Reset() +{ + if (out_stage_) + { + out_stage_->SetTransform(Transform{}); + } + + if (in_stage_) + { + in_stage_->SetTransform(Transform{}); + } +} + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/MoveTransition.h b/src/kiwano/2d/transition/MoveTransition.h new file mode 100644 index 00000000..899ee0b2 --- /dev/null +++ b/src/kiwano/2d/transition/MoveTransition.h @@ -0,0 +1,72 @@ +// 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 + +namespace kiwano +{ + +KGE_DECLARE_SMART_PTR(MoveTransition); + +/** + * \~chinese + * @brief Î»ÒÆ¹ý¶É¶¯»­ + * @details Á½³¡¾°ÒÔÎ»ÒÆµÄ·½Ê½Çл» + */ +class MoveTransition : public Transition +{ +public: + /** + * \~chinese + * @brief Î»ÒÆ·½Ê½ + */ + enum class Type : int + { + Up, ///< ÉÏÒÆ + Down, ///< ÏÂÒÆ + Left, ///< ×óÒÆ + Right ///< ÓÒÒÆ + }; + + /** + * \~chinese + * @brief ´´½¨Î»Òƹý¶É¶¯»­ + * @param duration ¶¯»­Ê±³¤ + * @param type Î»ÒÆ·½Ê½ + */ + MoveTransition(Duration duration, Type type); + + MoveTransition(); + +protected: + void Update(Duration dt) override; + + virtual void Init(Stage* prev, Stage* next) override; + + void Reset() override; + +private: + Type type_; + Point pos_delta_; + Point start_pos_; +}; + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/RotationTransition.cpp b/src/kiwano/2d/transition/RotationTransition.cpp new file mode 100644 index 00000000..4a407296 --- /dev/null +++ b/src/kiwano/2d/transition/RotationTransition.cpp @@ -0,0 +1,104 @@ +// 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 + +namespace kiwano +{ + +RotationTransition::RotationTransition(Duration duration, float rotation) + : rotation_(rotation) +{ + SetDuration(duration); +} + +RotationTransition::RotationTransition() + : rotation_(0.0f) +{ +} + +void RotationTransition::Init(Stage* prev, Stage* next) +{ + Transition::Init(prev, next); + + auto transform = Transform{}; + transform.position = Point{ window_size_.x / 2, window_size_.y / 2 }; + + if (out_stage_) + { + out_stage_->SetTransform(transform); + out_stage_->SetAnchor(Vec2{ 0.5f, 0.5f }); + } + + if (in_stage_) + { + in_stage_->SetTransform(transform); + in_stage_->SetAnchor(Vec2{ 0.5f, 0.5f }); + } + + in_layer_.SetOpacity(0.f); +} + +void RotationTransition::Update(Duration dt) +{ + Transition::Update(dt); + + if (process_ < .5f) + { + if (out_stage_) + { + auto transform = out_stage_->GetTransform(); + transform.scale = Point{ (.5f - process_) * 2, (.5f - process_) * 2 }; + transform.rotation = rotation_ * (.5f - process_) * 2; + out_stage_->SetTransform(transform); + } + } + else + { + if (in_stage_) + { + out_layer_.SetOpacity(0.f); + in_layer_.SetOpacity(1.f); + + auto transform = in_stage_->GetTransform(); + transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 }; + transform.rotation = rotation_ * (process_ - .5f) * 2; + + in_stage_->SetTransform(transform); + } + } +} + +void RotationTransition::Reset() +{ + if (out_stage_) + { + out_stage_->SetTransform(Transform{}); + out_stage_->SetAnchor(Vec2{ 0.f, 0.f }); + } + + if (in_stage_) + { + in_stage_->SetTransform(Transform{}); + in_stage_->SetAnchor(Vec2{ 0.f, 0.f }); + } +} + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/RotationTransition.h b/src/kiwano/2d/transition/RotationTransition.h new file mode 100644 index 00000000..6be27d34 --- /dev/null +++ b/src/kiwano/2d/transition/RotationTransition.h @@ -0,0 +1,58 @@ +// 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 + +namespace kiwano +{ + +KGE_DECLARE_SMART_PTR(RotationTransition); + +/** + * \~chinese + * @brief Ðýת¹ý¶É¶¯»­ + * @details ǰһ³¡¾°ÒÔÐýת·½Ê½ÊÕËõÖÁÏûʧ£¬ºóÒ»³¡¾°ÒÔÐýת·½Ê½À©´ó + */ +class RotationTransition : public Transition +{ +public: + /** + * \~chinese + * @brief ´´½¨Ðýת¹ý¶É¶¯»­ + * @param duration ¶¯»­Ê±³¤ + * @param rotation Ðýת¶ÈÊý + */ + RotationTransition(Duration duration, float rotation = 360.0f); + + RotationTransition(); + +protected: + void Update(Duration dt) override; + + virtual void Init(Stage* prev, Stage* next) override; + + void Reset() override; + +private: + float rotation_; +}; + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/Transition.cpp b/src/kiwano/2d/transition/Transition.cpp new file mode 100644 index 00000000..4b3b7040 --- /dev/null +++ b/src/kiwano/2d/transition/Transition.cpp @@ -0,0 +1,118 @@ +// 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 +{ + +Transition::Transition() + : done_(false) + , duration_() + , delta_() + , process_(0) + , window_size_() + , out_stage_(nullptr) + , in_stage_(nullptr) + , out_layer_() + , in_layer_() +{ +} + +Transition::~Transition() {} + +bool Transition::IsDone() +{ + return done_; +} + +void Transition::Init(Stage* prev, Stage* next) +{ + process_ = 0; + delta_ = Duration{}; + + out_stage_ = prev; + in_stage_ = next; + window_size_ = Renderer::GetInstance().GetOutputSize(); + + if (in_stage_) + { + in_layer_.SetClipRect(Rect{ Point(), window_size_ }); + } + + if (out_stage_) + { + out_layer_.SetClipRect(Rect{ Point(), window_size_ }); + } +} + +void Transition::Update(Duration dt) +{ + if (duration_.IsZero()) + { + process_ = 1; + } + else + { + delta_ += dt; + process_ = std::min(delta_ / duration_, 1.f); + } + + if (process_ >= 1) + { + this->Stop(); + } +} + +void Transition::Render(RenderContext& ctx) +{ + if (out_stage_) + { + out_stage_->PrepareToRender(ctx); + ctx.PushClipRect(Rect{ Point{}, window_size_ }); + ctx.PushLayer(out_layer_); + + out_stage_->Render(ctx); + + ctx.PopLayer(); + ctx.PopClipRect(); + } + + if (in_stage_) + { + in_stage_->PrepareToRender(ctx); + ctx.PushClipRect(Rect{ Point{}, window_size_ }); + ctx.PushLayer(in_layer_); + + in_stage_->Render(ctx); + + ctx.PopLayer(); + ctx.PopClipRect(); + } +} + +void Transition::Stop() +{ + done_ = true; + Reset(); +} + +} // namespace kiwano diff --git a/src/kiwano/2d/transition/Transition.h b/src/kiwano/2d/transition/Transition.h new file mode 100644 index 00000000..e648405f --- /dev/null +++ b/src/kiwano/2d/transition/Transition.h @@ -0,0 +1,121 @@ +// 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 +{ +class Director; +class RenderContext; + +KGE_DECLARE_SMART_PTR(Transition); + +/** + * \~chinese + * \defgroup Transition Îę̀¹ý¶É¶¯»­ + */ + +/** + * \addtogroup Transition + * @{ + */ + +/** + * \~chinese + * @brief Îę̀¹ý¶É¶¯»­ + */ +class KGE_API Transition : public ObjectBase +{ + friend class Director; + +public: + Transition(); + + virtual ~Transition(); + + /** + * \~chinese + * @brief ÉèÖö¯»­Ê±³¤ + */ + void SetDuration(Duration dt); + + /** + * \~chinese + * @brief ³¡¾°¹ý¶É¶¯»­ÊÇ·ñÒѽáÊø + */ + bool IsDone(); + +protected: + /** + * \~chinese + * @brief ³õʼ»¯³¡¾°¹ý¶É¶¯»­ + * @param[in] prev ת³ö³¡¾° + * @param[in] next תÈ볡¾° + */ + virtual void Init(Stage* prev, Stage* next); + + /** + * \~chinese + * @brief ¸üйý¶É¶¯»­ + * @param dt ¾àÉÏÒ»´Î¸üеÄʱ¼ä¼ä¸ô + */ + virtual void Update(Duration dt); + + /** + * \~chinese + * @brief äÖȾ¹ý¶È¶¯»­ + * @param[in] ctx äÖȾÉÏÏÂÎÄ + */ + virtual void Render(RenderContext& ctx); + + /** + * \~chinese + * @brief Í£Ö¹¶¯»­ + */ + virtual void Stop(); + + /** + * \~chinese + * @brief ÖØÖö¯»­ + */ + virtual void Reset() {} + +protected: + bool done_; + float process_; + Duration duration_; + Duration delta_; + Size window_size_; + StagePtr out_stage_; + StagePtr in_stage_; + Layer out_layer_; + Layer in_layer_; +}; + +/** @} */ + +inline void Transition::SetDuration(Duration dt) +{ + duration_ = dt; +} + +} // namespace kiwano diff --git a/src/kiwano/base/Director.cpp b/src/kiwano/base/Director.cpp index 340076a6..534cb1ec 100644 --- a/src/kiwano/base/Director.cpp +++ b/src/kiwano/base/Director.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include namespace kiwano diff --git a/src/kiwano/base/Director.h b/src/kiwano/base/Director.h index c216e590..a4b91420 100644 --- a/src/kiwano/base/Director.h +++ b/src/kiwano/base/Director.h @@ -21,7 +21,7 @@ #pragma once #include #include -#include +#include #include namespace kiwano diff --git a/src/kiwano/core/BinaryData.h b/src/kiwano/core/BinaryData.h new file mode 100644 index 00000000..98990856 --- /dev/null +++ b/src/kiwano/core/BinaryData.h @@ -0,0 +1,50 @@ +// 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 + +namespace kiwano +{ + +/// \~chinese +/// @brief ¶þ½øÖÆÊý¾Ý +struct KGE_API BinaryData +{ + void* buffer; ///< Êý¾Ý + uint32_t size; ///< Êý¾Ý´óС + + BinaryData(); + + bool IsValid() const; +}; + +inline BinaryData::BinaryData() + : buffer(nullptr) + , size(0) +{ +} + +inline bool BinaryData::IsValid() const +{ + return buffer != nullptr && size != 0; +} + +} // namespace kiwano diff --git a/src/kiwano/core/Resource.cpp b/src/kiwano/core/Resource.cpp index ec415340..9d598405 100644 --- a/src/kiwano/core/Resource.cpp +++ b/src/kiwano/core/Resource.cpp @@ -36,7 +36,7 @@ Resource::Resource(uint32_t id, const String& type) { } -Resource::Data Resource::GetData() const +BinaryData Resource::GetData() const { do { diff --git a/src/kiwano/core/Resource.h b/src/kiwano/core/Resource.h index 19c742db..0e362e00 100644 --- a/src/kiwano/core/Resource.h +++ b/src/kiwano/core/Resource.h @@ -19,11 +19,11 @@ // THE SOFTWARE. #pragma once -#include -#include +#include namespace kiwano { + /** * \~chinese * @brief ×ÊÔ´ @@ -40,17 +40,6 @@ namespace kiwano class KGE_API Resource { public: - /// \~chinese - /// @brief ×ÊÔ´µÄ¶þ½øÖÆÊý¾Ý - struct Data - { - void* buffer; ///< ×ÊÔ´Êý¾Ý - uint32_t size; ///< ×ÊÔ´Êý¾Ý´óС - - Data(); - - bool IsValid() const; - }; /// \~chinese /// @brief ¹¹Ôì×ÊÔ´ @@ -65,7 +54,7 @@ public: /// \~chinese /// @brief »ñÈ¡×ÊÔ´µÄ¶þ½øÖÆÊý¾Ý /// @return ×ÊÔ´Êý¾Ý - Resource::Data GetData() const; + BinaryData GetData() const; /// \~chinese /// @brief »ñÈ¡×ÊÔ´ ID @@ -79,20 +68,9 @@ private: uint32_t id_; String type_; - mutable Resource::Data data_; + mutable BinaryData data_; }; -inline Resource::Data::Data() - : buffer(nullptr) - , size(0) -{ -} - -inline bool Resource::Data::IsValid() const -{ - return buffer != nullptr && size; -} - inline uint32_t Resource::GetId() const { return id_; diff --git a/src/kiwano/event/EventDispatcher.cpp b/src/kiwano/event/EventDispatcher.cpp index 71abe117..b131819f 100644 --- a/src/kiwano/event/EventDispatcher.cpp +++ b/src/kiwano/event/EventDispatcher.cpp @@ -34,7 +34,7 @@ bool EventDispatcher::DispatchEvent(Event* evt) next = listener->GetNext(); if (listener->IsRunning()) - listener->Receive(evt); + listener->Handle(evt); if (listener->IsRemoveable()) listeners_.Remove(listener); @@ -58,13 +58,13 @@ EventListener* EventDispatcher::AddListener(EventListenerPtr listener) EventListener* EventDispatcher::AddListener(const String& name, EventType type, EventListener::Callback callback) { - auto lis = MakePtr(name, type, callback); + auto lis = EventListener::Create(name, type, callback); return AddListener(lis); } EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback) { - auto lis = MakePtr(type, callback); + auto lis = EventListener::Create(type, callback); return AddListener(lis); } @@ -101,39 +101,6 @@ void EventDispatcher::RemoveListeners(const String& name) } } -void EventDispatcher::StartListeners(const EventType& type) -{ - for (auto& listener : listeners_) - { - if (listener->GetEventType() == type) - { - listener->Start(); - } - } -} - -void EventDispatcher::StopListeners(const EventType& type) -{ - for (auto& listener : listeners_) - { - if (listener->GetEventType() == type) - { - listener->Stop(); - } - } -} - -void EventDispatcher::RemoveListeners(const EventType& type) -{ - for (auto& listener : listeners_) - { - if (listener->GetEventType() == type) - { - listener->Remove(); - } - } -} - void EventDispatcher::StartAllListeners() { for (auto& listener : listeners_) diff --git a/src/kiwano/event/EventDispatcher.h b/src/kiwano/event/EventDispatcher.h index 56be5fab..5c5e2952 100644 --- a/src/kiwano/event/EventDispatcher.h +++ b/src/kiwano/event/EventDispatcher.h @@ -90,21 +90,6 @@ public: /// @param name ¼àÌýÆ÷Ãû³Æ void RemoveListeners(const String& name); - /// \~chinese - /// @brief Æô¶¯¼àÌýÆ÷ - /// @param type ¼àÌýµÄʼþÀàÐÍ - void StartListeners(const EventType& type); - - /// \~chinese - /// @brief Í£Ö¹¼àÌýÆ÷ - /// @param type ¼àÌýµÄʼþÀàÐÍ - void StopListeners(const EventType& type); - - /// \~chinese - /// @brief ÒÆ³ý¼àÌýÆ÷ - /// @param type ¼àÌýµÄʼþÀàÐÍ - void RemoveListeners(const EventType& type); - /// \~chinese /// @brief Æô¶¯ËùÓмàÌýÆ÷ void StartAllListeners(); diff --git a/src/kiwano/event/EventListener.cpp b/src/kiwano/event/EventListener.cpp index 31800fb9..5821ebef 100644 --- a/src/kiwano/event/EventListener.cpp +++ b/src/kiwano/event/EventListener.cpp @@ -25,35 +25,63 @@ namespace kiwano { EventListener::EventListener() - : type_() - , callback_() - , running_(true) + : running_(true) , removeable_(false) , swallow_(false) { } -EventListener::EventListener(EventType type, const Callback& callback) - : EventListener() -{ - this->SetEventType(type); - this->SetCallback(callback); -} - -EventListener::EventListener(const String& name, EventType type, const Callback& callback) - : EventListener(type, callback) -{ - this->SetName(name); -} - EventListener::~EventListener() {} -void EventListener::Receive(Event* evt) +class CallbackEventListener : public EventListener { - if (ShouldHandle(evt) && callback_) +public: + CallbackEventListener(EventType type, const Callback& cb) + : type_(type) + , cb_(cb) { - callback_(evt); } + + void Handle(Event* evt) override + { + if (type_.IsNull() || type_ == evt->GetType()) + { + if (cb_) + { + cb_(evt); + } + } + } + +private: + EventType type_; + Callback cb_; +}; + +EventListenerPtr EventListener::Create(const Callback& callback) +{ + EventListenerPtr ptr = new CallbackEventListener(EventType(), callback); + return ptr; +} + +EventListenerPtr EventListener::Create(const String& name, const Callback& callback) +{ + EventListenerPtr ptr = new CallbackEventListener(EventType(), callback); + ptr->SetName(name); + return ptr; +} + +EventListenerPtr EventListener::Create(EventType type, const Callback& callback) +{ + EventListenerPtr ptr = new CallbackEventListener(type, callback); + return ptr; +} + +EventListenerPtr EventListener::Create(const String& name, EventType type, const Callback& callback) +{ + EventListenerPtr ptr = new CallbackEventListener(type, callback); + ptr->SetName(name); + return ptr; } } // namespace kiwano diff --git a/src/kiwano/event/EventListener.h b/src/kiwano/event/EventListener.h index d6383662..621619cd 100644 --- a/src/kiwano/event/EventListener.h +++ b/src/kiwano/event/EventListener.h @@ -48,20 +48,32 @@ public: EventListener(); + virtual ~EventListener(); + /// \~chinese /// @brief ´´½¨¼àÌýÆ÷ - /// @param type ¼àÌýµÄʼþÀàÐÍ /// @param callback »Øµ÷º¯Êý - EventListener(EventType type, const Callback& callback); + static EventListenerPtr Create(const Callback& callback); /// \~chinese /// @brief ´´½¨¼àÌýÆ÷ /// @param name ¼àÌýÆ÷Ãû³Æ /// @param type ¼àÌýµÄʼþÀàÐÍ /// @param callback »Øµ÷º¯Êý - EventListener(const String& name, EventType type, const Callback& callback); + static EventListenerPtr Create(const String& name, const Callback& callback); - virtual ~EventListener(); + /// \~chinese + /// @brief ´´½¨¼àÌýÆ÷ + /// @param type ¼àÌýµÄʼþÀàÐÍ + /// @param callback »Øµ÷º¯Êý + static EventListenerPtr Create(EventType type, const Callback& callback); + + /// \~chinese + /// @brief ´´½¨¼àÌýÆ÷ + /// @param name ¼àÌýÆ÷Ãû³Æ + /// @param type ¼àÌýµÄʼþÀàÐÍ + /// @param callback »Øµ÷º¯Êý + static EventListenerPtr Create(const String& name, EventType type, const Callback& callback); /// \~chinese /// @brief Æô¶¯¼àÌýÆ÷ @@ -93,45 +105,13 @@ public: void SetSwallowEnabled(bool enabled); /// \~chinese - /// @brief »ñÈ¡»Øµ÷º¯Êý - const Callback& GetCallback() const; - - /// \~chinese - /// @brief ÉèÖûص÷º¯Êý - void SetCallback(const Callback& cb); - - /// \~chinese - /// @brief »ñÈ¡¼àÌýµÄʼþÀàÐÍ - EventType GetEventType() const; - - /// \~chinese - /// @brief ÉèÖüàÌýµÄʼþÀàÐÍ - void SetEventType(const EventType& type); - - /// \~chinese - /// @brief ÅжÏÊÇ·ñ´¦Àíʼþ - virtual bool ShouldHandle(Event* evt) const; - - /// \~chinese - /// @brief ÉèÖüàÌýµÄʼþÀàÐÍ - /// @tparam _EventTy ʼþÀàÐÍ - template - inline void SetEventType() - { - static_assert(std::is_base_of::value, "_EventTy is not an event type."); - SetEventType(KGE_EVENT(_EventTy)); - } - - /// \~chinese - /// @brief ½ÓÊÕÏûÏ¢ - void Receive(Event* evt); + /// @brief ´¦ÀíÏûÏ¢ + virtual void Handle(Event* evt) = 0; private: bool running_; bool removeable_; bool swallow_; - EventType type_; - Callback callback_; }; inline void EventListener::Start() @@ -169,33 +149,4 @@ inline void EventListener::SetSwallowEnabled(bool enabled) swallow_ = enabled; } -inline const EventListener::Callback& EventListener::GetCallback() const -{ - return callback_; -} - -inline void EventListener::SetCallback(const Callback& cb) -{ - callback_ = cb; -} - -inline EventType EventListener::GetEventType() const -{ - return type_; -} - -inline void EventListener::SetEventType(const EventType& type) -{ - type_ = type; -} - -inline bool EventListener::ShouldHandle(Event* evt) const -{ - if (evt) - { - return evt->GetType() == type_; - } - return false; -} - } // namespace kiwano diff --git a/src/kiwano/event/EventType.h b/src/kiwano/event/EventType.h index 53dd8d24..ae104bc0 100644 --- a/src/kiwano/event/EventType.h +++ b/src/kiwano/event/EventType.h @@ -32,24 +32,28 @@ namespace kiwano /// \~chinese /// @brief ʼþÀàÐÍ -class EventType : public std::type_index +class EventType { - class Dummy - { - }; - public: - /// \~chinese - /// @brief ¹¹½¨Ê¼þÀàÐÍ EventType(); - using std::type_index::type_index; - using std::type_index::operator==; - using std::type_index::operator!=; - using std::type_index::operator<; - using std::type_index::operator>=; - using std::type_index::operator>; - using std::type_index::operator<=; + EventType(const std::type_index& type); + + /// \~chinese + /// @brief ÊÇ·ñÊÇ¿ÕÀàÐÍ + bool IsNull() const; + + const std::type_index& GetType() const; + + bool operator==(const EventType& rhs) const; + bool operator!=(const EventType& rhs) const; + bool operator<(const EventType& rhs) const; + bool operator<=(const EventType& rhs) const; + bool operator>(const EventType& rhs) const; + bool operator>=(const EventType& rhs) const; + +private: + std::type_index type_; }; /** @} */ @@ -57,8 +61,53 @@ public: #define KGE_EVENT(EVENT_TYPE) ::kiwano::EventType(typeid(EVENT_TYPE)) inline EventType::EventType() - : std::type_index(typeid(EventType::Dummy)) + : type_(typeid(void)) { } +inline EventType::EventType(const std::type_index& type) + : type_(type) +{ +} + +inline bool EventType::IsNull() const +{ + return type_ == typeid(void); +} + +inline const std::type_index& EventType::GetType() const +{ + return type_; +} + +inline bool EventType::operator==(const EventType& rhs) const +{ + return type_ == rhs.type_; +} + +inline bool EventType::operator!=(const EventType& rhs) const +{ + return type_ != rhs.type_; +} + +inline bool EventType::operator<(const EventType& rhs) const +{ + return type_ < rhs.type_; +} + +inline bool EventType::operator<=(const EventType& rhs) const +{ + return type_ <= rhs.type_; +} + +inline bool EventType::operator>(const EventType& rhs) const +{ + return type_ > rhs.type_; +} + +inline bool EventType::operator>=(const EventType& rhs) const +{ + return type_ >= rhs.type_; +} + } // namespace kiwano diff --git a/src/kiwano/event/KeyEvent.h b/src/kiwano/event/KeyEvent.h index 390cd01d..b97b4d11 100644 --- a/src/kiwano/event/KeyEvent.h +++ b/src/kiwano/event/KeyEvent.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include namespace kiwano diff --git a/src/kiwano/event/MouseEvent.h b/src/kiwano/event/MouseEvent.h index 6a308d93..013ea032 100644 --- a/src/kiwano/event/MouseEvent.h +++ b/src/kiwano/event/MouseEvent.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include #include diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index a01e941f..4b7c65b2 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -82,8 +82,6 @@ #include #include #include -#include -#include #include #include #include @@ -100,17 +98,34 @@ #include #include #include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include + +// +// transition +// + +#include +#include +#include +#include +#include + +// +// animation +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include // // platform diff --git a/src/kiwano/platform/FileSystem.cpp b/src/kiwano/platform/FileSystem.cpp index a8b4e0d6..6ff5239c 100644 --- a/src/kiwano/platform/FileSystem.cpp +++ b/src/kiwano/platform/FileSystem.cpp @@ -176,7 +176,7 @@ bool FileSystem::ExtractResourceToFile(const Resource& res, const String& dest_f if (file_handle == INVALID_HANDLE_VALUE) return false; - Resource::Data data = res.GetData(); + BinaryData data = res.GetData(); if (data.IsValid()) { DWORD written_bytes = 0; diff --git a/src/kiwano/platform/Input.h b/src/kiwano/platform/Input.h index 1b63d734..86537540 100644 --- a/src/kiwano/platform/Input.h +++ b/src/kiwano/platform/Input.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kiwano/core/Keys.h b/src/kiwano/platform/Keys.h similarity index 100% rename from src/kiwano/core/Keys.h rename to src/kiwano/platform/Keys.h diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp index 1b2ab925..93206243 100644 --- a/src/kiwano/platform/win32/WindowImpl.cpp +++ b/src/kiwano/platform/win32/WindowImpl.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/kiwano/render/DirectX/D2DDeviceResources.cpp b/src/kiwano/render/DirectX/D2DDeviceResources.cpp index 5633124e..368df4b5 100644 --- a/src/kiwano/render/DirectX/D2DDeviceResources.cpp +++ b/src/kiwano/render/DirectX/D2DDeviceResources.cpp @@ -72,8 +72,8 @@ public: HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr& font_collection, const Vector& file_paths) override; - HRESULT CreateFontCollectionFromResources(_Out_ ComPtr& font_collection, - const Vector& resources) override; + HRESULT CreateFontCollectionFromBinaryData(_Out_ ComPtr& font_collection, + const Vector& data) override; HRESULT GetFontFamilyNames(_Out_ Vector& family_names, _In_ ComPtr font_collection) override; @@ -548,8 +548,8 @@ HRESULT D2DDeviceResources::CreateFontCollectionFromFiles(ComPtr& font_collection, - const Vector& resources) +HRESULT D2DDeviceResources::CreateFontCollectionFromBinaryData(ComPtr& font_collection, + const Vector& data) { if (!dwrite_factory_ || !res_font_collection_loader_) return E_UNEXPECTED; @@ -557,7 +557,7 @@ HRESULT D2DDeviceResources::CreateFontCollectionFromResources(ComPtrAddResources(resources, &key, &key_size); + HRESULT hr = res_font_collection_loader_->AddResources(data, &key, &key_size); if (SUCCEEDED(hr)) { diff --git a/src/kiwano/render/DirectX/D2DDeviceResources.h b/src/kiwano/render/DirectX/D2DDeviceResources.h index b3c80ddb..985227fe 100644 --- a/src/kiwano/render/DirectX/D2DDeviceResources.h +++ b/src/kiwano/render/DirectX/D2DDeviceResources.h @@ -59,8 +59,8 @@ public: virtual HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr & font_collection, const Vector& file_paths) = 0; - virtual HRESULT CreateFontCollectionFromResources(_Out_ ComPtr & font_collection, - const Vector& resources) = 0; + virtual HRESULT CreateFontCollectionFromBinaryData(_Out_ ComPtr & font_collection, + const Vector& data) = 0; virtual HRESULT GetFontFamilyNames(_Out_ Vector & family_names, _In_ ComPtr font_collection) = 0; diff --git a/src/kiwano/render/DirectX/FontCollectionLoader.cpp b/src/kiwano/render/DirectX/FontCollectionLoader.cpp index 5cbc8b0b..826b35d2 100644 --- a/src/kiwano/render/DirectX/FontCollectionLoader.cpp +++ b/src/kiwano/render/DirectX/FontCollectionLoader.cpp @@ -344,7 +344,7 @@ public: } STDMETHOD(AddResources) - (const Vector& resources, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); + (const Vector& data, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); // IDWriteFontCollectionLoader methods virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, @@ -360,7 +360,7 @@ private: ULONG refCount_; IDWriteFontFileLoader* pFileLoader_; - typedef Vector ResourceCollection; + typedef Vector ResourceCollection; Vector resources_; Vector collectionKeys_; }; @@ -389,7 +389,8 @@ HRESULT IResourceFontCollectionLoader::Create(_Out_ IResourceFontCollectionLoade return hr; } -STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector& resources, _Out_ LPVOID* pCollectionKey, +STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector& data, + _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize) { if (!pCollectionKey || !pCollectionKeySize) @@ -401,7 +402,7 @@ STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector& { size_t collectionKey = resources_.size(); collectionKeys_.push_back(collectionKey); - resources_.push_back(resources); + resources_.push_back(data); *pCollectionKey = reinterpret_cast(&collectionKeys_.back()); *pCollectionKeySize = sizeof(collectionKey); @@ -423,7 +424,7 @@ HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::CreateEnumeratorFromKey( { HRESULT hr = S_OK; - if (collectionKey == NULL || collectionKeySize % sizeof(Resource*) != 0) + if (collectionKey == NULL || collectionKeySize % sizeof(BinaryData*) != 0) hr = E_INVALIDARG; if (SUCCEEDED(hr)) @@ -533,14 +534,14 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileLoader::CreateStreamFromKey(void const HRESULT hr = S_OK; // Make sure the key is the right size. - if (fontFileReferenceKeySize != sizeof(Resource)) + if (fontFileReferenceKeySize != sizeof(BinaryData)) hr = E_INVALIDARG; if (SUCCEEDED(hr)) { // Create the pFileStream object. IResourceFontFileStream* pFileStream = NULL; - Resource resource = *static_cast(fontFileReferenceKey); + BinaryData resource = *static_cast(fontFileReferenceKey); hr = IResourceFontFileStream::Create(&pFileStream, resource); @@ -601,7 +602,7 @@ public: STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader); - STDMETHOD(SetResources)(const Vector& resources); + STDMETHOD(SetResources)(const Vector& data); // IDWriteFontFileEnumerator methods virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); @@ -618,7 +619,7 @@ private: IDWriteFactory* pFactory_; IDWriteFontFile* currentFile_; IDWriteFontFileLoader* pLoader_; - Vector resources_; + Vector resources_; uint32_t nextIndex_; }; @@ -671,11 +672,11 @@ STDMETHODIMP ResourceFontFileEnumerator::Initialize(IDWriteFactory* pFactory, ID return E_INVALIDARG; } -STDMETHODIMP ResourceFontFileEnumerator::SetResources(const Vector& resources) +STDMETHODIMP ResourceFontFileEnumerator::SetResources(const Vector& data) { try { - resources_.assign(resources.begin(), resources.end()); + resources_.assign(data.begin(), data.end()); } catch (std::bad_alloc&) { @@ -697,7 +698,7 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::MoveNext(_Out_ BOOL* hasCu if (nextIndex_ < resources_.size()) { - hr = pFactory_->CreateCustomFontFileReference(&resources_[nextIndex_], sizeof(Resource), pLoader_, + hr = pFactory_->CreateCustomFontFileReference(&resources_[nextIndex_], sizeof(BinaryData), pLoader_, ¤tFile_); if (SUCCEEDED(hr)) @@ -758,7 +759,7 @@ class ResourceFontFileStream : public IResourceFontFileStream public: ResourceFontFileStream(); - STDMETHOD(Initialize)(Resource const resources); + STDMETHOD(Initialize)(const BinaryData& data); // IDWriteFontFileStream methods virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, @@ -781,7 +782,7 @@ private: DWORD resourceSize_; }; -HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream, const Resource resource) +HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream, const BinaryData& data) { HRESULT hr = S_OK; @@ -797,7 +798,7 @@ HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream if (SUCCEEDED(hr)) { - hr = pFileStream->Initialize(resource); + hr = pFileStream->Initialize(data); } if (SUCCEEDED(hr)) @@ -816,10 +817,9 @@ ResourceFontFileStream::ResourceFontFileStream() { } -STDMETHODIMP ResourceFontFileStream::Initialize(const Resource resource) +STDMETHODIMP ResourceFontFileStream::Initialize(const BinaryData& data) { - Resource::Data data = resource.GetData(); - HRESULT hr = data.IsValid() ? S_OK : E_FAIL; + HRESULT hr = data.IsValid() ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { diff --git a/src/kiwano/render/DirectX/FontCollectionLoader.h b/src/kiwano/render/DirectX/FontCollectionLoader.h index 518fd426..587c7e00 100644 --- a/src/kiwano/render/DirectX/FontCollectionLoader.h +++ b/src/kiwano/render/DirectX/FontCollectionLoader.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include #include @@ -52,7 +52,7 @@ public: IDWriteFontFileLoader * pFileLoader); STDMETHOD(AddResources) - (const Vector& resources, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize) PURE; + (const Vector& data, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize) PURE; }; interface DWRITE_DECLARE_INTERFACE("08D21408-6FC1-4E36-A4EB-4DA16BE3399E") IResourceFontFileLoader @@ -69,13 +69,14 @@ public: static HRESULT Create(_Out_ IResourceFontFileEnumerator * *ppEnumerator, IDWriteFactory * pFactory, IDWriteFontFileLoader * pFileLoader); - STDMETHOD(SetResources)(const Vector& resources) PURE; + STDMETHOD(SetResources)(const Vector& data) PURE; }; interface DWRITE_DECLARE_INTERFACE("A6267450-27F3-4948-995F-FF8345A72F88") IResourceFontFileStream : public IDWriteFontFileStream { public: - static HRESULT Create(_Out_ IResourceFontFileStream * *ppStream, const Resource resource); + static HRESULT Create(_Out_ IResourceFontFileStream * *ppStream, const BinaryData& data); }; + } // namespace kiwano diff --git a/src/kiwano/render/DirectX/RendererImpl.cpp b/src/kiwano/render/DirectX/RendererImpl.cpp index 64c9601d..d8040307 100644 --- a/src/kiwano/render/DirectX/RendererImpl.cpp +++ b/src/kiwano/render/DirectX/RendererImpl.cpp @@ -250,7 +250,7 @@ void RendererImpl::CreateTexture(Texture& texture, const String& file_path) KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture failed"); } -void RendererImpl::CreateTexture(Texture& texture, const Resource& resource) +void RendererImpl::CreateTexture(Texture& texture, const BinaryData& data) { HRESULT hr = S_OK; if (!d2d_res_) @@ -260,8 +260,6 @@ void RendererImpl::CreateTexture(Texture& texture, const Resource& resource) if (SUCCEEDED(hr)) { - Resource::Data data = resource.GetData(); - hr = data.IsValid() ? S_OK : E_FAIL; if (SUCCEEDED(hr)) @@ -334,7 +332,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path) KGE_SET_STATUS_IF_FAILED(hr, gif, "Load GIF texture failed"); } -void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource) +void RendererImpl::CreateGifImage(GifImage& gif, const BinaryData& data) { HRESULT hr = S_OK; if (!d2d_res_) @@ -344,8 +342,6 @@ void RendererImpl::CreateGifImage(GifImage& gif, const Resource& resource) if (SUCCEEDED(hr)) { - Resource::Data data = resource.GetData(); - hr = data.IsValid() ? S_OK : E_FAIL; if (SUCCEEDED(hr)) @@ -559,7 +555,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector& family_names KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed"); } -void RendererImpl::CreateFontCollection(Font& font, Vector& family_names, const Resource& res) +void RendererImpl::CreateFontCollection(Font& font, Vector& family_names, const BinaryData& data) { HRESULT hr = S_OK; if (!d2d_res_) @@ -570,7 +566,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector& family_names if (SUCCEEDED(hr)) { ComPtr font_collection; - hr = d2d_res_->CreateFontCollectionFromResources(font_collection, Vector{ res }); + hr = d2d_res_->CreateFontCollectionFromBinaryData(font_collection, Vector{ data }); if (SUCCEEDED(hr)) { diff --git a/src/kiwano/render/DirectX/RendererImpl.h b/src/kiwano/render/DirectX/RendererImpl.h index 434ef363..a534605c 100644 --- a/src/kiwano/render/DirectX/RendererImpl.h +++ b/src/kiwano/render/DirectX/RendererImpl.h @@ -34,17 +34,17 @@ public: void CreateTexture(Texture& texture, const String& file_path) override; - void CreateTexture(Texture& texture, const Resource& resource) override; + void CreateTexture(Texture& texture, const BinaryData& data) override; void CreateGifImage(GifImage& gif, const String& file_path) override; - void CreateGifImage(GifImage& gif, const Resource& resource) override; + void CreateGifImage(GifImage& gif, const BinaryData& data) override; void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) override; void CreateFontCollection(Font& font, Vector& family_names, const String& file_path) override; - void CreateFontCollection(Font& font, Vector& family_names, const Resource& res) override; + void CreateFontCollection(Font& font, Vector& family_names, const BinaryData& data) override; void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) override; diff --git a/src/kiwano/render/Font.cpp b/src/kiwano/render/Font.cpp index 164830ed..6150bbed 100644 --- a/src/kiwano/render/Font.cpp +++ b/src/kiwano/render/Font.cpp @@ -67,7 +67,7 @@ FontPtr Font::Preload(const Resource& resource) if (ptr) { Vector family_names; - Renderer::GetInstance().CreateFontCollection(*ptr, family_names, resource); + Renderer::GetInstance().CreateFontCollection(*ptr, family_names, resource.GetData()); if (ptr->IsValid()) { FontCache::GetInstance().AddFont(hash_code, ptr); diff --git a/src/kiwano/render/Frame.cpp b/src/kiwano/render/Frame.cpp deleted file mode 100644 index 54185929..00000000 --- a/src/kiwano/render/Frame.cpp +++ /dev/null @@ -1,87 +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 - -namespace kiwano -{ - -Frame::Frame(const String& file_path) -{ - Load(file_path); -} - -Frame::Frame(const Resource& res) -{ - Load(res); -} - -Frame::Frame(TexturePtr texture) -{ - SetTexture(texture); -} - -Frame::Frame() {} - -bool Frame::Load(const String& file_path) -{ - TexturePtr texture = Texture::Preload(file_path); - if (texture->IsValid()) - { - SetTexture(texture); - return true; - } - return false; -} - -bool Frame::Load(const Resource& res) -{ - TexturePtr texture = Texture::Preload(res); - if (texture->IsValid()) - { - SetTexture(texture); - return true; - } - return false; -} - -void Frame::SetCropRect(const Rect& crop_rect) -{ - if (texture_->IsValid()) - { - auto bitmap_size = texture_->GetSize(); - crop_rect_.left_top.x = std::min(std::max(crop_rect.left_top.x, 0.f), bitmap_size.x); - crop_rect_.left_top.y = std::min(std::max(crop_rect.left_top.y, 0.f), bitmap_size.y); - crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x); - crop_rect_.right_bottom.y = std::min(std::max(crop_rect.right_bottom.y, 0.f), bitmap_size.y); - } -} - -void Frame::SetTexture(TexturePtr texture) -{ - texture_ = texture; - if (texture_->IsValid()) - { - crop_rect_.left_top.x = crop_rect_.left_top.y = 0; - crop_rect_.right_bottom.x = texture_->GetWidth(); - crop_rect_.right_bottom.y = texture_->GetHeight(); - } -} -} // namespace kiwano diff --git a/src/kiwano/render/GifImage.cpp b/src/kiwano/render/GifImage.cpp index ca2b3aea..d3af8a95 100644 --- a/src/kiwano/render/GifImage.cpp +++ b/src/kiwano/render/GifImage.cpp @@ -92,7 +92,7 @@ bool GifImage::Load(const String& file_path) bool GifImage::Load(const Resource& res) { - Renderer::GetInstance().CreateGifImage(*this, res); + Renderer::GetInstance().CreateGifImage(*this, res.GetData()); if (IsValid()) { diff --git a/src/kiwano/render/NativeObject.h b/src/kiwano/render/NativeObject.h index 99627496..b5a1086d 100644 --- a/src/kiwano/render/NativeObject.h +++ b/src/kiwano/render/NativeObject.h @@ -37,7 +37,7 @@ KGE_DECLARE_SMART_PTR(NativeObject); /** * \~chinese - * @brief º¬Óб¾»úÖ¸ÕëµÄ¶ÔÏó + * @brief º¬Óб¾µØÖ¸ÕëµÄ¶ÔÏó */ class KGE_API NativeObjectBase : public ObjectBase { 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..5be17bcd 100644 --- a/src/kiwano/render/Renderer.h +++ b/src/kiwano/render/Renderer.h @@ -88,8 +88,8 @@ public: /// \~chinese /// @brief ´´½¨ÎÆÀíÄÚ²¿×ÊÔ´ /// @param[out] texture ÎÆÀí - /// @param[in] resource ͼƬ×ÊÔ´ - virtual void CreateTexture(Texture& texture, const Resource& resource) = 0; + /// @param[in] data ͼƬ¶þ½øÖÆÊý¾Ý + virtual void CreateTexture(Texture& texture, const BinaryData& data) = 0; /// \~chinese /// @brief ´´½¨GIFͼÏñÄÚ²¿×ÊÔ´ @@ -100,12 +100,12 @@ public: /// \~chinese /// @brief ´´½¨GIFͼÏñÄÚ²¿×ÊÔ´ /// @param[out] gif GIFͼÏñ - /// @param[in] resource ͼƬ×ÊÔ´ - virtual void CreateGifImage(GifImage& gif, const Resource& resource) = 0; + /// @param[in] data ͼƬ¶þ½øÖÆÊý¾Ý + virtual void CreateGifImage(GifImage& gif, const BinaryData& data) = 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; @@ -121,8 +121,8 @@ public: /// @brief ´´½¨×ÖÌ弯ÄÚ²¿×ÊÔ´ /// @param[out] font ×ÖÌå /// @param[out] family_names ×ÖÌå°üº¬µÄ×ÖÌå×å - /// @param[in] res_arr ×ÖÌå×ÊÔ´ - virtual void CreateFontCollection(Font& font, Vector& family_names, const Resource& res) = 0; + /// @param[in] data ×ÖÌå¶þ½øÖÆ×ÊÔ´ + virtual void CreateFontCollection(Font& font, Vector& family_names, const BinaryData& data) = 0; /// \~chinese /// @brief ´´½¨ÎÄ×Ö²¼¾ÖÄÚ²¿×ÊÔ´ diff --git a/src/kiwano/render/Texture.cpp b/src/kiwano/render/Texture.cpp index c77e64b5..1c10be9c 100644 --- a/src/kiwano/render/Texture.cpp +++ b/src/kiwano/render/Texture.cpp @@ -89,7 +89,7 @@ bool Texture::Load(const String& file_path) bool Texture::Load(const Resource& res) { - Renderer::GetInstance().CreateTexture(*this, res); + Renderer::GetInstance().CreateTexture(*this, res.GetData()); return IsValid(); } 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..70740a7a 100644 --- a/src/kiwano/utils/ResourceLoader.cpp +++ b/src/kiwano/utils/ResourceLoader.cpp @@ -23,6 +23,10 @@ #include #include #include +#include +#include +#include +#include namespace kiwano { @@ -195,10 +199,10 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& else if (!file.empty()) { // Simple image - FramePtr frame = MakePtr(); - if (frame && frame->Load(gdata->path + file)) + TexturePtr texture = MakePtr(); + if (texture && texture->Load(gdata->path + file)) { - cache->AddObject(id, frame); + cache->AddObject(id, texture); return; } } @@ -212,12 +216,12 @@ 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(); - if (frame->Load(gdata->path + file)) + SpriteFrame frame; + if (frame.Load(gdata->path + file)) { frames.push_back(frame); } @@ -243,14 +247,14 @@ 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 + SpriteFrame frame; + if (frame.Load(gdata->path + file)) { FrameSequencePtr frame_seq = MakePtr(); if (frame_seq) { - frame_seq->AddFrames(frame, cols, rows, max_num, padding_x, padding_y); + frame_seq->AddFrames(frame.Split(cols, rows, max_num, padding_x, padding_y)); cache->AddObject(id, frame_seq); return; } @@ -259,10 +263,10 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& else { // Simple image - FramePtr frame = MakePtr(); - if (frame && frame->Load(gdata->path + file)) + TexturePtr texture = MakePtr(); + if (texture && texture->Load(gdata->path + file)) { - cache->AddObject(id, frame); + cache->AddObject(id, texture); return; } }