From b129a1bf18ec9fb7da99bc9cce3d24a66a3fd5d0 Mon Sep 17 00:00:00 2001 From: Haibo Date: Thu, 8 Nov 2018 00:21:59 +0800 Subject: [PATCH] update: code style --- core/actions/Action.cpp | 160 +- core/actions/Animate.cpp | 197 +-- core/actions/Animation.cpp | 155 +- core/actions/CallFunc.cpp | 41 +- core/actions/Delay.cpp | 83 +- core/actions/FadeIn.cpp | 9 +- core/actions/FadeOut.cpp | 9 +- core/actions/FiniteTimeAction.cpp | 71 +- core/actions/JumpBy.cpp | 91 +- core/actions/JumpTo.cpp | 29 +- core/actions/Loop.cpp | 169 +-- core/actions/MoveBy.cpp | 67 +- core/actions/MoveTo.cpp | 29 +- core/actions/OpacityBy.cpp | 55 +- core/actions/OpacityTo.cpp | 29 +- core/actions/RotateBy.cpp | 55 +- core/actions/RotateTo.cpp | 29 +- core/actions/ScaleBy.cpp | 73 +- core/actions/ScaleTo.cpp | 46 +- core/actions/Sequence.cpp | 194 +-- core/actions/Spawn.cpp | 188 +-- core/components/Button.cpp | 427 +++--- core/components/Menu.cpp | 114 +- core/e2dutil.h | 10 +- core/events/KeyEvent.cpp | 147 +- core/events/MouseEvent.cpp | 105 +- core/modules/Audio.cpp | 75 +- core/modules/Device.cpp | 79 +- core/modules/Game.cpp | 994 ++++++------- core/modules/Graphics.cpp | 591 ++++---- core/modules/Input.cpp | 263 ++-- core/objects/Canvas.cpp | 395 ++--- core/objects/Image.cpp | 657 ++++----- core/objects/Node.cpp | 1773 ++++++++++++----------- core/objects/Scene.cpp | 157 +- core/objects/Sprite.cpp | 225 +-- core/objects/Task.cpp | 139 +- core/objects/Text.cpp | 814 +++++------ core/tools/Data.cpp | 225 +-- core/tools/File.cpp | 425 +++--- core/tools/Music.cpp | 481 +++--- core/tools/Path.cpp | 171 +-- core/tools/Player.cpp | 365 ++--- core/transitions/BoxTransition.cpp | 67 +- core/transitions/EmergeTransition.cpp | 35 +- core/transitions/FadeTransition.cpp | 47 +- core/transitions/MoveTransition.cpp | 145 +- core/transitions/RotationTransition.cpp | 129 +- core/transitions/Transition.cpp | 231 +-- core/utils/Color.cpp | 112 +- core/utils/Duration.cpp | 473 +++--- core/utils/Font.cpp | 13 +- core/utils/Point.cpp | 101 +- core/utils/Random.cpp | 13 +- core/utils/Rect.cpp | 101 +- core/utils/Ref.cpp | 57 +- core/utils/Resource.cpp | 145 +- core/utils/Size.cpp | 87 +- core/utils/Time.cpp | 135 +- core/utils/Transform.cpp | 89 +- 60 files changed, 6300 insertions(+), 6091 deletions(-) diff --git a/core/actions/Action.cpp b/core/actions/Action.cpp index 5f6aa5ce..8d05e7ff 100644 --- a/core/actions/Action.cpp +++ b/core/actions/Action.cpp @@ -20,86 +20,90 @@ #include "..\e2daction.h" -easy2d::Action::Action() - : running_(false) - , done_(false) - , initialized_(false) - , target_(nullptr) -{ -} -easy2d::Action::~Action() +namespace easy2d { -} - -bool easy2d::Action::IsRunning() -{ - return running_; -} - -void easy2d::Action::Resume() -{ - running_ = true; -} - -void easy2d::Action::Pause() -{ - running_ = false; -} - -void easy2d::Action::Stop() -{ - done_ = true; -} - -const std::wstring& easy2d::Action::GetName() const -{ - return name_; -} - -void easy2d::Action::SetName(const std::wstring& name) -{ - name_ = name; -} - -easy2d::Node * easy2d::Action::GetTarget() -{ - return target_; -} - -void easy2d::Action::Reset() -{ - initialized_ = false; - done_ = false; - started_ = Time::Now(); -} - -bool easy2d::Action::IsDone() const -{ - return done_; -} - -void easy2d::Action::StartWithTarget(Node* target) -{ - target_ = target; - running_ = true; - this->Reset(); -} - -void easy2d::Action::Init() -{ - initialized_ = true; - started_ = Time::Now(); -} - -void easy2d::Action::Update() -{ - if (!initialized_) + Action::Action() + : running_(false) + , done_(false) + , initialized_(false) + , target_(nullptr) { - Init(); } -} -void easy2d::Action::ResetTime() -{ -} + Action::~Action() + { + } + + bool Action::IsRunning() + { + return running_; + } + + void Action::Resume() + { + running_ = true; + } + + void Action::Pause() + { + running_ = false; + } + + void Action::Stop() + { + done_ = true; + } + + const std::wstring& Action::GetName() const + { + return name_; + } + + void Action::SetName(const std::wstring& name) + { + name_ = name; + } + + Node * Action::GetTarget() + { + return target_; + } + + void Action::Reset() + { + initialized_ = false; + done_ = false; + started_ = Time::Now(); + } + + bool Action::IsDone() const + { + return done_; + } + + void Action::StartWithTarget(Node* target) + { + target_ = target; + running_ = true; + this->Reset(); + } + + void Action::Init() + { + initialized_ = true; + started_ = Time::Now(); + } + + void Action::Update() + { + if (!initialized_) + { + Init(); + } + } + + void Action::ResetTime() + { + } +} \ No newline at end of file diff --git a/core/actions/Animate.cpp b/core/actions/Animate.cpp index 9896c8a2..6308fd92 100644 --- a/core/actions/Animate.cpp +++ b/core/actions/Animate.cpp @@ -21,115 +21,118 @@ #include "..\e2daction.h" #include "..\e2dobject.h" -easy2d::Animate::Animate() - : frame_index_(0) - , animation_(nullptr) +namespace easy2d { -} + Animate::Animate() + : frame_index_(0) + , animation_(nullptr) + { + } -easy2d::Animate::Animate(Animation * animation) - : frame_index_(0) - , animation_(nullptr) -{ - this->SetAnimation(animation); -} + Animate::Animate(Animation * animation) + : frame_index_(0) + , animation_(nullptr) + { + this->SetAnimation(animation); + } -easy2d::Animate::~Animate() -{ - SafeRelease(animation_); -} + Animate::~Animate() + { + SafeRelease(animation_); + } -easy2d::Animation * easy2d::Animate::GetAnimation() const -{ - return animation_; -} + Animation * Animate::GetAnimation() const + { + return animation_; + } -void easy2d::Animate::SetAnimation(Animation * animation) -{ - if (animation && animation != animation_) + void Animate::SetAnimation(Animation * animation) + { + if (animation && animation != animation_) + { + if (animation_) + { + animation_->Release(); + } + animation_ = animation; + animation_->Retain(); + frame_index_ = 0; + } + } + + void Animate::Init() + { + Action::Init(); + + auto target = dynamic_cast(target_); + if (target && animation_) + { + target->Load(animation_->GetFrames()[frame_index_]); + ++frame_index_; + } + } + + void Animate::Update() + { + Action::Update(); + + if (!animation_) + { + this->Stop(); + return; + } + + while ((Time::Now() - started_).Seconds() >= animation_->GetInterval()) + { + auto& frames = animation_->GetFrames(); + auto target = dynamic_cast(target_); + + if (target) + { + target->Load(frames[frame_index_]); + } + + started_ += Duration::Second * animation_->GetInterval(); + ++frame_index_; + + if (frame_index_ == frames.size()) + { + this->Stop(); + break; + } + } + } + + void Animate::ResetTime() + { + Action::ResetTime(); + } + + void Animate::Reset() + { + Action::Reset(); + frame_index_ = 0; + } + + Animate * Animate::Clone() const { if (animation_) { - animation_->Release(); + return new Animate(animation_); } - animation_ = animation; - animation_->Retain(); - frame_index_ = 0; - } -} - -void easy2d::Animate::Init() -{ - Action::Init(); - - auto target = dynamic_cast(target_); - if (target && animation_) - { - target->Load(animation_->GetFrames()[frame_index_]); - ++frame_index_; - } -} - -void easy2d::Animate::Update() -{ - Action::Update(); - - if (!animation_) - { - this->Stop(); - return; + return nullptr; } - while ((Time::Now() - started_).Seconds() >= animation_->GetInterval()) + Animate * Animate::Reverse() const { - auto& frames = animation_->GetFrames(); - auto target = dynamic_cast(target_); - - if (target) + if (animation_) { - target->Load(frames[frame_index_]); - } - - started_ += Duration::Second * animation_->GetInterval(); - ++frame_index_; - - if (frame_index_ == frames.size()) - { - this->Stop(); - break; + auto animation = animation_->Reverse(); + if (animation) + { + return new Animate(animation); + } } + return nullptr; } -} - -void easy2d::Animate::ResetTime() -{ - Action::ResetTime(); -} - -void easy2d::Animate::Reset() -{ - Action::Reset(); - frame_index_ = 0; -} - -easy2d::Animate * easy2d::Animate::Clone() const -{ - if (animation_) - { - return new Animate(animation_); - } - return nullptr; -} - -easy2d::Animate * easy2d::Animate::Reverse() const -{ - if (animation_) - { - auto animation = animation_->Reverse(); - if (animation) - { - return new Animate(animation); - } - } - return nullptr; -} +} \ No newline at end of file diff --git a/core/actions/Animation.cpp b/core/actions/Animation.cpp index 4f18f472..c6698a5b 100644 --- a/core/actions/Animation.cpp +++ b/core/actions/Animation.cpp @@ -20,101 +20,104 @@ #include "..\e2daction.h" -easy2d::Animation::Animation() - : interval_(1) +namespace easy2d { -} - -easy2d::Animation::Animation(const Images& frames) - : interval_(1) -{ - this->Add(frames); -} - -easy2d::Animation::Animation(float interval) - : interval_(interval) -{ -} - -easy2d::Animation::Animation(float interval, const Images& frames) - : interval_(interval) -{ - this->Add(frames); -} - -easy2d::Animation::~Animation() -{ - for (auto frame : frames_) + Animation::Animation() + : interval_(1) { - SafeRelease(frame); } -} -void easy2d::Animation::SetInterval(float interval) -{ - interval_ = std::max(interval, 0.f); -} - -void easy2d::Animation::Add(Image * frame) -{ - E2D_WARNING_IF(frame == nullptr, "Animation::Add failed, frame Is nullptr."); - if (frame) + Animation::Animation(const Images& frames) + : interval_(1) { - frames_.push_back(frame); - frame->Retain(); + this->Add(frames); } -} -void easy2d::Animation::Add(const Images& frames) -{ - for (const auto &image : frames) + Animation::Animation(float interval) + : interval_(interval) { - this->Add(image); } -} -float easy2d::Animation::GetInterval() const -{ - return interval_; -} - -const easy2d::Animation::Images& easy2d::Animation::GetFrames() const -{ - return frames_; -} - -easy2d::Animation * easy2d::Animation::Clone() const -{ - auto animation = new Animation(interval_); - if (animation) + Animation::Animation(float interval, const Images& frames) + : interval_(interval) { - for (const auto& frame : frames_) + this->Add(frames); + } + + Animation::~Animation() + { + for (auto frame : frames_) { - animation->Add(frame); + SafeRelease(frame); } } - return animation; -} -easy2d::Animation * easy2d::Animation::Reverse() const -{ - auto& oldFrames = this->GetFrames(); - Images frames(oldFrames.size()); - - if (!oldFrames.empty()) + void Animation::SetInterval(float interval) { - for (auto iter = oldFrames.crbegin(), - iterCrend = oldFrames.crend(); - iter != iterCrend; - ++iter) + interval_ = std::max(interval, 0.f); + } + + void Animation::Add(Image * frame) + { + E2D_WARNING_IF(frame == nullptr, "Animation::Add failed, frame Is nullptr."); + if (frame) { - Image* frame = *iter; - if (frame) + frames_.push_back(frame); + frame->Retain(); + } + } + + void Animation::Add(const Images& frames) + { + for (const auto &image : frames) + { + this->Add(image); + } + } + + float Animation::GetInterval() const + { + return interval_; + } + + const Animation::Images& Animation::GetFrames() const + { + return frames_; + } + + Animation * Animation::Clone() const + { + auto animation = new Animation(interval_); + if (animation) + { + for (const auto& frame : frames_) { - frames.push_back(frame); + animation->Add(frame); } } + return animation; } - return new Animation(this->GetInterval(), frames); -} + Animation * Animation::Reverse() const + { + auto& oldFrames = this->GetFrames(); + Images frames(oldFrames.size()); + + if (!oldFrames.empty()) + { + for (auto iter = oldFrames.crbegin(), + iterCrend = oldFrames.crend(); + iter != iterCrend; + ++iter) + { + Image* frame = *iter; + if (frame) + { + frames.push_back(frame); + } + } + } + + return new Animation(this->GetInterval(), frames); + } +} \ No newline at end of file diff --git a/core/actions/CallFunc.cpp b/core/actions/CallFunc.cpp index be27ea0e..25f4a1d8 100644 --- a/core/actions/CallFunc.cpp +++ b/core/actions/CallFunc.cpp @@ -20,27 +20,30 @@ #include "..\e2daction.h" -easy2d::CallFunc::CallFunc(const Callback& func) : - callback_(func) +namespace easy2d { -} + CallFunc::CallFunc(const Callback& func) : + callback_(func) + { + } -easy2d::CallFunc * easy2d::CallFunc::Clone() const -{ - return new CallFunc(callback_); -} + CallFunc * CallFunc::Clone() const + { + return new CallFunc(callback_); + } -easy2d::CallFunc * easy2d::CallFunc::Reverse() const -{ - return new CallFunc(callback_); -} + CallFunc * CallFunc::Reverse() const + { + return new CallFunc(callback_); + } -void easy2d::CallFunc::Init() -{ -} + void CallFunc::Init() + { + } -void easy2d::CallFunc::Update() -{ - callback_(); - this->Stop(); -} + void CallFunc::Update() + { + callback_(); + this->Stop(); + } +} \ No newline at end of file diff --git a/core/actions/Delay.cpp b/core/actions/Delay.cpp index 24ee9523..fb246646 100644 --- a/core/actions/Delay.cpp +++ b/core/actions/Delay.cpp @@ -20,47 +20,50 @@ #include "..\e2daction.h" -easy2d::Delay::Delay(float duration) - : delta_(0) - , delay_(std::max(duration, 0.f)) +namespace easy2d { -} - -easy2d::Delay * easy2d::Delay::Clone() const -{ - return new Delay(delay_); -} - -easy2d::Delay * easy2d::Delay::Reverse() const -{ - return new Delay(delay_); -} - -void easy2d::Delay::Reset() -{ - Action::Reset(); - delta_ = 0; -} - -void easy2d::Delay::Init() -{ - Action::Init(); -} - -void easy2d::Delay::Update() -{ - Action::Update(); - - delta_ = (Time::Now() - started_).Seconds(); - - if (delta_ >= delay_) + Delay::Delay(float duration) + : delta_(0) + , delay_(std::max(duration, 0.f)) { - this->Stop(); } -} -void easy2d::Delay::ResetTime() -{ - Action::ResetTime(); - started_ = Time::Now() - Duration::Second * delta_; -} + Delay * Delay::Clone() const + { + return new Delay(delay_); + } + + Delay * Delay::Reverse() const + { + return new Delay(delay_); + } + + void Delay::Reset() + { + Action::Reset(); + delta_ = 0; + } + + void Delay::Init() + { + Action::Init(); + } + + void Delay::Update() + { + Action::Update(); + + delta_ = (Time::Now() - started_).Seconds(); + + if (delta_ >= delay_) + { + this->Stop(); + } + } + + void Delay::ResetTime() + { + Action::ResetTime(); + started_ = Time::Now() - Duration::Second * delta_; + } +} \ No newline at end of file diff --git a/core/actions/FadeIn.cpp b/core/actions/FadeIn.cpp index 1da6da97..d4427df9 100644 --- a/core/actions/FadeIn.cpp +++ b/core/actions/FadeIn.cpp @@ -20,7 +20,10 @@ #include "..\e2daction.h" -easy2d::FadeIn::FadeIn(float duration) - : OpacityTo(duration, 1) +namespace easy2d { -} + FadeIn::FadeIn(float duration) + : OpacityTo(duration, 1) + { + } +} \ No newline at end of file diff --git a/core/actions/FadeOut.cpp b/core/actions/FadeOut.cpp index 56f28eea..11a9384e 100644 --- a/core/actions/FadeOut.cpp +++ b/core/actions/FadeOut.cpp @@ -20,7 +20,10 @@ #include "..\e2daction.h" -easy2d::FadeOut::FadeOut(float duration) - : OpacityTo(duration, 0) +namespace easy2d { -} + FadeOut::FadeOut(float duration) + : OpacityTo(duration, 0) + { + } +} \ No newline at end of file diff --git a/core/actions/FiniteTimeAction.cpp b/core/actions/FiniteTimeAction.cpp index 2053db99..5a7eb43f 100644 --- a/core/actions/FiniteTimeAction.cpp +++ b/core/actions/FiniteTimeAction.cpp @@ -20,45 +20,48 @@ #include "..\e2daction.h" -easy2d::FiniteTimeAction::FiniteTimeAction(float duration) - : delta_(0) - , duration_(std::max(duration, 0.f)) +namespace easy2d { -} - -void easy2d::FiniteTimeAction::Reset() -{ - Action::Reset(); - delta_ = 0; -} - -void easy2d::FiniteTimeAction::Init() -{ - Action::Init(); -} - -void easy2d::FiniteTimeAction::Update() -{ - Action::Update(); - - if (duration_ == 0) + FiniteTimeAction::FiniteTimeAction(float duration) + : delta_(0) + , duration_(std::max(duration, 0.f)) { - delta_ = 1; - this->Stop(); } - else - { - delta_ = std::min((Time::Now() - started_).Seconds() / duration_, 1.f); - if (delta_ >= 1) + void FiniteTimeAction::Reset() + { + Action::Reset(); + delta_ = 0; + } + + void FiniteTimeAction::Init() + { + Action::Init(); + } + + void FiniteTimeAction::Update() + { + Action::Update(); + + if (duration_ == 0) { + delta_ = 1; this->Stop(); } - } -} + else + { + delta_ = std::min((Time::Now() - started_).Seconds() / duration_, 1.f); -void easy2d::FiniteTimeAction::ResetTime() -{ - Action::ResetTime(); - started_ = Time::Now() - Duration::Second * (delta_ * duration_); -} + if (delta_ >= 1) + { + this->Stop(); + } + } + } + + void FiniteTimeAction::ResetTime() + { + Action::ResetTime(); + started_ = Time::Now() - Duration::Second * (delta_ * duration_); + } +} \ No newline at end of file diff --git a/core/actions/JumpBy.cpp b/core/actions/JumpBy.cpp index 4dc73317..4a888f96 100644 --- a/core/actions/JumpBy.cpp +++ b/core/actions/JumpBy.cpp @@ -21,53 +21,56 @@ #include "..\e2daction.h" #include "..\e2dobject.h" -easy2d::JumpBy::JumpBy(float duration, const Point & vec, float height, int jumps) - : FiniteTimeAction(duration) - , delta_pos_(vec) - , height_(height) - , jumps_(jumps) +namespace easy2d { -} - -easy2d::JumpBy * easy2d::JumpBy::Clone() const -{ - return new JumpBy(duration_, delta_pos_, height_, jumps_); -} - -easy2d::JumpBy * easy2d::JumpBy::Reverse() const -{ - return new JumpBy(duration_, -delta_pos_, height_, jumps_); -} - -void easy2d::JumpBy::Init() -{ - FiniteTimeAction::Init(); - - if (target_) + JumpBy::JumpBy(float duration, const Point & vec, float height, int jumps) + : FiniteTimeAction(duration) + , delta_pos_(vec) + , height_(height) + , jumps_(jumps) { - prev_pos_ = start_pos_ = target_->GetPosition(); } -} -void easy2d::JumpBy::Update() -{ - FiniteTimeAction::Update(); - - if (target_) + JumpBy * JumpBy::Clone() const { - float frac = fmod(delta_ * jumps_, 1.f); - float x = delta_pos_.x * delta_; - float y = height_ * 4 * frac * (1 - frac); - y += delta_pos_.y * delta_; - - Point currentPos = target_->GetPosition(); - - Point diff = currentPos - prev_pos_; - start_pos_ = diff + start_pos_; - - Point newPos = start_pos_ + Point(x, y); - target_->SetPosition(newPos); - - prev_pos_ = newPos; + return new JumpBy(duration_, delta_pos_, height_, jumps_); } -} + + JumpBy * JumpBy::Reverse() const + { + return new JumpBy(duration_, -delta_pos_, height_, jumps_); + } + + void JumpBy::Init() + { + FiniteTimeAction::Init(); + + if (target_) + { + prev_pos_ = start_pos_ = target_->GetPosition(); + } + } + + void JumpBy::Update() + { + FiniteTimeAction::Update(); + + if (target_) + { + float frac = fmod(delta_ * jumps_, 1.f); + float x = delta_pos_.x * delta_; + float y = height_ * 4 * frac * (1 - frac); + y += delta_pos_.y * delta_; + + Point currentPos = target_->GetPosition(); + + Point diff = currentPos - prev_pos_; + start_pos_ = diff + start_pos_; + + Point newPos = start_pos_ + Point(x, y); + target_->SetPosition(newPos); + + prev_pos_ = newPos; + } + } +} \ No newline at end of file diff --git a/core/actions/JumpTo.cpp b/core/actions/JumpTo.cpp index 3d3b4ef4..068be28e 100644 --- a/core/actions/JumpTo.cpp +++ b/core/actions/JumpTo.cpp @@ -21,19 +21,22 @@ #include "..\e2daction.h" #include "..\e2dobject.h" -easy2d::JumpTo::JumpTo(float duration, const Point & pos, float height, int jumps) - : JumpBy(duration, Point(), height, jumps) - , end_pos_(pos) +namespace easy2d { -} + JumpTo::JumpTo(float duration, const Point & pos, float height, int jumps) + : JumpBy(duration, Point(), height, jumps) + , end_pos_(pos) + { + } -easy2d::JumpTo * easy2d::JumpTo::Clone() const -{ - return new JumpTo(duration_, end_pos_, height_, jumps_); -} + JumpTo * JumpTo::Clone() const + { + return new JumpTo(duration_, end_pos_, height_, jumps_); + } -void easy2d::JumpTo::Init() -{ - JumpBy::Init(); - delta_pos_ = end_pos_ - start_pos_; -} + void JumpTo::Init() + { + JumpBy::Init(); + delta_pos_ = end_pos_ - start_pos_; + } +} \ No newline at end of file diff --git a/core/actions/Loop.cpp b/core/actions/Loop.cpp index 8b3efe73..2e794953 100644 --- a/core/actions/Loop.cpp +++ b/core/actions/Loop.cpp @@ -20,97 +20,100 @@ #include "..\e2daction.h" -easy2d::Loop::Loop(Action * action, int times /* = -1 */) - : action_(action) - , times_(0) - , total_times_(times) +namespace easy2d { - E2D_WARNING_IF(action == nullptr, "Loop NULL pointer exception!"); - - if (action) + Loop::Loop(Action * action, int times /* = -1 */) + : action_(action) + , times_(0) + , total_times_(times) { - action_ = action; - action_->Retain(); - } -} + E2D_WARNING_IF(action == nullptr, "Loop NULL pointer exception!"); -easy2d::Loop::~Loop() -{ - SafeRelease(action_); -} - -easy2d::Loop * easy2d::Loop::Clone() const -{ - if (action_) - { - return new Loop(action_->Clone()); - } - else - { - return nullptr; - } -} - -easy2d::Loop * easy2d::Loop::Reverse() const -{ - if (action_) - { - return new Loop(action_->Clone()); - } - else - { - return nullptr; - } -} - -void easy2d::Loop::Init() -{ - Action::Init(); - - if (action_) - { - action_->target_ = target_; - action_->Init(); - } -} - -void easy2d::Loop::Update() -{ - Action::Update(); - - if (times_ == total_times_) - { - this->Stop(); - return; - } - - if (action_) - { - action_->Update(); - - if (action_->IsDone()) + if (action) { - ++times_; - - Action::Reset(); - action_->Reset(); + action_ = action; + action_->Retain(); } } - else + + Loop::~Loop() { - this->Stop(); + SafeRelease(action_); } -} -void easy2d::Loop::Reset() -{ - Action::Reset(); + Loop * Loop::Clone() const + { + if (action_) + { + return new Loop(action_->Clone()); + } + else + { + return nullptr; + } + } - if (action_) action_->Reset(); - times_ = 0; -} + Loop * Loop::Reverse() const + { + if (action_) + { + return new Loop(action_->Clone()); + } + else + { + return nullptr; + } + } -void easy2d::Loop::ResetTime() -{ - if (action_) action_->ResetTime(); -} + void Loop::Init() + { + Action::Init(); + + if (action_) + { + action_->target_ = target_; + action_->Init(); + } + } + + void Loop::Update() + { + Action::Update(); + + if (times_ == total_times_) + { + this->Stop(); + return; + } + + if (action_) + { + action_->Update(); + + if (action_->IsDone()) + { + ++times_; + + Action::Reset(); + action_->Reset(); + } + } + else + { + this->Stop(); + } + } + + void Loop::Reset() + { + Action::Reset(); + + if (action_) action_->Reset(); + times_ = 0; + } + + void Loop::ResetTime() + { + if (action_) action_->ResetTime(); + } +} \ No newline at end of file diff --git a/core/actions/MoveBy.cpp b/core/actions/MoveBy.cpp index c18b44b3..4910320b 100644 --- a/core/actions/MoveBy.cpp +++ b/core/actions/MoveBy.cpp @@ -22,45 +22,48 @@ #include "..\e2dobject.h" -easy2d::MoveBy::MoveBy(float duration, Point vector) - : FiniteTimeAction(duration) +namespace easy2d { - delta_pos_ = vector; -} - -void easy2d::MoveBy::Init() -{ - FiniteTimeAction::Init(); - - if (target_) + MoveBy::MoveBy(float duration, Point vector) + : FiniteTimeAction(duration) { - prev_pos_ = start_pos_ = target_->GetPosition(); + delta_pos_ = vector; } -} -void easy2d::MoveBy::Update() -{ - FiniteTimeAction::Update(); - - if (target_) + void MoveBy::Init() { - Point currentPos = target_->GetPosition(); - Point diff = currentPos - prev_pos_; - start_pos_ = start_pos_ + diff; + FiniteTimeAction::Init(); - Point newPos = start_pos_ + (delta_pos_ * delta_); - target_->SetPosition(newPos); - - prev_pos_ = newPos; + if (target_) + { + prev_pos_ = start_pos_ = target_->GetPosition(); + } } -} -easy2d::MoveBy * easy2d::MoveBy::Clone() const -{ - return new MoveBy(duration_, delta_pos_); -} + void MoveBy::Update() + { + FiniteTimeAction::Update(); -easy2d::MoveBy * easy2d::MoveBy::Reverse() const -{ - return new MoveBy(duration_, -delta_pos_); + if (target_) + { + Point currentPos = target_->GetPosition(); + Point diff = currentPos - prev_pos_; + start_pos_ = start_pos_ + diff; + + Point newPos = start_pos_ + (delta_pos_ * delta_); + target_->SetPosition(newPos); + + prev_pos_ = newPos; + } + } + + MoveBy * MoveBy::Clone() const + { + return new MoveBy(duration_, delta_pos_); + } + + MoveBy * MoveBy::Reverse() const + { + return new MoveBy(duration_, -delta_pos_); + } } \ No newline at end of file diff --git a/core/actions/MoveTo.cpp b/core/actions/MoveTo.cpp index 0fdf1b12..33c7e586 100644 --- a/core/actions/MoveTo.cpp +++ b/core/actions/MoveTo.cpp @@ -21,19 +21,22 @@ #include "..\e2daction.h" #include "..\e2dobject.h" -easy2d::MoveTo::MoveTo(float duration, Point pos) - : MoveBy(duration, Point()) +namespace easy2d { - end_pos_ = pos; -} + MoveTo::MoveTo(float duration, Point pos) + : MoveBy(duration, Point()) + { + end_pos_ = pos; + } -easy2d::MoveTo * easy2d::MoveTo::Clone() const -{ - return new MoveTo(duration_, end_pos_); -} + MoveTo * MoveTo::Clone() const + { + return new MoveTo(duration_, end_pos_); + } -void easy2d::MoveTo::Init() -{ - MoveBy::Init(); - delta_pos_ = end_pos_ - start_pos_; -} + void MoveTo::Init() + { + MoveBy::Init(); + delta_pos_ = end_pos_ - start_pos_; + } +} \ No newline at end of file diff --git a/core/actions/OpacityBy.cpp b/core/actions/OpacityBy.cpp index adf8acbb..b26e7eda 100644 --- a/core/actions/OpacityBy.cpp +++ b/core/actions/OpacityBy.cpp @@ -22,38 +22,41 @@ #include "..\e2dobject.h" -easy2d::OpacityBy::OpacityBy(float duration, float opacity) - : FiniteTimeAction(duration) +namespace easy2d { - delta_val_ = opacity; -} - -void easy2d::OpacityBy::Init() -{ - FiniteTimeAction::Init(); - - if (target_) + OpacityBy::OpacityBy(float duration, float opacity) + : FiniteTimeAction(duration) { - start_val_ = target_->GetOpacity(); + delta_val_ = opacity; } -} -void easy2d::OpacityBy::Update() -{ - FiniteTimeAction::Update(); - - if (target_) + void OpacityBy::Init() { - target_->SetOpacity(start_val_ + delta_val_ * delta_); + FiniteTimeAction::Init(); + + if (target_) + { + start_val_ = target_->GetOpacity(); + } } -} -easy2d::OpacityBy * easy2d::OpacityBy::Clone() const -{ - return new OpacityBy(duration_, delta_val_); -} + void OpacityBy::Update() + { + FiniteTimeAction::Update(); -easy2d::OpacityBy * easy2d::OpacityBy::Reverse() const -{ - return new OpacityBy(duration_, -delta_val_); + if (target_) + { + target_->SetOpacity(start_val_ + delta_val_ * delta_); + } + } + + OpacityBy * OpacityBy::Clone() const + { + return new OpacityBy(duration_, delta_val_); + } + + OpacityBy * OpacityBy::Reverse() const + { + return new OpacityBy(duration_, -delta_val_); + } } \ No newline at end of file diff --git a/core/actions/OpacityTo.cpp b/core/actions/OpacityTo.cpp index e2126322..3b60d48d 100644 --- a/core/actions/OpacityTo.cpp +++ b/core/actions/OpacityTo.cpp @@ -22,19 +22,22 @@ #include "..\e2dobject.h" -easy2d::OpacityTo::OpacityTo(float duration, float opacity) - : OpacityBy(duration, 0) +namespace easy2d { - end_val_ = opacity; -} + OpacityTo::OpacityTo(float duration, float opacity) + : OpacityBy(duration, 0) + { + end_val_ = opacity; + } -easy2d::OpacityTo * easy2d::OpacityTo::Clone() const -{ - return new OpacityTo(duration_, end_val_); -} + OpacityTo * OpacityTo::Clone() const + { + return new OpacityTo(duration_, end_val_); + } -void easy2d::OpacityTo::Init() -{ - OpacityBy::Init(); - delta_val_ = end_val_ - start_val_; -} + void OpacityTo::Init() + { + OpacityBy::Init(); + delta_val_ = end_val_ - start_val_; + } +} \ No newline at end of file diff --git a/core/actions/RotateBy.cpp b/core/actions/RotateBy.cpp index 17e650b5..0a769fb8 100644 --- a/core/actions/RotateBy.cpp +++ b/core/actions/RotateBy.cpp @@ -22,38 +22,41 @@ #include "..\e2dobject.h" -easy2d::RotateBy::RotateBy(float duration, float rotation) - : FiniteTimeAction(duration) +namespace easy2d { - delta_val_ = rotation; -} - -void easy2d::RotateBy::Init() -{ - FiniteTimeAction::Init(); - - if (target_) + RotateBy::RotateBy(float duration, float rotation) + : FiniteTimeAction(duration) { - start_val_ = target_->GetRotation(); + delta_val_ = rotation; } -} -void easy2d::RotateBy::Update() -{ - FiniteTimeAction::Update(); - - if (target_) + void RotateBy::Init() { - target_->SetRotation(start_val_ + delta_val_ * delta_); + FiniteTimeAction::Init(); + + if (target_) + { + start_val_ = target_->GetRotation(); + } } -} -easy2d::RotateBy * easy2d::RotateBy::Clone() const -{ - return new RotateBy(duration_, delta_val_); -} + void RotateBy::Update() + { + FiniteTimeAction::Update(); -easy2d::RotateBy * easy2d::RotateBy::Reverse() const -{ - return new RotateBy(duration_, -delta_val_); + if (target_) + { + target_->SetRotation(start_val_ + delta_val_ * delta_); + } + } + + RotateBy * RotateBy::Clone() const + { + return new RotateBy(duration_, delta_val_); + } + + RotateBy * RotateBy::Reverse() const + { + return new RotateBy(duration_, -delta_val_); + } } \ No newline at end of file diff --git a/core/actions/RotateTo.cpp b/core/actions/RotateTo.cpp index 00b9bec8..0b77c65c 100644 --- a/core/actions/RotateTo.cpp +++ b/core/actions/RotateTo.cpp @@ -22,19 +22,22 @@ #include "..\e2dobject.h" -easy2d::RotateTo::RotateTo(float duration, float rotation) - : RotateBy(duration, 0) +namespace easy2d { - end_val_ = rotation; -} + RotateTo::RotateTo(float duration, float rotation) + : RotateBy(duration, 0) + { + end_val_ = rotation; + } -easy2d::RotateTo * easy2d::RotateTo::Clone() const -{ - return new RotateTo(duration_, end_val_); -} + RotateTo * RotateTo::Clone() const + { + return new RotateTo(duration_, end_val_); + } -void easy2d::RotateTo::Init() -{ - RotateBy::Init(); - delta_val_ = end_val_ - start_val_; -} + void RotateTo::Init() + { + RotateBy::Init(); + delta_val_ = end_val_ - start_val_; + } +} \ No newline at end of file diff --git a/core/actions/ScaleBy.cpp b/core/actions/ScaleBy.cpp index 63aa9689..16b99f63 100644 --- a/core/actions/ScaleBy.cpp +++ b/core/actions/ScaleBy.cpp @@ -22,47 +22,50 @@ #include "..\e2dobject.h" -easy2d::ScaleBy::ScaleBy(float duration, float scale) - : FiniteTimeAction(duration) +namespace easy2d { - delta_x_ = scale; - delta_y_ = scale; -} - -easy2d::ScaleBy::ScaleBy(float duration, float scale_x, float scale_y) - : FiniteTimeAction(duration) -{ - delta_x_ = scale_x; - delta_y_ = scale_y; -} - -void easy2d::ScaleBy::Init() -{ - FiniteTimeAction::Init(); - - if (target_) + ScaleBy::ScaleBy(float duration, float scale) + : FiniteTimeAction(duration) { - start_scale_x_ = target_->GetScaleX(); - start_scale_y_ = target_->GetScaleY(); + delta_x_ = scale; + delta_y_ = scale; } -} -void easy2d::ScaleBy::Update() -{ - FiniteTimeAction::Update(); - - if (target_) + ScaleBy::ScaleBy(float duration, float scale_x, float scale_y) + : FiniteTimeAction(duration) { - target_->SetScale(start_scale_x_ + delta_x_ * delta_, start_scale_y_ + delta_y_ * delta_); + delta_x_ = scale_x; + delta_y_ = scale_y; } -} -easy2d::ScaleBy * easy2d::ScaleBy::Clone() const -{ - return new ScaleBy(duration_, delta_x_, delta_y_); -} + void ScaleBy::Init() + { + FiniteTimeAction::Init(); -easy2d::ScaleBy * easy2d::ScaleBy::Reverse() const -{ - return new ScaleBy(duration_, -delta_x_, -delta_y_); + if (target_) + { + start_scale_x_ = target_->GetScaleX(); + start_scale_y_ = target_->GetScaleY(); + } + } + + void ScaleBy::Update() + { + FiniteTimeAction::Update(); + + if (target_) + { + target_->SetScale(start_scale_x_ + delta_x_ * delta_, start_scale_y_ + delta_y_ * delta_); + } + } + + ScaleBy * ScaleBy::Clone() const + { + return new ScaleBy(duration_, delta_x_, delta_y_); + } + + ScaleBy * ScaleBy::Reverse() const + { + return new ScaleBy(duration_, -delta_x_, -delta_y_); + } } \ No newline at end of file diff --git a/core/actions/ScaleTo.cpp b/core/actions/ScaleTo.cpp index 92a7f066..1980e572 100644 --- a/core/actions/ScaleTo.cpp +++ b/core/actions/ScaleTo.cpp @@ -21,28 +21,32 @@ #include "..\e2daction.h" #include "..\e2dobject.h" -easy2d::ScaleTo::ScaleTo(float duration, float scale) - : ScaleBy(duration, 0, 0) -{ - end_scale_x_ = scale; - end_scale_y_ = scale; -} -easy2d::ScaleTo::ScaleTo(float duration, float scale_x, float scale_y) - : ScaleBy(duration, 0, 0) +namespace easy2d { - end_scale_x_ = scale_x; - end_scale_y_ = scale_y; -} + ScaleTo::ScaleTo(float duration, float scale) + : ScaleBy(duration, 0, 0) + { + end_scale_x_ = scale; + end_scale_y_ = scale; + } -easy2d::ScaleTo * easy2d::ScaleTo::Clone() const -{ - return new ScaleTo(duration_, end_scale_x_, end_scale_y_); -} + ScaleTo::ScaleTo(float duration, float scale_x, float scale_y) + : ScaleBy(duration, 0, 0) + { + end_scale_x_ = scale_x; + end_scale_y_ = scale_y; + } -void easy2d::ScaleTo::Init() -{ - ScaleBy::Init(); - delta_x_ = end_scale_x_ - start_scale_x_; - delta_y_ = end_scale_y_ - start_scale_y_; -} + ScaleTo * ScaleTo::Clone() const + { + return new ScaleTo(duration_, end_scale_x_, end_scale_y_); + } + + void ScaleTo::Init() + { + ScaleBy::Init(); + delta_x_ = end_scale_x_ - start_scale_x_; + delta_y_ = end_scale_y_ - start_scale_y_; + } +} \ No newline at end of file diff --git a/core/actions/Sequence.cpp b/core/actions/Sequence.cpp index 6f4dc78d..c8077a5f 100644 --- a/core/actions/Sequence.cpp +++ b/core/actions/Sequence.cpp @@ -20,120 +20,124 @@ #include "..\e2daction.h" -easy2d::Sequence::Sequence() - : action_index_(0) -{ -} -easy2d::Sequence::Sequence(const Actions& actions) - : action_index_(0) +namespace easy2d { - this->Add(actions); -} - -easy2d::Sequence::~Sequence() -{ - for (auto action : actions_) + Sequence::Sequence() + : action_index_(0) { - SafeRelease(action); } -} -void easy2d::Sequence::Init() -{ - Action::Init(); - // 将所有动作与目标绑定 - if (target_) + Sequence::Sequence(const Actions& actions) + : action_index_(0) + { + this->Add(actions); + } + + Sequence::~Sequence() + { + for (auto action : actions_) + { + SafeRelease(action); + } + } + + void Sequence::Init() + { + Action::Init(); + // 将所有动作与目标绑定 + if (target_) + { + for (const auto& action : actions_) + { + action->target_ = target_; + } + } + // 初始化第一个动作 + actions_[0]->Init(); + } + + void Sequence::Update() + { + Action::Update(); + + auto &action = actions_[action_index_]; + action->Update(); + + if (action->IsDone()) + { + ++action_index_; + if (action_index_ == actions_.size()) + { + this->Stop(); + } + else + { + actions_[action_index_]->Init(); + } + } + } + + void Sequence::Reset() + { + Action::Reset(); + for (const auto& action : actions_) + { + action->Reset(); + } + action_index_ = 0; + } + + void Sequence::ResetTime() { for (const auto& action : actions_) { - action->target_ = target_; + action->ResetTime(); } } - // 初始化第一个动作 - actions_[0]->Init(); -} -void easy2d::Sequence::Update() -{ - Action::Update(); - - auto &action = actions_[action_index_]; - action->Update(); - - if (action->IsDone()) - { - ++action_index_; - if (action_index_ == actions_.size()) - { - this->Stop(); - } - else - { - actions_[action_index_]->Init(); - } - } -} - -void easy2d::Sequence::Reset() -{ - Action::Reset(); - for (const auto& action : actions_) - { - action->Reset(); - } - action_index_ = 0; -} - -void easy2d::Sequence::ResetTime() -{ - for (const auto& action : actions_) - { - action->ResetTime(); - } -} - -void easy2d::Sequence::Add(Action * action) -{ - if (action) - { - actions_.push_back(action); - action->Retain(); - } -} - -void easy2d::Sequence::Add(const Actions& actions) -{ - for (const auto &action : actions) - { - this->Add(action); - } -} - -easy2d::Sequence * easy2d::Sequence::Clone() const -{ - auto sequence = new Sequence(); - for (const auto& action : actions_) + void Sequence::Add(Action * action) { if (action) { - sequence->Add(action->Clone()); + actions_.push_back(action); + action->Retain(); } } - return sequence; -} -easy2d::Sequence * easy2d::Sequence::Reverse() const -{ - auto sequence = new Sequence(); - if (sequence && !actions_.empty()) + void Sequence::Add(const Actions& actions) { - std::vector newActions(actions_.size()); - for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter) + for (const auto &action : actions) { - newActions.push_back((*iter)->Reverse()); + this->Add(action); } - sequence->Add(newActions); } - return sequence; + + Sequence * Sequence::Clone() const + { + auto sequence = new Sequence(); + for (const auto& action : actions_) + { + if (action) + { + sequence->Add(action->Clone()); + } + } + return sequence; + } + + Sequence * Sequence::Reverse() const + { + auto sequence = new Sequence(); + if (sequence && !actions_.empty()) + { + std::vector newActions(actions_.size()); + for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter) + { + newActions.push_back((*iter)->Reverse()); + } + sequence->Add(newActions); + } + return sequence; + } } \ No newline at end of file diff --git a/core/actions/Spawn.cpp b/core/actions/Spawn.cpp index 04703b3a..e00cd3c4 100644 --- a/core/actions/Spawn.cpp +++ b/core/actions/Spawn.cpp @@ -20,118 +20,122 @@ #include "..\e2daction.h" -easy2d::Spawn::Spawn() -{ -} -easy2d::Spawn::Spawn(const Actions& actions) +namespace easy2d { - this->Add(actions); -} - -easy2d::Spawn::~Spawn() -{ - for (auto action : actions_) + Spawn::Spawn() { - SafeRelease(action); } -} -void easy2d::Spawn::Init() -{ - Action::Init(); + Spawn::Spawn(const Actions& actions) + { + this->Add(actions); + } - if (target_) + Spawn::~Spawn() + { + for (auto action : actions_) + { + SafeRelease(action); + } + } + + void Spawn::Init() + { + Action::Init(); + + if (target_) + { + for (const auto& action : actions_) + { + action->target_ = target_; + action->Init(); + } + } + } + + void Spawn::Update() + { + Action::Update(); + + size_t done_num = 0; + for (const auto& action : actions_) + { + if (action->IsDone()) + { + ++done_num; + } + else + { + action->Update(); + } + } + + if (done_num == actions_.size()) + { + this->Stop(); + } + } + + void Spawn::Reset() + { + Action::Reset(); + for (const auto& action : actions_) + { + action->Reset(); + } + } + + void Spawn::ResetTime() { for (const auto& action : actions_) { - action->target_ = target_; - action->Init(); - } - } -} - -void easy2d::Spawn::Update() -{ - Action::Update(); - - size_t done_num = 0; - for (const auto& action : actions_) - { - if (action->IsDone()) - { - ++done_num; - } - else - { - action->Update(); + action->ResetTime(); } } - if (done_num == actions_.size()) - { - this->Stop(); - } -} - -void easy2d::Spawn::Reset() -{ - Action::Reset(); - for (const auto& action : actions_) - { - action->Reset(); - } -} - -void easy2d::Spawn::ResetTime() -{ - for (const auto& action : actions_) - { - action->ResetTime(); - } -} - -void easy2d::Spawn::Add(Action * action) -{ - if (action) - { - actions_.push_back(action); - action->Retain(); - } -} - -void easy2d::Spawn::Add(const Actions& actions) -{ - for (const auto &action : actions) - { - this->Add(action); - } -} - -easy2d::Spawn * easy2d::Spawn::Clone() const -{ - auto spawn = new Spawn(); - for (const auto& action : actions_) + void Spawn::Add(Action * action) { if (action) { - spawn->Add(action->Clone()); + actions_.push_back(action); + action->Retain(); } } - return spawn; -} -easy2d::Spawn * easy2d::Spawn::Reverse() const -{ - auto spawn = new Spawn(); - if (spawn && !actions_.empty()) + void Spawn::Add(const Actions& actions) { - std::vector newActions(actions_.size()); - for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter) + for (const auto &action : actions) { - newActions.push_back((*iter)->Reverse()); + this->Add(action); } - spawn->Add(newActions); } - return spawn; + + Spawn * Spawn::Clone() const + { + auto spawn = new Spawn(); + for (const auto& action : actions_) + { + if (action) + { + spawn->Add(action->Clone()); + } + } + return spawn; + } + + Spawn * Spawn::Reverse() const + { + auto spawn = new Spawn(); + if (spawn && !actions_.empty()) + { + std::vector newActions(actions_.size()); + for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter) + { + newActions.push_back((*iter)->Reverse()); + } + spawn->Add(newActions); + } + return spawn; + } } \ No newline at end of file diff --git a/core/components/Button.cpp b/core/components/Button.cpp index 036238f5..adf4ffbc 100644 --- a/core/components/Button.cpp +++ b/core/components/Button.cpp @@ -37,246 +37,249 @@ } \ -easy2d::Button::Button() - : callback_(nullptr) - , status_(Status::Normal) - , enabled_(true) - , is_selected_(false) - , normal_(nullptr) - , mouseover_(nullptr) - , selected_(nullptr) - , disabled_(nullptr) +namespace easy2d { -} - -easy2d::Button::Button(Node * normal, const Callback& func) - : callback_(nullptr) - , status_(Status::Normal) - , enabled_(true) - , is_selected_(false) - , normal_(nullptr) - , mouseover_(nullptr) - , selected_(nullptr) - , disabled_(nullptr) -{ - this->SetNormal(normal); - this->SetCallbackOnClick(func); -} - -easy2d::Button::Button(Node * normal, Node * selected, const Callback& func) - : callback_(nullptr) - , status_(Status::Normal) - , enabled_(true) - , is_selected_(false) - , normal_(nullptr) - , mouseover_(nullptr) - , selected_(nullptr) - , disabled_(nullptr) -{ - this->SetNormal(normal); - this->SetSelected(selected); - this->SetCallbackOnClick(func); -} - -easy2d::Button::Button(Node * normal, Node * mouseover, Node * selected, const Callback& func) - : callback_(nullptr) - , status_(Status::Normal) - , enabled_(true) - , is_selected_(false) - , normal_(nullptr) - , mouseover_(nullptr) - , selected_(nullptr) - , disabled_(nullptr) -{ - this->SetNormal(normal); - this->SetMouseOver(mouseover); - this->SetSelected(selected); - this->SetCallbackOnClick(func); -} - -easy2d::Button::Button(Node * normal, Node * mouseover, Node * selected, Node * disabled, const Callback& func) - : callback_(nullptr) - , status_(Status::Normal) - , enabled_(true) - , is_selected_(false) - , normal_(nullptr) - , mouseover_(nullptr) - , selected_(nullptr) - , disabled_(nullptr) -{ - this->SetNormal(normal); - this->SetMouseOver(mouseover); - this->SetSelected(selected); - this->SetDisabled(disabled); - this->SetCallbackOnClick(func); -} - -bool easy2d::Button::IsEnable() const -{ - return enabled_; -} - -void easy2d::Button::SetNormal(Node * normal) -{ - SET_BUTTON_NODE(normal_, normal); - if (normal) + Button::Button() + : callback_(nullptr) + , status_(Status::Normal) + , enabled_(true) + , is_selected_(false) + , normal_(nullptr) + , mouseover_(nullptr) + , selected_(nullptr) + , disabled_(nullptr) { - this->SetSize(normal->GetWidth(), normal->GetHeight()); } -} -void easy2d::Button::SetMouseOver(Node * mouseover) -{ - SET_BUTTON_NODE(mouseover_, mouseover); -} - -void easy2d::Button::SetSelected(Node * selected) -{ - SET_BUTTON_NODE(selected_, selected); -} - -void easy2d::Button::SetDisabled(Node * disabled) -{ - SET_BUTTON_NODE(disabled_, disabled); -} - -void easy2d::Button::SetEnabled(bool enabled) -{ - if (enabled_ != enabled) + Button::Button(Node * normal, const Callback& func) + : callback_(nullptr) + , status_(Status::Normal) + , enabled_(true) + , is_selected_(false) + , normal_(nullptr) + , mouseover_(nullptr) + , selected_(nullptr) + , disabled_(nullptr) { - enabled_ = enabled; - UpdateVisible(); + this->SetNormal(normal); + this->SetCallbackOnClick(func); } -} -void easy2d::Button::SetCallbackOnClick(const Callback& func) -{ - callback_ = func; -} - -void easy2d::Button::SetPivot(float pivot_x, float pivot_y) -{ - Node::SetPivot(pivot_x, pivot_y); - SAFE_SET(normal_, SetPivot, pivot_x, pivot_y); - SAFE_SET(mouseover_, SetPivot, pivot_x, pivot_y); - SAFE_SET(selected_, SetPivot, pivot_x, pivot_y); - SAFE_SET(disabled_, SetPivot, pivot_x, pivot_y); -} - -bool easy2d::Button::Dispatch(const MouseEvent & e, bool handled) -{ - if (!handled && enabled_ && IsVisible() && normal_) + Button::Button(Node * normal, Node * selected, const Callback& func) + : callback_(nullptr) + , status_(Status::Normal) + , enabled_(true) + , is_selected_(false) + , normal_(nullptr) + , mouseover_(nullptr) + , selected_(nullptr) + , disabled_(nullptr) { - bool contains = normal_->ContainsPoint(e.GetPosition()); - if (e.GetType() == MouseEvent::Type::LeftUp && is_selected_ && contains) + this->SetNormal(normal); + this->SetSelected(selected); + this->SetCallbackOnClick(func); + } + + Button::Button(Node * normal, Node * mouseover, Node * selected, const Callback& func) + : callback_(nullptr) + , status_(Status::Normal) + , enabled_(true) + , is_selected_(false) + , normal_(nullptr) + , mouseover_(nullptr) + , selected_(nullptr) + , disabled_(nullptr) + { + this->SetNormal(normal); + this->SetMouseOver(mouseover); + this->SetSelected(selected); + this->SetCallbackOnClick(func); + } + + Button::Button(Node * normal, Node * mouseover, Node * selected, Node * disabled, const Callback& func) + : callback_(nullptr) + , status_(Status::Normal) + , enabled_(true) + , is_selected_(false) + , normal_(nullptr) + , mouseover_(nullptr) + , selected_(nullptr) + , disabled_(nullptr) + { + this->SetNormal(normal); + this->SetMouseOver(mouseover); + this->SetSelected(selected); + this->SetDisabled(disabled); + this->SetCallbackOnClick(func); + } + + bool Button::IsEnable() const + { + return enabled_; + } + + void Button::SetNormal(Node * normal) + { + SET_BUTTON_NODE(normal_, normal); + if (normal) { - if (callback_) + this->SetSize(normal->GetWidth(), normal->GetHeight()); + } + } + + void Button::SetMouseOver(Node * mouseover) + { + SET_BUTTON_NODE(mouseover_, mouseover); + } + + void Button::SetSelected(Node * selected) + { + SET_BUTTON_NODE(selected_, selected); + } + + void Button::SetDisabled(Node * disabled) + { + SET_BUTTON_NODE(disabled_, disabled); + } + + void Button::SetEnabled(bool enabled) + { + if (enabled_ != enabled) + { + enabled_ = enabled; + UpdateVisible(); + } + } + + void Button::SetCallbackOnClick(const Callback& func) + { + callback_ = func; + } + + void Button::SetPivot(float pivot_x, float pivot_y) + { + Node::SetPivot(pivot_x, pivot_y); + SAFE_SET(normal_, SetPivot, pivot_x, pivot_y); + SAFE_SET(mouseover_, SetPivot, pivot_x, pivot_y); + SAFE_SET(selected_, SetPivot, pivot_x, pivot_y); + SAFE_SET(disabled_, SetPivot, pivot_x, pivot_y); + } + + bool Button::Dispatch(const MouseEvent & e, bool handled) + { + if (!handled && enabled_ && IsVisible() && normal_) + { + bool contains = normal_->ContainsPoint(e.GetPosition()); + if (e.GetType() == MouseEvent::Type::LeftUp && is_selected_ && contains) { - callback_(); - } - is_selected_ = false; - SetStatus(Status::Normal); - return true; - } - else if (e.GetType() == MouseEvent::Type::LeftDown) - { - is_selected_ = contains; - SetStatus(contains ? Status::Selected : Status::Normal); - - if (contains) + if (callback_) + { + callback_(); + } + is_selected_ = false; + SetStatus(Status::Normal); return true; - } - else if (e.GetType() == MouseEvent::Type::LeftUp) - { - is_selected_ = false; - } - else if (e.GetType() == MouseEvent::Type::MoveBy && is_selected_ && contains) - { - SetStatus(Status::Selected); - return true; - } - else - { - if (!e.IsLButtonDown() && is_selected_) + } + else if (e.GetType() == MouseEvent::Type::LeftDown) + { + is_selected_ = contains; + SetStatus(contains ? Status::Selected : Status::Normal); + + if (contains) + return true; + } + else if (e.GetType() == MouseEvent::Type::LeftUp) { is_selected_ = false; } - - SetStatus(contains ? Status::Mouseover : Status::Normal); - - if (contains) + else if (e.GetType() == MouseEvent::Type::MoveBy && is_selected_ && contains) + { + SetStatus(Status::Selected); return true; + } + else + { + if (!e.IsLButtonDown() && is_selected_) + { + is_selected_ = false; + } + + SetStatus(contains ? Status::Mouseover : Status::Normal); + + if (contains) + return true; + } + } + + return Node::Dispatch(e, handled); + } + + void Button::Visit() + { + Node::Visit(); + + if (IsVisible() && + !enabled_ && + normal_ && + normal_->ContainsPoint(Device::GetInput()->GetMousePos())) + { + HCURSOR hcursor = ::LoadCursor(nullptr, IDC_NO); + if (hcursor) + { + ::SetCursor(hcursor); + } + } + else if (status_ == Status::Mouseover || status_ == Status::Selected) + { + HCURSOR hcursor = ::LoadCursor(nullptr, IDC_HAND); + if (hcursor) + { + ::SetCursor(hcursor); + } } } - return Node::Dispatch(e, handled); -} - -void easy2d::Button::Visit() -{ - Node::Visit(); - - if (IsVisible() && - !enabled_ && - normal_ && - normal_->ContainsPoint(Device::GetInput()->GetMousePos())) + void Button::SetStatus(Status status) { - HCURSOR hcursor = ::LoadCursor(nullptr, IDC_NO); - if (hcursor) + if (status_ != status) { - ::SetCursor(hcursor); + status_ = status; + UpdateVisible(); } } - else if (status_ == Status::Mouseover || status_ == Status::Selected) - { - HCURSOR hcursor = ::LoadCursor(nullptr, IDC_HAND); - if (hcursor) - { - ::SetCursor(hcursor); - } - } -} -void easy2d::Button::SetStatus(Status status) -{ - if (status_ != status) + void Button::UpdateVisible() { - status_ = status; - UpdateVisible(); - } -} + SAFE_SET(normal_, SetVisible, false); + SAFE_SET(mouseover_, SetVisible, false); + SAFE_SET(selected_, SetVisible, false); + SAFE_SET(disabled_, SetVisible, false); -void easy2d::Button::UpdateVisible() -{ - SAFE_SET(normal_, SetVisible, false); - SAFE_SET(mouseover_, SetVisible, false); - SAFE_SET(selected_, SetVisible, false); - SAFE_SET(disabled_, SetVisible, false); - - if (enabled_) - { - if (status_ == Status::Selected && selected_) + if (enabled_) { - selected_->SetVisible(true); - } - else if (status_ == Status::Mouseover && mouseover_) - { - mouseover_->SetVisible(true); + if (status_ == Status::Selected && selected_) + { + selected_->SetVisible(true); + } + else if (status_ == Status::Mouseover && mouseover_) + { + mouseover_->SetVisible(true); + } + else + { + if (normal_) normal_->SetVisible(true); + } } else { - if (normal_) normal_->SetVisible(true); + if (disabled_) + { + disabled_->SetVisible(true); + } + else + { + if (normal_) normal_->SetVisible(true); + } } } - else - { - if (disabled_) - { - disabled_->SetVisible(true); - } - else - { - if (normal_) normal_->SetVisible(true); - } - } -} +} \ No newline at end of file diff --git a/core/components/Menu.cpp b/core/components/Menu.cpp index fa0457ef..c51f7002 100644 --- a/core/components/Menu.cpp +++ b/core/components/Menu.cpp @@ -20,77 +20,81 @@ #include "..\e2dcomponent.h" -easy2d::Menu::Menu() - : enabled_(true) -{ -} -easy2d::Menu::Menu(const std::vector& buttons) - : enabled_(true) +namespace easy2d { - for (const auto& button : buttons) + Menu::Menu() + : enabled_(true) { - this->AddButton(button); } -} -bool easy2d::Menu::IsEnable() const -{ - return enabled_; -} - -size_t easy2d::Menu::GetButtonCount() const -{ - return buttons_.size(); -} - -void easy2d::Menu::SetEnabled(bool enabled) -{ - if (enabled_ != enabled) + Menu::Menu(const std::vector& buttons) + : enabled_(true) { - enabled_ = enabled; - - for (const auto& button : buttons_) + for (const auto& button : buttons) { - button->SetEnabled(enabled); + this->AddButton(button); } } -} -void easy2d::Menu::AddButton(Button * button) -{ - if (button) + bool Menu::IsEnable() const { - this->AddChild(button); - buttons_.push_back(button); - button->SetEnabled(enabled_); + return enabled_; } -} -bool easy2d::Menu::RemoveButton(Button * button) -{ - if (buttons_.empty()) + size_t Menu::GetButtonCount() const { + return buttons_.size(); + } + + void Menu::SetEnabled(bool enabled) + { + if (enabled_ != enabled) + { + enabled_ = enabled; + + for (const auto& button : buttons_) + { + button->SetEnabled(enabled); + } + } + } + + void Menu::AddButton(Button * button) + { + if (button) + { + this->AddChild(button); + buttons_.push_back(button); + button->SetEnabled(enabled_); + } + } + + bool Menu::RemoveButton(Button * button) + { + if (buttons_.empty()) + { + return false; + } + + this->RemoveChild(button); + + if (button) + { + auto iter = std::find(buttons_.begin(), buttons_.end(), button); + if (iter != buttons_.end()) + { + // 移除按钮前,将它启用 + button->SetEnabled(true); + buttons_.erase(iter); + return true; + } + } return false; } - this->RemoveChild(button); - - if (button) + const std::vector& Menu::GetAllButtons() const { - auto iter = std::find(buttons_.begin(), buttons_.end(), button); - if (iter != buttons_.end()) - { - // 移除按钮前,将它启用 - button->SetEnabled(true); - buttons_.erase(iter); - return true; - } + return buttons_; } - return false; -} - -const std::vector& easy2d::Menu::GetAllButtons() const -{ - return buttons_; -} +} \ No newline at end of file diff --git a/core/e2dutil.h b/core/e2dutil.h index f78eb0a1..cf5db84a 100644 --- a/core/e2dutil.h +++ b/core/e2dutil.h @@ -61,7 +61,7 @@ namespace easy2d Point operator - () const; bool operator== (const Point& other) const; - explicit operator easy2d::Size() const; + explicit operator Size() const; // 判断两点间距离 static float Distance( @@ -102,7 +102,7 @@ namespace easy2d Size operator - () const; bool operator== (const Size& other) const; - explicit operator easy2d::Point() const; + explicit operator Point() const; }; @@ -585,19 +585,19 @@ namespace easy2d template static inline T Range(T min, T max) { - return easy2d::Random::RandomInt(min, max); + return Random::RandomInt(min, max); } // 取得范围内的一个浮点数随机数 static inline float Range(float min, float max) { - return easy2d::Random::RandomReal(min, max); + return Random::RandomReal(min, max); } // 取得范围内的一个浮点数随机数 static inline double Range(double min, double max) { - return easy2d::Random::RandomReal(min, max); + return Random::RandomReal(min, max); } private: diff --git a/core/events/KeyEvent.cpp b/core/events/KeyEvent.cpp index 7dcbbeab..0c2953b0 100644 --- a/core/events/KeyEvent.cpp +++ b/core/events/KeyEvent.cpp @@ -21,80 +21,83 @@ #include "..\e2devent.h" -easy2d::KeyEvent::KeyEvent(UINT message, WPARAM w_param, LPARAM l_param) - : message_(message) - , w_param_(w_param) - , l_param_(l_param) +namespace easy2d { -} - -easy2d::KeyCode easy2d::KeyEvent::GetCode() const -{ - switch (w_param_) + KeyEvent::KeyEvent(UINT message, WPARAM w_param, LPARAM l_param) + : message_(message) + , w_param_(w_param) + , l_param_(l_param) { - case 'A': return KeyCode::A; - case 'B': return KeyCode::B; - case 'C': return KeyCode::C; - case 'D': return KeyCode::D; - case 'E': return KeyCode::E; - case 'F': return KeyCode::F; - case 'G': return KeyCode::G; - case 'H': return KeyCode::H; - case 'I': return KeyCode::I; - case 'J': return KeyCode::J; - case 'K': return KeyCode::K; - case 'L': return KeyCode::L; - case 'M': return KeyCode::M; - case 'N': return KeyCode::N; - case 'O': return KeyCode::O; - case 'P': return KeyCode::P; - case 'Q': return KeyCode::Q; - case 'R': return KeyCode::R; - case 'S': return KeyCode::S; - case 'T': return KeyCode::T; - case 'U': return KeyCode::U; - case 'V': return KeyCode::V; - case 'W': return KeyCode::W; - case 'X': return KeyCode::X; - case 'Y': return KeyCode::Y; - case 'Z': return KeyCode::Z; - case '0': return KeyCode::Num0; - case '1': return KeyCode::Num1; - case '2': return KeyCode::Num2; - case '3': return KeyCode::Num3; - case '4': return KeyCode::Num4; - case '5': return KeyCode::Num5; - case '6': return KeyCode::Num6; - case '7': return KeyCode::Num7; - case '8': return KeyCode::Num8; - case '9': return KeyCode::Num9; - case VK_NUMPAD0: return KeyCode::Numpad0; - case VK_NUMPAD1: return KeyCode::Numpad1; - case VK_NUMPAD2: return KeyCode::Numpad2; - case VK_NUMPAD3: return KeyCode::Numpad3; - case VK_NUMPAD4: return KeyCode::Numpad4; - case VK_NUMPAD5: return KeyCode::Numpad5; - case VK_NUMPAD6: return KeyCode::Numpad6; - case VK_NUMPAD7: return KeyCode::Numpad7; - case VK_NUMPAD8: return KeyCode::Numpad8; - case VK_NUMPAD9: return KeyCode::Numpad9; - case VK_UP: return KeyCode::Up; - case VK_DOWN: return KeyCode::Down; - case VK_LEFT: return KeyCode::Left; - case VK_RIGHT: return KeyCode::Right; - case VK_RETURN: return KeyCode::Enter; - case VK_SPACE: return KeyCode::Space; - case VK_ESCAPE: return KeyCode::Esc; - default: return KeyCode::Unknown; } -} -int easy2d::KeyEvent::GetCount() const -{ - return static_cast((DWORD)l_param_ & 0x0000FFFF); -} + KeyCode KeyEvent::GetCode() const + { + switch (w_param_) + { + case 'A': return KeyCode::A; + case 'B': return KeyCode::B; + case 'C': return KeyCode::C; + case 'D': return KeyCode::D; + case 'E': return KeyCode::E; + case 'F': return KeyCode::F; + case 'G': return KeyCode::G; + case 'H': return KeyCode::H; + case 'I': return KeyCode::I; + case 'J': return KeyCode::J; + case 'K': return KeyCode::K; + case 'L': return KeyCode::L; + case 'M': return KeyCode::M; + case 'N': return KeyCode::N; + case 'O': return KeyCode::O; + case 'P': return KeyCode::P; + case 'Q': return KeyCode::Q; + case 'R': return KeyCode::R; + case 'S': return KeyCode::S; + case 'T': return KeyCode::T; + case 'U': return KeyCode::U; + case 'V': return KeyCode::V; + case 'W': return KeyCode::W; + case 'X': return KeyCode::X; + case 'Y': return KeyCode::Y; + case 'Z': return KeyCode::Z; + case '0': return KeyCode::Num0; + case '1': return KeyCode::Num1; + case '2': return KeyCode::Num2; + case '3': return KeyCode::Num3; + case '4': return KeyCode::Num4; + case '5': return KeyCode::Num5; + case '6': return KeyCode::Num6; + case '7': return KeyCode::Num7; + case '8': return KeyCode::Num8; + case '9': return KeyCode::Num9; + case VK_NUMPAD0: return KeyCode::Numpad0; + case VK_NUMPAD1: return KeyCode::Numpad1; + case VK_NUMPAD2: return KeyCode::Numpad2; + case VK_NUMPAD3: return KeyCode::Numpad3; + case VK_NUMPAD4: return KeyCode::Numpad4; + case VK_NUMPAD5: return KeyCode::Numpad5; + case VK_NUMPAD6: return KeyCode::Numpad6; + case VK_NUMPAD7: return KeyCode::Numpad7; + case VK_NUMPAD8: return KeyCode::Numpad8; + case VK_NUMPAD9: return KeyCode::Numpad9; + case VK_UP: return KeyCode::Up; + case VK_DOWN: return KeyCode::Down; + case VK_LEFT: return KeyCode::Left; + case VK_RIGHT: return KeyCode::Right; + case VK_RETURN: return KeyCode::Enter; + case VK_SPACE: return KeyCode::Space; + case VK_ESCAPE: return KeyCode::Esc; + default: return KeyCode::Unknown; + } + } -easy2d::KeyEvent::Type easy2d::KeyEvent::GetType() const -{ - return Type(message_); -} + int KeyEvent::GetCount() const + { + return static_cast((DWORD)l_param_ & 0x0000FFFF); + } + + KeyEvent::Type KeyEvent::GetType() const + { + return Type(message_); + } +} \ No newline at end of file diff --git a/core/events/MouseEvent.cpp b/core/events/MouseEvent.cpp index 9e56bce2..da4b2a69 100644 --- a/core/events/MouseEvent.cpp +++ b/core/events/MouseEvent.cpp @@ -21,65 +21,68 @@ #include "..\e2devent.h" #include "..\e2dmodule.h" -easy2d::MouseEvent::MouseEvent(UINT message, WPARAM w_param, LPARAM l_param) - : message_(message) - , w_param_(w_param) - , l_param_(l_param) +namespace easy2d { -} + MouseEvent::MouseEvent(UINT message, WPARAM w_param, LPARAM l_param) + : message_(message) + , w_param_(w_param) + , l_param_(l_param) + { + } -float easy2d::MouseEvent::GetX() const -{ - float dpi = Graphics::GetDpi(); - return ((float)(short)LOWORD(l_param_)) * 96.f / dpi; -} + float MouseEvent::GetX() const + { + float dpi = Graphics::GetDpi(); + return ((float)(short)LOWORD(l_param_)) * 96.f / dpi; + } -float easy2d::MouseEvent::GetY() const -{ - float dpi = Graphics::GetDpi(); - return ((float)(short)HIWORD(l_param_)) * 96.f / dpi; -} + float MouseEvent::GetY() const + { + float dpi = Graphics::GetDpi(); + return ((float)(short)HIWORD(l_param_)) * 96.f / dpi; + } -easy2d::Point easy2d::MouseEvent::GetPosition() const -{ - float dpi = Graphics::GetDpi(); - return Point( - ((float)(short)LOWORD(l_param_)) * 96.f / dpi, - ((float)(short)HIWORD(l_param_)) * 96.f / dpi - ); -} + Point MouseEvent::GetPosition() const + { + float dpi = Graphics::GetDpi(); + return Point( + ((float)(short)LOWORD(l_param_)) * 96.f / dpi, + ((float)(short)HIWORD(l_param_)) * 96.f / dpi + ); + } -bool easy2d::MouseEvent::IsShiftDown() const -{ - return GET_KEYSTATE_WPARAM(w_param_) == MK_SHIFT; -} + bool MouseEvent::IsShiftDown() const + { + return GET_KEYSTATE_WPARAM(w_param_) == MK_SHIFT; + } -bool easy2d::MouseEvent::IsCtrlDown() const -{ - return GET_KEYSTATE_WPARAM(w_param_) == MK_CONTROL; -} + bool MouseEvent::IsCtrlDown() const + { + return GET_KEYSTATE_WPARAM(w_param_) == MK_CONTROL; + } -float easy2d::MouseEvent::GetWheelDelta() const -{ - return static_cast(GET_WHEEL_DELTA_WPARAM(w_param_)); -} + float MouseEvent::GetWheelDelta() const + { + return static_cast(GET_WHEEL_DELTA_WPARAM(w_param_)); + } -bool easy2d::MouseEvent::IsLButtonDown() const -{ - return GET_KEYSTATE_WPARAM(w_param_) == MK_LBUTTON; -} + bool MouseEvent::IsLButtonDown() const + { + return GET_KEYSTATE_WPARAM(w_param_) == MK_LBUTTON; + } -bool easy2d::MouseEvent::IsRButtonDown() const -{ - return GET_KEYSTATE_WPARAM(w_param_) == MK_RBUTTON; -} + bool MouseEvent::IsRButtonDown() const + { + return GET_KEYSTATE_WPARAM(w_param_) == MK_RBUTTON; + } -bool easy2d::MouseEvent::IsMButtonDown() const -{ - return GET_KEYSTATE_WPARAM(w_param_) == MK_MBUTTON; -} + bool MouseEvent::IsMButtonDown() const + { + return GET_KEYSTATE_WPARAM(w_param_) == MK_MBUTTON; + } -easy2d::MouseEvent::Type easy2d::MouseEvent::GetType() const -{ - return Type(message_); -} + MouseEvent::Type MouseEvent::GetType() const + { + return Type(message_); + } +} \ No newline at end of file diff --git a/core/modules/Audio.cpp b/core/modules/Audio.cpp index a1f07caf..9332ea3c 100644 --- a/core/modules/Audio.cpp +++ b/core/modules/Audio.cpp @@ -21,47 +21,50 @@ #include "..\e2dmodule.h" -easy2d::Audio::Audio() - : x_audio2_(nullptr) - , mastering_voice_(nullptr) +namespace easy2d { - ThrowIfFailed( - MFStartup(MF_VERSION) - ); - - ThrowIfFailed( - XAudio2Create(&x_audio2_) - ); - - ThrowIfFailed( - x_audio2_->CreateMasteringVoice(&mastering_voice_) - ); -} - -easy2d::Audio::~Audio() -{ - if (mastering_voice_) + Audio::Audio() + : x_audio2_(nullptr) + , mastering_voice_(nullptr) { - mastering_voice_->DestroyVoice(); - mastering_voice_ = nullptr; + ThrowIfFailed( + MFStartup(MF_VERSION) + ); + + ThrowIfFailed( + XAudio2Create(&x_audio2_) + ); + + ThrowIfFailed( + x_audio2_->CreateMasteringVoice(&mastering_voice_) + ); } - SafeRelease(x_audio2_); + Audio::~Audio() + { + if (mastering_voice_) + { + mastering_voice_->DestroyVoice(); + mastering_voice_ = nullptr; + } - MFShutdown(); -} + SafeRelease(x_audio2_); -HRESULT easy2d::Audio::CreateVoice(IXAudio2SourceVoice ** voice, WAVEFORMATEX * wfx) -{ - return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO); -} + MFShutdown(); + } -void easy2d::Audio::Open() -{ - x_audio2_->StartEngine(); -} + HRESULT Audio::CreateVoice(IXAudio2SourceVoice ** voice, WAVEFORMATEX * wfx) + { + return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO); + } -void easy2d::Audio::Close() -{ - x_audio2_->StopEngine(); -} + void Audio::Open() + { + x_audio2_->StartEngine(); + } + + void Audio::Close() + { + x_audio2_->StopEngine(); + } +} \ No newline at end of file diff --git a/core/modules/Device.cpp b/core/modules/Device.cpp index 75cc5643..e96a6d19 100644 --- a/core/modules/Device.cpp +++ b/core/modules/Device.cpp @@ -20,49 +20,56 @@ #include "..\e2dmodule.h" -static easy2d::Graphics * graphics_device = nullptr; -static easy2d::Input * input_device = nullptr; -static easy2d::Audio * audio_device = nullptr; -easy2d::Graphics * easy2d::Device::GetGraphics() +namespace easy2d { - return graphics_device; -} - -easy2d::Input * easy2d::Device::GetInput() -{ - return input_device; -} - -easy2d::Audio * easy2d::Device::GetAudio() -{ - return audio_device; -} - -void easy2d::Device::Init(HWND hwnd) -{ - graphics_device = new (std::nothrow) Graphics(hwnd); - input_device = new (std::nothrow) Input(hwnd); - audio_device = new (std::nothrow) Audio(); -} - -void easy2d::Device::Destroy() -{ - if (audio_device) + namespace { - delete audio_device; - audio_device = nullptr; + Graphics * graphics_device = nullptr; + Input * input_device = nullptr; + Audio * audio_device = nullptr; } - if (input_device) + Graphics * Device::GetGraphics() { - delete input_device; - input_device = nullptr; + return graphics_device; } - if (graphics_device) + Input * Device::GetInput() { - delete graphics_device; - graphics_device = nullptr; + return input_device; } -} + + Audio * Device::GetAudio() + { + return audio_device; + } + + void Device::Init(HWND hwnd) + { + graphics_device = new (std::nothrow) Graphics(hwnd); + input_device = new (std::nothrow) Input(hwnd); + audio_device = new (std::nothrow) Audio(); + } + + void Device::Destroy() + { + if (audio_device) + { + delete audio_device; + audio_device = nullptr; + } + + if (input_device) + { + delete input_device; + input_device = nullptr; + } + + if (graphics_device) + { + delete graphics_device; + graphics_device = nullptr; + } + } +} \ No newline at end of file diff --git a/core/modules/Game.cpp b/core/modules/Game.cpp index 0508eb55..f0c5ddf9 100644 --- a/core/modules/Game.cpp +++ b/core/modules/Game.cpp @@ -30,590 +30,596 @@ #define REGISTER_CLASS L"Easy2DApp" -static easy2d::Game * instance = nullptr; - -easy2d::Game * easy2d::Game::GetInstance() +namespace easy2d { - return instance; -} - -easy2d::Game::Game() - : hwnd_(nullptr) - , quit_(true) - , curr_scene_(nullptr) - , next_scene_(nullptr) - , transition_(nullptr) - , title_(L"Easy2D Game") - , width_(640) - , height_(480) - , icon_(0) - , debug_mode_(false) -{ - if (instance) + namespace { - throw std::runtime_error("同时只能存在一个游戏实例"); - } - instance = this; - - ::CoInitialize(nullptr); -} - -easy2d::Game::~Game() -{ - SafeRelease(transition_); - SafeRelease(curr_scene_); - SafeRelease(next_scene_); - - Image::ClearCache(); - Player::ClearCache(); - Device::Destroy(); - - if (hwnd_) - { - ::DestroyWindow(hwnd_); + Game * instance = nullptr; } - instance = nullptr; - - ::CoUninitialize(); -} - -void easy2d::Game::Run() -{ - // 初始化 - Init(); - - // 开始 - OnStart(); - - // 刷新场景 - if (next_scene_) + Game * Game::GetInstance() { - next_scene_->OnEnter(); - curr_scene_ = next_scene_; - next_scene_ = nullptr; + return instance; } - ::ShowWindow(hwnd_, SW_SHOWNORMAL); - ::UpdateWindow(hwnd_); - // 运行 - const int min_interval = 5; - Time last = Time::Now(); - MSG msg = { 0 }; - - while (!quit_) + Game::Game() + : hwnd_(nullptr) + , quit_(true) + , curr_scene_(nullptr) + , next_scene_(nullptr) + , transition_(nullptr) + , title_(L"Easy2D Game") + , width_(640) + , height_(480) + , icon_(0) + , debug_mode_(false) { - auto now = Time::Now(); - auto dur = now - last; - - if (dur.Milliseconds() > min_interval) + if (instance) { - float dt = (now - last).Seconds(); - last = now; - - Device::GetInput()->Flush(); - OnUpdate(dt); - UpdateScene(dt); - DrawScene(); - - while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } + throw std::runtime_error("同时只能存在一个游戏实例"); } - else + instance = this; + + ::CoInitialize(nullptr); + } + + Game::~Game() + { + SafeRelease(transition_); + SafeRelease(curr_scene_); + SafeRelease(next_scene_); + + Image::ClearCache(); + Player::ClearCache(); + Device::Destroy(); + + if (hwnd_) { - // ID2D1HwndRenderTarget 开启了垂直同步,在渲染时会等待显示器刷新, - // 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。 - // 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。 - int wait = min_interval - dur.Milliseconds(); - if (wait > 1) + ::DestroyWindow(hwnd_); + } + + instance = nullptr; + + ::CoUninitialize(); + } + + void Game::Run() + { + // 初始化 + Init(); + + // 开始 + OnStart(); + + // 刷新场景 + if (next_scene_) + { + next_scene_->OnEnter(); + curr_scene_ = next_scene_; + next_scene_ = nullptr; + } + ::ShowWindow(hwnd_, SW_SHOWNORMAL); + ::UpdateWindow(hwnd_); + + // 运行 + const int min_interval = 5; + Time last = Time::Now(); + MSG msg = { 0 }; + + while (!quit_) + { + auto now = Time::Now(); + auto dur = now - last; + + if (dur.Milliseconds() > min_interval) { - std::this_thread::sleep_for(std::chrono::milliseconds(wait)); + float dt = (now - last).Seconds(); + last = now; + + Device::GetInput()->Flush(); + OnUpdate(dt); + UpdateScene(dt); + DrawScene(); + + while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + } + else + { + // ID2D1HwndRenderTarget 开启了垂直同步,在渲染时会等待显示器刷新, + // 它起到了非常稳定的延时作用,所以大部分时候不需要手动挂起线程进行延时。 + // 下面的代码仅在一些情况下(例如窗口最小化时)挂起线程,防止占用过高 CPU 。 + int wait = min_interval - dur.Milliseconds(); + if (wait > 1) + { + std::this_thread::sleep_for(std::chrono::milliseconds(wait)); + } } } } -} -void easy2d::Game::Quit() -{ - quit_ = true; -} - -void easy2d::Game::EnterScene(Scene * scene, Transition * transition) -{ - if (scene == nullptr) + void Game::Quit() { - E2D_WARNING("Next scene is null pointer!"); - return; + quit_ = true; } - if (curr_scene_ == scene) { return; } - - if (next_scene_) + void Game::EnterScene(Scene * scene, Transition * transition) { - next_scene_->Release(); - } - next_scene_ = scene; - next_scene_->Retain(); - - if (transition) - { - if (transition_) - { - transition_->Stop(); - transition_->Release(); - } - transition_ = transition; - transition_->Retain(); - - transition_->Init(curr_scene_, next_scene_, this); - } -} - -easy2d::Scene * easy2d::Game::GetCurrentScene() -{ - return curr_scene_; -} - -bool easy2d::Game::IsTransitioning() const -{ - return transition_ != nullptr; -} - -void easy2d::Game::UpdateScene(float dt) -{ - auto update = [&](Scene * scene) -> void - { - if (scene) - { - scene->OnUpdate(dt); - Node * root = scene->GetRoot(); - if (root) - { - root->UpdateChildren(dt); - } - } - }; - - update(curr_scene_); - update(next_scene_); - - if (transition_) - { - transition_->Update(); - - if (transition_->IsDone()) - { - transition_->Release(); - transition_ = nullptr; - } - else + if (scene == nullptr) { + E2D_WARNING("Next scene is null pointer!"); return; } + + if (curr_scene_ == scene) { return; } + + if (next_scene_) + { + next_scene_->Release(); + } + next_scene_ = scene; + next_scene_->Retain(); + + if (transition) + { + if (transition_) + { + transition_->Stop(); + transition_->Release(); + } + transition_ = transition; + transition_->Retain(); + + transition_->Init(curr_scene_, next_scene_, this); + } } - if (next_scene_) + Scene * Game::GetCurrentScene() { - if (curr_scene_) + return curr_scene_; + } + + bool Game::IsTransitioning() const + { + return transition_ != nullptr; + } + + void Game::UpdateScene(float dt) + { + auto update = [&](Scene * scene) -> void { - curr_scene_->OnExit(); - curr_scene_->Release(); + if (scene) + { + scene->OnUpdate(dt); + Node * root = scene->GetRoot(); + if (root) + { + root->UpdateChildren(dt); + } + } + }; + + update(curr_scene_); + update(next_scene_); + + if (transition_) + { + transition_->Update(); + + if (transition_->IsDone()) + { + transition_->Release(); + transition_ = nullptr; + } + else + { + return; + } } - next_scene_->OnEnter(); - - curr_scene_ = next_scene_; - next_scene_ = nullptr; - } -} - -void easy2d::Game::DrawScene() -{ - auto graphics = Device::GetGraphics(); - graphics->BeginDraw(); - - if (transition_) - { - transition_->Draw(); - } - else if (curr_scene_) - { - curr_scene_->Draw(); - } - - if (debug_mode_) - { - if (curr_scene_ && curr_scene_->GetRoot()) + if (next_scene_) { - graphics->GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); - graphics->GetSolidBrush()->SetOpacity(1.f); - curr_scene_->GetRoot()->DrawBorder(); + if (curr_scene_) + { + curr_scene_->OnExit(); + curr_scene_->Release(); + } + + next_scene_->OnEnter(); + + curr_scene_ = next_scene_; + next_scene_ = nullptr; } - if (next_scene_ && next_scene_->GetRoot()) + } + + void Game::DrawScene() + { + auto graphics = Device::GetGraphics(); + graphics->BeginDraw(); + + if (transition_) { - graphics->GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); - graphics->GetSolidBrush()->SetOpacity(1.f); - next_scene_->GetRoot()->DrawBorder(); + transition_->Draw(); + } + else if (curr_scene_) + { + curr_scene_->Draw(); } - graphics->DrawDebugInfo(); + if (debug_mode_) + { + if (curr_scene_ && curr_scene_->GetRoot()) + { + graphics->GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + graphics->GetSolidBrush()->SetOpacity(1.f); + curr_scene_->GetRoot()->DrawBorder(); + } + if (next_scene_ && next_scene_->GetRoot()) + { + graphics->GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + graphics->GetSolidBrush()->SetOpacity(1.f); + next_scene_->GetRoot()->DrawBorder(); + } + + graphics->DrawDebugInfo(); + } + graphics->EndDraw(); } - graphics->EndDraw(); -} -void easy2d::Game::Init() -{ - HINSTANCE hinstance = GetModuleHandle(nullptr); - WNDCLASSEX wcex = { 0 }; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.lpszClassName = REGISTER_CLASS; - wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - wcex.lpfnWndProc = Game::WndProc; - wcex.hIcon = nullptr; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = sizeof(LONG_PTR); - wcex.hInstance = hinstance; - wcex.hbrBackground = nullptr; - wcex.lpszMenuName = nullptr; - wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW); - - if (icon_ != 0) + void Game::Init() { - wcex.hIcon = (HICON)::LoadImage( + HINSTANCE hinstance = GetModuleHandle(nullptr); + WNDCLASSEX wcex = { 0 }; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.lpszClassName = REGISTER_CLASS; + wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wcex.lpfnWndProc = Game::WndProc; + wcex.hIcon = nullptr; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = sizeof(LONG_PTR); + wcex.hInstance = hinstance; + wcex.hbrBackground = nullptr; + wcex.lpszMenuName = nullptr; + wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW); + + if (icon_ != 0) + { + wcex.hIcon = (HICON)::LoadImage( + hinstance, + MAKEINTRESOURCE(icon_), + IMAGE_ICON, + 0, + 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE + ); + } + + // 注册窗口类 + ::RegisterClassEx(&wcex); + + // 计算窗口大小 + Rect client_rect = Locate(width_, height_); + + // 创建窗口 + hwnd_ = ::CreateWindowEx( + NULL, + REGISTER_CLASS, + title_.c_str(), + WINDOW_STYLE, + int(client_rect.origin.x), + int(client_rect.origin.y), + int(client_rect.size.width), + int(client_rect.size.height), + nullptr, + nullptr, hinstance, - MAKEINTRESOURCE(icon_), - IMAGE_ICON, - 0, - 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE + this ); - } - // 注册窗口类 - ::RegisterClassEx(&wcex); - - // 计算窗口大小 - Rect client_rect = Locate(width_, height_); - - // 创建窗口 - hwnd_ = ::CreateWindowEx( - NULL, - REGISTER_CLASS, - title_.c_str(), - WINDOW_STYLE, - int(client_rect.origin.x), - int(client_rect.origin.y), - int(client_rect.size.width), - int(client_rect.size.height), - nullptr, - nullptr, - hinstance, - this - ); - - if (hwnd_ == nullptr) - { - ::UnregisterClass(REGISTER_CLASS, hinstance); - throw std::runtime_error("Create window failed"); - return; - } - - ::SetWindowLongPtrW( - hwnd_, - GWLP_USERDATA, - PtrToUlong(this) - ); - - // 初始化设备 - Device::Init(hwnd_); - - // 禁用输入法 - ::ImmAssociateContext(hwnd_, nullptr); - - // 若开启了调试模式,打开控制台 - HWND console = ::GetConsoleWindow(); - // 关闭控制台 - if (debug_mode_) - { - if (console) + if (hwnd_ == nullptr) { - ::ShowWindow(console, SW_SHOWNORMAL); + ::UnregisterClass(REGISTER_CLASS, hinstance); + throw std::runtime_error("Create window failed"); + return; + } + + ::SetWindowLongPtrW( + hwnd_, + GWLP_USERDATA, + PtrToUlong(this) + ); + + // 初始化设备 + Device::Init(hwnd_); + + // 禁用输入法 + ::ImmAssociateContext(hwnd_, nullptr); + + // 若开启了调试模式,打开控制台 + HWND console = ::GetConsoleWindow(); + // 关闭控制台 + if (debug_mode_) + { + if (console) + { + ::ShowWindow(console, SW_SHOWNORMAL); + } + else + { + // 显示一个新控制台 + if (::AllocConsole()) + { + console = ::GetConsoleWindow(); + // 重定向输入输出 + FILE * stdoutStream, *stdinStream, *stderrStream; + freopen_s(&stdoutStream, "conout$", "w+t", stdout); + freopen_s(&stdinStream, "conin$", "r+t", stdin); + freopen_s(&stderrStream, "conout$", "w+t", stderr); + // 禁用控制台关闭按钮 + HMENU hmenu = ::GetSystemMenu(console, FALSE); + ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); + } + } } else { - // 显示一个新控制台 - if (::AllocConsole()) + if (console) { - console = ::GetConsoleWindow(); - // 重定向输入输出 - FILE * stdoutStream, *stdinStream, *stderrStream; - freopen_s(&stdoutStream, "conout$", "w+t", stdout); - freopen_s(&stdinStream, "conin$", "r+t", stdin); - freopen_s(&stderrStream, "conout$", "w+t", stderr); - // 禁用控制台关闭按钮 - HMENU hmenu = ::GetSystemMenu(console, FALSE); - ::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); + ::ShowWindow(console, SW_HIDE); } } - } - else - { - if (console) - { - ::ShowWindow(console, SW_HIDE); - } + + quit_ = false; } - quit_ = false; -} - -easy2d::Rect easy2d::Game::Locate(int width, int height) -{ - int max_width = ::GetSystemMetrics(SM_CXSCREEN); - int max_height = ::GetSystemMetrics(SM_CYSCREEN); - - float dpi = Graphics::GetDpi(); - RECT rect = { 0, 0, LONG(ceil(width * dpi / 96.f)), LONG(ceil(height * dpi / 96.f)) }; - - // 计算合适的窗口大小 - ::AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, NULL); - width = static_cast(rect.right - rect.left); - height = static_cast(rect.bottom - rect.top); - - // 当输入的窗口大小比分辨率大时,给出警告 - E2D_WARNING_IF(max_width < width || max_height < height, "The window Is larger than screen!"); - width = std::min(width, max_width); - height = std::min(height, max_height); - - return Rect( - static_cast((max_width - width) / 2), - static_cast((max_height - height) / 2), - static_cast(width), - static_cast(height) - ); -} - -int easy2d::Game::GetWidth() const -{ - return width_; -} - -int easy2d::Game::GetHeight() const -{ - return height_; -} - -easy2d::Size easy2d::Game::GetSize() const -{ - return easy2d::Size( - static_cast(width_), - static_cast(height_) - ); -} - -HWND easy2d::Game::GetHWnd() const -{ - return hwnd_; -} - -const std::wstring& easy2d::Game::GetTitle() const -{ - return title_; -} - -void easy2d::Game::SetSize(int width, int height) -{ - if (width_ == width && height_ == height) - return; - - width_ = width; - height_ = height; - - if (hwnd_) + Rect Game::Locate(int width, int height) { - Rect rect = Locate(width, height); - ::MoveWindow( - hwnd_, - int(rect.origin.x), - int(rect.origin.y), - int(rect.size.width), - int(rect.size.height), - TRUE + int max_width = ::GetSystemMetrics(SM_CXSCREEN); + int max_height = ::GetSystemMetrics(SM_CYSCREEN); + + float dpi = Graphics::GetDpi(); + RECT rect = { 0, 0, LONG(ceil(width * dpi / 96.f)), LONG(ceil(height * dpi / 96.f)) }; + + // 计算合适的窗口大小 + ::AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, NULL); + width = static_cast(rect.right - rect.left); + height = static_cast(rect.bottom - rect.top); + + // 当输入的窗口大小比分辨率大时,给出警告 + E2D_WARNING_IF(max_width < width || max_height < height, "The window Is larger than screen!"); + width = std::min(width, max_width); + height = std::min(height, max_height); + + return Rect( + static_cast((max_width - width) / 2), + static_cast((max_height - height) / 2), + static_cast(width), + static_cast(height) ); } -} -void easy2d::Game::SetTitle(const std::wstring& title) -{ - title_ = title; - - if (hwnd_) + int Game::GetWidth() const { - ::SetWindowText(hwnd_, title.c_str()); + return width_; } -} -void easy2d::Game::SetIcon(int resource_id) -{ - icon_ = resource_id; - - if (hwnd_) + int Game::GetHeight() const { - HINSTANCE hinstance = GetModuleHandle(nullptr); - HICON icon = (HICON)::LoadImage( - hinstance, - MAKEINTRESOURCE(resource_id), - IMAGE_ICON, - 0, - 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE + return height_; + } + + Size Game::GetSize() const + { + return Size( + static_cast(width_), + static_cast(height_) ); - - ::SendMessage(hwnd_, WM_SETICON, ICON_BIG, (LPARAM)icon); - ::SendMessage(hwnd_, WM_SETICON, ICON_SMALL, (LPARAM)icon); } -} -void easy2d::Game::SetDebugMode(bool enabled) -{ - debug_mode_ = enabled; -} - - -LRESULT easy2d::Game::WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param) -{ - LRESULT result = 0; - bool was_handled = false; - Game * game = reinterpret_cast( - static_cast(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)) - ); - - switch (msg) + HWND Game::GetHWnd() const { + return hwnd_; + } - // 处理鼠标消息 - case WM_LBUTTONUP: - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - case WM_MOUSEMOVE: - case WM_MOUSEWHEEL: + const std::wstring& Game::GetTitle() const { - if (game->IsTransitioning()) - break; + return title_; + } - auto curr_scene = game->GetCurrentScene(); - if (curr_scene) + void Game::SetSize(int width, int height) + { + if (width_ == width && height_ == height) + return; + + width_ = width; + height_ = height; + + if (hwnd_) { - curr_scene->Dispatch(MouseEvent(msg, w_param, l_param)); + Rect rect = Locate(width, height); + ::MoveWindow( + hwnd_, + int(rect.origin.x), + int(rect.origin.y), + int(rect.size.width), + int(rect.size.height), + TRUE + ); } } - result = 0; - was_handled = true; - break; - // 处理按键消息 - case WM_KEYDOWN: - case WM_KEYUP: + void Game::SetTitle(const std::wstring& title) { - if (game->IsTransitioning()) - break; + title_ = title; - auto curr_scene = game->GetCurrentScene(); - if (curr_scene) + if (hwnd_) { - curr_scene->Dispatch(KeyEvent(msg, w_param, l_param)); + ::SetWindowText(hwnd_, title.c_str()); } } - result = 0; - was_handled = true; - break; - // 处理窗口大小变化消息 - case WM_SIZE: + void Game::SetIcon(int resource_id) { - UINT width = LOWORD(l_param); - UINT height = HIWORD(l_param); + icon_ = resource_id; - if (w_param == SIZE_RESTORED) + if (hwnd_) { - float dpi = Graphics::GetDpi(); - game->width_ = static_cast(width * 96.f / dpi); - game->height_ = static_cast(height * 96.f / dpi); - } + HINSTANCE hinstance = GetModuleHandle(nullptr); + HICON icon = (HICON)::LoadImage( + hinstance, + MAKEINTRESOURCE(resource_id), + IMAGE_ICON, + 0, + 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE + ); - // 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染 - // 目标的大小。它可能会调用失败,但是这里可以忽略有可能的 - // 错误,因为这个错误将在下一次调用 EndDraw 时产生 - auto render_target = Device::GetGraphics()->GetRenderTarget(); - if (render_target) - { - render_target->Resize(D2D1::SizeU(width, height)); + ::SendMessage(hwnd_, WM_SETICON, ICON_BIG, (LPARAM)icon); + ::SendMessage(hwnd_, WM_SETICON, ICON_SMALL, (LPARAM)icon); } } - break; - // 处理窗口标题变化消息 - case WM_SETTEXT: + void Game::SetDebugMode(bool enabled) { - game->title_ = (const wchar_t*)l_param; + debug_mode_ = enabled; } - break; - // 处理分辨率变化消息 - case WM_DISPLAYCHANGE: - { - // 重绘客户区 - ::InvalidateRect(hwnd, nullptr, FALSE); - } - result = 0; - was_handled = true; - break; - // 重绘窗口 - case WM_PAINT: + LRESULT Game::WndProc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { - game->DrawScene(); - ::ValidateRect(hwnd, nullptr); - } - result = 0; - was_handled = true; - break; + LRESULT result = 0; + bool was_handled = false; + Game * game = reinterpret_cast( + static_cast(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)) + ); - // 窗口关闭消息 - case WM_CLOSE: - { - if (game->OnClose()) + switch (msg) { - game->Quit(); + + // 处理鼠标消息 + case WM_LBUTTONUP: + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + { + if (game->IsTransitioning()) + break; + + auto curr_scene = game->GetCurrentScene(); + if (curr_scene) + { + curr_scene->Dispatch(MouseEvent(msg, w_param, l_param)); + } } - } - result = 0; - was_handled = true; - break; + result = 0; + was_handled = true; + break; - // 窗口销毁消息 - case WM_DESTROY: - { - ::PostQuitMessage(0); - } - result = 1; - was_handled = true; - break; + // 处理按键消息 + case WM_KEYDOWN: + case WM_KEYUP: + { + if (game->IsTransitioning()) + break; - } + auto curr_scene = game->GetCurrentScene(); + if (curr_scene) + { + curr_scene->Dispatch(KeyEvent(msg, w_param, l_param)); + } + } + result = 0; + was_handled = true; + break; - if (!was_handled) - { - result = ::DefWindowProc(hwnd, msg, w_param, l_param); + // 处理窗口大小变化消息 + case WM_SIZE: + { + UINT width = LOWORD(l_param); + UINT height = HIWORD(l_param); + + if (w_param == SIZE_RESTORED) + { + float dpi = Graphics::GetDpi(); + game->width_ = static_cast(width * 96.f / dpi); + game->height_ = static_cast(height * 96.f / dpi); + } + + // 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染 + // 目标的大小。它可能会调用失败,但是这里可以忽略有可能的 + // 错误,因为这个错误将在下一次调用 EndDraw 时产生 + auto render_target = Device::GetGraphics()->GetRenderTarget(); + if (render_target) + { + render_target->Resize(D2D1::SizeU(width, height)); + } + } + break; + + // 处理窗口标题变化消息 + case WM_SETTEXT: + { + game->title_ = (const wchar_t*)l_param; + } + break; + + // 处理分辨率变化消息 + case WM_DISPLAYCHANGE: + { + // 重绘客户区 + ::InvalidateRect(hwnd, nullptr, FALSE); + } + result = 0; + was_handled = true; + break; + + // 重绘窗口 + case WM_PAINT: + { + game->DrawScene(); + ::ValidateRect(hwnd, nullptr); + } + result = 0; + was_handled = true; + break; + + // 窗口关闭消息 + case WM_CLOSE: + { + if (game->OnClose()) + { + game->Quit(); + } + } + result = 0; + was_handled = true; + break; + + // 窗口销毁消息 + case WM_DESTROY: + { + ::PostQuitMessage(0); + } + result = 1; + was_handled = true; + break; + + } + + if (!was_handled) + { + result = ::DefWindowProc(hwnd, msg, w_param, l_param); + } + return result; } - return result; -} +} \ No newline at end of file diff --git a/core/modules/Graphics.cpp b/core/modules/Graphics.cpp index 1474096d..d26dfc2d 100644 --- a/core/modules/Graphics.cpp +++ b/core/modules/Graphics.cpp @@ -24,7 +24,10 @@ namespace easy2d { - // 文字渲染器 + //------------------------------------------------------- + // TextRenderer + //------------------------------------------------------- + class TextRenderer : public IDWriteTextRenderer { @@ -505,320 +508,324 @@ namespace easy2d return S_OK; } -} -easy2d::Graphics::Graphics(HWND hwnd) - : factory_(nullptr) - , imaging_factory_(nullptr) - , write_factory_(nullptr) - , miter_stroke_style_(nullptr) - , bevel_stroke_style_(nullptr) - , round_stroke_style_(nullptr) - , fps_text_format_(nullptr) - , fps_text_layout_(nullptr) - , render_target_(nullptr) - , solid_brush_(nullptr) - , text_renderer_(nullptr) - , clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) -{ - ThrowIfFailed( - D2D1CreateFactory( - D2D1_FACTORY_TYPE_SINGLE_THREADED, - &factory_ - ) - ); + //------------------------------------------------------- + // Graphics + //------------------------------------------------------- - ThrowIfFailed( - CoCreateInstance( - CLSID_WICImagingFactory, - nullptr, - CLSCTX_INPROC_SERVER, - IID_IWICImagingFactory, - reinterpret_cast(&imaging_factory_) - ) - ); - - ThrowIfFailed( - DWriteCreateFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast(&write_factory_) - ) - ); - - RECT rc; - ::GetClientRect(hwnd, &rc); - - D2D1_SIZE_U size = D2D1::SizeU( - rc.right - rc.left, - rc.bottom - rc.top - ); - - // 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建 - // 创建一个 Direct2D 渲染目标 - ThrowIfFailed( - factory_->CreateHwndRenderTarget( - D2D1::RenderTargetProperties(), - D2D1::HwndRenderTargetProperties( - hwnd, - size, - D2D1_PRESENT_OPTIONS_NONE), - &render_target_ - ) - ); - - // 创建画刷 - ThrowIfFailed( - render_target_->CreateSolidColorBrush( - D2D1::ColorF(D2D1::ColorF::White), - &solid_brush_ - ) - ); - - // 创建自定义的文字渲染器 - ThrowIfFailed( - TextRenderer::Create( - &text_renderer_, - factory_, - render_target_, - solid_brush_ - ) - ); -} - -easy2d::Graphics::~Graphics() -{ - SafeRelease(fps_text_format_); - SafeRelease(fps_text_layout_); - SafeRelease(text_renderer_); - SafeRelease(solid_brush_); - SafeRelease(render_target_); - - SafeRelease(miter_stroke_style_); - SafeRelease(bevel_stroke_style_); - SafeRelease(round_stroke_style_); - SafeRelease(factory_); - SafeRelease(imaging_factory_); - SafeRelease(write_factory_); -} - -void easy2d::Graphics::BeginDraw() -{ - render_target_->BeginDraw(); - render_target_->Clear(clear_color_); -} - -void easy2d::Graphics::EndDraw() -{ - HRESULT hr = render_target_->EndDraw(); - - if (hr == D2DERR_RECREATE_TARGET) + Graphics::Graphics(HWND hwnd) + : factory_(nullptr) + , imaging_factory_(nullptr) + , write_factory_(nullptr) + , miter_stroke_style_(nullptr) + , bevel_stroke_style_(nullptr) + , round_stroke_style_(nullptr) + , fps_text_format_(nullptr) + , fps_text_layout_(nullptr) + , render_target_(nullptr) + , solid_brush_(nullptr) + , text_renderer_(nullptr) + , clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) { - // 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源 - // 并在下一次调用时重建资源 - hr = S_OK; + ThrowIfFailed( + D2D1CreateFactory( + D2D1_FACTORY_TYPE_SINGLE_THREADED, + &factory_ + ) + ); + ThrowIfFailed( + CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IWICImagingFactory, + reinterpret_cast(&imaging_factory_) + ) + ); + + ThrowIfFailed( + DWriteCreateFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&write_factory_) + ) + ); + + RECT rc; + ::GetClientRect(hwnd, &rc); + + D2D1_SIZE_U size = D2D1::SizeU( + rc.right - rc.left, + rc.bottom - rc.top + ); + + // 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建 + // 创建一个 Direct2D 渲染目标 + ThrowIfFailed( + factory_->CreateHwndRenderTarget( + D2D1::RenderTargetProperties(), + D2D1::HwndRenderTargetProperties( + hwnd, + size, + D2D1_PRESENT_OPTIONS_NONE), + &render_target_ + ) + ); + + // 创建画刷 + ThrowIfFailed( + render_target_->CreateSolidColorBrush( + D2D1::ColorF(D2D1::ColorF::White), + &solid_brush_ + ) + ); + + // 创建自定义的文字渲染器 + ThrowIfFailed( + TextRenderer::Create( + &text_renderer_, + factory_, + render_target_, + solid_brush_ + ) + ); + } + + Graphics::~Graphics() + { SafeRelease(fps_text_format_); SafeRelease(fps_text_layout_); SafeRelease(text_renderer_); SafeRelease(solid_brush_); SafeRelease(render_target_); + + SafeRelease(miter_stroke_style_); + SafeRelease(bevel_stroke_style_); + SafeRelease(round_stroke_style_); + SafeRelease(factory_); + SafeRelease(imaging_factory_); + SafeRelease(write_factory_); } - ThrowIfFailed(hr); -} - -void easy2d::Graphics::DrawDebugInfo() -{ - static int render_times_ = 0; - static Time last_render_time_ = Time::Now(); - int duration = (Time::Now() - last_render_time_).Milliseconds(); - - if (!fps_text_format_) + void Graphics::BeginDraw() { - ThrowIfFailed( - write_factory_->CreateTextFormat( - L"", + render_target_->BeginDraw(); + render_target_->Clear(clear_color_); + } + + void Graphics::EndDraw() + { + HRESULT hr = render_target_->EndDraw(); + + if (hr == D2DERR_RECREATE_TARGET) + { + // 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源 + // 并在下一次调用时重建资源 + hr = S_OK; + + SafeRelease(fps_text_format_); + SafeRelease(fps_text_layout_); + SafeRelease(text_renderer_); + SafeRelease(solid_brush_); + SafeRelease(render_target_); + } + + ThrowIfFailed(hr); + } + + void Graphics::DrawDebugInfo() + { + static int render_times_ = 0; + static Time last_render_time_ = Time::Now(); + int duration = (Time::Now() - last_render_time_).Milliseconds(); + + if (!fps_text_format_) + { + ThrowIfFailed( + write_factory_->CreateTextFormat( + L"", + nullptr, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + 20, + L"", + &fps_text_format_ + ) + ); + + ThrowIfFailed( + fps_text_format_->SetWordWrapping( + DWRITE_WORD_WRAPPING_NO_WRAP + ) + ); + } + + ++render_times_; + if (duration >= 100) + { + wchar_t fps_text[12] = {}; + int len = swprintf_s(fps_text, L"FPS: %.1f", 1000.f / duration * render_times_); + + last_render_time_ = Time::Now(); + render_times_ = 0; + + SafeRelease(fps_text_layout_); + + ThrowIfFailed( + write_factory_->CreateTextLayout( + fps_text, + static_cast(len), + fps_text_format_, + 0, + 0, + &fps_text_layout_ + ) + ); + } + + if (fps_text_layout_) + { + render_target_->SetTransform(D2D1::Matrix3x2F::Identity()); + solid_brush_->SetOpacity(1.0f); + static_cast(text_renderer_)->SetTextStyle( + D2D1::ColorF(D2D1::ColorF::White), + TRUE, + D2D1::ColorF(D2D1::ColorF::Black, 0.4f), + 1.5f, + D2D1_LINE_JOIN_ROUND + ); + + fps_text_layout_->Draw( nullptr, - DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - 20, - L"", - &fps_text_format_ - ) - ); - - ThrowIfFailed( - fps_text_format_->SetWordWrapping( - DWRITE_WORD_WRAPPING_NO_WRAP - ) - ); + text_renderer_, + 10, + 0 + ); + } } - ++render_times_; - if (duration >= 100) + ID2D1HwndRenderTarget * Graphics::GetRenderTarget() const { - wchar_t fps_text[12] = {}; - int len = swprintf_s(fps_text, L"FPS: %.1f", 1000.f / duration * render_times_); - - last_render_time_ = Time::Now(); - render_times_ = 0; - - SafeRelease(fps_text_layout_); - - ThrowIfFailed( - write_factory_->CreateTextLayout( - fps_text, - static_cast(len), - fps_text_format_, - 0, - 0, - &fps_text_layout_ - ) - ); + return render_target_; } - if (fps_text_layout_) + ID2D1SolidColorBrush * Graphics::GetSolidBrush() const + { + return solid_brush_; + } + + IDWriteTextRenderer* Graphics::GetTextRender() const + { + return text_renderer_; + } + + ID2D1Factory * Graphics::GetFactory() const + { + return factory_; + } + + IWICImagingFactory * Graphics::GetImagingFactory() const + { + return imaging_factory_; + } + + IDWriteFactory * Graphics::GetWriteFactory() const + { + return write_factory_; + } + + ID2D1StrokeStyle * Graphics::GetMiterStrokeStyle() + { + if (!miter_stroke_style_) + { + ThrowIfFailed( + factory_->CreateStrokeStyle( + D2D1::StrokeStyleProperties( + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_LINE_JOIN_MITER, + 2.0f, + D2D1_DASH_STYLE_SOLID, + 0.0f), + nullptr, + 0, + &miter_stroke_style_ + ) + ); + } + return miter_stroke_style_; + } + + ID2D1StrokeStyle * Graphics::GetBevelStrokeStyle() + { + if (!bevel_stroke_style_) + { + ThrowIfFailed( + factory_->CreateStrokeStyle( + D2D1::StrokeStyleProperties( + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_LINE_JOIN_BEVEL, + 2.0f, + D2D1_DASH_STYLE_SOLID, + 0.0f), + nullptr, + 0, + &bevel_stroke_style_ + ) + ); + } + return bevel_stroke_style_; + } + + ID2D1StrokeStyle * Graphics::GetRoundStrokeStyle() + { + if (!round_stroke_style_) + { + ThrowIfFailed( + factory_->CreateStrokeStyle( + D2D1::StrokeStyleProperties( + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_CAP_STYLE_FLAT, + D2D1_LINE_JOIN_ROUND, + 2.0f, + D2D1_DASH_STYLE_SOLID, + 0.0f), + nullptr, + 0, + &round_stroke_style_ + ) + ); + } + return round_stroke_style_; + } + + void Graphics::SetTextRendererStyle(const Color & fill_color, bool has_outline, const Color & outline_color, float outline_width, Stroke outline_stroke) { - render_target_->SetTransform(D2D1::Matrix3x2F::Identity()); - solid_brush_->SetOpacity(1.0f); static_cast(text_renderer_)->SetTextStyle( - D2D1::ColorF(D2D1::ColorF::White), - TRUE, - D2D1::ColorF(D2D1::ColorF::Black, 0.4f), - 1.5f, - D2D1_LINE_JOIN_ROUND - ); - - fps_text_layout_->Draw( - nullptr, - text_renderer_, - 10, - 0 + D2D1_COLOR_F(fill_color), + has_outline, + D2D1_COLOR_F(outline_color), + outline_width, + D2D1_LINE_JOIN(outline_stroke) ); } -} -ID2D1HwndRenderTarget * easy2d::Graphics::GetRenderTarget() const -{ - return render_target_; -} - -ID2D1SolidColorBrush * easy2d::Graphics::GetSolidBrush() const -{ - return solid_brush_; -} - -IDWriteTextRenderer* easy2d::Graphics::GetTextRender() const -{ - return text_renderer_; -} - -ID2D1Factory * easy2d::Graphics::GetFactory() const -{ - return factory_; -} - -IWICImagingFactory * easy2d::Graphics::GetImagingFactory() const -{ - return imaging_factory_; -} - -IDWriteFactory * easy2d::Graphics::GetWriteFactory() const -{ - return write_factory_; -} - -ID2D1StrokeStyle * easy2d::Graphics::GetMiterStrokeStyle() -{ - if (!miter_stroke_style_) + float Graphics::GetDpi() { - ThrowIfFailed( - factory_->CreateStrokeStyle( - D2D1::StrokeStyleProperties( - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_LINE_JOIN_MITER, - 2.0f, - D2D1_DASH_STYLE_SOLID, - 0.0f), - nullptr, - 0, - &miter_stroke_style_ - ) - ); + static float dpi = -1; + if (dpi < 0) + { + HDC hdc = ::GetDC(0); + dpi = static_cast(::GetDeviceCaps(hdc, LOGPIXELSX)); + ::ReleaseDC(0, hdc); + } + return dpi; } - return miter_stroke_style_; -} - -ID2D1StrokeStyle * easy2d::Graphics::GetBevelStrokeStyle() -{ - if (!bevel_stroke_style_) - { - ThrowIfFailed( - factory_->CreateStrokeStyle( - D2D1::StrokeStyleProperties( - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_LINE_JOIN_BEVEL, - 2.0f, - D2D1_DASH_STYLE_SOLID, - 0.0f), - nullptr, - 0, - &bevel_stroke_style_ - ) - ); - } - return bevel_stroke_style_; -} - -ID2D1StrokeStyle * easy2d::Graphics::GetRoundStrokeStyle() -{ - if (!round_stroke_style_) - { - ThrowIfFailed( - factory_->CreateStrokeStyle( - D2D1::StrokeStyleProperties( - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_CAP_STYLE_FLAT, - D2D1_LINE_JOIN_ROUND, - 2.0f, - D2D1_DASH_STYLE_SOLID, - 0.0f), - nullptr, - 0, - &round_stroke_style_ - ) - ); - } - return round_stroke_style_; -} - -void easy2d::Graphics::SetTextRendererStyle(const Color & fill_color, bool has_outline, const Color & outline_color, float outline_width, Stroke outline_stroke) -{ - static_cast(text_renderer_)->SetTextStyle( - D2D1_COLOR_F(fill_color), - has_outline, - D2D1_COLOR_F(outline_color), - outline_width, - D2D1_LINE_JOIN(outline_stroke) - ); -} - -float easy2d::Graphics::GetDpi() -{ - static float dpi = -1; - if (dpi < 0) - { - HDC hdc = ::GetDC(0); - dpi = static_cast(::GetDeviceCaps(hdc, LOGPIXELSX)); - ::ReleaseDC(0, hdc); - } - return dpi; -} +} \ No newline at end of file diff --git a/core/modules/Input.cpp b/core/modules/Input.cpp index 3861be53..96ceed47 100644 --- a/core/modules/Input.cpp +++ b/core/modules/Input.cpp @@ -22,151 +22,154 @@ #include "..\e2dtool.h" -easy2d::Input::Input(HWND hwnd) - : direct_input_(nullptr) - , keyboard_device_(nullptr) - , mouse_device_(nullptr) +namespace easy2d { - ZeroMemory(key_buffer_, sizeof(key_buffer_)); - ZeroMemory(&mouse_state_, sizeof(mouse_state_)); - - HINSTANCE hinstance = GetModuleHandle(nullptr); - - // 初始化接口对象 - ThrowIfFailed( - DirectInput8Create( - hinstance, - DIRECTINPUT_VERSION, - IID_IDirectInput8, - (void**)&direct_input_, - nullptr - ) - ); - - // 初始化键盘设备 - ThrowIfFailed( - direct_input_->CreateDevice( - GUID_SysKeyboard, - &keyboard_device_, - nullptr - ) - ); - - keyboard_device_->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); - keyboard_device_->SetDataFormat(&c_dfDIKeyboard); - keyboard_device_->Acquire(); - keyboard_device_->Poll(); - - // 初始化鼠标设备 - ThrowIfFailed( - direct_input_->CreateDevice( - GUID_SysMouse, - &mouse_device_, - nullptr - ) - ); - - mouse_device_->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); - mouse_device_->SetDataFormat(&c_dfDIMouse); - mouse_device_->Acquire(); - mouse_device_->Poll(); -} - -easy2d::Input::~Input() -{ - if (keyboard_device_) - keyboard_device_->Unacquire(); - if (mouse_device_) - mouse_device_->Unacquire(); - - SafeRelease(mouse_device_); - SafeRelease(keyboard_device_); - SafeRelease(direct_input_); -} - -void easy2d::Input::Flush() -{ - if (keyboard_device_) + Input::Input(HWND hwnd) + : direct_input_(nullptr) + , keyboard_device_(nullptr) + , mouse_device_(nullptr) { - HRESULT hr = keyboard_device_->Poll(); - if (FAILED(hr)) + ZeroMemory(key_buffer_, sizeof(key_buffer_)); + ZeroMemory(&mouse_state_, sizeof(mouse_state_)); + + HINSTANCE hinstance = GetModuleHandle(nullptr); + + // 初始化接口对象 + ThrowIfFailed( + DirectInput8Create( + hinstance, + DIRECTINPUT_VERSION, + IID_IDirectInput8, + (void**)&direct_input_, + nullptr + ) + ); + + // 初始化键盘设备 + ThrowIfFailed( + direct_input_->CreateDevice( + GUID_SysKeyboard, + &keyboard_device_, + nullptr + ) + ); + + keyboard_device_->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); + keyboard_device_->SetDataFormat(&c_dfDIKeyboard); + keyboard_device_->Acquire(); + keyboard_device_->Poll(); + + // 初始化鼠标设备 + ThrowIfFailed( + direct_input_->CreateDevice( + GUID_SysMouse, + &mouse_device_, + nullptr + ) + ); + + mouse_device_->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); + mouse_device_->SetDataFormat(&c_dfDIMouse); + mouse_device_->Acquire(); + mouse_device_->Poll(); + } + + Input::~Input() + { + if (keyboard_device_) + keyboard_device_->Unacquire(); + if (mouse_device_) + mouse_device_->Unacquire(); + + SafeRelease(mouse_device_); + SafeRelease(keyboard_device_); + SafeRelease(direct_input_); + } + + void Input::Flush() + { + if (keyboard_device_) { - hr = keyboard_device_->Acquire(); - while (hr == DIERR_INPUTLOST) + HRESULT hr = keyboard_device_->Poll(); + if (FAILED(hr)) + { hr = keyboard_device_->Acquire(); + while (hr == DIERR_INPUTLOST) + hr = keyboard_device_->Acquire(); + } + else + { + keyboard_device_->GetDeviceState( + sizeof(key_buffer_), + (void**)&key_buffer_ + ); + } } - else - { - keyboard_device_->GetDeviceState( - sizeof(key_buffer_), - (void**)&key_buffer_ - ); - } - } - if (mouse_device_) - { - HRESULT hr = mouse_device_->Poll(); - if (FAILED(hr)) + if (mouse_device_) { - hr = mouse_device_->Acquire(); - while (hr == DIERR_INPUTLOST) + HRESULT hr = mouse_device_->Poll(); + if (FAILED(hr)) + { hr = mouse_device_->Acquire(); - } - else - { - mouse_device_->GetDeviceState( - sizeof(mouse_state_), - (void**)&mouse_state_ - ); + while (hr == DIERR_INPUTLOST) + hr = mouse_device_->Acquire(); + } + else + { + mouse_device_->GetDeviceState( + sizeof(mouse_state_), + (void**)&mouse_state_ + ); + } } } -} -bool easy2d::Input::IsDown(KeyCode key) -{ - if (key_buffer_[static_cast(key)] & 0x80) - return true; - return false; -} + bool Input::IsDown(KeyCode key) + { + if (key_buffer_[static_cast(key)] & 0x80) + return true; + return false; + } -bool easy2d::Input::IsDown(MouseCode code) -{ - if (mouse_state_.rgbButtons[static_cast(code)] & 0x80) - return true; - return false; -} + bool Input::IsDown(MouseCode code) + { + if (mouse_state_.rgbButtons[static_cast(code)] & 0x80) + return true; + return false; + } -float easy2d::Input::GetMouseX() -{ - return GetMousePos().x; -} + float Input::GetMouseX() + { + return GetMousePos().x; + } -float easy2d::Input::GetMouseY() -{ - return GetMousePos().y; -} + float Input::GetMouseY() + { + return GetMousePos().y; + } -easy2d::Point easy2d::Input::GetMousePos() -{ - POINT mousePos; - ::GetCursorPos(&mousePos); - ::ScreenToClient(Game::GetInstance()->GetHWnd(), &mousePos); - float dpi = Graphics::GetDpi(); - return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi); -} + Point Input::GetMousePos() + { + POINT mousePos; + ::GetCursorPos(&mousePos); + ::ScreenToClient(Game::GetInstance()->GetHWnd(), &mousePos); + float dpi = Graphics::GetDpi(); + return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi); + } -float easy2d::Input::GetMouseDeltaX() -{ - return (float)mouse_state_.lX; -} + float Input::GetMouseDeltaX() + { + return (float)mouse_state_.lX; + } -float easy2d::Input::GetMouseDeltaY() -{ - return (float)mouse_state_.lY; -} + float Input::GetMouseDeltaY() + { + return (float)mouse_state_.lY; + } -float easy2d::Input::GetMouseDeltaZ() -{ - return (float)mouse_state_.lZ; -} + float Input::GetMouseDeltaZ() + { + return (float)mouse_state_.lZ; + } +} \ No newline at end of file diff --git a/core/objects/Canvas.cpp b/core/objects/Canvas.cpp index 03ecf4b4..d21e8011 100644 --- a/core/objects/Canvas.cpp +++ b/core/objects/Canvas.cpp @@ -21,230 +21,233 @@ #include "..\e2dobject.h" #include "..\e2dmodule.h" -easy2d::Canvas::Canvas(float width, float height) - : render_target_(nullptr) - , fill_brush_(nullptr) - , line_brush_(nullptr) - , stroke_style_(nullptr) - , stroke_width_(1.0f) - , stroke_(Stroke::Miter) +namespace easy2d { - render_target_ = Device::GetGraphics()->GetRenderTarget(); - render_target_->AddRef(); - - ThrowIfFailed( - render_target_->CreateSolidColorBrush( - D2D1::ColorF(D2D1::ColorF::White), - &fill_brush_ - ) - ); - - ThrowIfFailed( - render_target_->CreateSolidColorBrush( - D2D1::ColorF(D2D1::ColorF::White), - &line_brush_ - ) - ); - - this->SetClipEnabled(true); - this->SetWidth(width); - this->SetHeight(height); - this->SetStrokeStyle(stroke_); -} - -easy2d::Canvas::~Canvas() -{ - SafeRelease(line_brush_); - SafeRelease(fill_brush_); - SafeRelease(render_target_); -} - -void easy2d::Canvas::SetLineColor(const Color & color) -{ - line_brush_->SetColor(D2D_COLOR_F(color)); -} - -void easy2d::Canvas::SetFillColor(const Color & color) -{ - fill_brush_->SetColor(D2D_COLOR_F(color)); -} - -void easy2d::Canvas::SetStrokeWidth(float width) -{ - stroke_width_ = std::max(width, 0.f); -} - -void easy2d::Canvas::SetStrokeStyle(Stroke strokeStyle) -{ - switch (strokeStyle) + Canvas::Canvas(float width, float height) + : render_target_(nullptr) + , fill_brush_(nullptr) + , line_brush_(nullptr) + , stroke_style_(nullptr) + , stroke_width_(1.0f) + , stroke_(Stroke::Miter) { - case easy2d::Stroke::Miter: - stroke_style_ = Device::GetGraphics()->GetMiterStrokeStyle(); - break; - case easy2d::Stroke::Bevel: - stroke_style_ = Device::GetGraphics()->GetBevelStrokeStyle(); - break; - case easy2d::Stroke::Round: - stroke_style_ = Device::GetGraphics()->GetRoundStrokeStyle(); - break; + render_target_ = Device::GetGraphics()->GetRenderTarget(); + render_target_->AddRef(); + + ThrowIfFailed( + render_target_->CreateSolidColorBrush( + D2D1::ColorF(D2D1::ColorF::White), + &fill_brush_ + ) + ); + + ThrowIfFailed( + render_target_->CreateSolidColorBrush( + D2D1::ColorF(D2D1::ColorF::White), + &line_brush_ + ) + ); + + this->SetClipEnabled(true); + this->SetWidth(width); + this->SetHeight(height); + this->SetStrokeStyle(stroke_); } -} -easy2d::Color easy2d::Canvas::GetLineColor() const -{ - return line_brush_->GetColor(); -} + Canvas::~Canvas() + { + SafeRelease(line_brush_); + SafeRelease(fill_brush_); + SafeRelease(render_target_); + } -easy2d::Color easy2d::Canvas::GetFillColor() const -{ - return fill_brush_->GetColor(); -} + void Canvas::SetLineColor(const Color & color) + { + line_brush_->SetColor(D2D_COLOR_F(color)); + } -float easy2d::Canvas::GetStrokeWidth() const -{ - return stroke_width_; -} + void Canvas::SetFillColor(const Color & color) + { + fill_brush_->SetColor(D2D_COLOR_F(color)); + } -easy2d::Stroke easy2d::Canvas::GetStrokeStyle() const -{ - return stroke_; -} + void Canvas::SetStrokeWidth(float width) + { + stroke_width_ = std::max(width, 0.f); + } -void easy2d::Canvas::DrawLine(const Point & begin, const Point & end) -{ - render_target_->DrawLine( - D2D1::Point2F(begin.x, begin.y), - D2D1::Point2F(end.x, end.y), - line_brush_, - stroke_width_, - stroke_style_ - ); -} + void Canvas::SetStrokeStyle(Stroke strokeStyle) + { + switch (strokeStyle) + { + case Stroke::Miter: + stroke_style_ = Device::GetGraphics()->GetMiterStrokeStyle(); + break; + case Stroke::Bevel: + stroke_style_ = Device::GetGraphics()->GetBevelStrokeStyle(); + break; + case Stroke::Round: + stroke_style_ = Device::GetGraphics()->GetRoundStrokeStyle(); + break; + } + } -void easy2d::Canvas::DrawCircle(const Point & center, float radius) -{ - render_target_->DrawEllipse( - D2D1::Ellipse( - D2D1::Point2F( - center.x, - center.y + Color Canvas::GetLineColor() const + { + return line_brush_->GetColor(); + } + + Color Canvas::GetFillColor() const + { + return fill_brush_->GetColor(); + } + + float Canvas::GetStrokeWidth() const + { + return stroke_width_; + } + + Stroke Canvas::GetStrokeStyle() const + { + return stroke_; + } + + void Canvas::DrawLine(const Point & begin, const Point & end) + { + render_target_->DrawLine( + D2D1::Point2F(begin.x, begin.y), + D2D1::Point2F(end.x, end.y), + line_brush_, + stroke_width_, + stroke_style_ + ); + } + + void Canvas::DrawCircle(const Point & center, float radius) + { + render_target_->DrawEllipse( + D2D1::Ellipse( + D2D1::Point2F( + center.x, + center.y + ), + radius, + radius ), - radius, - radius - ), - line_brush_, - stroke_width_, - stroke_style_ - ); -} + line_brush_, + stroke_width_, + stroke_style_ + ); + } -void easy2d::Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y) -{ - render_target_->DrawEllipse( - D2D1::Ellipse( - D2D1::Point2F( - center.x, - center.y + void Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y) + { + render_target_->DrawEllipse( + D2D1::Ellipse( + D2D1::Point2F( + center.x, + center.y + ), + radius_x, + radius_y ), - radius_x, - radius_y - ), - line_brush_, - stroke_width_, - stroke_style_ - ); -} + line_brush_, + stroke_width_, + stroke_style_ + ); + } -void easy2d::Canvas::DrawRect(const Rect & rect) -{ - render_target_->DrawRectangle( - D2D1::RectF( - rect.origin.x, - rect.origin.y, - rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height - ), - line_brush_, - stroke_width_, - stroke_style_ - ); -} - -void easy2d::Canvas::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y) -{ - render_target_->DrawRoundedRectangle( - D2D1::RoundedRect( + void Canvas::DrawRect(const Rect & rect) + { + render_target_->DrawRectangle( D2D1::RectF( rect.origin.x, rect.origin.y, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height ), - radius_x, - radius_y - ), - line_brush_, - stroke_width_, - stroke_style_ - ); -} + line_brush_, + stroke_width_, + stroke_style_ + ); + } -void easy2d::Canvas::FillCircle(const Point & center, float radius) -{ - render_target_->FillEllipse( - D2D1::Ellipse( - D2D1::Point2F( - center.x, - center.y + void Canvas::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y) + { + render_target_->DrawRoundedRectangle( + D2D1::RoundedRect( + D2D1::RectF( + rect.origin.x, + rect.origin.y, + rect.origin.x + rect.size.width, + rect.origin.y + rect.size.height + ), + radius_x, + radius_y ), - radius, - radius - ), - fill_brush_ - ); -} + line_brush_, + stroke_width_, + stroke_style_ + ); + } -void easy2d::Canvas::FillEllipse(const Point & center, float radius_x, float radius_y) -{ - render_target_->FillEllipse( - D2D1::Ellipse( - D2D1::Point2F( - center.x, - center.y + void Canvas::FillCircle(const Point & center, float radius) + { + render_target_->FillEllipse( + D2D1::Ellipse( + D2D1::Point2F( + center.x, + center.y + ), + radius, + radius ), - radius_x, - radius_y - ), - fill_brush_ - ); -} + fill_brush_ + ); + } -void easy2d::Canvas::FillRect(const Rect & rect) -{ - render_target_->FillRectangle( - D2D1::RectF( - rect.origin.x, - rect.origin.y, - rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height - ), - fill_brush_ - ); -} + void Canvas::FillEllipse(const Point & center, float radius_x, float radius_y) + { + render_target_->FillEllipse( + D2D1::Ellipse( + D2D1::Point2F( + center.x, + center.y + ), + radius_x, + radius_y + ), + fill_brush_ + ); + } -void easy2d::Canvas::FillRoundedRect(const Rect & rect, float radius_x, float radius_y) -{ - render_target_->FillRoundedRectangle( - D2D1::RoundedRect( + void Canvas::FillRect(const Rect & rect) + { + render_target_->FillRectangle( D2D1::RectF( rect.origin.x, rect.origin.y, rect.origin.x + rect.size.width, rect.origin.y + rect.size.height ), - radius_x, - radius_y - ), - fill_brush_ - ); -} + fill_brush_ + ); + } + + void Canvas::FillRoundedRect(const Rect & rect, float radius_x, float radius_y) + { + render_target_->FillRoundedRectangle( + D2D1::RoundedRect( + D2D1::RectF( + rect.origin.x, + rect.origin.y, + rect.origin.x + rect.size.width, + rect.origin.y + rect.size.height + ), + radius_x, + radius_y + ), + fill_brush_ + ); + } +} \ No newline at end of file diff --git a/core/objects/Image.cpp b/core/objects/Image.cpp index 6a2e1bf8..dec4fb7f 100644 --- a/core/objects/Image.cpp +++ b/core/objects/Image.cpp @@ -22,371 +22,374 @@ #include "..\e2dmodule.h" #include "..\e2dtool.h" -std::map easy2d::Image::bitmap_cache_; - -easy2d::Image::Image() - : bitmap_(nullptr) - , crop_rect_() +namespace easy2d { -} + std::map Image::bitmap_cache_; -easy2d::Image::Image(Resource& res) - : bitmap_(nullptr) - , crop_rect_() -{ - this->Load(res); -} - -easy2d::Image::Image(Resource& res, const Rect& crop_rect) - : bitmap_(nullptr) - , crop_rect_() -{ - this->Load(res); - this->Crop(crop_rect); -} - -easy2d::Image::Image(const std::wstring & file_name) - : bitmap_(nullptr) - , crop_rect_() -{ - this->Load(file_name); -} - -easy2d::Image::Image(const std::wstring & file_name, const Rect & crop_rect) - : bitmap_(nullptr) - , crop_rect_() -{ - this->Load(file_name); - this->Crop(crop_rect); -} - -easy2d::Image::~Image() -{ - SafeRelease(bitmap_); -} - -bool easy2d::Image::Load(Resource& res) -{ - if (!Image::CacheBitmap(res)) + Image::Image() + : bitmap_(nullptr) + , crop_rect_() { - E2D_WARNING("Load Image from file failed!"); - return false; } - this->SetBitmap(bitmap_cache_.at(res.GetHashCode())); - return true; -} - -bool easy2d::Image::Load(const std::wstring & file_name) -{ - E2D_WARNING_IF(file_name.empty(), "Image Load failed! Invalid file name."); - - if (file_name.empty()) - return false; - - if (!Image::CacheBitmap(file_name)) + Image::Image(Resource& res) + : bitmap_(nullptr) + , crop_rect_() { - E2D_WARNING("Load Image from file failed!"); - return false; + this->Load(res); } - this->SetBitmap(bitmap_cache_.at(std::hash{}(file_name))); - return true; -} - -void easy2d::Image::Crop(const Rect& crop_rect) -{ - if (bitmap_) + Image::Image(Resource& res, const Rect& crop_rect) + : bitmap_(nullptr) + , crop_rect_() { - auto bitmap_size = bitmap_->GetSize(); - crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.width); - crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.height); - crop_rect_.size.width = std::min(std::max(crop_rect.size.width, 0.f), bitmap_size.width - crop_rect.origin.x); - crop_rect_.size.height = std::min(std::max(crop_rect.size.height, 0.f), bitmap_size.height - crop_rect.origin.y); + this->Load(res); + this->Crop(crop_rect); } -} -float easy2d::Image::GetWidth() const -{ - return crop_rect_.size.width; -} - -float easy2d::Image::GetHeight() const -{ - return crop_rect_.size.height; -} - -easy2d::Size easy2d::Image::GetSize() const -{ - return crop_rect_.size; -} - -float easy2d::Image::GetSourceWidth() const -{ - if (bitmap_) + Image::Image(const std::wstring & file_name) + : bitmap_(nullptr) + , crop_rect_() { - return bitmap_->GetSize().width; + this->Load(file_name); } - else + + Image::Image(const std::wstring & file_name, const Rect & crop_rect) + : bitmap_(nullptr) + , crop_rect_() { - return 0; + this->Load(file_name); + this->Crop(crop_rect); } -} -float easy2d::Image::GetSourceHeight() const -{ - if (bitmap_) + Image::~Image() { - return bitmap_->GetSize().height; + SafeRelease(bitmap_); } - else + + bool Image::Load(Resource& res) { - return 0; - } -} + if (!Image::CacheBitmap(res)) + { + E2D_WARNING("Load Image from file failed!"); + return false; + } -easy2d::Size easy2d::Image::GetSourceSize() const -{ - if (bitmap_) - { - auto bitmap_size = bitmap_->GetSize(); - return Size{ bitmap_size.width, bitmap_size.height }; - } - return Size{}; -} - -float easy2d::Image::GetCropX() const -{ - return crop_rect_.origin.x; -} - -float easy2d::Image::GetCropY() const -{ - return crop_rect_.origin.y; -} - -easy2d::Point easy2d::Image::GetCropPos() const -{ - return crop_rect_.origin; -} - -const easy2d::Rect & easy2d::Image::GetCropRect() const -{ - return crop_rect_; -} - -ID2D1Bitmap * easy2d::Image::GetBitmap() const -{ - return bitmap_; -} - -bool easy2d::Image::CacheBitmap(Resource& res) -{ - size_t hash_code = res.GetHashCode(); - if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) - { + this->SetBitmap(bitmap_cache_.at(res.GetHashCode())); return true; } - HRESULT hr; - - HINSTANCE hinstance = GetModuleHandle(nullptr); - IWICImagingFactory* imaging_factory = Device::GetGraphics()->GetImagingFactory(); - ID2D1HwndRenderTarget* render_target = Device::GetGraphics()->GetRenderTarget(); - IWICBitmapDecoder* decoder = nullptr; - IWICBitmapFrameDecode* source = nullptr; - IWICStream* stream = nullptr; - IWICFormatConverter* converter = nullptr; - ID2D1Bitmap* bitmap = nullptr; - - // 加载资源 - hr = res.Load() ? S_OK : E_FAIL; - - if (SUCCEEDED(hr)) + bool Image::Load(const std::wstring & file_name) { - // 创建 WIC 流 - hr = imaging_factory->CreateStream(&stream); + E2D_WARNING_IF(file_name.empty(), "Image Load failed! Invalid file name."); + + if (file_name.empty()) + return false; + + if (!Image::CacheBitmap(file_name)) + { + E2D_WARNING("Load Image from file failed!"); + return false; + } + + this->SetBitmap(bitmap_cache_.at(std::hash{}(file_name))); + return true; } - if (SUCCEEDED(hr)) + void Image::Crop(const Rect& crop_rect) { - // 初始化流 - hr = stream->InitializeFromMemory( - static_cast(res.GetData()), - res.GetDataSize() - ); + if (bitmap_) + { + auto bitmap_size = bitmap_->GetSize(); + crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.width); + crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.height); + crop_rect_.size.width = std::min(std::max(crop_rect.size.width, 0.f), bitmap_size.width - crop_rect.origin.x); + crop_rect_.size.height = std::min(std::max(crop_rect.size.height, 0.f), bitmap_size.height - crop_rect.origin.y); + } } - if (SUCCEEDED(hr)) + float Image::GetWidth() const { - // 创建流的解码器 - hr = imaging_factory->CreateDecoderFromStream( - stream, + return crop_rect_.size.width; + } + + float Image::GetHeight() const + { + return crop_rect_.size.height; + } + + Size Image::GetSize() const + { + return crop_rect_.size; + } + + float Image::GetSourceWidth() const + { + if (bitmap_) + { + return bitmap_->GetSize().width; + } + else + { + return 0; + } + } + + float Image::GetSourceHeight() const + { + if (bitmap_) + { + return bitmap_->GetSize().height; + } + else + { + return 0; + } + } + + Size Image::GetSourceSize() const + { + if (bitmap_) + { + auto bitmap_size = bitmap_->GetSize(); + return Size{ bitmap_size.width, bitmap_size.height }; + } + return Size{}; + } + + float Image::GetCropX() const + { + return crop_rect_.origin.x; + } + + float Image::GetCropY() const + { + return crop_rect_.origin.y; + } + + Point Image::GetCropPos() const + { + return crop_rect_.origin; + } + + const Rect & Image::GetCropRect() const + { + return crop_rect_; + } + + ID2D1Bitmap * Image::GetBitmap() const + { + return bitmap_; + } + + bool Image::CacheBitmap(Resource& res) + { + size_t hash_code = res.GetHashCode(); + if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) + { + return true; + } + + HRESULT hr; + + HINSTANCE hinstance = GetModuleHandle(nullptr); + IWICImagingFactory* imaging_factory = Device::GetGraphics()->GetImagingFactory(); + ID2D1HwndRenderTarget* render_target = Device::GetGraphics()->GetRenderTarget(); + IWICBitmapDecoder* decoder = nullptr; + IWICBitmapFrameDecode* source = nullptr; + IWICStream* stream = nullptr; + IWICFormatConverter* converter = nullptr; + ID2D1Bitmap* bitmap = nullptr; + + // 加载资源 + hr = res.Load() ? S_OK : E_FAIL; + + if (SUCCEEDED(hr)) + { + // 创建 WIC 流 + hr = imaging_factory->CreateStream(&stream); + } + + if (SUCCEEDED(hr)) + { + // 初始化流 + hr = stream->InitializeFromMemory( + static_cast(res.GetData()), + res.GetDataSize() + ); + } + + if (SUCCEEDED(hr)) + { + // 创建流的解码器 + hr = imaging_factory->CreateDecoderFromStream( + stream, + nullptr, + WICDecodeMetadataCacheOnLoad, + &decoder + ); + } + + if (SUCCEEDED(hr)) + { + // 创建初始化框架 + hr = decoder->GetFrame(0, &source); + } + + if (SUCCEEDED(hr)) + { + // 创建图片格式转换器 + hr = imaging_factory->CreateFormatConverter(&converter); + } + + if (SUCCEEDED(hr)) + { + // 图片格式转换成 32bppPBGRA + hr = converter->Initialize( + source, + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + nullptr, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + + if (SUCCEEDED(hr)) + { + // 从 WIC 位图创建一个 Direct2D 位图 + hr = render_target->CreateBitmapFromWicBitmap( + converter, + nullptr, + &bitmap + ); + } + + if (SUCCEEDED(hr)) + { + bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); + } + + // 释放相关资源 + SafeRelease(decoder); + SafeRelease(source); + SafeRelease(stream); + SafeRelease(converter); + + return SUCCEEDED(hr); + } + + bool Image::CacheBitmap(const std::wstring & file_name) + { + size_t hash_code = std::hash{}(file_name); + if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) + return true; + + File image_file; + if (!image_file.Open(file_name)) + return false; + + // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加 + // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 + std::wstring image_file_path = image_file.GetPath(); + + Graphics* graphics_device = Device::GetGraphics(); + IWICImagingFactory* imaging_factory = graphics_device->GetImagingFactory(); + ID2D1HwndRenderTarget* render_target = graphics_device->GetRenderTarget(); + IWICBitmapDecoder* decoder = nullptr; + IWICBitmapFrameDecode* source = nullptr; + IWICStream* stream = nullptr; + IWICFormatConverter* converter = nullptr; + ID2D1Bitmap* bitmap = nullptr; + + // 创建解码器 + HRESULT hr = imaging_factory->CreateDecoderFromFilename( + image_file_path.c_str(), nullptr, + GENERIC_READ, WICDecodeMetadataCacheOnLoad, &decoder ); + + if (SUCCEEDED(hr)) + { + // 创建初始化框架 + hr = decoder->GetFrame(0, &source); + } + + if (SUCCEEDED(hr)) + { + // 创建图片格式转换器 + hr = imaging_factory->CreateFormatConverter(&converter); + } + + if (SUCCEEDED(hr)) + { + // 图片格式转换成 32bppPBGRA + hr = converter->Initialize( + source, + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + nullptr, + 0.f, + WICBitmapPaletteTypeMedianCut + ); + } + + if (SUCCEEDED(hr)) + { + // 从 WIC 位图创建一个 Direct2D 位图 + hr = render_target->CreateBitmapFromWicBitmap( + converter, + nullptr, + &bitmap + ); + } + + if (SUCCEEDED(hr)) + { + bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); + } + + // 释放相关资源 + SafeRelease(decoder); + SafeRelease(source); + SafeRelease(stream); + SafeRelease(converter); + + return SUCCEEDED(hr); } - if (SUCCEEDED(hr)) + void Image::ClearCache() { - // 创建初始化框架 - hr = decoder->GetFrame(0, &source); + if (bitmap_cache_.empty()) + return; + + for (const auto& bitmap : bitmap_cache_) + { + bitmap.second->Release(); + } + bitmap_cache_.clear(); } - if (SUCCEEDED(hr)) + void Image::SetBitmap(ID2D1Bitmap * bitmap) { - // 创建图片格式转换器 - hr = imaging_factory->CreateFormatConverter(&converter); + if (bitmap_ == bitmap) + return; + + if (bitmap_) + { + bitmap_->Release(); + } + + if (bitmap) + { + bitmap->AddRef(); + + bitmap_ = bitmap; + crop_rect_.origin.x = crop_rect_.origin.y = 0; + crop_rect_.size.width = bitmap_->GetSize().width; + crop_rect_.size.height = bitmap_->GetSize().height; + } } - - if (SUCCEEDED(hr)) - { - // 图片格式转换成 32bppPBGRA - hr = converter->Initialize( - source, - GUID_WICPixelFormat32bppPBGRA, - WICBitmapDitherTypeNone, - nullptr, - 0.f, - WICBitmapPaletteTypeMedianCut - ); - } - - if (SUCCEEDED(hr)) - { - // 从 WIC 位图创建一个 Direct2D 位图 - hr = render_target->CreateBitmapFromWicBitmap( - converter, - nullptr, - &bitmap - ); - } - - if (SUCCEEDED(hr)) - { - bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); - } - - // 释放相关资源 - SafeRelease(decoder); - SafeRelease(source); - SafeRelease(stream); - SafeRelease(converter); - - return SUCCEEDED(hr); -} - -bool easy2d::Image::CacheBitmap(const std::wstring & file_name) -{ - size_t hash_code = std::hash{}(file_name); - if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) - return true; - - File image_file; - if (!image_file.Open(file_name)) - return false; - - // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加 - // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 - std::wstring image_file_path = image_file.GetPath(); - - Graphics* graphics_device = Device::GetGraphics(); - IWICImagingFactory* imaging_factory = graphics_device->GetImagingFactory(); - ID2D1HwndRenderTarget* render_target = graphics_device->GetRenderTarget(); - IWICBitmapDecoder* decoder = nullptr; - IWICBitmapFrameDecode* source = nullptr; - IWICStream* stream = nullptr; - IWICFormatConverter* converter = nullptr; - ID2D1Bitmap* bitmap = nullptr; - - // 创建解码器 - HRESULT hr = imaging_factory->CreateDecoderFromFilename( - image_file_path.c_str(), - nullptr, - GENERIC_READ, - WICDecodeMetadataCacheOnLoad, - &decoder - ); - - if (SUCCEEDED(hr)) - { - // 创建初始化框架 - hr = decoder->GetFrame(0, &source); - } - - if (SUCCEEDED(hr)) - { - // 创建图片格式转换器 - hr = imaging_factory->CreateFormatConverter(&converter); - } - - if (SUCCEEDED(hr)) - { - // 图片格式转换成 32bppPBGRA - hr = converter->Initialize( - source, - GUID_WICPixelFormat32bppPBGRA, - WICBitmapDitherTypeNone, - nullptr, - 0.f, - WICBitmapPaletteTypeMedianCut - ); - } - - if (SUCCEEDED(hr)) - { - // 从 WIC 位图创建一个 Direct2D 位图 - hr = render_target->CreateBitmapFromWicBitmap( - converter, - nullptr, - &bitmap - ); - } - - if (SUCCEEDED(hr)) - { - bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); - } - - // 释放相关资源 - SafeRelease(decoder); - SafeRelease(source); - SafeRelease(stream); - SafeRelease(converter); - - return SUCCEEDED(hr); -} - -void easy2d::Image::ClearCache() -{ - if (bitmap_cache_.empty()) - return; - - for (const auto& bitmap : bitmap_cache_) - { - bitmap.second->Release(); - } - bitmap_cache_.clear(); -} - -void easy2d::Image::SetBitmap(ID2D1Bitmap * bitmap) -{ - if (bitmap_ == bitmap) - return; - - if (bitmap_) - { - bitmap_->Release(); - } - - if (bitmap) - { - bitmap->AddRef(); - - bitmap_ = bitmap; - crop_rect_.origin.x = crop_rect_.origin.y = 0; - crop_rect_.size.width = bitmap_->GetSize().width; - crop_rect_.size.height = bitmap_->GetSize().height; - } -} +} \ No newline at end of file diff --git a/core/objects/Node.cpp b/core/objects/Node.cpp index de2e9ba8..b85e4b41 100644 --- a/core/objects/Node.cpp +++ b/core/objects/Node.cpp @@ -25,1042 +25,1045 @@ #include -easy2d::Node::Node() - : visible_(true) - , parent_(nullptr) - , parent_scene_(nullptr) - , hash_name_(0) - , clip_enabled_(false) - , dirty_sort_(false) - , dirty_transform_(false) - , border_(nullptr) - , order_(0) - , transform_() - , display_opacity_(1.f) - , real_opacity_(1.f) - , children_() - , actions_() - , tasks_() - , initial_matrix_(D2D1::Matrix3x2F::Identity()) - , final_matrix_(D2D1::Matrix3x2F::Identity()) - , border_color_(Color::Red, 0.6f) +namespace easy2d { -} - -easy2d::Node::~Node() -{ - SafeRelease(border_); - - for (auto action : actions_) + Node::Node() + : visible_(true) + , parent_(nullptr) + , parent_scene_(nullptr) + , hash_name_(0) + , clip_enabled_(false) + , dirty_sort_(false) + , dirty_transform_(false) + , border_(nullptr) + , order_(0) + , transform_() + , display_opacity_(1.f) + , real_opacity_(1.f) + , children_() + , actions_() + , tasks_() + , initial_matrix_(D2D1::Matrix3x2F::Identity()) + , final_matrix_(D2D1::Matrix3x2F::Identity()) + , border_color_(Color::Red, 0.6f) { - SafeRelease(action); } - for (auto task : tasks_) + Node::~Node() { - SafeRelease(task); + SafeRelease(border_); + + for (auto action : actions_) + { + SafeRelease(action); + } + + for (auto task : tasks_) + { + SafeRelease(task); + } + + for (auto child : children_) + { + SafeRelease(child); + } } - for (auto child : children_) + void Node::Visit() { - SafeRelease(child); + if (!visible_) + return; + + auto render_target = Device::GetGraphics()->GetRenderTarget(); + if (clip_enabled_) + { + render_target->SetTransform(final_matrix_); + render_target->PushAxisAlignedClip( + D2D1::RectF(0, 0, transform_.size.width, transform_.size.height), + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE + ); + } + + if (children_.empty()) + { + render_target->SetTransform(final_matrix_); + OnDraw(); + } + else + { + // 子节点排序 + if (dirty_sort_) + { + std::sort( + std::begin(children_), + std::end(children_), + [](Node * n1, Node * n2) { return n1->GetOrder() < n2->GetOrder(); } + ); + + dirty_sort_ = false; + } + + size_t i; + for (i = 0; i < children_.size(); ++i) + { + auto child = children_[i]; + // 访问 Order 小于零的节点 + if (child->GetOrder() < 0) + { + child->Visit(); + } + else + { + break; + } + } + + render_target->SetTransform(final_matrix_); + OnDraw(); + + // 访问剩余节点 + for (; i < children_.size(); ++i) + children_[i]->Visit(); + } + + if (clip_enabled_) + { + render_target->PopAxisAlignedClip(); + } } -} -void easy2d::Node::Visit() -{ - if (!visible_) - return; - - auto render_target = Device::GetGraphics()->GetRenderTarget(); - if (clip_enabled_) + void Node::UpdateChildren(float dt) { - render_target->SetTransform(final_matrix_); - render_target->PushAxisAlignedClip( - D2D1::RectF(0, 0, transform_.size.width, transform_.size.height), - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE + if (children_.empty()) + { + OnUpdate(dt); + UpdateActions(); + UpdateTasks(); + UpdateTransform(); + } + else + { + size_t i; + for (i = 0; i < children_.size(); ++i) + { + auto child = children_[i]; + // 访问 Order 小于零的节点 + if (child->GetOrder() < 0) + { + child->UpdateChildren(dt); + } + else + { + break; + } + } + + OnUpdate(dt); + UpdateActions(); + UpdateTasks(); + UpdateTransform(); + + // 访问剩余节点 + for (; i < children_.size(); ++i) + children_[i]->UpdateChildren(dt); + } + } + + void Node::DrawBorder() + { + if (visible_) + { + if (border_) + { + auto graphics = Device::GetGraphics(); + auto brush = graphics->GetSolidBrush(); + brush->SetColor(D2D1_COLOR_F(border_color_)); + graphics->GetRenderTarget()->DrawGeometry( + border_, + brush, + 1.5f + ); + } + + for (const auto& child : children_) + { + child->DrawBorder(); + } + } + } + + void Node::UpdateTransform() + { + if (!dirty_transform_) + return; + + dirty_transform_ = false; + + final_matrix_ = static_cast(transform_); + + // 根据自身支点计算 Initial 矩阵,子节点将根据这个矩阵进行变换 + auto pivot = Point( + transform_.size.width * transform_.pivot_x, + transform_.size.height * transform_.pivot_y ); - } + initial_matrix_ = final_matrix_ * D2D1::Matrix3x2F::Translation(pivot.x, pivot.y); - if (children_.empty()) - { - render_target->SetTransform(final_matrix_); - OnDraw(); - } - else - { - // 子节点排序 - if (dirty_sort_) + if (parent_) { - std::sort( - std::begin(children_), - std::end(children_), - [](Node * n1, Node * n2) { return n1->GetOrder() < n2->GetOrder(); } - ); - - dirty_sort_ = false; + initial_matrix_ = initial_matrix_ * parent_->initial_matrix_; + final_matrix_ = final_matrix_ * parent_->initial_matrix_; + } + else if (parent_scene_) + { + initial_matrix_ = initial_matrix_ * parent_scene_->GetTransform(); + final_matrix_ = final_matrix_ * parent_scene_->GetTransform(); } - size_t i; - for (i = 0; i < children_.size(); ++i) + // 重新构造轮廓 + SafeRelease(border_); + + ID2D1Factory * factory = Device::GetGraphics()->GetFactory(); + ID2D1RectangleGeometry * rectangle = nullptr; + ID2D1TransformedGeometry * transformed = nullptr; + ThrowIfFailed( + factory->CreateRectangleGeometry( + D2D1::RectF(0, 0, transform_.size.width, transform_.size.height), + &rectangle + ) + ); + ThrowIfFailed( + factory->CreateTransformedGeometry( + rectangle, + final_matrix_, + &transformed + ) + ); + border_ = transformed; + + SafeRelease(rectangle); + + // 通知子节点进行转换 + for (const auto& child : children_) { - auto child = children_[i]; - // 访问 Order 小于零的节点 - if (child->GetOrder() < 0) + child->dirty_transform_ = true; + } + } + + bool Node::Dispatch(const MouseEvent & e, bool handled) + { + if (visible_) + { + for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter) + handled = (*riter)->Dispatch(e, handled); + + auto handler = dynamic_cast(this); + if (handler) + handler->Handle(e); + } + + return handled; + } + + bool Node::Dispatch(const KeyEvent & e, bool handled) + { + if (visible_) + { + for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter) + handled = (*riter)->Dispatch(e, handled); + + auto handler = dynamic_cast(this); + if (handler) + handler->Handle(e); + } + + return handled; + } + + void Node::UpdateOpacity() + { + if (parent_) + { + display_opacity_ = real_opacity_ * parent_->display_opacity_; + } + for (const auto& child : children_) + { + child->UpdateOpacity(); + } + } + + void Node::UpdateActions() + { + if (actions_.empty()) + return; + + std::vector currActions; + currActions.reserve(actions_.size()); + std::copy_if( + actions_.begin(), + actions_.end(), + std::back_inserter(currActions), + [](Action* action) { return action->IsRunning() && !action->IsDone(); } + ); + + // 遍历所有正在运行的动作 + for (const auto& action : currActions) + action->Update(); + + // 清除完成的动作 + for (auto iter = actions_.begin(); iter != actions_.end();) + { + if ((*iter)->IsDone()) { - child->Visit(); + (*iter)->Release(); + iter = actions_.erase(iter); } else { - break; + ++iter; } } - - render_target->SetTransform(final_matrix_); - OnDraw(); - - // 访问剩余节点 - for (; i < children_.size(); ++i) - children_[i]->Visit(); } - if (clip_enabled_) + bool Node::IsVisible() const { - render_target->PopAxisAlignedClip(); + return visible_; } -} -void easy2d::Node::UpdateChildren(float dt) -{ - if (children_.empty()) + const std::wstring& Node::GetName() const { - OnUpdate(dt); - UpdateActions(); - UpdateTasks(); - UpdateTransform(); + return name_; } - else + + size_t Node::GetHashName() const { - size_t i; - for (i = 0; i < children_.size(); ++i) + return hash_name_; + } + + const Point& Node::GetPosition() const + { + return transform_.position; + } + + float Node::GetWidth() const + { + return transform_.size.width * transform_.scale_x; + } + + float Node::GetHeight() const + { + return transform_.size.height * transform_.scale_y; + } + + float Node::GetRealWidth() const + { + return transform_.size.width; + } + + float Node::GetRealHeight() const + { + return transform_.size.height; + } + + const Size& Node::GetRealSize() const + { + return transform_.size; + } + + float Node::GetPivotX() const + { + return transform_.pivot_x; + } + + float Node::GetPivotY() const + { + return transform_.pivot_y; + } + + Size Node::GetSize() const + { + return Size{ GetWidth(), GetHeight() }; + } + + float Node::GetScaleX() const + { + return transform_.scale_x; + } + + float Node::GetScaleY() const + { + return transform_.scale_y; + } + + float Node::GetSkewX() const + { + return transform_.skew_x; + } + + float Node::GetSkewY() const + { + return transform_.skew_y; + } + + float Node::GetRotation() const + { + return transform_.rotation; + } + + const Transform & Node::GetTransform() const + { + return transform_; + } + + float Node::GetOpacity() const + { + return real_opacity_; + } + + float Node::GetDisplayOpacity() const + { + return display_opacity_; + } + + int Node::GetOrder() const + { + return order_; + } + + void Node::SetOrder(int order) + { + if (order_ == order) + return; + + order_ = order; + if (parent_) { - auto child = children_[i]; - // 访问 Order 小于零的节点 - if (child->GetOrder() < 0) - { - child->UpdateChildren(dt); - } - else - { - break; - } + parent_->dirty_sort_ = true; } - - OnUpdate(dt); - UpdateActions(); - UpdateTasks(); - UpdateTransform(); - - // 访问剩余节点 - for (; i < children_.size(); ++i) - children_[i]->UpdateChildren(dt); } -} -void easy2d::Node::DrawBorder() -{ - if (visible_) + void Node::SetPositionX(float x) { - if (border_) + this->SetPosition(x, transform_.position.y); + } + + void Node::SetPositionY(float y) + { + this->SetPosition(transform_.position.x, y); + } + + void Node::SetPosition(const Point & p) + { + this->SetPosition(p.x, p.y); + } + + void Node::SetPosition(float x, float y) + { + if (transform_.position.x == x && transform_.position.y == y) + return; + + transform_.position.x = x; + transform_.position.y = y; + dirty_transform_ = true; + } + + void Node::MoveBy(float x, float y) + { + this->SetPosition(transform_.position.x + x, transform_.position.y + y); + } + + void Node::MoveBy(const Point & v) + { + this->MoveBy(v.x, v.y); + } + + void Node::SetScaleX(float scale_x) + { + this->SetScale(scale_x, transform_.scale_y); + } + + void Node::SetScaleY(float scale_y) + { + this->SetScale(transform_.scale_x, scale_y); + } + + void Node::SetScale(float scale) + { + this->SetScale(scale, scale); + } + + void Node::SetScale(float scale_x, float scale_y) + { + if (transform_.scale_x == scale_x && transform_.scale_y == scale_y) + return; + + transform_.scale_x = scale_x; + transform_.scale_y = scale_y; + dirty_transform_ = true; + } + + void Node::SetSkewX(float skew_x) + { + this->SetSkew(skew_x, transform_.skew_y); + } + + void Node::SetSkewY(float skew_y) + { + this->SetSkew(transform_.skew_x, skew_y); + } + + void Node::SetSkew(float skew_x, float skew_y) + { + if (transform_.skew_x == skew_x && transform_.skew_y == skew_y) + return; + + transform_.skew_x = skew_x; + transform_.skew_y = skew_y; + dirty_transform_ = true; + } + + void Node::SetRotation(float angle) + { + if (transform_.rotation == angle) + return; + + transform_.rotation = angle; + dirty_transform_ = true; + } + + void Node::SetOpacity(float opacity) + { + if (real_opacity_ == opacity) + return; + + display_opacity_ = real_opacity_ = std::min(std::max(opacity, 0.f), 1.f); + // 更新节点透明度 + UpdateOpacity(); + } + + void Node::SetPivotX(float pivot_x) + { + this->SetPivot(pivot_x, transform_.pivot_y); + } + + void Node::SetPivotY(float pivot_y) + { + this->SetPivot(transform_.pivot_x, pivot_y); + } + + void Node::SetPivot(float pivot_x, float pivot_y) + { + if (transform_.pivot_x == pivot_x && transform_.pivot_y == pivot_y) + return; + + transform_.pivot_x = pivot_x; + transform_.pivot_y = pivot_y; + dirty_transform_ = true; + } + + void Node::SetWidth(float width) + { + this->SetSize(width, transform_.size.height); + } + + void Node::SetHeight(float height) + { + this->SetSize(transform_.size.width, height); + } + + void Node::SetSize(float width, float height) + { + if (transform_.size.width == width && transform_.size.height == height) + return; + + transform_.size.width = width; + transform_.size.height = height; + dirty_transform_ = true; + } + + void Node::SetSize(const Size& size) + { + this->SetSize(size.width, size.height); + } + + void Node::SetTransform(const Transform & transform) + { + transform_ = transform; + dirty_transform_ = true; + } + + void Node::SetClipEnabled(bool enabled) + { + clip_enabled_ = enabled; + } + + void Node::SetBorderColor(const Color & color) + { + border_color_ = color; + } + + void Node::AddChild(Node * child, int order) + { + E2D_WARNING_IF(child == nullptr, "Node::AddChild NULL pointer exception."); + + if (child) { - auto graphics = Device::GetGraphics(); - auto brush = graphics->GetSolidBrush(); - brush->SetColor(D2D1_COLOR_F(border_color_)); - graphics->GetRenderTarget()->DrawGeometry( - border_, - brush, - 1.5f - ); + if (child->parent_ != nullptr) + { + throw std::runtime_error("节点已有父节点, 不能再添加到其他节点"); + } + + for (Node * parent = this; parent != nullptr; parent = parent->GetParent()) + { + if (child == parent) + { + throw std::runtime_error("一个节点不能同时是另一个节点的父节点和子节点"); + } + } + + child->Retain(); + children_.push_back(child); + child->SetOrder(order); + child->parent_ = this; + if (this->parent_scene_) + { + child->SetParentScene(this->parent_scene_); + } + + // 更新子节点透明度 + child->UpdateOpacity(); + // 更新节点转换 + child->dirty_transform_ = true; + // 更新子节点排序 + dirty_sort_ = true; } + } + + void Node::AddChild(const Nodes& nodes, int order) + { + for (const auto& node : nodes) + { + this->AddChild(node, order); + } + } + + Node * Node::GetParent() const + { + return parent_; + } + + Scene * Node::GetParentScene() const + { + return parent_scene_; + } + + Node::Nodes Node::GetChildren(const std::wstring& name) const + { + Nodes children; + size_t hash_code = std::hash{}(name); for (const auto& child : children_) { - child->DrawBorder(); - } - } -} - -void easy2d::Node::UpdateTransform() -{ - if (!dirty_transform_) - return; - - dirty_transform_ = false; - - final_matrix_ = static_cast(transform_); - - // 根据自身支点计算 Initial 矩阵,子节点将根据这个矩阵进行变换 - auto pivot = Point( - transform_.size.width * transform_.pivot_x, - transform_.size.height * transform_.pivot_y - ); - initial_matrix_ = final_matrix_ * D2D1::Matrix3x2F::Translation(pivot.x, pivot.y); - - if (parent_) - { - initial_matrix_ = initial_matrix_ * parent_->initial_matrix_; - final_matrix_ = final_matrix_ * parent_->initial_matrix_; - } - else if (parent_scene_) - { - initial_matrix_ = initial_matrix_ * parent_scene_->GetTransform(); - final_matrix_ = final_matrix_ * parent_scene_->GetTransform(); - } - - // 重新构造轮廓 - SafeRelease(border_); - - ID2D1Factory * factory = Device::GetGraphics()->GetFactory(); - ID2D1RectangleGeometry * rectangle = nullptr; - ID2D1TransformedGeometry * transformed = nullptr; - ThrowIfFailed( - factory->CreateRectangleGeometry( - D2D1::RectF(0, 0, transform_.size.width, transform_.size.height), - &rectangle - ) - ); - ThrowIfFailed( - factory->CreateTransformedGeometry( - rectangle, - final_matrix_, - &transformed - ) - ); - border_ = transformed; - - SafeRelease(rectangle); - - // 通知子节点进行转换 - for (const auto& child : children_) - { - child->dirty_transform_ = true; - } -} - -bool easy2d::Node::Dispatch(const MouseEvent & e, bool handled) -{ - if (visible_) - { - for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter) - handled = (*riter)->Dispatch(e, handled); - - auto handler = dynamic_cast(this); - if (handler) - handler->Handle(e); - } - - return handled; -} - -bool easy2d::Node::Dispatch(const KeyEvent & e, bool handled) -{ - if (visible_) - { - for (auto riter = children_.crbegin(); riter != children_.crend(); ++riter) - handled = (*riter)->Dispatch(e, handled); - - auto handler = dynamic_cast(this); - if (handler) - handler->Handle(e); - } - - return handled; -} - -void easy2d::Node::UpdateOpacity() -{ - if (parent_) - { - display_opacity_ = real_opacity_ * parent_->display_opacity_; - } - for (const auto& child : children_) - { - child->UpdateOpacity(); - } -} - -void easy2d::Node::UpdateActions() -{ - if (actions_.empty()) - return; - - std::vector currActions; - currActions.reserve(actions_.size()); - std::copy_if( - actions_.begin(), - actions_.end(), - std::back_inserter(currActions), - [](Action* action) { return action->IsRunning() && !action->IsDone(); } - ); - - // 遍历所有正在运行的动作 - for (const auto& action : currActions) - action->Update(); - - // 清除完成的动作 - for (auto iter = actions_.begin(); iter != actions_.end();) - { - if ((*iter)->IsDone()) - { - (*iter)->Release(); - iter = actions_.erase(iter); - } - else - { - ++iter; - } - } -} - -bool easy2d::Node::IsVisible() const -{ - return visible_; -} - -const std::wstring& easy2d::Node::GetName() const -{ - return name_; -} - -size_t easy2d::Node::GetHashName() const -{ - return hash_name_; -} - -const easy2d::Point& easy2d::Node::GetPosition() const -{ - return transform_.position; -} - -float easy2d::Node::GetWidth() const -{ - return transform_.size.width * transform_.scale_x; -} - -float easy2d::Node::GetHeight() const -{ - return transform_.size.height * transform_.scale_y; -} - -float easy2d::Node::GetRealWidth() const -{ - return transform_.size.width; -} - -float easy2d::Node::GetRealHeight() const -{ - return transform_.size.height; -} - -const easy2d::Size& easy2d::Node::GetRealSize() const -{ - return transform_.size; -} - -float easy2d::Node::GetPivotX() const -{ - return transform_.pivot_x; -} - -float easy2d::Node::GetPivotY() const -{ - return transform_.pivot_y; -} - -easy2d::Size easy2d::Node::GetSize() const -{ - return Size{ GetWidth(), GetHeight() }; -} - -float easy2d::Node::GetScaleX() const -{ - return transform_.scale_x; -} - -float easy2d::Node::GetScaleY() const -{ - return transform_.scale_y; -} - -float easy2d::Node::GetSkewX() const -{ - return transform_.skew_x; -} - -float easy2d::Node::GetSkewY() const -{ - return transform_.skew_y; -} - -float easy2d::Node::GetRotation() const -{ - return transform_.rotation; -} - -const easy2d::Transform & easy2d::Node::GetTransform() const -{ - return transform_; -} - -float easy2d::Node::GetOpacity() const -{ - return real_opacity_; -} - -float easy2d::Node::GetDisplayOpacity() const -{ - return display_opacity_; -} - -int easy2d::Node::GetOrder() const -{ - return order_; -} - -void easy2d::Node::SetOrder(int order) -{ - if (order_ == order) - return; - - order_ = order; - if (parent_) - { - parent_->dirty_sort_ = true; - } -} - -void easy2d::Node::SetPositionX(float x) -{ - this->SetPosition(x, transform_.position.y); -} - -void easy2d::Node::SetPositionY(float y) -{ - this->SetPosition(transform_.position.x, y); -} - -void easy2d::Node::SetPosition(const Point & p) -{ - this->SetPosition(p.x, p.y); -} - -void easy2d::Node::SetPosition(float x, float y) -{ - if (transform_.position.x == x && transform_.position.y == y) - return; - - transform_.position.x = x; - transform_.position.y = y; - dirty_transform_ = true; -} - -void easy2d::Node::MoveBy(float x, float y) -{ - this->SetPosition(transform_.position.x + x, transform_.position.y + y); -} - -void easy2d::Node::MoveBy(const Point & v) -{ - this->MoveBy(v.x, v.y); -} - -void easy2d::Node::SetScaleX(float scale_x) -{ - this->SetScale(scale_x, transform_.scale_y); -} - -void easy2d::Node::SetScaleY(float scale_y) -{ - this->SetScale(transform_.scale_x, scale_y); -} - -void easy2d::Node::SetScale(float scale) -{ - this->SetScale(scale, scale); -} - -void easy2d::Node::SetScale(float scale_x, float scale_y) -{ - if (transform_.scale_x == scale_x && transform_.scale_y == scale_y) - return; - - transform_.scale_x = scale_x; - transform_.scale_y = scale_y; - dirty_transform_ = true; -} - -void easy2d::Node::SetSkewX(float skew_x) -{ - this->SetSkew(skew_x, transform_.skew_y); -} - -void easy2d::Node::SetSkewY(float skew_y) -{ - this->SetSkew(transform_.skew_x, skew_y); -} - -void easy2d::Node::SetSkew(float skew_x, float skew_y) -{ - if (transform_.skew_x == skew_x && transform_.skew_y == skew_y) - return; - - transform_.skew_x = skew_x; - transform_.skew_y = skew_y; - dirty_transform_ = true; -} - -void easy2d::Node::SetRotation(float angle) -{ - if (transform_.rotation == angle) - return; - - transform_.rotation = angle; - dirty_transform_ = true; -} - -void easy2d::Node::SetOpacity(float opacity) -{ - if (real_opacity_ == opacity) - return; - - display_opacity_ = real_opacity_ = std::min(std::max(opacity, 0.f), 1.f); - // 更新节点透明度 - UpdateOpacity(); -} - -void easy2d::Node::SetPivotX(float pivot_x) -{ - this->SetPivot(pivot_x, transform_.pivot_y); -} - -void easy2d::Node::SetPivotY(float pivot_y) -{ - this->SetPivot(transform_.pivot_x, pivot_y); -} - -void easy2d::Node::SetPivot(float pivot_x, float pivot_y) -{ - if (transform_.pivot_x == pivot_x && transform_.pivot_y == pivot_y) - return; - - transform_.pivot_x = pivot_x; - transform_.pivot_y = pivot_y; - dirty_transform_ = true; -} - -void easy2d::Node::SetWidth(float width) -{ - this->SetSize(width, transform_.size.height); -} - -void easy2d::Node::SetHeight(float height) -{ - this->SetSize(transform_.size.width, height); -} - -void easy2d::Node::SetSize(float width, float height) -{ - if (transform_.size.width == width && transform_.size.height == height) - return; - - transform_.size.width = width; - transform_.size.height = height; - dirty_transform_ = true; -} - -void easy2d::Node::SetSize(const Size& size) -{ - this->SetSize(size.width, size.height); -} - -void easy2d::Node::SetTransform(const Transform & transform) -{ - transform_ = transform; - dirty_transform_ = true; -} - -void easy2d::Node::SetClipEnabled(bool enabled) -{ - clip_enabled_ = enabled; -} - -void easy2d::Node::SetBorderColor(const Color & color) -{ - border_color_ = color; -} - -void easy2d::Node::AddChild(Node * child, int order) -{ - E2D_WARNING_IF(child == nullptr, "Node::AddChild NULL pointer exception."); - - if (child) - { - if (child->parent_ != nullptr) - { - throw std::runtime_error("节点已有父节点, 不能再添加到其他节点"); - } - - for (Node * parent = this; parent != nullptr; parent = parent->GetParent()) - { - if (child == parent) + // 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度 + if (child->hash_name_ == hash_code && child->name_ == name) { - throw std::runtime_error("一个节点不能同时是另一个节点的父节点和子节点"); + children.push_back(child); } } + return children; + } - child->Retain(); - children_.push_back(child); - child->SetOrder(order); - child->parent_ = this; - if (this->parent_scene_) + Node * Node::GetChild(const std::wstring& name) const + { + size_t hash_code = std::hash{}(name); + + for (const auto& child : children_) { - child->SetParentScene(this->parent_scene_); + // 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度 + if (child->hash_name_ == hash_code && child->name_ == name) + { + return child; + } } - - // 更新子节点透明度 - child->UpdateOpacity(); - // 更新节点转换 - child->dirty_transform_ = true; - // 更新子节点排序 - dirty_sort_ = true; + return nullptr; } -} -void easy2d::Node::AddChild(const Nodes& nodes, int order) -{ - for (const auto& node : nodes) + const std::vector& Node::GetAllChildren() const { - this->AddChild(node, order); + return children_; } -} -easy2d::Node * easy2d::Node::GetParent() const -{ - return parent_; -} - -easy2d::Scene * easy2d::Node::GetParentScene() const -{ - return parent_scene_; -} - -easy2d::Node::Nodes easy2d::Node::GetChildren(const std::wstring& name) const -{ - Nodes children; - size_t hash_code = std::hash{}(name); - - for (const auto& child : children_) + int Node::GetChildrenCount() const { - // 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度 - if (child->hash_name_ == hash_code && child->name_ == name) + return static_cast(children_.size()); + } + + void Node::RemoveFromParent() + { + if (parent_) { - children.push_back(child); + parent_->RemoveChild(this); } } - return children; -} -easy2d::Node * easy2d::Node::GetChild(const std::wstring& name) const -{ - size_t hash_code = std::hash{}(name); - - for (const auto& child : children_) + bool Node::RemoveChild(Node * child) { - // 不同的名称可能会有相同的 Hash 值,但是先比较 Hash 可以提升搜索速度 - if (child->hash_name_ == hash_code && child->name_ == name) + E2D_WARNING_IF(child == nullptr, "Node::RemoveChildren NULL pointer exception."); + + if (children_.empty()) { - return child; + return false; } - } - return nullptr; -} -const std::vector& easy2d::Node::GetAllChildren() const -{ - return children_; -} + if (child) + { + auto iter = std::find(children_.begin(), children_.end(), child); + if (iter != children_.end()) + { + children_.erase(iter); + child->parent_ = nullptr; -int easy2d::Node::GetChildrenCount() const -{ - return static_cast(children_.size()); -} + if (child->parent_scene_) + { + child->SetParentScene(nullptr); + } -void easy2d::Node::RemoveFromParent() -{ - if (parent_) - { - parent_->RemoveChild(this); - } -} - -bool easy2d::Node::RemoveChild(Node * child) -{ - E2D_WARNING_IF(child == nullptr, "Node::RemoveChildren NULL pointer exception."); - - if (children_.empty()) - { + child->Release(); + return true; + } + } return false; } - if (child) + void Node::RemoveChildren(const std::wstring& child_name) { - auto iter = std::find(children_.begin(), children_.end(), child); - if (iter != children_.end()) + if (children_.empty()) { - children_.erase(iter); - child->parent_ = nullptr; + return; + } - if (child->parent_scene_) + size_t hash_code = std::hash{}(child_name); + for (auto iter = children_.begin(); iter != children_.end();) + { + if ((*iter)->hash_name_ == hash_code && (*iter)->name_ == child_name) { - child->SetParentScene(nullptr); + (*iter)->parent_ = nullptr; + if ((*iter)->parent_scene_) + { + (*iter)->SetParentScene(nullptr); + } + (*iter)->Release(); + iter = children_.erase(iter); } + else + { + ++iter; + } + } + } + void Node::RemoveAllChildren() + { + // 所有节点的引用计数减一 + for (const auto& child : children_) + { child->Release(); - return true; } - } - return false; -} - -void easy2d::Node::RemoveChildren(const std::wstring& child_name) -{ - if (children_.empty()) - { - return; + // 清空储存节点的容器 + children_.clear(); } - size_t hash_code = std::hash{}(child_name); - for (auto iter = children_.begin(); iter != children_.end();) + void Node::RunAction(Action * action) { - if ((*iter)->hash_name_ == hash_code && (*iter)->name_ == child_name) + E2D_WARNING_IF(action == nullptr, "Action NULL pointer exception!"); + + if (action) { - (*iter)->parent_ = nullptr; - if ((*iter)->parent_scene_) + if (action->GetTarget() == nullptr) { - (*iter)->SetParentScene(nullptr); + auto iter = std::find(actions_.begin(), actions_.end(), action); + if (iter == actions_.end()) + { + action->Retain(); + action->StartWithTarget(this); + actions_.push_back(action); + } } - (*iter)->Release(); - iter = children_.erase(iter); - } - else - { - ++iter; - } - } -} - -void easy2d::Node::RemoveAllChildren() -{ - // 所有节点的引用计数减一 - for (const auto& child : children_) - { - child->Release(); - } - // 清空储存节点的容器 - children_.clear(); -} - -void easy2d::Node::RunAction(Action * action) -{ - E2D_WARNING_IF(action == nullptr, "Action NULL pointer exception!"); - - if (action) - { - if (action->GetTarget() == nullptr) - { - auto iter = std::find(actions_.begin(), actions_.end(), action); - if (iter == actions_.end()) + else { - action->Retain(); - action->StartWithTarget(this); - actions_.push_back(action); + throw std::runtime_error("该 Action 已有执行目标"); } } - else + } + + void Node::ResumeAction(const std::wstring& name) + { + if (actions_.empty()) + return; + + for (const auto& action : actions_) { - throw std::runtime_error("该 Action 已有执行目标"); + if (action->GetName() == name) + { + action->Resume(); + } } } -} -void easy2d::Node::ResumeAction(const std::wstring& name) -{ - if (actions_.empty()) - return; - - for (const auto& action : actions_) + void Node::PauseAction(const std::wstring& name) { - if (action->GetName() == name) + if (actions_.empty()) + return; + + for (const auto& action : actions_) + { + if (action->GetName() == name) + { + action->Pause(); + } + } + } + + void Node::StopAction(const std::wstring& name) + { + if (actions_.empty()) + return; + + for (const auto& action : actions_) + { + if (action->GetName() == name) + { + action->Stop(); + } + } + } + + bool Node::ContainsPoint(const Point& point) + { + if (transform_.size.width == 0.f || transform_.size.height == 0.f) + return false; + + UpdateTransform(); + + BOOL ret = 0; + ThrowIfFailed( + border_->FillContainsPoint( + D2D1::Point2F(point.x, point.y), + D2D1::Matrix3x2F::Identity(), + &ret + ) + ); + return ret != 0; + } + + bool Node::Intersects(Node * node) + { + if (transform_.size.width == 0.f || transform_.size.height == 0.f || node->transform_.size.width == 0.f || node->transform_.size.height == 0.f) + return false; + + // 更新转换矩阵 + UpdateTransform(); + node->UpdateTransform(); + + // 获取相交状态 + D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN; + ThrowIfFailed( + border_->CompareWithGeometry( + node->border_, + D2D1::Matrix3x2F::Identity(), + &relation + ) + ); + return relation != D2D1_GEOMETRY_RELATION_UNKNOWN && + relation != D2D1_GEOMETRY_RELATION_DISJOINT; + } + + void Node::ResumeAllActions() + { + if (actions_.empty()) + return; + + for (const auto& action : actions_) { action->Resume(); } } -} -void easy2d::Node::PauseAction(const std::wstring& name) -{ - if (actions_.empty()) - return; - - for (const auto& action : actions_) + void Node::PauseAllActions() { - if (action->GetName() == name) + if (actions_.empty()) + return; + + for (const auto& action : actions_) { action->Pause(); } } -} -void easy2d::Node::StopAction(const std::wstring& name) -{ - if (actions_.empty()) - return; - - for (const auto& action : actions_) + void Node::StopAllActions() { - if (action->GetName() == name) + if (actions_.empty()) + return; + + for (const auto& action : actions_) { action->Stop(); } } -} -bool easy2d::Node::ContainsPoint(const Point& point) -{ - if (transform_.size.width == 0.f || transform_.size.height == 0.f) - return false; - - UpdateTransform(); - - BOOL ret = 0; - ThrowIfFailed( - border_->FillContainsPoint( - D2D1::Point2F(point.x, point.y), - D2D1::Matrix3x2F::Identity(), - &ret - ) - ); - return ret != 0; -} - -bool easy2d::Node::Intersects(Node * node) -{ - if (transform_.size.width == 0.f || transform_.size.height == 0.f || node->transform_.size.width == 0.f || node->transform_.size.height == 0.f) - return false; - - // 更新转换矩阵 - UpdateTransform(); - node->UpdateTransform(); - - // 获取相交状态 - D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN; - ThrowIfFailed( - border_->CompareWithGeometry( - node->border_, - D2D1::Matrix3x2F::Identity(), - &relation - ) - ); - return relation != D2D1_GEOMETRY_RELATION_UNKNOWN && - relation != D2D1_GEOMETRY_RELATION_DISJOINT; -} - -void easy2d::Node::ResumeAllActions() -{ - if (actions_.empty()) - return; - - for (const auto& action : actions_) + const Node::Actions & Node::GetAllActions() const { - action->Resume(); + return actions_; } -} -void easy2d::Node::PauseAllActions() -{ - if (actions_.empty()) - return; - - for (const auto& action : actions_) + void Node::AddTask(Task * task) { - action->Pause(); - } -} - -void easy2d::Node::StopAllActions() -{ - if (actions_.empty()) - return; - - for (const auto& action : actions_) - { - action->Stop(); - } -} - -const easy2d::Node::Actions & easy2d::Node::GetAllActions() const -{ - return actions_; -} - -void easy2d::Node::AddTask(Task * task) -{ - if (task) - { - auto iter = std::find(tasks_.begin(), tasks_.end(), task); - if (iter == tasks_.end()) + if (task) { - task->Retain(); - task->last_time_ = Time::Now(); - tasks_.push_back(task); + auto iter = std::find(tasks_.begin(), tasks_.end(), task); + if (iter == tasks_.end()) + { + task->Retain(); + task->last_time_ = Time::Now(); + tasks_.push_back(task); + } } } -} -void easy2d::Node::StopTasks(const std::wstring& name) -{ - for (const auto& task : tasks_) + void Node::StopTasks(const std::wstring& name) { - if (task->GetName() == name) + for (const auto& task : tasks_) + { + if (task->GetName() == name) + { + task->Stop(); + } + } + } + + void Node::StartTasks(const std::wstring& name) + { + for (const auto& task : tasks_) + { + if (task->GetName() == name) + { + task->Start(); + } + } + } + + void Node::RemoveTasks(const std::wstring& name) + { + for (const auto& task : tasks_) + { + if (task->GetName() == name) + { + task->stopped_ = true; + } + } + } + + void Node::StopAllTasks() + { + for (const auto& task : tasks_) { task->Stop(); } } -} -void easy2d::Node::StartTasks(const std::wstring& name) -{ - for (const auto& task : tasks_) + void Node::StartAllTasks() { - if (task->GetName() == name) + for (const auto& task : tasks_) { task->Start(); } } -} -void easy2d::Node::RemoveTasks(const std::wstring& name) -{ - for (const auto& task : tasks_) + void Node::RemoveAllTasks() { - if (task->GetName() == name) + for (const auto& task : tasks_) { task->stopped_ = true; } } -} -void easy2d::Node::StopAllTasks() -{ - for (const auto& task : tasks_) + const Node::Tasks & Node::GetAllTasks() const { - task->Stop(); + return tasks_; } -} -void easy2d::Node::StartAllTasks() -{ - for (const auto& task : tasks_) + void Node::UpdateTasks() { - task->Start(); - } -} + if (tasks_.empty()) + return; -void easy2d::Node::RemoveAllTasks() -{ - for (const auto& task : tasks_) - { - task->stopped_ = true; - } -} + std::vector currTasks; + currTasks.reserve(tasks_.size()); + std::copy_if( + tasks_.begin(), + tasks_.end(), + std::back_inserter(currTasks), + [](Task* task) { return task->IsReady() && !task->stopped_; } + ); -const easy2d::Node::Tasks & easy2d::Node::GetAllTasks() const -{ - return tasks_; -} + // 遍历就绪的任务 + for (const auto& task : currTasks) + task->Update(); -void easy2d::Node::UpdateTasks() -{ - if (tasks_.empty()) - return; - - std::vector currTasks; - currTasks.reserve(tasks_.size()); - std::copy_if( - tasks_.begin(), - tasks_.end(), - std::back_inserter(currTasks), - [](Task* task) { return task->IsReady() && !task->stopped_; } - ); - - // 遍历就绪的任务 - for (const auto& task : currTasks) - task->Update(); - - // 清除结束的任务 - for (auto iter = tasks_.begin(); iter != tasks_.end();) - { - if ((*iter)->stopped_) + // 清除结束的任务 + for (auto iter = tasks_.begin(); iter != tasks_.end();) { - (*iter)->Release(); - iter = tasks_.erase(iter); - } - else - { - ++iter; + if ((*iter)->stopped_) + { + (*iter)->Release(); + iter = tasks_.erase(iter); + } + else + { + ++iter; + } } } -} -void easy2d::Node::UpdateTime() -{ - for (const auto& action : actions_) + void Node::UpdateTime() { - action->ResetTime(); + for (const auto& action : actions_) + { + action->ResetTime(); + } + + for (const auto& task : tasks_) + { + task->ResetTime(); + } + + for (const auto& child : children_) + { + child->UpdateTime(); + } } - for (const auto& task : tasks_) + void Node::SetVisible(bool value) { - task->ResetTime(); + visible_ = value; } - for (const auto& child : children_) + void Node::SetName(const std::wstring& name) { - child->UpdateTime(); + if (name_ != name) + { + // 保存节点名 + name_ = name; + // 保存节点 Hash 名 + hash_name_ = std::hash{}(name); + } } -} -void easy2d::Node::SetVisible(bool value) -{ - visible_ = value; -} - -void easy2d::Node::SetName(const std::wstring& name) -{ - if (name_ != name) + void Node::SetParentScene(Scene * scene) { - // 保存节点名 - name_ = name; - // 保存节点 Hash 名 - hash_name_ = std::hash{}(name); - } -} - -void easy2d::Node::SetParentScene(Scene * scene) -{ - parent_scene_ = scene; - for (const auto& child : children_) - { - child->SetParentScene(scene); + parent_scene_ = scene; + for (const auto& child : children_) + { + child->SetParentScene(scene); + } } } \ No newline at end of file diff --git a/core/objects/Scene.cpp b/core/objects/Scene.cpp index 14a526da..27088f78 100644 --- a/core/objects/Scene.cpp +++ b/core/objects/Scene.cpp @@ -21,100 +21,103 @@ #include "..\e2dmodule.h" #include "..\e2dobject.h" -easy2d::Scene::Scene() - : root_(nullptr) - , transform_(D2D1::Matrix3x2F::Identity()) +namespace easy2d { -} - -easy2d::Scene::Scene(Node * root) - : root_(nullptr) - , transform_(D2D1::Matrix3x2F::Identity()) -{ - this->SetRoot(root); -} - -easy2d::Scene::~Scene() -{ - if (root_) + Scene::Scene() + : root_(nullptr) + , transform_(D2D1::Matrix3x2F::Identity()) { - root_->SetParentScene(nullptr); - root_->Release(); - } -} - -void easy2d::Scene::SetRoot(Node * root) -{ - if (root_ == root) - return; - - if (root_) - { - root_->SetParentScene(nullptr); - root_->Release(); } - if (root) + Scene::Scene(Node * root) + : root_(nullptr) + , transform_(D2D1::Matrix3x2F::Identity()) { - root->Retain(); - root->SetParentScene(this); + this->SetRoot(root); } - root_ = root; -} - -easy2d::Node * easy2d::Scene::GetRoot() const -{ - return root_; -} - -void easy2d::Scene::Draw() -{ - if (root_) + Scene::~Scene() { - root_->Visit(); - } -} - -void easy2d::Scene::Dispatch(const MouseEvent & e) -{ - auto handler = dynamic_cast(this); - if (handler) - { - handler->Handle(e); + if (root_) + { + root_->SetParentScene(nullptr); + root_->Release(); + } } - if (root_) + void Scene::SetRoot(Node * root) { - root_->Dispatch(e, false); - } -} + if (root_ == root) + return; -void easy2d::Scene::Dispatch(const KeyEvent & e) -{ - auto handler = dynamic_cast(this); - if (handler) - { - handler->Handle(e); + if (root_) + { + root_->SetParentScene(nullptr); + root_->Release(); + } + + if (root) + { + root->Retain(); + root->SetParentScene(this); + } + + root_ = root; } - if (root_) + Node * Scene::GetRoot() const { - root_->Dispatch(e, false); + return root_; } -} -void easy2d::Scene::SetTransform(const D2D1::Matrix3x2F& matrix) -{ - transform_ = matrix; - - if (root_) + void Scene::Draw() { - root_->dirty_transform_ = true; + if (root_) + { + root_->Visit(); + } } -} -const D2D1::Matrix3x2F & easy2d::Scene::GetTransform() const -{ - return transform_; -} + void Scene::Dispatch(const MouseEvent & e) + { + auto handler = dynamic_cast(this); + if (handler) + { + handler->Handle(e); + } + + if (root_) + { + root_->Dispatch(e, false); + } + } + + void Scene::Dispatch(const KeyEvent & e) + { + auto handler = dynamic_cast(this); + if (handler) + { + handler->Handle(e); + } + + if (root_) + { + root_->Dispatch(e, false); + } + } + + void Scene::SetTransform(const D2D1::Matrix3x2F& matrix) + { + transform_ = matrix; + + if (root_) + { + root_->dirty_transform_ = true; + } + } + + const D2D1::Matrix3x2F & Scene::GetTransform() const + { + return transform_; + } +} \ No newline at end of file diff --git a/core/objects/Sprite.cpp b/core/objects/Sprite.cpp index 62a31984..04ff1adf 100644 --- a/core/objects/Sprite.cpp +++ b/core/objects/Sprite.cpp @@ -21,128 +21,131 @@ #include "..\e2dobject.h" #include "..\e2dmodule.h" -easy2d::Sprite::Sprite() - : image_(nullptr) +namespace easy2d { -} - -easy2d::Sprite::Sprite(Image * image) - : image_(nullptr) -{ - Load(image); -} - -easy2d::Sprite::Sprite(Resource& res) - : image_(nullptr) -{ - Load(res); -} - -easy2d::Sprite::Sprite(Resource& res, const Rect& crop_rect) - : image_(nullptr) -{ - Load(res); - Crop(crop_rect); -} - -easy2d::Sprite::Sprite(const std::wstring & file_name) - : image_(nullptr) -{ - Load(file_name); -} - -easy2d::Sprite::Sprite(const std::wstring & file_name, const Rect & crop_rect) - : image_(nullptr) -{ - Load(file_name); - Crop(crop_rect); -} - -easy2d::Sprite::~Sprite() -{ - SafeRelease(image_); -} - -bool easy2d::Sprite::Load(Image * image) -{ - if (image) + Sprite::Sprite() + : image_(nullptr) { - if (image_) + } + + Sprite::Sprite(Image * image) + : image_(nullptr) + { + Load(image); + } + + Sprite::Sprite(Resource& res) + : image_(nullptr) + { + Load(res); + } + + Sprite::Sprite(Resource& res, const Rect& crop_rect) + : image_(nullptr) + { + Load(res); + Crop(crop_rect); + } + + Sprite::Sprite(const std::wstring & file_name) + : image_(nullptr) + { + Load(file_name); + } + + Sprite::Sprite(const std::wstring & file_name, const Rect & crop_rect) + : image_(nullptr) + { + Load(file_name); + Crop(crop_rect); + } + + Sprite::~Sprite() + { + SafeRelease(image_); + } + + bool Sprite::Load(Image * image) + { + if (image) { - image_->Release(); + if (image_) + { + image_->Release(); + } + + image_ = image; + image_->Retain(); + + Node::SetSize(image_->GetWidth(), image_->GetHeight()); + return true; + } + return false; + } + + bool Sprite::Load(Resource& res) + { + if (!image_) + { + image_ = new Image(); + image_->Retain(); } - image_ = image; - image_->Retain(); - - Node::SetSize(image_->GetWidth(), image_->GetHeight()); - return true; - } - return false; -} - -bool easy2d::Sprite::Load(Resource& res) -{ - if (!image_) - { - image_ = new Image(); - image_->Retain(); + if (image_->Load(res)) + { + Node::SetSize(image_->GetWidth(), image_->GetHeight()); + return true; + } + return false; } - if (image_->Load(res)) + bool Sprite::Load(const std::wstring & file_name) { - Node::SetSize(image_->GetWidth(), image_->GetHeight()); - return true; - } - return false; -} + if (!image_) + { + image_ = new Image(); + image_->Retain(); + } -bool easy2d::Sprite::Load(const std::wstring & file_name) -{ - if (!image_) - { - image_ = new Image(); - image_->Retain(); + if (image_->Load(file_name)) + { + Node::SetSize(image_->GetWidth(), image_->GetHeight()); + return true; + } + return false; } - if (image_->Load(file_name)) + void Sprite::Crop(const Rect& crop_rect) { - Node::SetSize(image_->GetWidth(), image_->GetHeight()); - return true; - } - return false; -} - -void easy2d::Sprite::Crop(const Rect& crop_rect) -{ - image_->Crop(crop_rect); - Node::SetSize( - std::min(std::max(crop_rect.size.width, 0.f), image_->GetSourceWidth() - image_->GetCropX()), - std::min(std::max(crop_rect.size.height, 0.f), image_->GetSourceHeight() - image_->GetCropY()) - ); -} - -easy2d::Image * easy2d::Sprite::GetImage() const -{ - return image_; -} - -void easy2d::Sprite::OnDraw() const -{ - if (image_ && image_->GetBitmap()) - { - auto crop_pos = image_->GetCropPos(); - Device::GetGraphics()->GetRenderTarget()->DrawBitmap( - image_->GetBitmap(), - D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height), - GetDisplayOpacity(), - D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, - D2D1::RectF( - crop_pos.x, - crop_pos.y, - crop_pos.y + GetTransform().size.width, - crop_pos.y + GetTransform().size.height - ) + image_->Crop(crop_rect); + Node::SetSize( + std::min(std::max(crop_rect.size.width, 0.f), image_->GetSourceWidth() - image_->GetCropX()), + std::min(std::max(crop_rect.size.height, 0.f), image_->GetSourceHeight() - image_->GetCropY()) ); } -} + + Image * Sprite::GetImage() const + { + return image_; + } + + void Sprite::OnDraw() const + { + if (image_ && image_->GetBitmap()) + { + auto crop_pos = image_->GetCropPos(); + Device::GetGraphics()->GetRenderTarget()->DrawBitmap( + image_->GetBitmap(), + D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height), + GetDisplayOpacity(), + D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, + D2D1::RectF( + crop_pos.x, + crop_pos.y, + crop_pos.y + GetTransform().size.width, + crop_pos.y + GetTransform().size.height + ) + ); + } + } +} \ No newline at end of file diff --git a/core/objects/Task.cpp b/core/objects/Task.cpp index ba9bad21..54201176 100644 --- a/core/objects/Task.cpp +++ b/core/objects/Task.cpp @@ -21,89 +21,92 @@ #include "..\e2dobject.h" -easy2d::Task::Task(const Callback & func, const std::wstring & name) - : running_(true) - , stopped_(false) - , run_times_(0) - , total_times_(-1) - , delay_() - , callback_(func) - , name_(name) +namespace easy2d { -} - -easy2d::Task::Task(const Callback & func, float delay, int times, const std::wstring & name) - : running_(true) - , stopped_(false) - , run_times_(0) - , delay_(Duration::Second * std::max(delay, 0.f)) - , total_times_(times) - , callback_(func) - , name_(name) -{ -} - -void easy2d::Task::Start() -{ - running_ = true; - last_time_ = Time::Now(); -} - -void easy2d::Task::Stop() -{ - running_ = false; -} - -void easy2d::Task::Update() -{ - if (total_times_ == 0) + Task::Task(const Callback & func, const std::wstring & name) + : running_(true) + , stopped_(false) + , run_times_(0) + , total_times_(-1) + , delay_() + , callback_(func) + , name_(name) { - stopped_ = true; - return; } - ++run_times_; - last_time_ += delay_; - - if (callback_) + Task::Task(const Callback & func, float delay, int times, const std::wstring & name) + : running_(true) + , stopped_(false) + , run_times_(0) + , delay_(Duration::Second * std::max(delay, 0.f)) + , total_times_(times) + , callback_(func) + , name_(name) { - callback_(); } - if (run_times_ == total_times_) + void Task::Start() { - stopped_ = true; - return; + running_ = true; + last_time_ = Time::Now(); } -} -void easy2d::Task::ResetTime() -{ - last_time_ = Time::Now(); -} - -bool easy2d::Task::IsReady() const -{ - if (running_) + void Task::Stop() { - if (delay_.Milliseconds() == 0) + running_ = false; + } + + void Task::Update() + { + if (total_times_ == 0) { - return true; + stopped_ = true; + return; } - if (Time::Now() - last_time_ >= delay_) + + ++run_times_; + last_time_ += delay_; + + if (callback_) { - return true; + callback_(); + } + + if (run_times_ == total_times_) + { + stopped_ = true; + return; } } - return false; -} -bool easy2d::Task::IsRunning() const -{ - return running_; -} + void Task::ResetTime() + { + last_time_ = Time::Now(); + } -const std::wstring& easy2d::Task::GetName() const -{ - return name_; -} + bool Task::IsReady() const + { + if (running_) + { + if (delay_.Milliseconds() == 0) + { + return true; + } + if (Time::Now() - last_time_ >= delay_) + { + return true; + } + } + return false; + } + + bool Task::IsRunning() const + { + return running_; + } + + const std::wstring& Task::GetName() const + { + return name_; + } +} \ No newline at end of file diff --git a/core/objects/Text.cpp b/core/objects/Text.cpp index a4f6d078..3d9fb0cd 100644 --- a/core/objects/Text.cpp +++ b/core/objects/Text.cpp @@ -21,449 +21,453 @@ #include "..\e2dobject.h" #include "..\e2dmodule.h" -//------------------------------------------------------- -// Style -//------------------------------------------------------- -easy2d::Text::Style::Style() - : color(Color::White) - , alignment(Align::Left) - , wrap(false) - , wrap_width(0.f) - , line_spacing(0.f) - , underline(false) - , strikethrough(false) - , outline(true) - , outline_color(Color(Color::Black, 0.5)) - , outline_width(1.f) - , outline_stroke(Stroke::Round) -{} - -easy2d::Text::Style::Style( - Color color, - Align alignment, - bool wrap, - float wrap_width, - float line_spacing, - bool underline, - bool strikethrough, - bool outline, - Color outline_color, - float outline_width, - Stroke outline_stroke -) - : color(color) - , alignment(alignment) - , wrap(wrap) - , wrap_width(wrap_width) - , line_spacing(line_spacing) - , underline(underline) - , strikethrough(strikethrough) - , outline(outline) - , outline_color(outline_color) - , outline_width(outline_width) - , outline_stroke(outline_stroke) -{} - - - -//------------------------------------------------------- -// Text -//------------------------------------------------------- - -easy2d::Text::Text() - : font_() - , style_() - , text_layout_(nullptr) - , text_format_(nullptr) +namespace easy2d { -} + //------------------------------------------------------- + // Style + //------------------------------------------------------- -easy2d::Text::Text(const std::wstring & text, const Font & font, const Style & style) - : font_(font) - , style_(style) - , text_layout_(nullptr) - , text_format_(nullptr) - , text_(text) -{ - Reset(); -} + Text::Style::Style() + : color(Color::White) + , alignment(Align::Left) + , wrap(false) + , wrap_width(0.f) + , line_spacing(0.f) + , underline(false) + , strikethrough(false) + , outline(true) + , outline_color(Color(Color::Black, 0.5)) + , outline_width(1.f) + , outline_stroke(Stroke::Round) + {} -easy2d::Text::~Text() -{ - SafeRelease(text_format_); - SafeRelease(text_layout_); -} + Text::Style::Style( + Color color, + Align alignment, + bool wrap, + float wrap_width, + float line_spacing, + bool underline, + bool strikethrough, + bool outline, + Color outline_color, + float outline_width, + Stroke outline_stroke + ) + : color(color) + , alignment(alignment) + , wrap(wrap) + , wrap_width(wrap_width) + , line_spacing(line_spacing) + , underline(underline) + , strikethrough(strikethrough) + , outline(outline) + , outline_color(outline_color) + , outline_width(outline_width) + , outline_stroke(outline_stroke) + {} -const std::wstring& easy2d::Text::GetText() const -{ - return text_; -} -const easy2d::Font& easy2d::Text::GetFont() const -{ - return font_; -} -const easy2d::Text::Style& easy2d::Text::GetStyle() const -{ - return style_; -} + //------------------------------------------------------- + // Text + //------------------------------------------------------- -const std::wstring& easy2d::Text::GetFontFamily() const -{ - return font_.family; -} - -float easy2d::Text::GetFontSize() const -{ - return font_.size; -} - -UINT easy2d::Text::GetFontWeight() const -{ - return font_.weight; -} - -const easy2d::Color& easy2d::Text::GetColor() const -{ - return style_.color; -} - -const easy2d::Color& easy2d::Text::GetOutlineColor() const -{ - return style_.outline_color; -} - -float easy2d::Text::GetOutlineWidth() const -{ - return style_.outline_width; -} - -easy2d::Stroke easy2d::Text::GetOutlineStroke() const -{ - return style_.outline_stroke; -} - -int easy2d::Text::GetLineCount() const -{ - if (text_layout_) + Text::Text() + : font_() + , style_() + , text_layout_(nullptr) + , text_format_(nullptr) { - DWRITE_TEXT_METRICS metrics; - text_layout_->GetMetrics(&metrics); - return static_cast(metrics.lineCount); } - else + + Text::Text(const std::wstring & text, const Font & font, const Style & style) + : font_(font) + , style_(style) + , text_layout_(nullptr) + , text_format_(nullptr) + , text_(text) { - return 0; - } -} - -bool easy2d::Text::IsItalic() const -{ - return font_.italic; -} - -bool easy2d::Text::strikethrough() const -{ - return style_.strikethrough; -} - -bool easy2d::Text::underline() const -{ - return style_.underline; -} - -bool easy2d::Text::outline() const -{ - return style_.outline; -} - -void easy2d::Text::SetText(const std::wstring& text) -{ - text_ = text; - Reset(); -} - -void easy2d::Text::SetStyle(const Style& style) -{ - style_ = style; - Reset(); -} - -void easy2d::Text::SetFont(const Font & font) -{ - font_ = font; - Reset(); -} - -void easy2d::Text::SetFontFamily(const std::wstring& family) -{ - font_.family = family; - Reset(); -} - -void easy2d::Text::SetFontSize(float size) -{ - font_.size = size; - Reset(); -} - -void easy2d::Text::SetFontWeight(UINT weight) -{ - font_.weight = weight; - Reset(); -} - -void easy2d::Text::SetColor(Color color) -{ - style_.color = color; -} - -void easy2d::Text::SetItalic(bool value) -{ - font_.italic = value; - Reset(); -} - -void easy2d::Text::SetWrapEnabled(bool wrap) -{ - if (style_.wrap != wrap) - { - style_.wrap = wrap; Reset(); } -} -void easy2d::Text::SetWrapWidth(float wrap_width) -{ - if (style_.wrap_width != wrap_width) + Text::~Text() { - style_.wrap_width = std::max(wrap_width, 0.f); + SafeRelease(text_format_); + SafeRelease(text_layout_); + } - if (style_.wrap) + const std::wstring& Text::GetText() const + { + return text_; + } + + const Font& Text::GetFont() const + { + return font_; + } + + const Text::Style& Text::GetStyle() const + { + return style_; + } + + const std::wstring& Text::GetFontFamily() const + { + return font_.family; + } + + float Text::GetFontSize() const + { + return font_.size; + } + + UINT Text::GetFontWeight() const + { + return font_.weight; + } + + const Color& Text::GetColor() const + { + return style_.color; + } + + const Color& Text::GetOutlineColor() const + { + return style_.outline_color; + } + + float Text::GetOutlineWidth() const + { + return style_.outline_width; + } + + Stroke Text::GetOutlineStroke() const + { + return style_.outline_stroke; + } + + int Text::GetLineCount() const + { + if (text_layout_) { + DWRITE_TEXT_METRICS metrics; + text_layout_->GetMetrics(&metrics); + return static_cast(metrics.lineCount); + } + else + { + return 0; + } + } + + bool Text::IsItalic() const + { + return font_.italic; + } + + bool Text::strikethrough() const + { + return style_.strikethrough; + } + + bool Text::underline() const + { + return style_.underline; + } + + bool Text::outline() const + { + return style_.outline; + } + + void Text::SetText(const std::wstring& text) + { + text_ = text; + Reset(); + } + + void Text::SetStyle(const Style& style) + { + style_ = style; + Reset(); + } + + void Text::SetFont(const Font & font) + { + font_ = font; + Reset(); + } + + void Text::SetFontFamily(const std::wstring& family) + { + font_.family = family; + Reset(); + } + + void Text::SetFontSize(float size) + { + font_.size = size; + Reset(); + } + + void Text::SetFontWeight(UINT weight) + { + font_.weight = weight; + Reset(); + } + + void Text::SetColor(Color color) + { + style_.color = color; + } + + void Text::SetItalic(bool value) + { + font_.italic = value; + Reset(); + } + + void Text::SetWrapEnabled(bool wrap) + { + if (style_.wrap != wrap) + { + style_.wrap = wrap; Reset(); } } -} -void easy2d::Text::SetLineSpacing(float line_spacing) -{ - if (style_.line_spacing != line_spacing) + void Text::SetWrapWidth(float wrap_width) { - style_.line_spacing = line_spacing; - Reset(); + if (style_.wrap_width != wrap_width) + { + style_.wrap_width = std::max(wrap_width, 0.f); + + if (style_.wrap) + { + Reset(); + } + } } -} -void easy2d::Text::SetAlignment(Align align) -{ - if (style_.alignment != align) + void Text::SetLineSpacing(float line_spacing) { - style_.alignment = align; - Reset(); + if (style_.line_spacing != line_spacing) + { + style_.line_spacing = line_spacing; + Reset(); + } } -} -void easy2d::Text::SetUnderline(bool underline) -{ - if (style_.underline != underline) + void Text::SetAlignment(Align align) { - style_.underline = underline; - if (!text_format_) - CreateFormat(); + if (style_.alignment != align) + { + style_.alignment = align; + Reset(); + } + } + + void Text::SetUnderline(bool underline) + { + if (style_.underline != underline) + { + style_.underline = underline; + if (!text_format_) + CreateFormat(); + CreateLayout(); + } + } + + void Text::SetStrikethrough(bool strikethrough) + { + if (style_.strikethrough != strikethrough) + { + style_.strikethrough = strikethrough; + if (!text_format_) + CreateFormat(); + CreateLayout(); + } + } + + void Text::SetOutline(bool outline) + { + style_.outline = outline; + } + + void Text::SetOutlineColor(Color outline_color) + { + style_.outline_color = outline_color; + } + + void Text::SetOutlineWidth(float outline_width) + { + style_.outline_width = outline_width; + } + + void Text::SetOutlineStroke(Stroke outline_stroke) + { + style_.outline_stroke = outline_stroke; + } + + void Text::OnDraw() const + { + if (text_layout_) + { + auto graphics = Device::GetGraphics(); + // 创建文本区域 + D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height); + // 设置画刷颜色和透明度 + graphics->GetSolidBrush()->SetOpacity(GetDisplayOpacity()); + // 获取文本渲染器 + auto text_renderer = graphics->GetTextRender(); + graphics->SetTextRendererStyle( + style_.color, + style_.outline, + style_.outline_color, + style_.outline_width, + style_.outline_stroke + ); + text_layout_->Draw(nullptr, text_renderer, 0, 0); + } + } + + void Text::Reset() + { + // 创建文字格式化 + CreateFormat(); + // 创建文字布局 CreateLayout(); } -} -void easy2d::Text::SetStrikethrough(bool strikethrough) -{ - if (style_.strikethrough != strikethrough) + void Text::CreateFormat() { - style_.strikethrough = strikethrough; - if (!text_format_) - CreateFormat(); - CreateLayout(); - } -} + SafeRelease(text_format_); -void easy2d::Text::SetOutline(bool outline) -{ - style_.outline = outline; -} - -void easy2d::Text::SetOutlineColor(Color outline_color) -{ - style_.outline_color = outline_color; -} - -void easy2d::Text::SetOutlineWidth(float outline_width) -{ - style_.outline_width = outline_width; -} - -void easy2d::Text::SetOutlineStroke(Stroke outline_stroke) -{ - style_.outline_stroke = outline_stroke; -} - -void easy2d::Text::OnDraw() const -{ - if (text_layout_) - { - auto graphics = Device::GetGraphics(); - // 创建文本区域 - D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, GetTransform().size.width, GetTransform().size.height); - // 设置画刷颜色和透明度 - graphics->GetSolidBrush()->SetOpacity(GetDisplayOpacity()); - // 获取文本渲染器 - auto text_renderer = graphics->GetTextRender(); - graphics->SetTextRendererStyle( - style_.color, - style_.outline, - style_.outline_color, - style_.outline_width, - style_.outline_stroke - ); - text_layout_->Draw(nullptr, text_renderer, 0, 0); - } -} - -void easy2d::Text::Reset() -{ - // 创建文字格式化 - CreateFormat(); - // 创建文字布局 - CreateLayout(); -} - -void easy2d::Text::CreateFormat() -{ - SafeRelease(text_format_); - - ThrowIfFailed( - Device::GetGraphics()->GetWriteFactory()->CreateTextFormat( - font_.family.c_str(), - nullptr, - DWRITE_FONT_WEIGHT(font_.weight), - font_.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - font_.size, - L"", - &text_format_ - ) - ); - - // 设置文字对齐方式 - text_format_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(style_.alignment)); - - // 设置行间距 - if (style_.line_spacing == 0.f) - { - text_format_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0); - } - else - { - text_format_->SetLineSpacing( - DWRITE_LINE_SPACING_METHOD_UNIFORM, - style_.line_spacing, - style_.line_spacing * 0.8f - ); - } - - // 打开文本自动换行时,设置换行属性 - if (style_.wrap) - { - text_format_->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP); - } - else - { - text_format_->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); - } -} - -void easy2d::Text::CreateLayout() -{ - SafeRelease(text_layout_); - - // 文本为空字符串时,重置属性 - if (text_.empty()) - { - this->SetSize(0, 0); - return; - } - - if (text_format_ == nullptr) - { - E2D_WARNING("Text::CreateLayout failed! text_format_ NULL pointer exception."); - return; - } - - UINT32 length = static_cast(text_.size()); - auto writeFactory = Device::GetGraphics()->GetWriteFactory(); - - // 对文本自动换行情况下进行处理 - if (style_.wrap) - { ThrowIfFailed( - writeFactory->CreateTextLayout( - text_.c_str(), - length, - text_format_, - style_.wrap_width, - 0, - &text_layout_ - ) - ); - // 获取文本布局的宽度和高度 - DWRITE_TEXT_METRICS metrics; - text_layout_->GetMetrics(&metrics); - // 重设文本宽高 - this->SetSize(metrics.layoutWidth, metrics.height); - } - else - { - // 为防止文本对齐问题,根据先创建 layout 以获取宽度 - ThrowIfFailed( - writeFactory->CreateTextLayout( - text_.c_str(), - length, - text_format_, - 0, - 0, - &text_layout_ + Device::GetGraphics()->GetWriteFactory()->CreateTextFormat( + font_.family.c_str(), + nullptr, + DWRITE_FONT_WEIGHT(font_.weight), + font_.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + font_.size, + L"", + &text_format_ ) ); - // 获取文本布局的宽度和高度 - DWRITE_TEXT_METRICS metrics; - text_layout_->GetMetrics(&metrics); - // 重设文本宽高 - this->SetSize(metrics.width, metrics.height); + // 设置文字对齐方式 + text_format_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(style_.alignment)); - // 重新创建 layout + // 设置行间距 + if (style_.line_spacing == 0.f) + { + text_format_->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, 0, 0); + } + else + { + text_format_->SetLineSpacing( + DWRITE_LINE_SPACING_METHOD_UNIFORM, + style_.line_spacing, + style_.line_spacing * 0.8f + ); + } + + // 打开文本自动换行时,设置换行属性 + if (style_.wrap) + { + text_format_->SetWordWrapping(DWRITE_WORD_WRAPPING_WRAP); + } + else + { + text_format_->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); + } + } + + void Text::CreateLayout() + { SafeRelease(text_layout_); - ThrowIfFailed( - writeFactory->CreateTextLayout( - text_.c_str(), - length, - text_format_, - GetTransform().size.width, - 0, - &text_layout_ - ) - ); - } - // 添加下划线和删除线 - DWRITE_TEXT_RANGE Range = { 0, length }; - if (style_.underline) - { - text_layout_->SetUnderline(true, Range); + // 文本为空字符串时,重置属性 + if (text_.empty()) + { + this->SetSize(0, 0); + return; + } + + if (text_format_ == nullptr) + { + E2D_WARNING("Text::CreateLayout failed! text_format_ NULL pointer exception."); + return; + } + + UINT32 length = static_cast(text_.size()); + auto writeFactory = Device::GetGraphics()->GetWriteFactory(); + + // 对文本自动换行情况下进行处理 + if (style_.wrap) + { + ThrowIfFailed( + writeFactory->CreateTextLayout( + text_.c_str(), + length, + text_format_, + style_.wrap_width, + 0, + &text_layout_ + ) + ); + // 获取文本布局的宽度和高度 + DWRITE_TEXT_METRICS metrics; + text_layout_->GetMetrics(&metrics); + // 重设文本宽高 + this->SetSize(metrics.layoutWidth, metrics.height); + } + else + { + // 为防止文本对齐问题,根据先创建 layout 以获取宽度 + ThrowIfFailed( + writeFactory->CreateTextLayout( + text_.c_str(), + length, + text_format_, + 0, + 0, + &text_layout_ + ) + ); + + // 获取文本布局的宽度和高度 + DWRITE_TEXT_METRICS metrics; + text_layout_->GetMetrics(&metrics); + // 重设文本宽高 + this->SetSize(metrics.width, metrics.height); + + // 重新创建 layout + SafeRelease(text_layout_); + ThrowIfFailed( + writeFactory->CreateTextLayout( + text_.c_str(), + length, + text_format_, + GetTransform().size.width, + 0, + &text_layout_ + ) + ); + } + + // 添加下划线和删除线 + DWRITE_TEXT_RANGE Range = { 0, length }; + if (style_.underline) + { + text_layout_->SetUnderline(true, Range); + } + if (style_.strikethrough) + { + text_layout_->SetStrikethrough(true, Range); + } } - if (style_.strikethrough) - { - text_layout_->SetStrikethrough(true, Range); - } -} +} \ No newline at end of file diff --git a/core/tools/Data.cpp b/core/tools/Data.cpp index 7f505892..cafaa9a7 100644 --- a/core/tools/Data.cpp +++ b/core/tools/Data.cpp @@ -21,126 +21,129 @@ #include "..\e2dtool.h" -easy2d::Data::Data(const std::wstring & key, const std::wstring & field) - : key_(key) - , field_(field) - , data_path_(Path::GetDataPath()) +namespace easy2d { -} + Data::Data(const std::wstring & key, const std::wstring & field) + : key_(key) + , field_(field) + , data_path_(Path::GetDataPath()) + { + } -bool easy2d::Data::Exists() const -{ - wchar_t temp[256] = { 0 }; - ::GetPrivateProfileStringW( - field_.c_str(), - key_.c_str(), - L"", - temp, - 255, - data_path_.c_str() - ); - return temp[0] == L'\0'; -} + bool Data::Exists() const + { + wchar_t temp[256] = { 0 }; + ::GetPrivateProfileStringW( + field_.c_str(), + key_.c_str(), + L"", + temp, + 255, + data_path_.c_str() + ); + return temp[0] == L'\0'; + } -bool easy2d::Data::SaveInt(int value) -{ - BOOL ret = ::WritePrivateProfileStringW( - field_.c_str(), - key_.c_str(), - std::to_wstring(value).c_str(), - data_path_.c_str() - ); - return ret == TRUE; -} + bool Data::SaveInt(int value) + { + BOOL ret = ::WritePrivateProfileStringW( + field_.c_str(), + key_.c_str(), + std::to_wstring(value).c_str(), + data_path_.c_str() + ); + return ret == TRUE; + } -bool easy2d::Data::SaveFloat(float value) -{ - BOOL ret = ::WritePrivateProfileStringW( - field_.c_str(), - key_.c_str(), - std::to_wstring(value).c_str(), - data_path_.c_str() - ); - return ret == TRUE; -} + bool Data::SaveFloat(float value) + { + BOOL ret = ::WritePrivateProfileStringW( + field_.c_str(), + key_.c_str(), + std::to_wstring(value).c_str(), + data_path_.c_str() + ); + return ret == TRUE; + } -bool easy2d::Data::SaveDouble(double value) -{ - BOOL ret = ::WritePrivateProfileStringW( - field_.c_str(), - key_.c_str(), - std::to_wstring(value).c_str(), - data_path_.c_str() - ); - return ret == TRUE; -} + bool Data::SaveDouble(double value) + { + BOOL ret = ::WritePrivateProfileStringW( + field_.c_str(), + key_.c_str(), + std::to_wstring(value).c_str(), + data_path_.c_str() + ); + return ret == TRUE; + } -bool easy2d::Data::SaveBool(bool value) -{ - BOOL ret = ::WritePrivateProfileStringW( - field_.c_str(), - key_.c_str(), - (value ? L"1" : L"0"), - data_path_.c_str() - ); - return ret == TRUE; -} + bool Data::SaveBool(bool value) + { + BOOL ret = ::WritePrivateProfileStringW( + field_.c_str(), + key_.c_str(), + (value ? L"1" : L"0"), + data_path_.c_str() + ); + return ret == TRUE; + } -bool easy2d::Data::SaveString(const std::wstring& value) -{ - BOOL ret = ::WritePrivateProfileStringW( - field_.c_str(), - key_.c_str(), - value.c_str(), - data_path_.c_str() - ); - return ret == TRUE; -} + bool Data::SaveString(const std::wstring& value) + { + BOOL ret = ::WritePrivateProfileStringW( + field_.c_str(), + key_.c_str(), + value.c_str(), + data_path_.c_str() + ); + return ret == TRUE; + } -int easy2d::Data::GetInt() const -{ - return ::GetPrivateProfileIntW( - field_.c_str(), - key_.c_str(), - 0, - data_path_.c_str() - ); -} + int Data::GetInt() const + { + return ::GetPrivateProfileIntW( + field_.c_str(), + key_.c_str(), + 0, + data_path_.c_str() + ); + } -float easy2d::Data::GetFloat() const -{ - wchar_t temp[32] = { 0 }; - ::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str()); - return std::stof(temp); -} + float Data::GetFloat() const + { + wchar_t temp[32] = { 0 }; + ::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str()); + return std::stof(temp); + } -double easy2d::Data::GetDouble() const -{ - wchar_t temp[32] = { 0 }; - ::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str()); - return std::stod(temp); -} + double Data::GetDouble() const + { + wchar_t temp[32] = { 0 }; + ::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str()); + return std::stod(temp); + } -bool easy2d::Data::GetBool() const -{ - int nValue = ::GetPrivateProfileIntW( - field_.c_str(), - key_.c_str(), - 0, - data_path_.c_str()); - return nValue == TRUE; -} + bool Data::GetBool() const + { + int nValue = ::GetPrivateProfileIntW( + field_.c_str(), + key_.c_str(), + 0, + data_path_.c_str()); + return nValue == TRUE; + } -std::wstring easy2d::Data::GetString() -{ - wchar_t temp[256] = { 0 }; - ::GetPrivateProfileStringW( - field_.c_str(), - key_.c_str(), - L"", - temp, - 255, - data_path_.c_str() - ); - return temp; -} + std::wstring Data::GetString() + { + wchar_t temp[256] = { 0 }; + ::GetPrivateProfileStringW( + field_.c_str(), + key_.c_str(), + L"", + temp, + 255, + data_path_.c_str() + ); + return temp; + } +} \ No newline at end of file diff --git a/core/tools/File.cpp b/core/tools/File.cpp index d25a2a77..bb941b5f 100644 --- a/core/tools/File.cpp +++ b/core/tools/File.cpp @@ -23,270 +23,273 @@ #include #include -std::list easy2d::File::search_paths_; - -easy2d::File::File() - : file_path_() +namespace easy2d { -} + std::list File::search_paths_; -easy2d::File::File(const std::wstring & file_name) - : file_path_(file_name) -{ - this->Open(file_name); -} - -easy2d::File::~File() -{ -} - -bool easy2d::File::Open(const std::wstring & file_name) -{ - if (file_name.empty()) - return false; - - auto FindFile = [](const std::wstring & path) -> bool + File::File() + : file_path_() { - if (::PathFileExists(path.c_str())) - return true; - return false; - }; - - if (FindFile(file_name)) - { - file_path_ = file_name; - return true; } - - for (const auto& path : search_paths_) + + File::File(const std::wstring & file_name) + : file_path_(file_name) { - if (FindFile(path + file_name)) + this->Open(file_name); + } + + File::~File() + { + } + + bool File::Open(const std::wstring & file_name) + { + if (file_name.empty()) + return false; + + auto FindFile = [](const std::wstring & path) -> bool { - file_path_ = path + file_name; + if (::PathFileExists(path.c_str())) + return true; + return false; + }; + + if (FindFile(file_name)) + { + file_path_ = file_name; return true; } + + for (const auto& path : search_paths_) + { + if (FindFile(path + file_name)) + { + file_path_ = path + file_name; + return true; + } + } + return false; } - return false; -} -bool easy2d::File::Exists() const -{ - if (::PathFileExists(file_path_.c_str())) - return true; - return false; -} - -const std::wstring& easy2d::File::GetPath() const -{ - return file_path_; -} - -std::wstring easy2d::File::GetExtension() const -{ - std::wstring file_ext; - // 找到文件名中的最后一个 '.' 的位置 - size_t pos = file_path_.find_last_of(L'.'); - // 判断 pos 是否是有效位置 - if (pos != std::wstring::npos) + bool File::Exists() const { - // 截取扩展名 - file_ext = file_path_.substr(pos); - // 转换为小写字母 - std::transform(file_ext.begin(), file_ext.end(), file_ext.begin(), std::towlower); + if (::PathFileExists(file_path_.c_str())) + return true; + return false; } - return file_ext; -} -bool easy2d::File::Delete() -{ - if (::DeleteFile(file_path_.c_str())) - return true; - return false; -} + const std::wstring& File::GetPath() const + { + return file_path_; + } -easy2d::File easy2d::File::Extract(Resource& res, const std::wstring& dest_file_name) -{ - File file; - HANDLE file_handle = ::CreateFile( - dest_file_name.c_str(), - GENERIC_WRITE, - NULL, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY, - NULL - ); + std::wstring File::GetExtension() const + { + std::wstring file_ext; + // 找到文件名中的最后一个 '.' 的位置 + size_t pos = file_path_.find_last_of(L'.'); + // 判断 pos 是否是有效位置 + if (pos != std::wstring::npos) + { + // 截取扩展名 + file_ext = file_path_.substr(pos); + // 转换为小写字母 + std::transform(file_ext.begin(), file_ext.end(), file_ext.begin(), std::towlower); + } + return file_ext; + } + + bool File::Delete() + { + if (::DeleteFile(file_path_.c_str())) + return true; + return false; + } + + File File::Extract(Resource& res, const std::wstring& dest_file_name) + { + File file; + HANDLE file_handle = ::CreateFile( + dest_file_name.c_str(), + GENERIC_WRITE, + NULL, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY, + NULL + ); + + if (file_handle == INVALID_HANDLE_VALUE) + return file; + + if (res.Load()) + { + // 写入文件 + DWORD written_bytes = 0; + ::WriteFile(file_handle, res.GetData(), res.GetDataSize(), &written_bytes, NULL); + ::CloseHandle(file_handle); + + file.Open(dest_file_name); + } + else + { + ::CloseHandle(file_handle); + ::DeleteFile(dest_file_name.c_str()); + } - if (file_handle == INVALID_HANDLE_VALUE) return file; - - if (res.Load()) - { - // 写入文件 - DWORD written_bytes = 0; - ::WriteFile(file_handle, res.GetData(), res.GetDataSize(), &written_bytes, NULL); - ::CloseHandle(file_handle); - - file.Open(dest_file_name); - } - else - { - ::CloseHandle(file_handle); - ::DeleteFile(dest_file_name.c_str()); } - return file; -} - -void easy2d::File::AddSearchPath(const std::wstring & path) -{ - std::wstring tmp = path; - size_t pos = 0; - while ((pos = tmp.find(L"/", pos)) != std::wstring::npos) + void File::AddSearchPath(const std::wstring & path) { - tmp.replace(pos, 1, L"\\"); - pos++; + std::wstring tmp = path; + size_t pos = 0; + while ((pos = tmp.find(L"/", pos)) != std::wstring::npos) + { + tmp.replace(pos, 1, L"\\"); + pos++; + } + + if (tmp.at(tmp.length() - 1) != L'\\') + { + tmp.append(L"\\"); + } + auto iter = std::find(search_paths_.cbegin(), search_paths_.cend(), tmp); + if (iter == search_paths_.cend()) + { + search_paths_.push_front(path); + } } - if (tmp.at(tmp.length() - 1) != L'\\') + File File::ShowOpenDialog(const std::wstring & title, const std::wstring & filter) { - tmp.append(L"\\"); - } - auto iter = std::find(search_paths_.cbegin(), search_paths_.cend(), tmp); - if (iter == search_paths_.cend()) - { - search_paths_.push_front(path); - } -} - -easy2d::File easy2d::File::ShowOpenDialog(const std::wstring & title, const std::wstring & filter) -{ - std::wstring file_path; - HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - - if (SUCCEEDED(hr)) - { - IFileOpenDialog *file_open; - - hr = ::CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, - IID_IFileOpenDialog, reinterpret_cast(&file_open)); + std::wstring file_path; + HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { - if (!title.empty()) - { - file_open->SetTitle(title.c_str()); - } + IFileOpenDialog *file_open; - if (!filter.empty()) - { - COMDLG_FILTERSPEC spec[] = - { - { L"", filter.c_str() } - }; - file_open->SetFileTypes(1, spec); - } - else - { - COMDLG_FILTERSPEC spec[] = - { - { L"所有文件", L"*.*" } - }; - file_open->SetFileTypes(1, spec); - } - - hr = file_open->Show(nullptr); + hr = ::CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, + IID_IFileOpenDialog, reinterpret_cast(&file_open)); if (SUCCEEDED(hr)) { - IShellItem *item; - hr = file_open->GetResult(&item); + if (!title.empty()) + { + file_open->SetTitle(title.c_str()); + } + + if (!filter.empty()) + { + COMDLG_FILTERSPEC spec[] = + { + { L"", filter.c_str() } + }; + file_open->SetFileTypes(1, spec); + } + else + { + COMDLG_FILTERSPEC spec[] = + { + { L"所有文件", L"*.*" } + }; + file_open->SetFileTypes(1, spec); + } + + hr = file_open->Show(nullptr); + if (SUCCEEDED(hr)) { - PWSTR str_file_path; - hr = item->GetDisplayName(SIGDN_FILESYSPATH, &str_file_path); - + IShellItem *item; + hr = file_open->GetResult(&item); if (SUCCEEDED(hr)) { - file_path = str_file_path; - ::CoTaskMemFree(str_file_path); + PWSTR str_file_path; + hr = item->GetDisplayName(SIGDN_FILESYSPATH, &str_file_path); + + if (SUCCEEDED(hr)) + { + file_path = str_file_path; + ::CoTaskMemFree(str_file_path); + } + item->Release(); } - item->Release(); } + file_open->Release(); } - file_open->Release(); + ::CoUninitialize(); } - ::CoUninitialize(); + return File(file_path); } - return File(file_path); -} -easy2d::File easy2d::File::ShowSaveDialog(const std::wstring & title, const std::wstring& def_file, const std::wstring & def_ext) -{ - std::wstring file_path; - HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - - if (SUCCEEDED(hr)) + File File::ShowSaveDialog(const std::wstring & title, const std::wstring& def_file, const std::wstring & def_ext) { - IFileSaveDialog *file_save; - - hr = ::CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, - IID_IFileSaveDialog, reinterpret_cast(&file_save)); + std::wstring file_path; + HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { - if (!title.empty()) - { - file_save->SetTitle(title.c_str()); - } + IFileSaveDialog *file_save; - if (!def_file.empty()) - { - file_save->SetFileName(def_file.c_str()); - } - - if (!def_ext.empty()) - { - file_save->SetDefaultExtension(def_ext.c_str()); - - std::wstring ext = L"*." + def_ext; - COMDLG_FILTERSPEC spec[] = - { - { L"", ext.c_str() } - }; - file_save->SetFileTypes(1, spec); - } - else - { - COMDLG_FILTERSPEC spec[] = - { - { L"所有文件", L"*.*" } - }; - file_save->SetFileTypes(1, spec); - } - - hr = file_save->Show(nullptr); + hr = ::CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, + IID_IFileSaveDialog, reinterpret_cast(&file_save)); if (SUCCEEDED(hr)) { - IShellItem *item; - hr = file_save->GetResult(&item); + if (!title.empty()) + { + file_save->SetTitle(title.c_str()); + } + + if (!def_file.empty()) + { + file_save->SetFileName(def_file.c_str()); + } + + if (!def_ext.empty()) + { + file_save->SetDefaultExtension(def_ext.c_str()); + + std::wstring ext = L"*." + def_ext; + COMDLG_FILTERSPEC spec[] = + { + { L"", ext.c_str() } + }; + file_save->SetFileTypes(1, spec); + } + else + { + COMDLG_FILTERSPEC spec[] = + { + { L"所有文件", L"*.*" } + }; + file_save->SetFileTypes(1, spec); + } + + hr = file_save->Show(nullptr); + if (SUCCEEDED(hr)) { - PWSTR str_file_path; - hr = item->GetDisplayName(SIGDN_FILESYSPATH, &str_file_path); - + IShellItem *item; + hr = file_save->GetResult(&item); if (SUCCEEDED(hr)) { - file_path = str_file_path; - ::CoTaskMemFree(str_file_path); + PWSTR str_file_path; + hr = item->GetDisplayName(SIGDN_FILESYSPATH, &str_file_path); + + if (SUCCEEDED(hr)) + { + file_path = str_file_path; + ::CoTaskMemFree(str_file_path); + } + item->Release(); } - item->Release(); } + file_save->Release(); } - file_save->Release(); + ::CoUninitialize(); } - ::CoUninitialize(); + return File(file_path); } - return File(file_path); -} +} \ No newline at end of file diff --git a/core/tools/Music.cpp b/core/tools/Music.cpp index fe16a2b3..4e07a1f9 100644 --- a/core/tools/Music.cpp +++ b/core/tools/Music.cpp @@ -22,38 +22,40 @@ #include "..\e2dmodule.h" -namespace -{ - void OutputDebugStringExW(LPCWSTR pszOutput, ...) - { - va_list args = NULL; - va_start(args, pszOutput); - - size_t nLen = _vscwprintf(pszOutput, args) + 1; - wchar_t* psBuffer = new wchar_t[nLen]; - _vsnwprintf_s(psBuffer, nLen, nLen, pszOutput, args); - - va_end(args); - - ::OutputDebugStringW(psBuffer); - delete[] psBuffer; - } - - inline void TraceError(LPCWSTR output) - { - OutputDebugStringExW(L"[easy2d] Music error: %s failed!\r\n", output); - } - - inline void TraceError(LPCWSTR output, HRESULT hr) - { - OutputDebugStringExW(L"[easy2d] Music error: %s (%#X)\r\n", output, hr); - } -} - - namespace easy2d { - // 音频解码器 + namespace + { + void OutputDebugStringExW(LPCWSTR pszOutput, ...) + { + va_list args = NULL; + va_start(args, pszOutput); + + size_t nLen = _vscwprintf(pszOutput, args) + 1; + wchar_t* psBuffer = new wchar_t[nLen]; + _vsnwprintf_s(psBuffer, nLen, nLen, pszOutput, args); + + va_end(args); + + ::OutputDebugStringW(psBuffer); + delete[] psBuffer; + } + + inline void TraceError(LPCWSTR output) + { + OutputDebugStringExW(L"[easy2d] Music error: %s failed!\r\n", output); + } + + inline void TraceError(LPCWSTR output, HRESULT hr) + { + OutputDebugStringExW(L"[easy2d] Music error: %s (%#X)\r\n", output, hr); + } + } + + //------------------------------------------------------- + // Transcoder + //------------------------------------------------------- + class Transcoder { WAVEFORMATEX* wave_format_; @@ -304,252 +306,255 @@ namespace easy2d } }; -} + //------------------------------------------------------- + // Music + //------------------------------------------------------- -easy2d::Music::Music() - : opened_(false) - , playing_(false) - , wave_data_(nullptr) - , size_(0) - , voice_(nullptr) -{ -} + Music::Music() + : opened_(false) + , playing_(false) + , wave_data_(nullptr) + , size_(0) + , voice_(nullptr) + { + } -easy2d::Music::Music(const std::wstring& file_path) - : opened_(false) - , playing_(false) - , wave_data_(nullptr) - , size_(0) - , voice_(nullptr) -{ - Load(file_path); -} + Music::Music(const std::wstring& file_path) + : opened_(false) + , playing_(false) + , wave_data_(nullptr) + , size_(0) + , voice_(nullptr) + { + Load(file_path); + } -easy2d::Music::Music(Resource& res) - : opened_(false) - , playing_(false) - , wave_data_(nullptr) - , size_(0) - , voice_(nullptr) -{ - Load(res); -} + Music::Music(Resource& res) + : opened_(false) + , playing_(false) + , wave_data_(nullptr) + , size_(0) + , voice_(nullptr) + { + Load(res); + } -easy2d::Music::~Music() -{ - Close(); -} - -bool easy2d::Music::Load(const std::wstring & file_path) -{ - if (opened_) + Music::~Music() { Close(); } - File music_file; - if (!music_file.Open(file_path)) + bool Music::Load(const std::wstring & file_path) { - E2D_WARNING("Media file not found."); - return false; - } - - // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加 - // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 - std::wstring music_file_path = music_file.GetPath(); - - Transcoder transcoder; - if (!transcoder.LoadMediaFile(music_file_path.c_str(), &wave_data_, &size_)) - { - return false; - } - - HRESULT hr = Device::GetAudio()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); - if (FAILED(hr)) - { - if (wave_data_) + if (opened_) { - delete[] wave_data_; - wave_data_ = nullptr; + Close(); } - TraceError(L"Create source voice error", hr); - return false; - } - opened_ = true; - return true; -} - -bool easy2d::Music::Load(Resource& res) -{ - if (opened_) - { - Close(); - } - - Transcoder transcoder; - if (!transcoder.LoadMediaResource(res, &wave_data_, &size_)) - { - return false; - } - - HRESULT hr = Device::GetAudio()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); - if (FAILED(hr)) - { - if (wave_data_) + File music_file; + if (!music_file.Open(file_path)) { - delete[] wave_data_; - wave_data_ = nullptr; + E2D_WARNING("Media file not found."); + return false; } - TraceError(L"Create source voice error", hr); - return false; - } - opened_ = true; - return true; -} + // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加 + // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 + std::wstring music_file_path = music_file.GetPath(); -bool easy2d::Music::Play(int loop_count) -{ - if (!opened_) - { - E2D_WARNING("Music must be opened first!"); - return false; - } - - if (voice_ == nullptr) - { - E2D_WARNING("IXAudio2SourceVoice Null pointer exception!"); - return false; - } - - XAUDIO2_VOICE_STATE state; - voice_->GetState(&state); - if (state.BuffersQueued) - { - Stop(); - } - - if (loop_count < 0) - { - loop_count = XAUDIO2_LOOP_INFINITE; - } - else - { - loop_count = std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1); - } - - // 提交 wave 样本数据 - XAUDIO2_BUFFER buffer = { 0 }; - buffer.pAudioData = wave_data_; - buffer.Flags = XAUDIO2_END_OF_STREAM; - buffer.AudioBytes = size_; - buffer.LoopCount = loop_count; - - HRESULT hr; - if (FAILED(hr = voice_->SubmitSourceBuffer(&buffer))) - { - TraceError(L"Submitting source buffer error", hr); - return false; - } - - hr = voice_->Start(0); - - playing_ = SUCCEEDED(hr); - - return playing_; -} - -void easy2d::Music::Pause() -{ - if (voice_) - { - if (SUCCEEDED(voice_->Stop())) + Transcoder transcoder; + if (!transcoder.LoadMediaFile(music_file_path.c_str(), &wave_data_, &size_)) { - playing_ = false; + return false; } - } -} -void easy2d::Music::Resume() -{ - if (voice_) - { - if (SUCCEEDED(voice_->Start())) + HRESULT hr = Device::GetAudio()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); + if (FAILED(hr)) { - playing_ = true; + if (wave_data_) + { + delete[] wave_data_; + wave_data_ = nullptr; + } + TraceError(L"Create source voice error", hr); + return false; } - } -} -void easy2d::Music::Stop() -{ - if (voice_) + opened_ = true; + return true; + } + + bool Music::Load(Resource& res) { - if (SUCCEEDED(voice_->Stop())) + if (opened_) { - voice_->ExitLoop(); - voice_->FlushSourceBuffers(); - playing_ = false; + Close(); } - } -} -void easy2d::Music::Close() -{ - if (voice_) - { - voice_->Stop(); - voice_->FlushSourceBuffers(); - voice_->DestroyVoice(); - voice_ = nullptr; + Transcoder transcoder; + if (!transcoder.LoadMediaResource(res, &wave_data_, &size_)) + { + return false; + } + + HRESULT hr = Device::GetAudio()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); + if (FAILED(hr)) + { + if (wave_data_) + { + delete[] wave_data_; + wave_data_ = nullptr; + } + TraceError(L"Create source voice error", hr); + return false; + } + + opened_ = true; + return true; } - if (wave_data_) + bool Music::Play(int loop_count) { - delete[] wave_data_; - wave_data_ = nullptr; - } + if (!opened_) + { + E2D_WARNING("Music must be opened first!"); + return false; + } - opened_ = false; - playing_ = false; -} + if (voice_ == nullptr) + { + E2D_WARNING("IXAudio2SourceVoice Null pointer exception!"); + return false; + } -bool easy2d::Music::IsPlaying() const -{ - if (opened_ && voice_) - { XAUDIO2_VOICE_STATE state; voice_->GetState(&state); - if (state.BuffersQueued && playing_) - return true; - } - return false; -} + if (state.BuffersQueued) + { + Stop(); + } -float easy2d::Music::GetVolume() const -{ - if (voice_) + if (loop_count < 0) + { + loop_count = XAUDIO2_LOOP_INFINITE; + } + else + { + loop_count = std::min(loop_count, XAUDIO2_LOOP_INFINITE - 1); + } + + // 提交 wave 样本数据 + XAUDIO2_BUFFER buffer = { 0 }; + buffer.pAudioData = wave_data_; + buffer.Flags = XAUDIO2_END_OF_STREAM; + buffer.AudioBytes = size_; + buffer.LoopCount = loop_count; + + HRESULT hr; + if (FAILED(hr = voice_->SubmitSourceBuffer(&buffer))) + { + TraceError(L"Submitting source buffer error", hr); + return false; + } + + hr = voice_->Start(0); + + playing_ = SUCCEEDED(hr); + + return playing_; + } + + void Music::Pause() { - float volume = 0.f; - voice_->GetVolume(&volume); - return volume; + if (voice_) + { + if (SUCCEEDED(voice_->Stop())) + { + playing_ = false; + } + } } - return 0.f; -} -bool easy2d::Music::SetVolume(float volume) -{ - if (voice_) + void Music::Resume() { - volume = std::min(std::max(volume, -224.f), 224.f); - return SUCCEEDED(voice_->SetVolume(volume)); + if (voice_) + { + if (SUCCEEDED(voice_->Start())) + { + playing_ = true; + } + } } - return false; -} -IXAudio2SourceVoice * easy2d::Music::GetSourceVoice() const -{ - return voice_; -} + void Music::Stop() + { + if (voice_) + { + if (SUCCEEDED(voice_->Stop())) + { + voice_->ExitLoop(); + voice_->FlushSourceBuffers(); + playing_ = false; + } + } + } + + void Music::Close() + { + if (voice_) + { + voice_->Stop(); + voice_->FlushSourceBuffers(); + voice_->DestroyVoice(); + voice_ = nullptr; + } + + if (wave_data_) + { + delete[] wave_data_; + wave_data_ = nullptr; + } + + opened_ = false; + playing_ = false; + } + + bool Music::IsPlaying() const + { + if (opened_ && voice_) + { + XAUDIO2_VOICE_STATE state; + voice_->GetState(&state); + if (state.BuffersQueued && playing_) + return true; + } + return false; + } + + float Music::GetVolume() const + { + if (voice_) + { + float volume = 0.f; + voice_->GetVolume(&volume); + return volume; + } + return 0.f; + } + + bool Music::SetVolume(float volume) + { + if (voice_) + { + volume = std::min(std::max(volume, -224.f), 224.f); + return SUCCEEDED(voice_->SetVolume(volume)); + } + return false; + } + + IXAudio2SourceVoice * Music::GetSourceVoice() const + { + return voice_; + } +} \ No newline at end of file diff --git a/core/tools/Path.cpp b/core/tools/Path.cpp index 4ad87fb4..7938874e 100644 --- a/core/tools/Path.cpp +++ b/core/tools/Path.cpp @@ -23,115 +23,118 @@ #include -namespace +namespace easy2d { - // 创建指定文件夹 - bool CreateFolder(const std::wstring & dir_path) + namespace { - if (dir_path.empty() || dir_path.size() >= MAX_PATH) - return false; - - wchar_t tmp_dir_path[MAX_PATH] = { 0 }; - size_t length = dir_path.length(); - - for (size_t i = 0; i < length; ++i) + // 创建指定文件夹 + bool CreateFolder(const std::wstring & dir_path) { - tmp_dir_path[i] = dir_path.at(i); - if (tmp_dir_path[i] == L'\\' || tmp_dir_path[i] == L'/' || i == (length - 1)) + if (dir_path.empty() || dir_path.size() >= MAX_PATH) + return false; + + wchar_t tmp_dir_path[MAX_PATH] = { 0 }; + size_t length = dir_path.length(); + + for (size_t i = 0; i < length; ++i) { - if (::_waccess(tmp_dir_path, 0) != 0) + tmp_dir_path[i] = dir_path.at(i); + if (tmp_dir_path[i] == L'\\' || tmp_dir_path[i] == L'/' || i == (length - 1)) { - if (::_wmkdir(tmp_dir_path) != 0) + if (::_waccess(tmp_dir_path, 0) != 0) { - return false; + if (::_wmkdir(tmp_dir_path) != 0) + { + return false; + } } } } + return true; } - return true; } -} -const std::wstring& easy2d::Path::GetDataPath() -{ - static std::wstring data_path; - if (data_path.empty()) + const std::wstring& Path::GetDataPath() { - // 设置数据的保存路径 - std::wstring local_app_data_path = Path::GetLocalAppDataPath(); - std::wstring title = Game::GetInstance()->GetTitle(); - std::wstring folder_name = std::to_wstring(std::hash{}(title)); - - if (!local_app_data_path.empty()) + static std::wstring data_path; + if (data_path.empty()) { - data_path.append(local_app_data_path) - .append(L"\\Easy2DGameData\\") - .append(folder_name) - .append(L"\\"); + // 设置数据的保存路径 + std::wstring local_app_data_path = Path::GetLocalAppDataPath(); + std::wstring title = Game::GetInstance()->GetTitle(); + std::wstring folder_name = std::to_wstring(std::hash{}(title)); - File file(data_path); - if (!file.Exists() && !CreateFolder(data_path)) + if (!local_app_data_path.empty()) { - data_path = L""; + data_path.append(local_app_data_path) + .append(L"\\Easy2DGameData\\") + .append(folder_name) + .append(L"\\"); + + File file(data_path); + if (!file.Exists() && !CreateFolder(data_path)) + { + data_path = L""; + } + } + data_path.append(L"Data.ini"); + } + return data_path; + } + + const std::wstring& Path::GetTemporaryPath() + { + static std::wstring temp_path; + if (temp_path.empty()) + { + // 设置临时文件保存路径 + wchar_t path[_MAX_PATH]; + std::wstring title = Game::GetInstance()->GetTitle(); + std::wstring folder_name = std::to_wstring(std::hash{}(title)); + + if (0 != ::GetTempPath(_MAX_PATH, path)) + { + temp_path.append(path) + .append(L"\\Easy2DGameTemp\\") + .append(folder_name) + .append(L"\\"); + + File file(temp_path); + if (!file.Exists() && !CreateFolder(temp_path)) + { + temp_path = L""; + } } } - data_path.append(L"Data.ini"); + return temp_path; } - return data_path; -} -const std::wstring& easy2d::Path::GetTemporaryPath() -{ - static std::wstring temp_path; - if (temp_path.empty()) + const std::wstring& Path::GetLocalAppDataPath() { - // 设置临时文件保存路径 - wchar_t path[_MAX_PATH]; - std::wstring title = Game::GetInstance()->GetTitle(); - std::wstring folder_name = std::to_wstring(std::hash{}(title)); - - if (0 != ::GetTempPath(_MAX_PATH, path)) + static std::wstring local_app_data_path; + if (local_app_data_path.empty()) { - temp_path.append(path) - .append(L"\\Easy2DGameTemp\\") - .append(folder_name) - .append(L"\\"); + // 获取 AppData/Local 文件夹的路径 + wchar_t path[MAX_PATH] = { 0 }; + ::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path); + local_app_data_path = path; + } - File file(temp_path); - if (!file.Exists() && !CreateFolder(temp_path)) + return local_app_data_path; + } + + const std::wstring& Path::GetExeFilePath() + { + static std::wstring exe_file_path; + if (exe_file_path.empty()) + { + TCHAR path[_MAX_PATH] = { 0 }; + if (::GetModuleFileName(nullptr, path, _MAX_PATH) != 0) { - temp_path = L""; + exe_file_path = path; } } + return exe_file_path; } - return temp_path; -} - -const std::wstring& easy2d::Path::GetLocalAppDataPath() -{ - static std::wstring local_app_data_path; - if (local_app_data_path.empty()) - { - // 获取 AppData/Local 文件夹的路径 - wchar_t path[MAX_PATH] = { 0 }; - ::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path); - local_app_data_path = path; - } - - return local_app_data_path; -} - -const std::wstring& easy2d::Path::GetExeFilePath() -{ - static std::wstring exe_file_path; - if (exe_file_path.empty()) - { - TCHAR path[_MAX_PATH] = { 0 }; - if (::GetModuleFileName(nullptr, path, _MAX_PATH) != 0) - { - exe_file_path = path; - } - } - return exe_file_path; -} +} \ No newline at end of file diff --git a/core/tools/Player.cpp b/core/tools/Player.cpp index 4c990fe0..384e6fa8 100644 --- a/core/tools/Player.cpp +++ b/core/tools/Player.cpp @@ -1,212 +1,215 @@ #include "..\e2dtool.h" -std::map easy2d::Player::musics_; - -easy2d::Player::Player() - : volume_(1.f) +namespace easy2d { -} + std::map Player::musics_; -easy2d::Player::~Player() -{ -} - -bool easy2d::Player::Load(const std::wstring & file_path) -{ - if (file_path.empty()) - return false; - - Music * music = new (std::nothrow) Music(); - - if (music) + Player::Player() + : volume_(1.f) { - if (music->Load(file_path)) - { - music->SetVolume(volume_); - - size_t hash_code = std::hash{}(file_path); - musics_.insert(std::make_pair(hash_code, music)); - return true; - } - else - { - music->Release(); - } } - return false; -} -bool easy2d::Player::Play(const std::wstring & file_path, int loop_count) -{ - if (file_path.empty()) - return false; - - if (Load(file_path)) + Player::~Player() { - auto music = musics_[std::hash{}(file_path)]; - if (music->Play(loop_count)) - { - return true; - } } - return false; -} -void easy2d::Player::Pause(const std::wstring & file_path) -{ - if (file_path.empty()) - return; - - size_t hash_code = std::hash{}(file_path); - if (musics_.end() != musics_.find(hash_code)) - musics_[hash_code]->Pause(); -} - -void easy2d::Player::Resume(const std::wstring & file_path) -{ - if (file_path.empty()) - return; - - size_t hash_code = std::hash{}(file_path); - if (musics_.end() != musics_.find(hash_code)) - musics_[hash_code]->Resume(); -} - -void easy2d::Player::Stop(const std::wstring & file_path) -{ - if (file_path.empty()) - return; - - size_t hash_code = std::hash{}(file_path); - if (musics_.end() != musics_.find(hash_code)) - musics_[hash_code]->Stop(); -} - -bool easy2d::Player::IsPlaying(const std::wstring & file_path) -{ - if (file_path.empty()) - return false; - - size_t hash_code = std::hash{}(file_path); - if (musics_.end() != musics_.find(hash_code)) - return musics_[hash_code]->IsPlaying(); - return false; -} - -bool easy2d::Player::Load(Resource& res) -{ - size_t hash_code = res.GetHashCode(); - if (musics_.end() != musics_.find(hash_code)) - return true; - - Music * music = new (std::nothrow) Music(); - - if (music) + bool Player::Load(const std::wstring & file_path) { - if (music->Load(res)) - { - music->SetVolume(volume_); - musics_.insert(std::make_pair(hash_code, music)); - return true; - } - else - { - music->Release(); - } - } - return false; -} + if (file_path.empty()) + return false; -bool easy2d::Player::Play(Resource& res, int loop_count) -{ - if (Load(res)) + Music * music = new (std::nothrow) Music(); + + if (music) + { + if (music->Load(file_path)) + { + music->SetVolume(volume_); + + size_t hash_code = std::hash{}(file_path); + musics_.insert(std::make_pair(hash_code, music)); + return true; + } + else + { + music->Release(); + } + } + return false; + } + + bool Player::Play(const std::wstring & file_path, int loop_count) + { + if (file_path.empty()) + return false; + + if (Load(file_path)) + { + auto music = musics_[std::hash{}(file_path)]; + if (music->Play(loop_count)) + { + return true; + } + } + return false; + } + + void Player::Pause(const std::wstring & file_path) + { + if (file_path.empty()) + return; + + size_t hash_code = std::hash{}(file_path); + if (musics_.end() != musics_.find(hash_code)) + musics_[hash_code]->Pause(); + } + + void Player::Resume(const std::wstring & file_path) + { + if (file_path.empty()) + return; + + size_t hash_code = std::hash{}(file_path); + if (musics_.end() != musics_.find(hash_code)) + musics_[hash_code]->Resume(); + } + + void Player::Stop(const std::wstring & file_path) + { + if (file_path.empty()) + return; + + size_t hash_code = std::hash{}(file_path); + if (musics_.end() != musics_.find(hash_code)) + musics_[hash_code]->Stop(); + } + + bool Player::IsPlaying(const std::wstring & file_path) + { + if (file_path.empty()) + return false; + + size_t hash_code = std::hash{}(file_path); + if (musics_.end() != musics_.find(hash_code)) + return musics_[hash_code]->IsPlaying(); + return false; + } + + bool Player::Load(Resource& res) { size_t hash_code = res.GetHashCode(); - auto music = musics_[hash_code]; - if (music->Play(loop_count)) - { + if (musics_.end() != musics_.find(hash_code)) return true; + + Music * music = new (std::nothrow) Music(); + + if (music) + { + if (music->Load(res)) + { + music->SetVolume(volume_); + musics_.insert(std::make_pair(hash_code, music)); + return true; + } + else + { + music->Release(); + } + } + return false; + } + + bool Player::Play(Resource& res, int loop_count) + { + if (Load(res)) + { + size_t hash_code = res.GetHashCode(); + auto music = musics_[hash_code]; + if (music->Play(loop_count)) + { + return true; + } + } + return false; + } + + void Player::Pause(Resource& res) + { + size_t hash_code = res.GetHashCode(); + if (musics_.end() != musics_.find(hash_code)) + musics_[hash_code]->Pause(); + } + + void Player::Resume(Resource& res) + { + size_t hash_code = res.GetHashCode(); + if (musics_.end() != musics_.find(hash_code)) + musics_[hash_code]->Resume(); + } + + void Player::Stop(Resource& res) + { + size_t hash_code = res.GetHashCode(); + if (musics_.end() != musics_.find(hash_code)) + musics_[hash_code]->Stop(); + } + + bool Player::IsPlaying(Resource& res) + { + size_t hash_code = res.GetHashCode(); + if (musics_.end() != musics_.find(hash_code)) + return musics_[hash_code]->IsPlaying(); + return false; + } + + float Player::GetVolume() const + { + return volume_; + } + + void Player::SetVolume(float volume) + { + volume_ = std::min(std::max(volume, -224.f), 224.f); + for (const auto& pair : musics_) + { + pair.second->SetVolume(volume_); } } - return false; -} -void easy2d::Player::Pause(Resource& res) -{ - size_t hash_code = res.GetHashCode(); - if (musics_.end() != musics_.find(hash_code)) - musics_[hash_code]->Pause(); -} - -void easy2d::Player::Resume(Resource& res) -{ - size_t hash_code = res.GetHashCode(); - if (musics_.end() != musics_.find(hash_code)) - musics_[hash_code]->Resume(); -} - -void easy2d::Player::Stop(Resource& res) -{ - size_t hash_code = res.GetHashCode(); - if (musics_.end() != musics_.find(hash_code)) - musics_[hash_code]->Stop(); -} - -bool easy2d::Player::IsPlaying(Resource& res) -{ - size_t hash_code = res.GetHashCode(); - if (musics_.end() != musics_.find(hash_code)) - return musics_[hash_code]->IsPlaying(); - return false; -} - -float easy2d::Player::GetVolume() const -{ - return volume_; -} - -void easy2d::Player::SetVolume(float volume) -{ - volume_ = std::min(std::max(volume, -224.f), 224.f); - for (const auto& pair : musics_) + void Player::PauseAll() { - pair.second->SetVolume(volume_); + for (const auto& pair : musics_) + { + pair.second->Pause(); + } } -} -void easy2d::Player::PauseAll() -{ - for (const auto& pair : musics_) + void Player::ResumeAll() { - pair.second->Pause(); + for (const auto& pair : musics_) + { + pair.second->Resume(); + } } -} -void easy2d::Player::ResumeAll() -{ - for (const auto& pair : musics_) + void Player::StopAll() { - pair.second->Resume(); + for (const auto& pair : musics_) + { + pair.second->Stop(); + } } -} -void easy2d::Player::StopAll() -{ - for (const auto& pair : musics_) + void Player::ClearCache() { - pair.second->Stop(); - } -} + if (musics_.empty()) + return; -void easy2d::Player::ClearCache() -{ - if (musics_.empty()) - return; - - for (const auto& pair : musics_) - { - pair.second->Release(); + for (const auto& pair : musics_) + { + pair.second->Release(); + } + musics_.clear(); } - musics_.clear(); -} +} \ No newline at end of file diff --git a/core/transitions/BoxTransition.cpp b/core/transitions/BoxTransition.cpp index 487d4332..74c1c3a4 100644 --- a/core/transitions/BoxTransition.cpp +++ b/core/transitions/BoxTransition.cpp @@ -21,40 +21,43 @@ #include "..\e2dtransition.h" #include "..\e2dobject.h" -easy2d::BoxTransition::BoxTransition(float duration) - : Transition(duration) +namespace easy2d { -} - -void easy2d::BoxTransition::Init(Scene * prev, Scene * next, Game * game) -{ - Transition::Init(prev, next, game); - - in_layer_param_.opacity = 0; -} - -void easy2d::BoxTransition::Update() -{ - Transition::Update(); - - if (process_ < .5f) + BoxTransition::BoxTransition(float duration) + : Transition(duration) { - out_layer_param_.contentBounds = D2D1::RectF( - window_size_.width * process_, - window_size_.height * process_, - window_size_.width * (1 - process_), - window_size_.height * (1 - process_) - ); } - else + + void BoxTransition::Init(Scene * prev, Scene * next, Game * game) { - out_layer_param_.opacity = 0; - in_layer_param_.opacity = 1; - in_layer_param_.contentBounds = D2D1::RectF( - window_size_.width * (1 - process_), - window_size_.height * (1 - process_), - window_size_.width * process_, - window_size_.height * process_ - ); + Transition::Init(prev, next, game); + + in_layer_param_.opacity = 0; } -} + + void BoxTransition::Update() + { + Transition::Update(); + + if (process_ < .5f) + { + out_layer_param_.contentBounds = D2D1::RectF( + window_size_.width * process_, + window_size_.height * process_, + window_size_.width * (1 - process_), + window_size_.height * (1 - process_) + ); + } + else + { + out_layer_param_.opacity = 0; + in_layer_param_.opacity = 1; + in_layer_param_.contentBounds = D2D1::RectF( + window_size_.width * (1 - process_), + window_size_.height * (1 - process_), + window_size_.width * process_, + window_size_.height * process_ + ); + } + } +} \ No newline at end of file diff --git a/core/transitions/EmergeTransition.cpp b/core/transitions/EmergeTransition.cpp index 37e315dd..b95b91db 100644 --- a/core/transitions/EmergeTransition.cpp +++ b/core/transitions/EmergeTransition.cpp @@ -21,23 +21,26 @@ #include "..\e2dtransition.h" #include "..\e2dobject.h" -easy2d::EmergeTransition::EmergeTransition(float duration) - : Transition(duration) +namespace easy2d { -} + EmergeTransition::EmergeTransition(float duration) + : Transition(duration) + { + } -void easy2d::EmergeTransition::Init(Scene * prev, Scene * next, Game * game) -{ - Transition::Init(prev, next, game); - - out_layer_param_.opacity = 1; - in_layer_param_.opacity = 0; -} + void EmergeTransition::Init(Scene * prev, Scene * next, Game * game) + { + Transition::Init(prev, next, game); -void easy2d::EmergeTransition::Update() -{ - Transition::Update(); + out_layer_param_.opacity = 1; + in_layer_param_.opacity = 0; + } - out_layer_param_.opacity = 1 - process_; - in_layer_param_.opacity = process_; -} + void EmergeTransition::Update() + { + Transition::Update(); + + out_layer_param_.opacity = 1 - process_; + in_layer_param_.opacity = process_; + } +} \ No newline at end of file diff --git a/core/transitions/FadeTransition.cpp b/core/transitions/FadeTransition.cpp index 1224e605..f8c2704a 100644 --- a/core/transitions/FadeTransition.cpp +++ b/core/transitions/FadeTransition.cpp @@ -21,31 +21,34 @@ #include "..\e2dtransition.h" #include "..\e2dobject.h" -easy2d::FadeTransition::FadeTransition(float duration) - : Transition(duration) +namespace easy2d { -} - -void easy2d::FadeTransition::Init(Scene * prev, Scene * next, Game * game) -{ - Transition::Init(prev, next, game); - - out_layer_param_.opacity = 1; - in_layer_param_.opacity = 0; -} - -void easy2d::FadeTransition::Update() -{ - Transition::Update(); - - if (process_ < 0.5) + FadeTransition::FadeTransition(float duration) + : Transition(duration) { - out_layer_param_.opacity = 1 - process_ * 2; + } + + void FadeTransition::Init(Scene * prev, Scene * next, Game * game) + { + Transition::Init(prev, next, game); + + out_layer_param_.opacity = 1; in_layer_param_.opacity = 0; } - else + + void FadeTransition::Update() { - out_layer_param_.opacity = 0; - in_layer_param_.opacity = (process_ - 0.5f) * 2; + Transition::Update(); + + if (process_ < 0.5) + { + out_layer_param_.opacity = 1 - process_ * 2; + in_layer_param_.opacity = 0; + } + else + { + out_layer_param_.opacity = 0; + in_layer_param_.opacity = (process_ - 0.5f) * 2; + } } -} +} \ No newline at end of file diff --git a/core/transitions/MoveTransition.cpp b/core/transitions/MoveTransition.cpp index 30f5cadd..675efb9d 100644 --- a/core/transitions/MoveTransition.cpp +++ b/core/transitions/MoveTransition.cpp @@ -21,88 +21,91 @@ #include "..\e2dtransition.h" #include "..\e2dobject.h" -easy2d::MoveTransition::MoveTransition(float duration, Direction direction) - : Transition(duration) - , direction_(direction) +namespace easy2d { -} - -void easy2d::MoveTransition::Init(Scene * prev, Scene * next, Game * game) -{ - Transition::Init(prev, next, game); - - switch (direction_) + MoveTransition::MoveTransition(float duration, Direction direction) + : Transition(duration) + , direction_(direction) { - case Direction::Up: - pos_delta_ = Point(0, -window_size_.height); - start_pos_ = Point(0, window_size_.height); - break; - case Direction::Down: - pos_delta_ = Point(0, window_size_.height); - start_pos_ = Point(0, -window_size_.height); - break; - case Direction::Left: - pos_delta_ = Point(-window_size_.width, 0); - start_pos_ = Point(window_size_.width, 0); - break; - case Direction::Right: - pos_delta_ = Point(window_size_.width, 0); - start_pos_ = Point(-window_size_.width, 0); - break; } - if (out_scene_) + void MoveTransition::Init(Scene * prev, Scene * next, Game * game) { - out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); - } - - if (in_scene_) - { - in_scene_->SetTransform( - D2D1::Matrix3x2F::Translation( - start_pos_.x, - start_pos_.y - ) - ); - } -} + Transition::Init(prev, next, game); -void easy2d::MoveTransition::Update() -{ - Transition::Update(); + switch (direction_) + { + case Direction::Up: + pos_delta_ = Point(0, -window_size_.height); + start_pos_ = Point(0, window_size_.height); + break; + case Direction::Down: + pos_delta_ = Point(0, window_size_.height); + start_pos_ = Point(0, -window_size_.height); + break; + case Direction::Left: + pos_delta_ = Point(-window_size_.width, 0); + start_pos_ = Point(window_size_.width, 0); + break; + case Direction::Right: + pos_delta_ = Point(window_size_.width, 0); + start_pos_ = Point(-window_size_.width, 0); + break; + } - if (out_scene_) - { - auto translation = pos_delta_ * process_; - out_scene_->SetTransform( - D2D1::Matrix3x2F::Translation( - translation.x, - translation.y - ) - ); + if (out_scene_) + { + out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + } + + if (in_scene_) + { + in_scene_->SetTransform( + D2D1::Matrix3x2F::Translation( + start_pos_.x, + start_pos_.y + ) + ); + } } - if (in_scene_) + void MoveTransition::Update() { - auto translation = start_pos_ + pos_delta_ * process_; - in_scene_->SetTransform( - D2D1::Matrix3x2F::Translation( - translation.x, - translation.y - ) - ); - } -} + Transition::Update(); -void easy2d::MoveTransition::Reset() -{ - if (out_scene_) - { - out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + if (out_scene_) + { + auto translation = pos_delta_ * process_; + out_scene_->SetTransform( + D2D1::Matrix3x2F::Translation( + translation.x, + translation.y + ) + ); + } + + if (in_scene_) + { + auto translation = start_pos_ + pos_delta_ * process_; + in_scene_->SetTransform( + D2D1::Matrix3x2F::Translation( + translation.x, + translation.y + ) + ); + } } - - if (in_scene_) + + void MoveTransition::Reset() { - in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + if (out_scene_) + { + out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + } + + if (in_scene_) + { + in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + } } -} +} \ No newline at end of file diff --git a/core/transitions/RotationTransition.cpp b/core/transitions/RotationTransition.cpp index 8c4b02fa..9648efba 100644 --- a/core/transitions/RotationTransition.cpp +++ b/core/transitions/RotationTransition.cpp @@ -21,84 +21,87 @@ #include "..\e2dtransition.h" #include "..\e2dobject.h" -easy2d::RotationTransition::RotationTransition(float duration, float rotation) - : Transition(duration) - , rotation_(rotation) +namespace easy2d { -} - -void easy2d::RotationTransition::Init(Scene * prev, Scene * next, Game * game) -{ - Transition::Init(prev, next, game); - - if (out_scene_) + RotationTransition::RotationTransition(float duration, float rotation) + : Transition(duration) + , rotation_(rotation) { - out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); } - if (in_scene_) + void RotationTransition::Init(Scene * prev, Scene * next, Game * game) { - in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + Transition::Init(prev, next, game); + + if (out_scene_) + { + out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + } + + if (in_scene_) + { + in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); + } + + in_layer_param_.opacity = 0; } - in_layer_param_.opacity = 0; -} + void RotationTransition::Update() + { + Transition::Update(); -void easy2d::RotationTransition::Update() -{ - Transition::Update(); + auto center_pos = D2D1::Point2F( + window_size_.width / 2, + window_size_.height / 2 + ); - auto center_pos = D2D1::Point2F( - window_size_.width / 2, - window_size_.height / 2 - ); + if (process_ < .5f) + { + if (out_scene_) + { + out_scene_->SetTransform( + D2D1::Matrix3x2F::Scale( + (.5f - process_) * 2, + (.5f - process_) * 2, + center_pos + ) * D2D1::Matrix3x2F::Rotation( + rotation_ * (.5f - process_) * 2, + center_pos + ) + ); + } + } + else + { + if (in_scene_) + { + out_layer_param_.opacity = 0; + in_layer_param_.opacity = 1; - if (process_ < .5f) + in_scene_->SetTransform( + D2D1::Matrix3x2F::Scale( + (process_ - .5f) * 2, + (process_ - .5f) * 2, + center_pos + ) * D2D1::Matrix3x2F::Rotation( + rotation_ * (process_ - .5f) * 2, + center_pos + ) + ); + } + } + } + + void RotationTransition::Reset() { if (out_scene_) { - out_scene_->SetTransform( - D2D1::Matrix3x2F::Scale( - (.5f - process_) * 2, - (.5f - process_) * 2, - center_pos - ) * D2D1::Matrix3x2F::Rotation( - rotation_ * (.5f - process_) * 2, - center_pos - ) - ); + out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); } - } - else - { + if (in_scene_) { - out_layer_param_.opacity = 0; - in_layer_param_.opacity = 1; - - in_scene_->SetTransform( - D2D1::Matrix3x2F::Scale( - (process_ - .5f) * 2, - (process_ - .5f) * 2, - center_pos - ) * D2D1::Matrix3x2F::Rotation( - rotation_ * (process_ - .5f) * 2, - center_pos - ) - ); + in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); } } -} - -void easy2d::RotationTransition::Reset() -{ - if (out_scene_) - { - out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); - } - - if (in_scene_) - { - in_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); - } -} +} \ No newline at end of file diff --git a/core/transitions/Transition.cpp b/core/transitions/Transition.cpp index 635a6441..3ec33296 100644 --- a/core/transitions/Transition.cpp +++ b/core/transitions/Transition.cpp @@ -22,143 +22,146 @@ #include "..\e2dobject.h" #include "..\e2dmodule.h" -easy2d::Transition::Transition(float duration) - : done_(false) - , started_() - , process_(0) - , window_size_() - , out_scene_(nullptr) - , in_scene_(nullptr) - , out_layer_(nullptr) - , in_layer_(nullptr) - , out_layer_param_() - , in_layer_param_() +namespace easy2d { - duration_ = std::max(duration, 0.f); -} - -easy2d::Transition::~Transition() -{ - SafeRelease(out_layer_); - SafeRelease(in_layer_); - SafeRelease(out_scene_); - SafeRelease(in_scene_); -} - -bool easy2d::Transition::IsDone() -{ - return done_; -} - -void easy2d::Transition::Init(Scene * prev, Scene * next, Game * game) -{ - started_ = Time::Now(); - out_scene_ = prev; - in_scene_ = next; - - if (out_scene_) - out_scene_->Retain(); - - if (in_scene_) - in_scene_->Retain(); - - auto graphics = Device::GetGraphics(); - if (in_scene_) + Transition::Transition(float duration) + : done_(false) + , started_() + , process_(0) + , window_size_() + , out_scene_(nullptr) + , in_scene_(nullptr) + , out_layer_(nullptr) + , in_layer_(nullptr) + , out_layer_param_() + , in_layer_param_() { - ThrowIfFailed( - graphics->GetRenderTarget()->CreateLayer(&in_layer_) - ); + duration_ = std::max(duration, 0.f); } - if (out_scene_) + Transition::~Transition() { - ThrowIfFailed( - graphics->GetRenderTarget()->CreateLayer(&out_layer_) - ); + SafeRelease(out_layer_); + SafeRelease(in_layer_); + SafeRelease(out_scene_); + SafeRelease(in_scene_); } - window_size_ = game->GetSize(); - out_layer_param_ = in_layer_param_ = D2D1::LayerParameters( - D2D1::RectF( - 0.f, - 0.f, - window_size_.width, - window_size_.height - ), - nullptr, - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, - D2D1::Matrix3x2F::Identity(), - 1.f, - graphics->GetSolidBrush(), - D2D1_LAYER_OPTIONS_NONE - ); -} - -void easy2d::Transition::Update() -{ - if (duration_ == 0) + bool Transition::IsDone() { - process_ = 1; - } - else - { - process_ = (Time::Now() - started_).Seconds() / duration_; - process_ = std::min(process_, 1.f); + return done_; } - if (process_ >= 1) + void Transition::Init(Scene * prev, Scene * next, Game * game) { - this->Stop(); - } -} + started_ = Time::Now(); + out_scene_ = prev; + in_scene_ = next; -void easy2d::Transition::Draw() -{ - auto render_target = Device::GetGraphics()->GetRenderTarget(); + if (out_scene_) + out_scene_->Retain(); - if (out_scene_) - { - render_target->SetTransform(out_scene_->GetTransform()); - render_target->PushAxisAlignedClip( + if (in_scene_) + in_scene_->Retain(); + + auto graphics = Device::GetGraphics(); + if (in_scene_) + { + ThrowIfFailed( + graphics->GetRenderTarget()->CreateLayer(&in_layer_) + ); + } + + if (out_scene_) + { + ThrowIfFailed( + graphics->GetRenderTarget()->CreateLayer(&out_layer_) + ); + } + + window_size_ = game->GetSize(); + out_layer_param_ = in_layer_param_ = D2D1::LayerParameters( D2D1::RectF( 0.f, 0.f, window_size_.width, window_size_.height ), - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE + nullptr, + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, + D2D1::Matrix3x2F::Identity(), + 1.f, + graphics->GetSolidBrush(), + D2D1_LAYER_OPTIONS_NONE ); - render_target->PushLayer(out_layer_param_, out_layer_); - - out_scene_->Draw(); - - render_target->PopLayer(); - render_target->PopAxisAlignedClip(); } - if (in_scene_) + void Transition::Update() { - render_target->SetTransform(in_scene_->GetTransform()); - render_target->PushAxisAlignedClip( - D2D1::RectF( - 0.f, - 0.f, - window_size_.width, - window_size_.height - ), - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE - ); - render_target->PushLayer(in_layer_param_, in_layer_); + if (duration_ == 0) + { + process_ = 1; + } + else + { + process_ = (Time::Now() - started_).Seconds() / duration_; + process_ = std::min(process_, 1.f); + } - in_scene_->Draw(); - - render_target->PopLayer(); - render_target->PopAxisAlignedClip(); + if (process_ >= 1) + { + this->Stop(); + } } -} -void easy2d::Transition::Stop() -{ - done_ = true; - Reset(); -} + void Transition::Draw() + { + auto render_target = Device::GetGraphics()->GetRenderTarget(); + + if (out_scene_) + { + render_target->SetTransform(out_scene_->GetTransform()); + render_target->PushAxisAlignedClip( + D2D1::RectF( + 0.f, + 0.f, + window_size_.width, + window_size_.height + ), + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE + ); + render_target->PushLayer(out_layer_param_, out_layer_); + + out_scene_->Draw(); + + render_target->PopLayer(); + render_target->PopAxisAlignedClip(); + } + + if (in_scene_) + { + render_target->SetTransform(in_scene_->GetTransform()); + render_target->PushAxisAlignedClip( + D2D1::RectF( + 0.f, + 0.f, + window_size_.width, + window_size_.height + ), + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE + ); + render_target->PushLayer(in_layer_param_, in_layer_); + + in_scene_->Draw(); + + render_target->PopLayer(); + render_target->PopAxisAlignedClip(); + } + } + + void Transition::Stop() + { + done_ = true; + Reset(); + } +} \ No newline at end of file diff --git a/core/utils/Color.cpp b/core/utils/Color.cpp index b697ac7b..53e6d1a1 100644 --- a/core/utils/Color.cpp +++ b/core/utils/Color.cpp @@ -20,63 +20,69 @@ #include "..\e2dutil.h" -static const UINT kRedShift = 16; -static const UINT kGreenShift = 8; -static const UINT kBlueShift = 0; - -static const UINT kRedMask = 0xff << kRedShift; -static const UINT kGreenMask = 0xff << kGreenShift; -static const UINT kBlueMask = 0xff << kBlueShift; - -easy2d::Color::Color() - : r(0) - , g(0) - , b(0) - , a(1.f) +namespace easy2d { -} + namespace + { + const UINT RED_SHIFT = 16; + const UINT GREEN_SHIFT = 8; + const UINT BLUE_SHIFT = 0; -easy2d::Color::Color(float r, float g, float b) - : r(r) - , g(g) - , b(b) - , a(1.f) -{ -} + const UINT RED_MASK = 0xff << RED_SHIFT; + const UINT GREEN_MASK = 0xff << GREEN_SHIFT; + const UINT BLUE_MASK = 0xff << BLUE_SHIFT; + } -easy2d::Color::Color(float r, float g, float b, float alpha) - : r(r) - , g(g) - , b(b) - , a(alpha) -{ -} + Color::Color() + : r(0) + , g(0) + , b(0) + , a(1.f) + { + } -easy2d::Color::Color(UINT rgb) - : r(((rgb & kRedMask) >> kRedShift) / 255.f) - , g(((rgb & kGreenMask) >> kGreenShift) / 255.f) - , b(((rgb & kBlueMask) >> kBlueShift) / 255.f) - , a(1.f) -{ -} + Color::Color(float r, float g, float b) + : r(r) + , g(g) + , b(b) + , a(1.f) + { + } -easy2d::Color::Color(UINT rgb, float alpha) - : r(((rgb & kRedMask) >> kRedShift) / 255.f) - , g(((rgb & kGreenMask) >> kGreenShift) / 255.f) - , b(((rgb & kBlueMask) >> kBlueShift) / 255.f) - , a(alpha) -{ -} + Color::Color(float r, float g, float b, float alpha) + : r(r) + , g(g) + , b(b) + , a(alpha) + { + } -easy2d::Color::Color(const D2D1_COLOR_F& color) - : r(color.r) - , g(color.g) - , b(color.b) - , a(color.a) -{ -} + Color::Color(UINT rgb) + : r(((rgb & RED_MASK) >> RED_SHIFT) / 255.f) + , g(((rgb & GREEN_MASK) >> GREEN_SHIFT) / 255.f) + , b(((rgb & BLUE_MASK) >> BLUE_SHIFT) / 255.f) + , a(1.f) + { + } -easy2d::Color::operator D2D1_COLOR_F() const -{ - return D2D1::ColorF(r, g, b, a); -} + Color::Color(UINT rgb, float alpha) + : r(((rgb & RED_MASK) >> RED_SHIFT) / 255.f) + , g(((rgb & GREEN_MASK) >> GREEN_SHIFT) / 255.f) + , b(((rgb & BLUE_MASK) >> BLUE_SHIFT) / 255.f) + , a(alpha) + { + } + + Color::Color(const D2D1_COLOR_F& color) + : r(color.r) + , g(color.g) + , b(color.b) + , a(color.a) + { + } + + Color::operator D2D1_COLOR_F() const + { + return D2D1::ColorF(r, g, b, a); + } +} \ No newline at end of file diff --git a/core/utils/Duration.cpp b/core/utils/Duration.cpp index ac396a09..5676bb93 100644 --- a/core/utils/Duration.cpp +++ b/core/utils/Duration.cpp @@ -22,275 +22,288 @@ #include -const easy2d::Duration easy2d::Duration::Millisecond = easy2d::Duration(1); -const easy2d::Duration easy2d::Duration::Second = 1000 * easy2d::Duration::Millisecond; -const easy2d::Duration easy2d::Duration::Minute = 60 * easy2d::Duration::Second; -const easy2d::Duration easy2d::Duration::Hour = 60 * easy2d::Duration::Minute; - -easy2d::Duration::Duration() - : milliseconds_(0) +namespace easy2d { -} + const Duration Duration::Millisecond = Duration(1); + const Duration Duration::Second = 1000 * Duration::Millisecond; + const Duration Duration::Minute = 60 * Duration::Second; + const Duration Duration::Hour = 60 * Duration::Minute; -easy2d::Duration::Duration(int milliseconds) - : milliseconds_(milliseconds) -{ -} - -int easy2d::Duration::Milliseconds() const -{ - return milliseconds_; -} - -float easy2d::Duration::Seconds() const -{ - int64_t sec = milliseconds_ / Second.milliseconds_; - int64_t ms = milliseconds_ % Second.milliseconds_; - return static_cast(sec) + static_cast(ms) / 1000.f; -} - -float easy2d::Duration::Minutes() const -{ - int64_t min = milliseconds_ / Minute.milliseconds_; - int64_t ms = milliseconds_ % Minute.milliseconds_; - return static_cast(min) + static_cast(ms) / (60 * 1000.f); -} - -float easy2d::Duration::Hours() const -{ - int64_t hour = milliseconds_ / Hour.milliseconds_; - int64_t ms = milliseconds_ % Hour.milliseconds_; - return static_cast(hour) + static_cast(ms) / (60 * 60 * 1000.f); -} - -easy2d::Duration easy2d::Duration::Parse(const std::wstring & str) -{ - typedef std::map UnitMap; - static const auto regex = std::wregex(L"[-+]?([0-9]*(\\.[0-9]*)?[a-z]+)+"); - static const auto unit_map = UnitMap{{L"ms", Millisecond}, {L"s", Second}, {L"m", Minute}, {L"h", Hour}}; - - size_t len = str.length(); - size_t pos = 0; - bool negative = false; - Duration d; - - if (!std::regex_match(str, regex)) + namespace { - E2D_WARNING("Duration::Parse: invalid duration"); + const auto duration_regex = std::wregex(L"[-+]?([0-9]*(\\.[0-9]*)?[a-z]+)+"); + + typedef std::map UnitMap; + const auto unit_map = UnitMap{ + {L"ms", Duration::Millisecond}, + {L"s", Duration::Second}, + {L"m", Duration::Minute}, + {L"h", Duration::Hour} + }; + } + + Duration::Duration() + : milliseconds_(0) + { + } + + Duration::Duration(int milliseconds) + : milliseconds_(milliseconds) + { + } + + int Duration::Milliseconds() const + { + return milliseconds_; + } + + float Duration::Seconds() const + { + int64_t sec = milliseconds_ / Second.milliseconds_; + int64_t ms = milliseconds_ % Second.milliseconds_; + return static_cast(sec) + static_cast(ms) / 1000.f; + } + + float Duration::Minutes() const + { + int64_t min = milliseconds_ / Minute.milliseconds_; + int64_t ms = milliseconds_ % Minute.milliseconds_; + return static_cast(min) + static_cast(ms) / (60 * 1000.f); + } + + float Duration::Hours() const + { + int64_t hour = milliseconds_ / Hour.milliseconds_; + int64_t ms = milliseconds_ % Hour.milliseconds_; + return static_cast(hour) + static_cast(ms) / (60 * 60 * 1000.f); + } + + Duration Duration::Parse(const std::wstring & str) + { + size_t len = str.length(); + size_t pos = 0; + bool negative = false; + Duration d; + + if (!std::regex_match(str, duration_regex)) + { + E2D_WARNING("Duration::Parse: invalid duration"); + return d; + } + + if (str.empty() || str == L"0") { return d; } + + // 符号位 + if (str[0] == L'-' || str[0] == L'+') + { + negative = (str[0] == L'-'); + pos++; + } + + while (pos < len) + { + // 数值 + size_t i = pos; + for (; i < len; ++i) + { + wchar_t ch = str[i]; + if (!(ch == L'.' || L'0' <= ch && ch <= L'9')) + { + break; + } + } + + std::wstring num_str = str.substr(pos, i - pos); + pos = i; + + if (num_str.empty() || num_str == L".") + { + E2D_WARNING("Duration::Parse: invalid duration"); + return Duration(); + } + + // 单位 + for (; i < len; ++i) + { + wchar_t ch = str[i]; + if (ch == L'.' || L'0' <= ch && ch <= L'9') + { + break; + } + } + + std::wstring unit_str = str.substr(pos, i - pos); + pos = i; + + if (unit_map.find(unit_str) == unit_map.end()) + { + E2D_WARNING("Duration::Parse: invalid duration"); + return Duration(); + } + + double num = std::stod(num_str); + Duration unit = unit_map.at(unit_str); + d += unit * num; + } + + if (negative) + { + d.milliseconds_ = -d.milliseconds_; + } return d; } - if (str.empty() || str == L"0") { return d; } - - // 符号位 - if (str[0] == L'-' || str[0] == L'+') + bool Duration::operator==(const Duration & other) const { - negative = (str[0] == L'-'); - pos++; + return milliseconds_ == other.milliseconds_; } - while (pos < len) + bool Duration::operator!=(const Duration & other) const { - // 数值 - size_t i = pos; - for (; i < len; ++i) - { - wchar_t ch = str[i]; - if (!(ch == L'.' || L'0' <= ch && ch <= L'9')) - { - break; - } - } - - std::wstring num_str = str.substr(pos, i - pos); - pos = i; - - if (num_str.empty() || num_str == L".") - { - E2D_WARNING("Duration::Parse: invalid duration"); - return Duration(); - } - - // 单位 - for (; i < len; ++i) - { - wchar_t ch = str[i]; - if (ch == L'.' || L'0' <= ch && ch <= L'9') - { - break; - } - } - - std::wstring unit_str = str.substr(pos, i - pos); - pos = i; - - if (unit_map.find(unit_str) == unit_map.end()) - { - E2D_WARNING("Duration::Parse: invalid duration"); - return Duration(); - } - - double num = std::stod(num_str); - Duration unit = unit_map.at(unit_str); - d += unit * num; + return milliseconds_ != other.milliseconds_; } - if (negative) + bool Duration::operator>(const Duration & other) const { - d.milliseconds_ = -d.milliseconds_; + return milliseconds_ > other.milliseconds_; } - return d; -} -bool easy2d::Duration::operator==(const Duration & other) const -{ - return milliseconds_ == other.milliseconds_; -} + bool Duration::operator>=(const Duration & other) const + { + return milliseconds_ >= other.milliseconds_; + } -bool easy2d::Duration::operator!=(const Duration & other) const -{ - return milliseconds_ != other.milliseconds_; -} + bool Duration::operator<(const Duration & other) const + { + return milliseconds_ < other.milliseconds_; + } -bool easy2d::Duration::operator>(const Duration & other) const -{ - return milliseconds_ > other.milliseconds_; -} + bool Duration::operator<=(const Duration & other) const + { + return milliseconds_ <= other.milliseconds_; + } -bool easy2d::Duration::operator>=(const Duration & other) const -{ - return milliseconds_ >= other.milliseconds_; -} + Duration Duration::operator+(const Duration & other) const + { + return Duration(milliseconds_ + other.milliseconds_); + } -bool easy2d::Duration::operator<(const Duration & other) const -{ - return milliseconds_ < other.milliseconds_; -} + Duration Duration::operator-(const Duration & other) const + { + return Duration(milliseconds_ - other.milliseconds_); + } -bool easy2d::Duration::operator<=(const Duration & other) const -{ - return milliseconds_ <= other.milliseconds_; -} + Duration Duration::operator-() const + { + return Duration(-milliseconds_); + } -easy2d::Duration easy2d::Duration::operator+(const Duration & other) const -{ - return Duration(milliseconds_ + other.milliseconds_); -} + Duration Duration::operator*(int value) const + { + return Duration(milliseconds_ * value); + } -easy2d::Duration easy2d::Duration::operator-(const Duration & other) const -{ - return Duration(milliseconds_ - other.milliseconds_); -} + Duration Duration::operator/(int value) const + { + return Duration(milliseconds_ / value); + } -easy2d::Duration easy2d::Duration::operator-() const -{ - return Duration(-milliseconds_); -} + Duration Duration::operator*(float value) const + { + return Duration(static_cast(milliseconds_ * value)); + } -easy2d::Duration easy2d::Duration::operator*(int value) const -{ - return Duration(milliseconds_ * value); -} + Duration Duration::operator/(float value) const + { + return Duration(static_cast(milliseconds_ / value)); + } -easy2d::Duration easy2d::Duration::operator/(int value) const -{ - return Duration(milliseconds_ / value); -} + Duration Duration::operator*(double value) const + { + return Duration(static_cast(milliseconds_ * value)); + } -easy2d::Duration easy2d::Duration::operator*(float value) const -{ - return Duration(static_cast(milliseconds_ * value)); -} + Duration Duration::operator/(double value) const + { + return Duration(static_cast(milliseconds_ / value)); + } -easy2d::Duration easy2d::Duration::operator/(float value) const -{ - return Duration(static_cast(milliseconds_ / value)); -} + Duration & Duration::operator+=(const Duration &other) + { + milliseconds_ += other.milliseconds_; + return (*this); + } -easy2d::Duration easy2d::Duration::operator*(double value) const -{ - return Duration(static_cast(milliseconds_ * value)); -} + Duration & Duration::operator-=(const Duration &other) + { + milliseconds_ -= other.milliseconds_; + return (*this); + } -easy2d::Duration easy2d::Duration::operator/(double value) const -{ - return Duration(static_cast(milliseconds_ / value)); -} + Duration & Duration::operator*=(int value) + { + milliseconds_ *= value; + return (*this); + } -easy2d::Duration & easy2d::Duration::operator+=(const Duration &other) -{ - milliseconds_ += other.milliseconds_; - return (*this); -} + Duration & Duration::operator/=(int value) + { + milliseconds_ /= value; + return (*this); + } -easy2d::Duration & easy2d::Duration::operator-=(const Duration &other) -{ - milliseconds_ -= other.milliseconds_; - return (*this); -} + Duration & Duration::operator*=(float value) + { + milliseconds_ = static_cast(milliseconds_ * value); + return (*this); + } -easy2d::Duration & easy2d::Duration::operator*=(int value) -{ - milliseconds_ *= value; - return (*this); -} + Duration & Duration::operator/=(float value) + { + milliseconds_ = static_cast(milliseconds_ / value); + return (*this); + } -easy2d::Duration & easy2d::Duration::operator/=(int value) -{ - milliseconds_ /= value; - return (*this); -} + Duration & Duration::operator*=(double value) + { + milliseconds_ = static_cast(milliseconds_ * value); + return (*this); + } -easy2d::Duration & easy2d::Duration::operator*=(float value) -{ - milliseconds_ = static_cast(milliseconds_ * value); - return (*this); -} + Duration & Duration::operator/=(double value) + { + milliseconds_ = static_cast(milliseconds_ / value); + return (*this); + } -easy2d::Duration & easy2d::Duration::operator/=(float value) -{ - milliseconds_ = static_cast(milliseconds_ / value); - return (*this); -} + Duration operator*(int value, const Duration & dur) + { + return dur * value; + } -easy2d::Duration & easy2d::Duration::operator*=(double value) -{ - milliseconds_ = static_cast(milliseconds_ * value); - return (*this); -} + Duration operator/(int value, const Duration & dur) + { + return dur / value; + } -easy2d::Duration & easy2d::Duration::operator/=(double value) -{ - milliseconds_ = static_cast(milliseconds_ / value); - return (*this); -} + Duration operator*(float value, const Duration & dur) + { + return dur * value; + } -easy2d::Duration easy2d::operator*(int value, const Duration & dur) -{ - return dur * value; -} + Duration operator/(float value, const Duration & dur) + { + return dur / value; + } -easy2d::Duration easy2d::operator/(int value, const Duration & dur) -{ - return dur / value; -} + Duration operator*(double value, const Duration & dur) + { + return dur * value; + } -easy2d::Duration easy2d::operator*(float value, const Duration & dur) -{ - return dur * value; -} + Duration operator/(double value, const Duration & dur) + { + return dur / value; + } -easy2d::Duration easy2d::operator/(float value, const Duration & dur) -{ - return dur / value; -} - -easy2d::Duration easy2d::operator*(double value, const Duration & dur) -{ - return dur * value; -} - -easy2d::Duration easy2d::operator/(double value, const Duration & dur) -{ - return dur / value; } diff --git a/core/utils/Font.cpp b/core/utils/Font.cpp index 549e1ad2..0530c1f0 100644 --- a/core/utils/Font.cpp +++ b/core/utils/Font.cpp @@ -21,10 +21,13 @@ #include "..\e2dutil.h" -easy2d::Font::Font(const std::wstring & family, float size, UINT weight, bool italic) - : family(family) - , size(size) - , weight(weight) - , italic(italic) +namespace easy2d { + Font::Font(const std::wstring & family, float size, UINT weight, bool italic) + : family(family) + , size(size) + , weight(weight) + , italic(italic) + { + } } \ No newline at end of file diff --git a/core/utils/Point.cpp b/core/utils/Point.cpp index 00baa834..2243336e 100644 --- a/core/utils/Point.cpp +++ b/core/utils/Point.cpp @@ -22,63 +22,66 @@ #include -easy2d::Point::Point() +namespace easy2d { - x = 0; - y = 0; -} + Point::Point() + { + x = 0; + y = 0; + } -easy2d::Point::Point(float x, float y) -{ - this->x = x; - this->y = y; -} + Point::Point(float x, float y) + { + this->x = x; + this->y = y; + } -easy2d::Point::Point(const Point & other) -{ - x = other.x; - y = other.y; -} + Point::Point(const Point & other) + { + x = other.x; + y = other.y; + } -easy2d::Point easy2d::Point::operator+(const Point & p) const -{ - return Point(x + p.x, y + p.y); -} + Point Point::operator+(const Point & p) const + { + return Point(x + p.x, y + p.y); + } -easy2d::Point easy2d::Point::operator-(const Point & p) const -{ - return Point(x - p.x, y - p.y); -} + Point Point::operator-(const Point & p) const + { + return Point(x - p.x, y - p.y); + } -easy2d::Point easy2d::Point::operator*(float value) const -{ - return Point(x * value, y * value); -} + Point Point::operator*(float value) const + { + return Point(x * value, y * value); + } -easy2d::Point easy2d::Point::operator/(float value) const -{ - return Point(x / value, y / value); -} + Point Point::operator/(float value) const + { + return Point(x / value, y / value); + } -easy2d::Point::operator easy2d::Size() const -{ - return Size(x, y); -} + Point::operator Size() const + { + return Size(x, y); + } -float easy2d::Point::Distance(const Point &p1, const Point &p2) -{ - return sqrt( - (p1.x - p2.x) * (p1.x - p2.x) + - (p1.y - p2.y) * (p1.y - p2.y) - ); -} + float Point::Distance(const Point &p1, const Point &p2) + { + return sqrt( + (p1.x - p2.x) * (p1.x - p2.x) + + (p1.y - p2.y) * (p1.y - p2.y) + ); + } -easy2d::Point easy2d::Point::operator-() const -{ - return Point(-x, -y); -} + Point Point::operator-() const + { + return Point(-x, -y); + } -bool easy2d::Point::operator==(const Point & point) const -{ - return (x == point.x) && (y == point.y); -} + bool Point::operator==(const Point & point) const + { + return (x == point.x) && (y == point.y); + } +} \ No newline at end of file diff --git a/core/utils/Random.cpp b/core/utils/Random.cpp index f6aab299..3c00c46c 100644 --- a/core/utils/Random.cpp +++ b/core/utils/Random.cpp @@ -20,9 +20,12 @@ #include "..\e2dutil.h" -std::default_random_engine &easy2d::Random::GetEngine() +namespace easy2d { - static std::random_device device; - static std::default_random_engine engine(device()); - return engine; -} + std::default_random_engine &Random::GetEngine() + { + static std::random_device device; + static std::default_random_engine engine(device()); + return engine; + } +} \ No newline at end of file diff --git a/core/utils/Rect.cpp b/core/utils/Rect.cpp index 248645c8..cff5859c 100644 --- a/core/utils/Rect.cpp +++ b/core/utils/Rect.cpp @@ -20,56 +20,59 @@ #include "..\e2dutil.h" -easy2d::Rect::Rect(void) - : origin() - , size() +namespace easy2d { -} - -easy2d::Rect::Rect(float x, float y, float width, float height) - : origin(x, y) - , size(width, height) -{ -} - -easy2d::Rect::Rect(const Point& pos, const Size& size) - : origin(pos.x, pos.y) - , size(size.width, size.height) -{ -} - -easy2d::Rect::Rect(const Rect& other) - : origin(other.origin.x, other.origin.y) - , size(other.size.width, other.size.height) -{ -} - -easy2d::Rect& easy2d::Rect::operator= (const Rect& other) -{ - origin = other.origin; - size = other.size; - return *this; -} - -bool easy2d::Rect::operator==(const Rect & rect) const -{ - return (origin == rect.origin) && (size == rect.size); -} - -bool easy2d::Rect::ContainsPoint(const Point& point) const -{ - if (point.x >= origin.x && point.x <= (origin.y + size.height) - && point.y >= origin.y && point.y <= (origin.y + size.height)) + Rect::Rect(void) + : origin() + , size() { - return true; } - return false; -} -bool easy2d::Rect::Intersects(const Rect& rect) const -{ - return !((origin.x + size.width) < rect.origin.x || - (rect.origin.x + rect.size.width) < origin.x || - (origin.y + size.height) < rect.origin.y || - (rect.origin.y + rect.size.height) < origin.y); -} + Rect::Rect(float x, float y, float width, float height) + : origin(x, y) + , size(width, height) + { + } + + Rect::Rect(const Point& pos, const Size& size) + : origin(pos.x, pos.y) + , size(size.width, size.height) + { + } + + Rect::Rect(const Rect& other) + : origin(other.origin.x, other.origin.y) + , size(other.size.width, other.size.height) + { + } + + Rect& Rect::operator= (const Rect& other) + { + origin = other.origin; + size = other.size; + return *this; + } + + bool Rect::operator==(const Rect & rect) const + { + return (origin == rect.origin) && (size == rect.size); + } + + bool Rect::ContainsPoint(const Point& point) const + { + if (point.x >= origin.x && point.x <= (origin.y + size.height) + && point.y >= origin.y && point.y <= (origin.y + size.height)) + { + return true; + } + return false; + } + + bool Rect::Intersects(const Rect& rect) const + { + return !((origin.x + size.width) < rect.origin.x || + (rect.origin.x + rect.size.width) < origin.x || + (origin.y + size.height) < rect.origin.y || + (rect.origin.y + rect.size.height) < origin.y); + } +} \ No newline at end of file diff --git a/core/utils/Ref.cpp b/core/utils/Ref.cpp index ce89c485..e510d37c 100644 --- a/core/utils/Ref.cpp +++ b/core/utils/Ref.cpp @@ -20,35 +20,38 @@ #include "..\e2dobject.h" -easy2d::Ref::Ref() +namespace easy2d { - // 当对象被创建时,意味着它已经被引用了一次 - ref_count_ = 1; -} - -easy2d::Ref::~Ref() -{ -} - -LONG easy2d::Ref::Retain() -{ - return ::InterlockedIncrement(&ref_count_); -} - -LONG easy2d::Ref::Release() -{ - LONG new_count = ::InterlockedDecrement(&ref_count_); - - if (new_count <= 0) + Ref::Ref() { - delete this; - return 0; + // 当对象被创建时,意味着它已经被引用了一次 + ref_count_ = 1; } - return new_count; -} + Ref::~Ref() + { + } -LONG easy2d::Ref::GetRefCount() const -{ - return ref_count_; -} + LONG Ref::Retain() + { + return ::InterlockedIncrement(&ref_count_); + } + + LONG Ref::Release() + { + LONG new_count = ::InterlockedDecrement(&ref_count_); + + if (new_count <= 0) + { + delete this; + return 0; + } + + return new_count; + } + + LONG Ref::GetRefCount() const + { + return ref_count_; + } +} \ No newline at end of file diff --git a/core/utils/Resource.cpp b/core/utils/Resource.cpp index 558baa70..f1484f38 100644 --- a/core/utils/Resource.cpp +++ b/core/utils/Resource.cpp @@ -21,77 +21,80 @@ #include "..\e2dtool.h" -easy2d::Resource::Resource(LPCWSTR name, LPCWSTR type) - : name_(name) - , type_(type) - , data_(nullptr) - , data_size_(0) - , loaded_(false) +namespace easy2d { -} - -LPCWSTR easy2d::Resource::GetName() const -{ - return name_; -} - -LPCWSTR easy2d::Resource::GetType() const -{ - return type_; -} - -LPVOID easy2d::Resource::GetData() const -{ - return data_; -} - -DWORD easy2d::Resource::GetDataSize() const -{ - return data_size_; -} - -size_t easy2d::Resource::GetHashCode() const -{ - return std::hash{}(name_); -} - -bool easy2d::Resource::Load() -{ - if (!loaded_) + Resource::Resource(LPCWSTR name, LPCWSTR type) + : name_(name) + , type_(type) + , data_(nullptr) + , data_size_(0) + , loaded_(false) { - HRSRC res_info; - HGLOBAL res_data; - HINSTANCE hinstance = GetModuleHandle(NULL); - - res_info = FindResourceW(hinstance, name_, type_); - if (res_info == nullptr) - { - E2D_WARNING("FindResource"); - return false; - } - - res_data = LoadResource(hinstance, res_info); - if (res_data == nullptr) - { - E2D_WARNING("LoadResource"); - return false; - } - - data_size_ = SizeofResource(hinstance, res_info); - if (data_size_ == 0) - { - E2D_WARNING("SizeofResource"); - return false; - } - - data_ = LockResource(res_data); - if (data_ == nullptr) - { - E2D_WARNING("LockResource"); - return false; - } - - loaded_ = true; } - return true; -} + + LPCWSTR Resource::GetName() const + { + return name_; + } + + LPCWSTR Resource::GetType() const + { + return type_; + } + + LPVOID Resource::GetData() const + { + return data_; + } + + DWORD Resource::GetDataSize() const + { + return data_size_; + } + + size_t Resource::GetHashCode() const + { + return std::hash{}(name_); + } + + bool Resource::Load() + { + if (!loaded_) + { + HRSRC res_info; + HGLOBAL res_data; + HINSTANCE hinstance = GetModuleHandle(NULL); + + res_info = FindResourceW(hinstance, name_, type_); + if (res_info == nullptr) + { + E2D_WARNING("FindResource"); + return false; + } + + res_data = LoadResource(hinstance, res_info); + if (res_data == nullptr) + { + E2D_WARNING("LoadResource"); + return false; + } + + data_size_ = SizeofResource(hinstance, res_info); + if (data_size_ == 0) + { + E2D_WARNING("SizeofResource"); + return false; + } + + data_ = LockResource(res_data); + if (data_ == nullptr) + { + E2D_WARNING("LockResource"); + return false; + } + + loaded_ = true; + } + return true; + } +} \ No newline at end of file diff --git a/core/utils/Size.cpp b/core/utils/Size.cpp index 582bee2e..1c083cbb 100644 --- a/core/utils/Size.cpp +++ b/core/utils/Size.cpp @@ -20,55 +20,58 @@ #include "..\e2dutil.h" -easy2d::Size::Size() +namespace easy2d { - width = 0; - height = 0; -} + Size::Size() + { + width = 0; + height = 0; + } -easy2d::Size::Size(float width, float height) -{ - this->width = width; - this->height = height; -} + Size::Size(float width, float height) + { + this->width = width; + this->height = height; + } -easy2d::Size::Size(const Size & other) -{ - width = other.width; - height = other.height; -} + Size::Size(const Size & other) + { + width = other.width; + height = other.height; + } -easy2d::Size easy2d::Size::operator+(const Size & other) const -{ - return Size(width + other.width, height + other.height); -} + Size Size::operator+(const Size & other) const + { + return Size(width + other.width, height + other.height); + } -easy2d::Size easy2d::Size::operator-(const Size & other) const -{ - return Size(width - other.width, height - other.height); -} + Size Size::operator-(const Size & other) const + { + return Size(width - other.width, height - other.height); + } -easy2d::Size easy2d::Size::operator*(float value) const -{ - return Size(width * value, height * value); -} + Size Size::operator*(float value) const + { + return Size(width * value, height * value); + } -easy2d::Size easy2d::Size::operator/(float value) const -{ - return Size(width / value, height / value); -} + Size Size::operator/(float value) const + { + return Size(width / value, height / value); + } -easy2d::Size::operator easy2d::Point() const -{ - return Point(width, height); -} + Size::operator Point() const + { + return Point(width, height); + } -easy2d::Size easy2d::Size::operator-() const -{ - return Size(-width, -height); -} + Size Size::operator-() const + { + return Size(-width, -height); + } -bool easy2d::Size::operator==(const Size & other) const -{ - return (width == other.width) && (height == other.height); -} + bool Size::operator==(const Size & other) const + { + return (width == other.width) && (height == other.height); + } +} \ No newline at end of file diff --git a/core/utils/Time.cpp b/core/utils/Time.cpp index 615d0397..3af19e4e 100644 --- a/core/utils/Time.cpp +++ b/core/utils/Time.cpp @@ -20,86 +20,89 @@ #include "..\e2dutil.h" -using namespace std::chrono; - - -easy2d::Time::Time() +namespace easy2d { -} + using namespace std::chrono; -easy2d::Time::Time(std::chrono::steady_clock::time_point time) - : time_(time) -{ -} -easy2d::Time::Time(const Time & other) - : time_(other.time_) -{ -} + Time::Time() + { + } -easy2d::Time::Time(Time && other) - : time_(std::move(other.time_)) -{ -} + Time::Time(std::chrono::steady_clock::time_point time) + : time_(time) + { + } -time_t easy2d::Time::GetTimeStamp() const -{ - auto& duration = time_point_cast(time_).time_since_epoch(); - return static_cast(duration.count()); -} + Time::Time(const Time & other) + : time_(other.time_) + { + } -bool easy2d::Time::IsZero() const -{ - return time_.time_since_epoch().count() == 0LL; -} + Time::Time(Time && other) + : time_(std::move(other.time_)) + { + } -easy2d::Time easy2d::Time::operator+(const Duration & other) const -{ - return Time(time_ + milliseconds(other.Milliseconds())); -} + time_t Time::GetTimeStamp() const + { + auto& duration = time_point_cast(time_).time_since_epoch(); + return static_cast(duration.count()); + } -easy2d::Time easy2d::Time::operator-(const Duration & other) const -{ - return Time(time_ - milliseconds(other.Milliseconds())); -} + bool Time::IsZero() const + { + return time_.time_since_epoch().count() == 0LL; + } -easy2d::Time & easy2d::Time::operator+=(const Duration & other) -{ - time_ += milliseconds(other.Milliseconds()); - return (*this); -} + Time Time::operator+(const Duration & other) const + { + return Time(time_ + milliseconds(other.Milliseconds())); + } -easy2d::Time & easy2d::Time::operator-=(const Duration &other) -{ - time_ -= milliseconds(other.Milliseconds()); - return (*this); -} + Time Time::operator-(const Duration & other) const + { + return Time(time_ - milliseconds(other.Milliseconds())); + } -easy2d::Duration easy2d::Time::operator-(const Time & other) const -{ - auto ms = duration_cast(time_ - other.time_).count(); - return Duration(static_cast(ms)); -} + Time & Time::operator+=(const Duration & other) + { + time_ += milliseconds(other.Milliseconds()); + return (*this); + } -easy2d::Time& easy2d::Time::operator=(const Time & other) E2D_NOEXCEPT -{ - if (this == &other) + Time & Time::operator-=(const Duration &other) + { + time_ -= milliseconds(other.Milliseconds()); + return (*this); + } + + Duration Time::operator-(const Time & other) const + { + auto ms = duration_cast(time_ - other.time_).count(); + return Duration(static_cast(ms)); + } + + Time& Time::operator=(const Time & other) E2D_NOEXCEPT + { + if (this == &other) + return *this; + + time_ = other.time_; return *this; + } - time_ = other.time_; - return *this; -} + Time& Time::operator=(Time && other) E2D_NOEXCEPT + { + if (this == &other) + return *this; -easy2d::Time& easy2d::Time::operator=(Time && other) E2D_NOEXCEPT -{ - if (this == &other) + time_ = std::move(other.time_); return *this; + } - time_ = std::move(other.time_); - return *this; -} - -easy2d::Time easy2d::Time::Now() -{ - return Time(steady_clock::now()); -} + Time Time::Now() + { + return Time(steady_clock::now()); + } +} \ No newline at end of file diff --git a/core/utils/Transform.cpp b/core/utils/Transform.cpp index b62e8a67..caa8aa29 100644 --- a/core/utils/Transform.cpp +++ b/core/utils/Transform.cpp @@ -21,49 +21,52 @@ #include "..\e2dutil.h" -easy2d::Transform::Transform() - : position() - , size() - , scale_x(1.f) - , scale_y(1.f) - , rotation(0) - , skew_x(0) - , skew_y(0) - , pivot_x(0) - , pivot_y(0) +namespace easy2d { -} + Transform::Transform() + : position() + , size() + , scale_x(1.f) + , scale_y(1.f) + , rotation(0) + , skew_x(0) + , skew_y(0) + , pivot_x(0) + , pivot_y(0) + { + } -easy2d::Transform::operator D2D1::Matrix3x2F() const -{ - auto pivot = D2D1::Point2F(size.width * pivot_x, size.height * pivot_y); - auto matrix = D2D1::Matrix3x2F::Scale( - scale_x, - scale_y, - pivot - ) * D2D1::Matrix3x2F::Skew( - skew_x, - skew_y, - pivot - ) * D2D1::Matrix3x2F::Rotation( - rotation, - pivot - ) * D2D1::Matrix3x2F::Translation( - position.x - pivot.x, - position.y - pivot.y - ); - return matrix; -} + Transform::operator D2D1::Matrix3x2F() const + { + auto pivot = D2D1::Point2F(size.width * pivot_x, size.height * pivot_y); + auto matrix = D2D1::Matrix3x2F::Scale( + scale_x, + scale_y, + pivot + ) * D2D1::Matrix3x2F::Skew( + skew_x, + skew_y, + pivot + ) * D2D1::Matrix3x2F::Rotation( + rotation, + pivot + ) * D2D1::Matrix3x2F::Translation( + position.x - pivot.x, + position.y - pivot.y + ); + return matrix; + } -bool easy2d::Transform::operator==(const Transform & other) const -{ - return position == other.position && - size == other.size && - scale_x == other.scale_x && - scale_y == other.scale_y && - skew_x == other.skew_x && - skew_y == other.skew_y && - rotation == other.rotation && - pivot_x == other.pivot_x && - pivot_y == other.pivot_y; -} + bool Transform::operator==(const Transform & other) const + { + return position == other.position && + size == other.size && + scale_x == other.scale_x && + scale_y == other.scale_y && + skew_x == other.skew_x && + skew_y == other.skew_y && + rotation == other.rotation && + pivot_x == other.pivot_x && + pivot_y == other.pivot_y; + } +} \ No newline at end of file