update: code style

This commit is contained in:
Haibo 2018-11-08 00:21:59 +08:00 committed by Nomango
parent 0f1ba104dd
commit b129a1bf18
60 changed files with 6300 additions and 6091 deletions

View File

@ -20,86 +20,90 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::Action::Action()
: running_(false)
, done_(false)
, initialized_(false)
, target_(nullptr)
{
}
easy2d::Action::~Action() namespace easy2d
{ {
} Action::Action()
: running_(false)
bool easy2d::Action::IsRunning() , done_(false)
{ , initialized_(false)
return running_; , target_(nullptr)
}
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_)
{ {
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()
{
}
}

View File

@ -21,115 +21,118 @@
#include "..\e2daction.h" #include "..\e2daction.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::Animate::Animate() namespace easy2d
: frame_index_(0)
, animation_(nullptr)
{ {
} Animate::Animate()
: frame_index_(0)
, animation_(nullptr)
{
}
easy2d::Animate::Animate(Animation * animation) Animate::Animate(Animation * animation)
: frame_index_(0) : frame_index_(0)
, animation_(nullptr) , animation_(nullptr)
{ {
this->SetAnimation(animation); this->SetAnimation(animation);
} }
easy2d::Animate::~Animate() Animate::~Animate()
{ {
SafeRelease(animation_); SafeRelease(animation_);
} }
easy2d::Animation * easy2d::Animate::GetAnimation() const Animation * Animate::GetAnimation() const
{ {
return animation_; return animation_;
} }
void easy2d::Animate::SetAnimation(Animation * animation) void Animate::SetAnimation(Animation * animation)
{ {
if (animation && 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<Sprite*>(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<Sprite*>(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_) if (animation_)
{ {
animation_->Release(); return new Animate(animation_);
} }
animation_ = animation; return nullptr;
animation_->Retain();
frame_index_ = 0;
}
}
void easy2d::Animate::Init()
{
Action::Init();
auto target = dynamic_cast<Sprite*>(target_);
if (target && animation_)
{
target->Load(animation_->GetFrames()[frame_index_]);
++frame_index_;
}
}
void easy2d::Animate::Update()
{
Action::Update();
if (!animation_)
{
this->Stop();
return;
} }
while ((Time::Now() - started_).Seconds() >= animation_->GetInterval()) Animate * Animate::Reverse() const
{ {
auto& frames = animation_->GetFrames(); if (animation_)
auto target = dynamic_cast<Sprite*>(target_);
if (target)
{ {
target->Load(frames[frame_index_]); auto animation = animation_->Reverse();
} if (animation)
{
started_ += Duration::Second * animation_->GetInterval(); return new Animate(animation);
++frame_index_; }
if (frame_index_ == frames.size())
{
this->Stop();
break;
} }
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;
}

View File

@ -20,101 +20,104 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::Animation::Animation() namespace easy2d
: interval_(1)
{ {
} Animation::Animation()
: interval_(1)
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_)
{ {
SafeRelease(frame);
} }
}
void easy2d::Animation::SetInterval(float interval) Animation::Animation(const Images& frames)
{ : interval_(1)
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)
{ {
frames_.push_back(frame); this->Add(frames);
frame->Retain();
} }
}
void easy2d::Animation::Add(const Images& frames) Animation::Animation(float interval)
{ : interval_(interval)
for (const auto &image : frames)
{ {
this->Add(image);
} }
}
float easy2d::Animation::GetInterval() const Animation::Animation(float interval, const Images& frames)
{ : interval_(interval)
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)
{ {
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 void Animation::SetInterval(float interval)
{
auto& oldFrames = this->GetFrames();
Images frames(oldFrames.size());
if (!oldFrames.empty())
{ {
for (auto iter = oldFrames.crbegin(), interval_ = std::max(interval, 0.f);
iterCrend = oldFrames.crend(); }
iter != iterCrend;
++iter) void Animation::Add(Image * frame)
{
E2D_WARNING_IF(frame == nullptr, "Animation::Add failed, frame Is nullptr.");
if (frame)
{ {
Image* frame = *iter; frames_.push_back(frame);
if (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);
}
}

View File

@ -20,27 +20,30 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::CallFunc::CallFunc(const Callback& func) : namespace easy2d
callback_(func)
{ {
} CallFunc::CallFunc(const Callback& func) :
callback_(func)
{
}
easy2d::CallFunc * easy2d::CallFunc::Clone() const CallFunc * CallFunc::Clone() const
{ {
return new CallFunc(callback_); return new CallFunc(callback_);
} }
easy2d::CallFunc * easy2d::CallFunc::Reverse() const CallFunc * CallFunc::Reverse() const
{ {
return new CallFunc(callback_); return new CallFunc(callback_);
} }
void easy2d::CallFunc::Init() void CallFunc::Init()
{ {
} }
void easy2d::CallFunc::Update() void CallFunc::Update()
{ {
callback_(); callback_();
this->Stop(); this->Stop();
} }
}

View File

@ -20,47 +20,50 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::Delay::Delay(float duration) namespace easy2d
: delta_(0)
, delay_(std::max(duration, 0.f))
{ {
} Delay::Delay(float duration)
: delta_(0)
easy2d::Delay * easy2d::Delay::Clone() const , delay_(std::max(duration, 0.f))
{
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_)
{ {
this->Stop();
} }
}
void easy2d::Delay::ResetTime() Delay * Delay::Clone() const
{ {
Action::ResetTime(); return new Delay(delay_);
started_ = Time::Now() - Duration::Second * delta_; }
}
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_;
}
}

View File

@ -20,7 +20,10 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::FadeIn::FadeIn(float duration) namespace easy2d
: OpacityTo(duration, 1)
{ {
} FadeIn::FadeIn(float duration)
: OpacityTo(duration, 1)
{
}
}

View File

@ -20,7 +20,10 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::FadeOut::FadeOut(float duration) namespace easy2d
: OpacityTo(duration, 0)
{ {
} FadeOut::FadeOut(float duration)
: OpacityTo(duration, 0)
{
}
}

View File

@ -20,45 +20,48 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::FiniteTimeAction::FiniteTimeAction(float duration) namespace easy2d
: delta_(0)
, duration_(std::max(duration, 0.f))
{ {
} FiniteTimeAction::FiniteTimeAction(float duration)
: delta_(0)
void easy2d::FiniteTimeAction::Reset() , duration_(std::max(duration, 0.f))
{
Action::Reset();
delta_ = 0;
}
void easy2d::FiniteTimeAction::Init()
{
Action::Init();
}
void easy2d::FiniteTimeAction::Update()
{
Action::Update();
if (duration_ == 0)
{ {
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(); this->Stop();
} }
} else
} {
delta_ = std::min((Time::Now() - started_).Seconds() / duration_, 1.f);
void easy2d::FiniteTimeAction::ResetTime() if (delta_ >= 1)
{ {
Action::ResetTime(); this->Stop();
started_ = Time::Now() - Duration::Second * (delta_ * duration_); }
} }
}
void FiniteTimeAction::ResetTime()
{
Action::ResetTime();
started_ = Time::Now() - Duration::Second * (delta_ * duration_);
}
}

View File

@ -21,53 +21,56 @@
#include "..\e2daction.h" #include "..\e2daction.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::JumpBy::JumpBy(float duration, const Point & vec, float height, int jumps) namespace easy2d
: FiniteTimeAction(duration)
, delta_pos_(vec)
, height_(height)
, jumps_(jumps)
{ {
} JumpBy::JumpBy(float duration, const Point & vec, float height, int jumps)
: FiniteTimeAction(duration)
easy2d::JumpBy * easy2d::JumpBy::Clone() const , delta_pos_(vec)
{ , height_(height)
return new JumpBy(duration_, delta_pos_, height_, jumps_); , jumps_(jumps)
}
easy2d::JumpBy * easy2d::JumpBy::Reverse() const
{
return new JumpBy(duration_, -delta_pos_, height_, jumps_);
}
void easy2d::JumpBy::Init()
{
FiniteTimeAction::Init();
if (target_)
{ {
prev_pos_ = start_pos_ = target_->GetPosition();
} }
}
void easy2d::JumpBy::Update() JumpBy * JumpBy::Clone() const
{
FiniteTimeAction::Update();
if (target_)
{ {
float frac = fmod(delta_ * jumps_, 1.f); return new JumpBy(duration_, delta_pos_, height_, jumps_);
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;
} }
}
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;
}
}
}

View File

@ -21,19 +21,22 @@
#include "..\e2daction.h" #include "..\e2daction.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::JumpTo::JumpTo(float duration, const Point & pos, float height, int jumps) namespace easy2d
: JumpBy(duration, Point(), height, jumps)
, end_pos_(pos)
{ {
} 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 JumpTo * JumpTo::Clone() const
{ {
return new JumpTo(duration_, end_pos_, height_, jumps_); return new JumpTo(duration_, end_pos_, height_, jumps_);
} }
void easy2d::JumpTo::Init() void JumpTo::Init()
{ {
JumpBy::Init(); JumpBy::Init();
delta_pos_ = end_pos_ - start_pos_; delta_pos_ = end_pos_ - start_pos_;
} }
}

View File

@ -20,97 +20,100 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::Loop::Loop(Action * action, int times /* = -1 */) namespace easy2d
: action_(action)
, times_(0)
, total_times_(times)
{ {
E2D_WARNING_IF(action == nullptr, "Loop NULL pointer exception!"); Loop::Loop(Action * action, int times /* = -1 */)
: action_(action)
if (action) , times_(0)
, total_times_(times)
{ {
action_ = action; E2D_WARNING_IF(action == nullptr, "Loop NULL pointer exception!");
action_->Retain();
}
}
easy2d::Loop::~Loop() if (action)
{
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())
{ {
++times_; action_ = action;
action_->Retain();
Action::Reset();
action_->Reset();
} }
} }
else
Loop::~Loop()
{ {
this->Stop(); SafeRelease(action_);
} }
}
void easy2d::Loop::Reset() Loop * Loop::Clone() const
{ {
Action::Reset(); if (action_)
{
return new Loop(action_->Clone());
}
else
{
return nullptr;
}
}
if (action_) action_->Reset(); Loop * Loop::Reverse() const
times_ = 0; {
} if (action_)
{
return new Loop(action_->Clone());
}
else
{
return nullptr;
}
}
void easy2d::Loop::ResetTime() void Loop::Init()
{ {
if (action_) action_->ResetTime(); 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();
}
}

View File

@ -22,45 +22,48 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::MoveBy::MoveBy(float duration, Point vector) namespace easy2d
: FiniteTimeAction(duration)
{ {
delta_pos_ = vector; MoveBy::MoveBy(float duration, Point vector)
} : FiniteTimeAction(duration)
void easy2d::MoveBy::Init()
{
FiniteTimeAction::Init();
if (target_)
{ {
prev_pos_ = start_pos_ = target_->GetPosition(); delta_pos_ = vector;
} }
}
void easy2d::MoveBy::Update() void MoveBy::Init()
{
FiniteTimeAction::Update();
if (target_)
{ {
Point currentPos = target_->GetPosition(); FiniteTimeAction::Init();
Point diff = currentPos - prev_pos_;
start_pos_ = start_pos_ + diff;
Point newPos = start_pos_ + (delta_pos_ * delta_); if (target_)
target_->SetPosition(newPos); {
prev_pos_ = start_pos_ = target_->GetPosition();
prev_pos_ = newPos; }
} }
}
easy2d::MoveBy * easy2d::MoveBy::Clone() const void MoveBy::Update()
{ {
return new MoveBy(duration_, delta_pos_); FiniteTimeAction::Update();
}
easy2d::MoveBy * easy2d::MoveBy::Reverse() const if (target_)
{ {
return new MoveBy(duration_, -delta_pos_); 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_);
}
} }

View File

@ -21,19 +21,22 @@
#include "..\e2daction.h" #include "..\e2daction.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::MoveTo::MoveTo(float duration, Point pos) namespace easy2d
: MoveBy(duration, Point())
{ {
end_pos_ = pos; MoveTo::MoveTo(float duration, Point pos)
} : MoveBy(duration, Point())
{
end_pos_ = pos;
}
easy2d::MoveTo * easy2d::MoveTo::Clone() const MoveTo * MoveTo::Clone() const
{ {
return new MoveTo(duration_, end_pos_); return new MoveTo(duration_, end_pos_);
} }
void easy2d::MoveTo::Init() void MoveTo::Init()
{ {
MoveBy::Init(); MoveBy::Init();
delta_pos_ = end_pos_ - start_pos_; delta_pos_ = end_pos_ - start_pos_;
} }
}

View File

@ -22,38 +22,41 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::OpacityBy::OpacityBy(float duration, float opacity) namespace easy2d
: FiniteTimeAction(duration)
{ {
delta_val_ = opacity; OpacityBy::OpacityBy(float duration, float opacity)
} : FiniteTimeAction(duration)
void easy2d::OpacityBy::Init()
{
FiniteTimeAction::Init();
if (target_)
{ {
start_val_ = target_->GetOpacity(); delta_val_ = opacity;
} }
}
void easy2d::OpacityBy::Update() void OpacityBy::Init()
{
FiniteTimeAction::Update();
if (target_)
{ {
target_->SetOpacity(start_val_ + delta_val_ * delta_); FiniteTimeAction::Init();
if (target_)
{
start_val_ = target_->GetOpacity();
}
} }
}
easy2d::OpacityBy * easy2d::OpacityBy::Clone() const void OpacityBy::Update()
{ {
return new OpacityBy(duration_, delta_val_); FiniteTimeAction::Update();
}
easy2d::OpacityBy * easy2d::OpacityBy::Reverse() const if (target_)
{ {
return new OpacityBy(duration_, -delta_val_); 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_);
}
} }

View File

@ -22,19 +22,22 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::OpacityTo::OpacityTo(float duration, float opacity) namespace easy2d
: OpacityBy(duration, 0)
{ {
end_val_ = opacity; OpacityTo::OpacityTo(float duration, float opacity)
} : OpacityBy(duration, 0)
{
end_val_ = opacity;
}
easy2d::OpacityTo * easy2d::OpacityTo::Clone() const OpacityTo * OpacityTo::Clone() const
{ {
return new OpacityTo(duration_, end_val_); return new OpacityTo(duration_, end_val_);
} }
void easy2d::OpacityTo::Init() void OpacityTo::Init()
{ {
OpacityBy::Init(); OpacityBy::Init();
delta_val_ = end_val_ - start_val_; delta_val_ = end_val_ - start_val_;
} }
}

View File

@ -22,38 +22,41 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::RotateBy::RotateBy(float duration, float rotation) namespace easy2d
: FiniteTimeAction(duration)
{ {
delta_val_ = rotation; RotateBy::RotateBy(float duration, float rotation)
} : FiniteTimeAction(duration)
void easy2d::RotateBy::Init()
{
FiniteTimeAction::Init();
if (target_)
{ {
start_val_ = target_->GetRotation(); delta_val_ = rotation;
} }
}
void easy2d::RotateBy::Update() void RotateBy::Init()
{
FiniteTimeAction::Update();
if (target_)
{ {
target_->SetRotation(start_val_ + delta_val_ * delta_); FiniteTimeAction::Init();
if (target_)
{
start_val_ = target_->GetRotation();
}
} }
}
easy2d::RotateBy * easy2d::RotateBy::Clone() const void RotateBy::Update()
{ {
return new RotateBy(duration_, delta_val_); FiniteTimeAction::Update();
}
easy2d::RotateBy * easy2d::RotateBy::Reverse() const if (target_)
{ {
return new RotateBy(duration_, -delta_val_); 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_);
}
} }

View File

@ -22,19 +22,22 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::RotateTo::RotateTo(float duration, float rotation) namespace easy2d
: RotateBy(duration, 0)
{ {
end_val_ = rotation; RotateTo::RotateTo(float duration, float rotation)
} : RotateBy(duration, 0)
{
end_val_ = rotation;
}
easy2d::RotateTo * easy2d::RotateTo::Clone() const RotateTo * RotateTo::Clone() const
{ {
return new RotateTo(duration_, end_val_); return new RotateTo(duration_, end_val_);
} }
void easy2d::RotateTo::Init() void RotateTo::Init()
{ {
RotateBy::Init(); RotateBy::Init();
delta_val_ = end_val_ - start_val_; delta_val_ = end_val_ - start_val_;
} }
}

View File

@ -22,47 +22,50 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::ScaleBy::ScaleBy(float duration, float scale) namespace easy2d
: FiniteTimeAction(duration)
{ {
delta_x_ = scale; ScaleBy::ScaleBy(float duration, float scale)
delta_y_ = scale; : FiniteTimeAction(duration)
}
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_)
{ {
start_scale_x_ = target_->GetScaleX(); delta_x_ = scale;
start_scale_y_ = target_->GetScaleY(); delta_y_ = scale;
} }
}
void easy2d::ScaleBy::Update() ScaleBy::ScaleBy(float duration, float scale_x, float scale_y)
{ : FiniteTimeAction(duration)
FiniteTimeAction::Update();
if (target_)
{ {
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 void ScaleBy::Init()
{ {
return new ScaleBy(duration_, delta_x_, delta_y_); FiniteTimeAction::Init();
}
easy2d::ScaleBy * easy2d::ScaleBy::Reverse() const if (target_)
{ {
return new ScaleBy(duration_, -delta_x_, -delta_y_); 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_);
}
} }

View File

@ -21,28 +21,32 @@
#include "..\e2daction.h" #include "..\e2daction.h"
#include "..\e2dobject.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) namespace easy2d
: ScaleBy(duration, 0, 0)
{ {
end_scale_x_ = scale_x; ScaleTo::ScaleTo(float duration, float scale)
end_scale_y_ = scale_y; : ScaleBy(duration, 0, 0)
} {
end_scale_x_ = scale;
end_scale_y_ = scale;
}
easy2d::ScaleTo * easy2d::ScaleTo::Clone() const ScaleTo::ScaleTo(float duration, float scale_x, float scale_y)
{ : ScaleBy(duration, 0, 0)
return new ScaleTo(duration_, end_scale_x_, end_scale_y_); {
} end_scale_x_ = scale_x;
end_scale_y_ = scale_y;
}
void easy2d::ScaleTo::Init() ScaleTo * ScaleTo::Clone() const
{ {
ScaleBy::Init(); return new ScaleTo(duration_, end_scale_x_, end_scale_y_);
delta_x_ = end_scale_x_ - start_scale_x_; }
delta_y_ = end_scale_y_ - start_scale_y_;
} void ScaleTo::Init()
{
ScaleBy::Init();
delta_x_ = end_scale_x_ - start_scale_x_;
delta_y_ = end_scale_y_ - start_scale_y_;
}
}

View File

@ -20,120 +20,124 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::Sequence::Sequence()
: action_index_(0)
{
}
easy2d::Sequence::Sequence(const Actions& actions) namespace easy2d
: action_index_(0)
{ {
this->Add(actions); Sequence::Sequence()
} : action_index_(0)
easy2d::Sequence::~Sequence()
{
for (auto action : actions_)
{ {
SafeRelease(action);
} }
}
void easy2d::Sequence::Init() Sequence::Sequence(const Actions& actions)
{ : action_index_(0)
Action::Init(); {
// 将所有动作与目标绑定 this->Add(actions);
if (target_) }
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_) for (const auto& action : actions_)
{ {
action->target_ = target_; action->ResetTime();
} }
} }
// 初始化第一个动作
actions_[0]->Init();
}
void easy2d::Sequence::Update() void Sequence::Add(Action * action)
{
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_)
{ {
if (action) if (action)
{ {
sequence->Add(action->Clone()); actions_.push_back(action);
action->Retain();
} }
} }
return sequence;
}
easy2d::Sequence * easy2d::Sequence::Reverse() const void Sequence::Add(const Actions& actions)
{
auto sequence = new Sequence();
if (sequence && !actions_.empty())
{ {
std::vector<Action*> newActions(actions_.size()); for (const auto &action : actions)
for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter)
{ {
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<Action*> newActions(actions_.size());
for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter)
{
newActions.push_back((*iter)->Reverse());
}
sequence->Add(newActions);
}
return sequence;
}
} }

View File

@ -20,118 +20,122 @@
#include "..\e2daction.h" #include "..\e2daction.h"
easy2d::Spawn::Spawn()
{
}
easy2d::Spawn::Spawn(const Actions& actions) namespace easy2d
{ {
this->Add(actions); Spawn::Spawn()
}
easy2d::Spawn::~Spawn()
{
for (auto action : actions_)
{ {
SafeRelease(action);
} }
}
void easy2d::Spawn::Init() Spawn::Spawn(const Actions& actions)
{ {
Action::Init(); 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_) for (const auto& action : actions_)
{ {
action->target_ = target_; action->ResetTime();
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();
} }
} }
if (done_num == actions_.size()) void Spawn::Add(Action * action)
{
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_)
{ {
if (action) if (action)
{ {
spawn->Add(action->Clone()); actions_.push_back(action);
action->Retain();
} }
} }
return spawn;
}
easy2d::Spawn * easy2d::Spawn::Reverse() const void Spawn::Add(const Actions& actions)
{
auto spawn = new Spawn();
if (spawn && !actions_.empty())
{ {
std::vector<Action*> newActions(actions_.size()); for (const auto &action : actions)
for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter)
{ {
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<Action*> newActions(actions_.size());
for (auto iter = actions_.crbegin(), iterCrend = actions_.crend(); iter != iterCrend; ++iter)
{
newActions.push_back((*iter)->Reverse());
}
spawn->Add(newActions);
}
return spawn;
}
} }

View File

@ -37,246 +37,249 @@
} \ } \
easy2d::Button::Button() namespace easy2d
: callback_(nullptr)
, status_(Status::Normal)
, enabled_(true)
, is_selected_(false)
, normal_(nullptr)
, mouseover_(nullptr)
, selected_(nullptr)
, disabled_(nullptr)
{ {
} Button::Button()
: callback_(nullptr)
easy2d::Button::Button(Node * normal, const Callback& func) , status_(Status::Normal)
: callback_(nullptr) , enabled_(true)
, status_(Status::Normal) , is_selected_(false)
, enabled_(true) , normal_(nullptr)
, is_selected_(false) , mouseover_(nullptr)
, normal_(nullptr) , selected_(nullptr)
, mouseover_(nullptr) , disabled_(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)
{ {
this->SetSize(normal->GetWidth(), normal->GetHeight());
} }
}
void easy2d::Button::SetMouseOver(Node * mouseover) Button::Button(Node * normal, const Callback& func)
{ : callback_(nullptr)
SET_BUTTON_NODE(mouseover_, mouseover); , status_(Status::Normal)
} , enabled_(true)
, is_selected_(false)
void easy2d::Button::SetSelected(Node * selected) , normal_(nullptr)
{ , mouseover_(nullptr)
SET_BUTTON_NODE(selected_, selected); , selected_(nullptr)
} , disabled_(nullptr)
void easy2d::Button::SetDisabled(Node * disabled)
{
SET_BUTTON_NODE(disabled_, disabled);
}
void easy2d::Button::SetEnabled(bool enabled)
{
if (enabled_ != enabled)
{ {
enabled_ = enabled; this->SetNormal(normal);
UpdateVisible(); this->SetCallbackOnClick(func);
} }
}
void easy2d::Button::SetCallbackOnClick(const Callback& func) Button::Button(Node * normal, Node * selected, const Callback& func)
{ : callback_(nullptr)
callback_ = func; , status_(Status::Normal)
} , enabled_(true)
, is_selected_(false)
void easy2d::Button::SetPivot(float pivot_x, float pivot_y) , normal_(nullptr)
{ , mouseover_(nullptr)
Node::SetPivot(pivot_x, pivot_y); , selected_(nullptr)
SAFE_SET(normal_, SetPivot, pivot_x, pivot_y); , disabled_(nullptr)
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_)
{ {
bool contains = normal_->ContainsPoint(e.GetPosition()); this->SetNormal(normal);
if (e.GetType() == MouseEvent::Type::LeftUp && is_selected_ && contains) 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_(); if (callback_)
} {
is_selected_ = false; callback_();
SetStatus(Status::Normal); }
return true; is_selected_ = false;
} SetStatus(Status::Normal);
else if (e.GetType() == MouseEvent::Type::LeftDown)
{
is_selected_ = contains;
SetStatus(contains ? Status::Selected : Status::Normal);
if (contains)
return true; return true;
} }
else if (e.GetType() == MouseEvent::Type::LeftUp) else if (e.GetType() == MouseEvent::Type::LeftDown)
{ {
is_selected_ = false; is_selected_ = contains;
} SetStatus(contains ? Status::Selected : Status::Normal);
else if (e.GetType() == MouseEvent::Type::MoveBy && is_selected_ && contains)
{ if (contains)
SetStatus(Status::Selected); return true;
return true; }
} else if (e.GetType() == MouseEvent::Type::LeftUp)
else
{
if (!e.IsLButtonDown() && is_selected_)
{ {
is_selected_ = false; is_selected_ = false;
} }
else if (e.GetType() == MouseEvent::Type::MoveBy && is_selected_ && contains)
SetStatus(contains ? Status::Mouseover : Status::Normal); {
SetStatus(Status::Selected);
if (contains)
return true; 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 Button::SetStatus(Status status)
}
void easy2d::Button::Visit()
{
Node::Visit();
if (IsVisible() &&
!enabled_ &&
normal_ &&
normal_->ContainsPoint(Device::GetInput()->GetMousePos()))
{ {
HCURSOR hcursor = ::LoadCursor(nullptr, IDC_NO); if (status_ != status)
if (hcursor)
{ {
::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) void Button::UpdateVisible()
{
if (status_ != status)
{ {
status_ = status; SAFE_SET(normal_, SetVisible, false);
UpdateVisible(); SAFE_SET(mouseover_, SetVisible, false);
} SAFE_SET(selected_, SetVisible, false);
} SAFE_SET(disabled_, SetVisible, false);
void easy2d::Button::UpdateVisible() if (enabled_)
{
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_)
{ {
selected_->SetVisible(true); if (status_ == Status::Selected && selected_)
} {
else if (status_ == Status::Mouseover && mouseover_) selected_->SetVisible(true);
{ }
mouseover_->SetVisible(true); else if (status_ == Status::Mouseover && mouseover_)
{
mouseover_->SetVisible(true);
}
else
{
if (normal_) normal_->SetVisible(true);
}
} }
else 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);
}
}
}

View File

@ -20,77 +20,81 @@
#include "..\e2dcomponent.h" #include "..\e2dcomponent.h"
easy2d::Menu::Menu()
: enabled_(true)
{
}
easy2d::Menu::Menu(const std::vector<Button*>& buttons) namespace easy2d
: enabled_(true)
{ {
for (const auto& button : buttons) Menu::Menu()
: enabled_(true)
{ {
this->AddButton(button);
} }
}
bool easy2d::Menu::IsEnable() const Menu::Menu(const std::vector<Button*>& buttons)
{ : enabled_(true)
return enabled_;
}
size_t easy2d::Menu::GetButtonCount() const
{
return buttons_.size();
}
void easy2d::Menu::SetEnabled(bool enabled)
{
if (enabled_ != enabled)
{ {
enabled_ = enabled; for (const auto& button : buttons)
for (const auto& button : buttons_)
{ {
button->SetEnabled(enabled); this->AddButton(button);
} }
} }
}
void easy2d::Menu::AddButton(Button * button) bool Menu::IsEnable() const
{
if (button)
{ {
this->AddChild(button); return enabled_;
buttons_.push_back(button);
button->SetEnabled(enabled_);
} }
}
bool easy2d::Menu::RemoveButton(Button * button) size_t Menu::GetButtonCount() const
{
if (buttons_.empty())
{ {
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; return false;
} }
this->RemoveChild(button); const std::vector<Button*>& Menu::GetAllButtons() const
if (button)
{ {
auto iter = std::find(buttons_.begin(), buttons_.end(), button); return buttons_;
if (iter != buttons_.end())
{
// ÒÆ³ý°´Å¥Ç°£¬½«ËüÆôÓÃ
button->SetEnabled(true);
buttons_.erase(iter);
return true;
}
} }
return false; }
}
const std::vector<easy2d::Button*>& easy2d::Menu::GetAllButtons() const
{
return buttons_;
}

View File

@ -61,7 +61,7 @@ namespace easy2d
Point operator - () const; Point operator - () const;
bool operator== (const Point& other) const; bool operator== (const Point& other) const;
explicit operator easy2d::Size() const; explicit operator Size() const;
// 判断两点间距离 // 判断两点间距离
static float Distance( static float Distance(
@ -102,7 +102,7 @@ namespace easy2d
Size operator - () const; Size operator - () const;
bool operator== (const Size& other) const; bool operator== (const Size& other) const;
explicit operator easy2d::Point() const; explicit operator Point() const;
}; };
@ -585,19 +585,19 @@ namespace easy2d
template<typename T> template<typename T>
static inline T Range(T min, T max) 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) 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) static inline double Range(double min, double max)
{ {
return easy2d::Random::RandomReal(min, max); return Random::RandomReal(min, max);
} }
private: private:

View File

@ -21,80 +21,83 @@
#include "..\e2devent.h" #include "..\e2devent.h"
easy2d::KeyEvent::KeyEvent(UINT message, WPARAM w_param, LPARAM l_param) namespace easy2d
: message_(message)
, w_param_(w_param)
, l_param_(l_param)
{ {
} KeyEvent::KeyEvent(UINT message, WPARAM w_param, LPARAM l_param)
: message_(message)
easy2d::KeyCode easy2d::KeyEvent::GetCode() const , w_param_(w_param)
{ , l_param_(l_param)
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;
} }
}
int easy2d::KeyEvent::GetCount() const KeyCode KeyEvent::GetCode() const
{ {
return static_cast<int>((DWORD)l_param_ & 0x0000FFFF); 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 int KeyEvent::GetCount() const
{ {
return Type(message_); return static_cast<int>((DWORD)l_param_ & 0x0000FFFF);
} }
KeyEvent::Type KeyEvent::GetType() const
{
return Type(message_);
}
}

View File

@ -21,65 +21,68 @@
#include "..\e2devent.h" #include "..\e2devent.h"
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
easy2d::MouseEvent::MouseEvent(UINT message, WPARAM w_param, LPARAM l_param) namespace easy2d
: message_(message)
, w_param_(w_param)
, l_param_(l_param)
{ {
} 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 MouseEvent::GetX() const
{ {
float dpi = Graphics::GetDpi(); float dpi = Graphics::GetDpi();
return ((float)(short)LOWORD(l_param_)) * 96.f / dpi; return ((float)(short)LOWORD(l_param_)) * 96.f / dpi;
} }
float easy2d::MouseEvent::GetY() const float MouseEvent::GetY() const
{ {
float dpi = Graphics::GetDpi(); float dpi = Graphics::GetDpi();
return ((float)(short)HIWORD(l_param_)) * 96.f / dpi; return ((float)(short)HIWORD(l_param_)) * 96.f / dpi;
} }
easy2d::Point easy2d::MouseEvent::GetPosition() const Point MouseEvent::GetPosition() const
{ {
float dpi = Graphics::GetDpi(); float dpi = Graphics::GetDpi();
return Point( return Point(
((float)(short)LOWORD(l_param_)) * 96.f / dpi, ((float)(short)LOWORD(l_param_)) * 96.f / dpi,
((float)(short)HIWORD(l_param_)) * 96.f / dpi ((float)(short)HIWORD(l_param_)) * 96.f / dpi
); );
} }
bool easy2d::MouseEvent::IsShiftDown() const bool MouseEvent::IsShiftDown() const
{ {
return GET_KEYSTATE_WPARAM(w_param_) == MK_SHIFT; return GET_KEYSTATE_WPARAM(w_param_) == MK_SHIFT;
} }
bool easy2d::MouseEvent::IsCtrlDown() const bool MouseEvent::IsCtrlDown() const
{ {
return GET_KEYSTATE_WPARAM(w_param_) == MK_CONTROL; return GET_KEYSTATE_WPARAM(w_param_) == MK_CONTROL;
} }
float easy2d::MouseEvent::GetWheelDelta() const float MouseEvent::GetWheelDelta() const
{ {
return static_cast<float>(GET_WHEEL_DELTA_WPARAM(w_param_)); return static_cast<float>(GET_WHEEL_DELTA_WPARAM(w_param_));
} }
bool easy2d::MouseEvent::IsLButtonDown() const bool MouseEvent::IsLButtonDown() const
{ {
return GET_KEYSTATE_WPARAM(w_param_) == MK_LBUTTON; return GET_KEYSTATE_WPARAM(w_param_) == MK_LBUTTON;
} }
bool easy2d::MouseEvent::IsRButtonDown() const bool MouseEvent::IsRButtonDown() const
{ {
return GET_KEYSTATE_WPARAM(w_param_) == MK_RBUTTON; return GET_KEYSTATE_WPARAM(w_param_) == MK_RBUTTON;
} }
bool easy2d::MouseEvent::IsMButtonDown() const bool MouseEvent::IsMButtonDown() const
{ {
return GET_KEYSTATE_WPARAM(w_param_) == MK_MBUTTON; return GET_KEYSTATE_WPARAM(w_param_) == MK_MBUTTON;
} }
easy2d::MouseEvent::Type easy2d::MouseEvent::GetType() const MouseEvent::Type MouseEvent::GetType() const
{ {
return Type(message_); return Type(message_);
} }
}

View File

@ -21,47 +21,50 @@
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
easy2d::Audio::Audio() namespace easy2d
: x_audio2_(nullptr)
, mastering_voice_(nullptr)
{ {
ThrowIfFailed( Audio::Audio()
MFStartup(MF_VERSION) : x_audio2_(nullptr)
); , mastering_voice_(nullptr)
ThrowIfFailed(
XAudio2Create(&x_audio2_)
);
ThrowIfFailed(
x_audio2_->CreateMasteringVoice(&mastering_voice_)
);
}
easy2d::Audio::~Audio()
{
if (mastering_voice_)
{ {
mastering_voice_->DestroyVoice(); ThrowIfFailed(
mastering_voice_ = nullptr; 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) MFShutdown();
{ }
return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
}
void easy2d::Audio::Open() HRESULT Audio::CreateVoice(IXAudio2SourceVoice ** voice, WAVEFORMATEX * wfx)
{ {
x_audio2_->StartEngine(); return x_audio2_->CreateSourceVoice(voice, wfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO);
} }
void easy2d::Audio::Close() void Audio::Open()
{ {
x_audio2_->StopEngine(); x_audio2_->StartEngine();
} }
void Audio::Close()
{
x_audio2_->StopEngine();
}
}

View File

@ -20,49 +20,56 @@
#include "..\e2dmodule.h" #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; namespace
}
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)
{ {
delete audio_device; Graphics * graphics_device = nullptr;
audio_device = nullptr; Input * input_device = nullptr;
Audio * audio_device = nullptr;
} }
if (input_device) Graphics * Device::GetGraphics()
{ {
delete input_device; return graphics_device;
input_device = nullptr;
} }
if (graphics_device) Input * Device::GetInput()
{ {
delete graphics_device; return input_device;
graphics_device = nullptr;
} }
}
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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,10 @@
namespace easy2d namespace easy2d
{ {
// 文字渲染器 //-------------------------------------------------------
// TextRenderer
//-------------------------------------------------------
class TextRenderer class TextRenderer
: public IDWriteTextRenderer : public IDWriteTextRenderer
{ {
@ -505,320 +508,324 @@ namespace easy2d
return S_OK; return S_OK;
} }
}
easy2d::Graphics::Graphics(HWND hwnd) //-------------------------------------------------------
: factory_(nullptr) // Graphics
, 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_
)
);
ThrowIfFailed( Graphics::Graphics(HWND hwnd)
CoCreateInstance( : factory_(nullptr)
CLSID_WICImagingFactory, , imaging_factory_(nullptr)
nullptr, , write_factory_(nullptr)
CLSCTX_INPROC_SERVER, , miter_stroke_style_(nullptr)
IID_IWICImagingFactory, , bevel_stroke_style_(nullptr)
reinterpret_cast<void**>(&imaging_factory_) , round_stroke_style_(nullptr)
) , fps_text_format_(nullptr)
); , fps_text_layout_(nullptr)
, render_target_(nullptr)
ThrowIfFailed( , solid_brush_(nullptr)
DWriteCreateFactory( , text_renderer_(nullptr)
DWRITE_FACTORY_TYPE_SHARED, , clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&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)
{ {
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源 ThrowIfFailed(
// 并在下一次调用时重建资源 D2D1CreateFactory(
hr = S_OK; D2D1_FACTORY_TYPE_SINGLE_THREADED,
&factory_
)
);
ThrowIfFailed(
CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void**>(&imaging_factory_)
)
);
ThrowIfFailed(
DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&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_format_);
SafeRelease(fps_text_layout_); SafeRelease(fps_text_layout_);
SafeRelease(text_renderer_); SafeRelease(text_renderer_);
SafeRelease(solid_brush_); SafeRelease(solid_brush_);
SafeRelease(render_target_); 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 Graphics::BeginDraw()
}
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_)
{ {
ThrowIfFailed( render_target_->BeginDraw();
write_factory_->CreateTextFormat( render_target_->Clear(clear_color_);
L"", }
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<UINT32>(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<TextRenderer*>(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, nullptr,
DWRITE_FONT_WEIGHT_NORMAL, text_renderer_,
DWRITE_FONT_STYLE_NORMAL, 10,
DWRITE_FONT_STRETCH_NORMAL, 0
20, );
L"", }
&fps_text_format_
)
);
ThrowIfFailed(
fps_text_format_->SetWordWrapping(
DWRITE_WORD_WRAPPING_NO_WRAP
)
);
} }
++render_times_; ID2D1HwndRenderTarget * Graphics::GetRenderTarget() const
if (duration >= 100)
{ {
wchar_t fps_text[12] = {}; return render_target_;
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<UINT32>(len),
fps_text_format_,
0,
0,
&fps_text_layout_
)
);
} }
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<TextRenderer*>(text_renderer_)->SetTextStyle( static_cast<TextRenderer*>(text_renderer_)->SetTextStyle(
D2D1::ColorF(D2D1::ColorF::White), D2D1_COLOR_F(fill_color),
TRUE, has_outline,
D2D1::ColorF(D2D1::ColorF::Black, 0.4f), D2D1_COLOR_F(outline_color),
1.5f, outline_width,
D2D1_LINE_JOIN_ROUND D2D1_LINE_JOIN(outline_stroke)
);
fps_text_layout_->Draw(
nullptr,
text_renderer_,
10,
0
); );
} }
}
ID2D1HwndRenderTarget * easy2d::Graphics::GetRenderTarget() const float Graphics::GetDpi()
{
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_)
{ {
ThrowIfFailed( static float dpi = -1;
factory_->CreateStrokeStyle( if (dpi < 0)
D2D1::StrokeStyleProperties( {
D2D1_CAP_STYLE_FLAT, HDC hdc = ::GetDC(0);
D2D1_CAP_STYLE_FLAT, dpi = static_cast<float>(::GetDeviceCaps(hdc, LOGPIXELSX));
D2D1_CAP_STYLE_FLAT, ::ReleaseDC(0, hdc);
D2D1_LINE_JOIN_MITER, }
2.0f, return dpi;
D2D1_DASH_STYLE_SOLID,
0.0f),
nullptr,
0,
&miter_stroke_style_
)
);
} }
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<TextRenderer*>(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<float>(::GetDeviceCaps(hdc, LOGPIXELSX));
::ReleaseDC(0, hdc);
}
return dpi;
}

View File

@ -22,151 +22,154 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
easy2d::Input::Input(HWND hwnd) namespace easy2d
: direct_input_(nullptr)
, keyboard_device_(nullptr)
, mouse_device_(nullptr)
{ {
ZeroMemory(key_buffer_, sizeof(key_buffer_)); Input::Input(HWND hwnd)
ZeroMemory(&mouse_state_, sizeof(mouse_state_)); : direct_input_(nullptr)
, keyboard_device_(nullptr)
HINSTANCE hinstance = GetModuleHandle(nullptr); , mouse_device_(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_)
{ {
HRESULT hr = keyboard_device_->Poll(); ZeroMemory(key_buffer_, sizeof(key_buffer_));
if (FAILED(hr)) 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(); HRESULT hr = keyboard_device_->Poll();
while (hr == DIERR_INPUTLOST) if (FAILED(hr))
{
hr = keyboard_device_->Acquire(); 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_) if (mouse_device_)
{
HRESULT hr = mouse_device_->Poll();
if (FAILED(hr))
{ {
hr = mouse_device_->Acquire(); HRESULT hr = mouse_device_->Poll();
while (hr == DIERR_INPUTLOST) if (FAILED(hr))
{
hr = mouse_device_->Acquire(); hr = mouse_device_->Acquire();
} while (hr == DIERR_INPUTLOST)
else hr = mouse_device_->Acquire();
{ }
mouse_device_->GetDeviceState( else
sizeof(mouse_state_), {
(void**)&mouse_state_ mouse_device_->GetDeviceState(
); sizeof(mouse_state_),
(void**)&mouse_state_
);
}
} }
} }
}
bool easy2d::Input::IsDown(KeyCode key) bool Input::IsDown(KeyCode key)
{ {
if (key_buffer_[static_cast<int>(key)] & 0x80) if (key_buffer_[static_cast<int>(key)] & 0x80)
return true; return true;
return false; return false;
} }
bool easy2d::Input::IsDown(MouseCode code) bool Input::IsDown(MouseCode code)
{ {
if (mouse_state_.rgbButtons[static_cast<int>(code)] & 0x80) if (mouse_state_.rgbButtons[static_cast<int>(code)] & 0x80)
return true; return true;
return false; return false;
} }
float easy2d::Input::GetMouseX() float Input::GetMouseX()
{ {
return GetMousePos().x; return GetMousePos().x;
} }
float easy2d::Input::GetMouseY() float Input::GetMouseY()
{ {
return GetMousePos().y; return GetMousePos().y;
} }
easy2d::Point easy2d::Input::GetMousePos() Point Input::GetMousePos()
{ {
POINT mousePos; POINT mousePos;
::GetCursorPos(&mousePos); ::GetCursorPos(&mousePos);
::ScreenToClient(Game::GetInstance()->GetHWnd(), &mousePos); ::ScreenToClient(Game::GetInstance()->GetHWnd(), &mousePos);
float dpi = Graphics::GetDpi(); float dpi = Graphics::GetDpi();
return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi); return Point(mousePos.x * 96.f / dpi, mousePos.y * 96.f / dpi);
} }
float easy2d::Input::GetMouseDeltaX() float Input::GetMouseDeltaX()
{ {
return (float)mouse_state_.lX; return (float)mouse_state_.lX;
} }
float easy2d::Input::GetMouseDeltaY() float Input::GetMouseDeltaY()
{ {
return (float)mouse_state_.lY; return (float)mouse_state_.lY;
} }
float easy2d::Input::GetMouseDeltaZ() float Input::GetMouseDeltaZ()
{ {
return (float)mouse_state_.lZ; return (float)mouse_state_.lZ;
} }
}

View File

@ -21,230 +21,233 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
easy2d::Canvas::Canvas(float width, float height) namespace easy2d
: render_target_(nullptr)
, fill_brush_(nullptr)
, line_brush_(nullptr)
, stroke_style_(nullptr)
, stroke_width_(1.0f)
, stroke_(Stroke::Miter)
{ {
render_target_ = Device::GetGraphics()->GetRenderTarget(); Canvas::Canvas(float width, float height)
render_target_->AddRef(); : render_target_(nullptr)
, fill_brush_(nullptr)
ThrowIfFailed( , line_brush_(nullptr)
render_target_->CreateSolidColorBrush( , stroke_style_(nullptr)
D2D1::ColorF(D2D1::ColorF::White), , stroke_width_(1.0f)
&fill_brush_ , stroke_(Stroke::Miter)
)
);
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)
{ {
case easy2d::Stroke::Miter: render_target_ = Device::GetGraphics()->GetRenderTarget();
stroke_style_ = Device::GetGraphics()->GetMiterStrokeStyle(); render_target_->AddRef();
break;
case easy2d::Stroke::Bevel: ThrowIfFailed(
stroke_style_ = Device::GetGraphics()->GetBevelStrokeStyle(); render_target_->CreateSolidColorBrush(
break; D2D1::ColorF(D2D1::ColorF::White),
case easy2d::Stroke::Round: &fill_brush_
stroke_style_ = Device::GetGraphics()->GetRoundStrokeStyle(); )
break; );
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 Canvas::~Canvas()
{ {
return line_brush_->GetColor(); SafeRelease(line_brush_);
} SafeRelease(fill_brush_);
SafeRelease(render_target_);
}
easy2d::Color easy2d::Canvas::GetFillColor() const void Canvas::SetLineColor(const Color & color)
{ {
return fill_brush_->GetColor(); line_brush_->SetColor(D2D_COLOR_F(color));
} }
float easy2d::Canvas::GetStrokeWidth() const void Canvas::SetFillColor(const Color & color)
{ {
return stroke_width_; fill_brush_->SetColor(D2D_COLOR_F(color));
} }
easy2d::Stroke easy2d::Canvas::GetStrokeStyle() const void Canvas::SetStrokeWidth(float width)
{ {
return stroke_; stroke_width_ = std::max(width, 0.f);
} }
void easy2d::Canvas::DrawLine(const Point & begin, const Point & end) void Canvas::SetStrokeStyle(Stroke strokeStyle)
{ {
render_target_->DrawLine( switch (strokeStyle)
D2D1::Point2F(begin.x, begin.y), {
D2D1::Point2F(end.x, end.y), case Stroke::Miter:
line_brush_, stroke_style_ = Device::GetGraphics()->GetMiterStrokeStyle();
stroke_width_, break;
stroke_style_ 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) Color Canvas::GetLineColor() const
{ {
render_target_->DrawEllipse( return line_brush_->GetColor();
D2D1::Ellipse( }
D2D1::Point2F(
center.x, Color Canvas::GetFillColor() const
center.y {
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, line_brush_,
radius stroke_width_,
), stroke_style_
line_brush_, );
stroke_width_, }
stroke_style_
);
}
void easy2d::Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y) void Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y)
{ {
render_target_->DrawEllipse( render_target_->DrawEllipse(
D2D1::Ellipse( D2D1::Ellipse(
D2D1::Point2F( D2D1::Point2F(
center.x, center.x,
center.y center.y
),
radius_x,
radius_y
), ),
radius_x, line_brush_,
radius_y stroke_width_,
), stroke_style_
line_brush_, );
stroke_width_, }
stroke_style_
);
}
void easy2d::Canvas::DrawRect(const Rect & rect) void Canvas::DrawRect(const Rect & rect)
{ {
render_target_->DrawRectangle( 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(
D2D1::RectF( D2D1::RectF(
rect.origin.x, rect.origin.x,
rect.origin.y, rect.origin.y,
rect.origin.x + rect.size.width, rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height rect.origin.y + rect.size.height
), ),
radius_x, line_brush_,
radius_y stroke_width_,
), stroke_style_
line_brush_, );
stroke_width_, }
stroke_style_
);
}
void easy2d::Canvas::FillCircle(const Point & center, float radius) void Canvas::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y)
{ {
render_target_->FillEllipse( render_target_->DrawRoundedRectangle(
D2D1::Ellipse( D2D1::RoundedRect(
D2D1::Point2F( D2D1::RectF(
center.x, rect.origin.x,
center.y rect.origin.y,
rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height
),
radius_x,
radius_y
), ),
radius, line_brush_,
radius stroke_width_,
), stroke_style_
fill_brush_ );
); }
}
void easy2d::Canvas::FillEllipse(const Point & center, float radius_x, float radius_y) void Canvas::FillCircle(const Point & center, float radius)
{ {
render_target_->FillEllipse( render_target_->FillEllipse(
D2D1::Ellipse( D2D1::Ellipse(
D2D1::Point2F( D2D1::Point2F(
center.x, center.x,
center.y center.y
),
radius,
radius
), ),
radius_x, fill_brush_
radius_y );
), }
fill_brush_
);
}
void easy2d::Canvas::FillRect(const Rect & rect) void Canvas::FillEllipse(const Point & center, float radius_x, float radius_y)
{ {
render_target_->FillRectangle( render_target_->FillEllipse(
D2D1::RectF( D2D1::Ellipse(
rect.origin.x, D2D1::Point2F(
rect.origin.y, center.x,
rect.origin.x + rect.size.width, center.y
rect.origin.y + rect.size.height ),
), radius_x,
fill_brush_ radius_y
); ),
} fill_brush_
);
}
void easy2d::Canvas::FillRoundedRect(const Rect & rect, float radius_x, float radius_y) void Canvas::FillRect(const Rect & rect)
{ {
render_target_->FillRoundedRectangle( render_target_->FillRectangle(
D2D1::RoundedRect(
D2D1::RectF( D2D1::RectF(
rect.origin.x, rect.origin.x,
rect.origin.y, rect.origin.y,
rect.origin.x + rect.size.width, rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height rect.origin.y + rect.size.height
), ),
radius_x, fill_brush_
radius_y );
), }
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_
);
}
}

View File

@ -22,371 +22,374 @@
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
#include "..\e2dtool.h" #include "..\e2dtool.h"
std::map<size_t, ID2D1Bitmap*> easy2d::Image::bitmap_cache_; namespace easy2d
easy2d::Image::Image()
: bitmap_(nullptr)
, crop_rect_()
{ {
} std::map<size_t, ID2D1Bitmap*> Image::bitmap_cache_;
easy2d::Image::Image(Resource& res) Image::Image()
: bitmap_(nullptr) : bitmap_(nullptr)
, crop_rect_() , 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))
{ {
E2D_WARNING("Load Image from file failed!");
return false;
} }
this->SetBitmap(bitmap_cache_.at(res.GetHashCode())); Image::Image(Resource& res)
return true; : bitmap_(nullptr)
} , crop_rect_()
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))
{ {
E2D_WARNING("Load Image from file failed!"); this->Load(res);
return false;
} }
this->SetBitmap(bitmap_cache_.at(std::hash<std::wstring>{}(file_name))); Image::Image(Resource& res, const Rect& crop_rect)
return true; : bitmap_(nullptr)
} , crop_rect_()
void easy2d::Image::Crop(const Rect& crop_rect)
{
if (bitmap_)
{ {
auto bitmap_size = bitmap_->GetSize(); this->Load(res);
crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.width); this->Crop(crop_rect);
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);
} }
}
float easy2d::Image::GetWidth() const Image::Image(const std::wstring & file_name)
{ : bitmap_(nullptr)
return crop_rect_.size.width; , crop_rect_()
}
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_)
{ {
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 Image::~Image()
{
if (bitmap_)
{ {
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 this->SetBitmap(bitmap_cache_.at(res.GetHashCode()));
{
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())
{
return true; return true;
} }
HRESULT hr; bool Image::Load(const std::wstring & file_name)
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 流 E2D_WARNING_IF(file_name.empty(), "Image Load failed! Invalid file name.");
hr = imaging_factory->CreateStream(&stream);
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<std::wstring>{}(file_name)));
return true;
} }
if (SUCCEEDED(hr)) void Image::Crop(const Rect& crop_rect)
{ {
// 初始化流 if (bitmap_)
hr = stream->InitializeFromMemory( {
static_cast<WICInProcPointer>(res.GetData()), auto bitmap_size = bitmap_->GetSize();
res.GetDataSize() 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
{ {
// 创建流的解码器 return crop_rect_.size.width;
hr = imaging_factory->CreateDecoderFromStream( }
stream,
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<WICInProcPointer>(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<std::wstring>{}(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, nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad, WICDecodeMetadataCacheOnLoad,
&decoder &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()
{ {
// 创建初始化框架 if (bitmap_cache_.empty())
hr = decoder->GetFrame(0, &source); return;
for (const auto& bitmap : bitmap_cache_)
{
bitmap.second->Release();
}
bitmap_cache_.clear();
} }
if (SUCCEEDED(hr)) void Image::SetBitmap(ID2D1Bitmap * bitmap)
{ {
// 创建图片格式转换器 if (bitmap_ == bitmap)
hr = imaging_factory->CreateFormatConverter(&converter); 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<std::wstring>{}(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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -21,100 +21,103 @@
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::Scene::Scene() namespace easy2d
: root_(nullptr)
, transform_(D2D1::Matrix3x2F::Identity())
{ {
} Scene::Scene()
: root_(nullptr)
easy2d::Scene::Scene(Node * root) , transform_(D2D1::Matrix3x2F::Identity())
: root_(nullptr)
, transform_(D2D1::Matrix3x2F::Identity())
{
this->SetRoot(root);
}
easy2d::Scene::~Scene()
{
if (root_)
{ {
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(); this->SetRoot(root);
root->SetParentScene(this);
} }
root_ = root; Scene::~Scene()
}
easy2d::Node * easy2d::Scene::GetRoot() const
{
return root_;
}
void easy2d::Scene::Draw()
{
if (root_)
{ {
root_->Visit(); if (root_)
} {
} root_->SetParentScene(nullptr);
root_->Release();
void easy2d::Scene::Dispatch(const MouseEvent & e) }
{
auto handler = dynamic_cast<MouseEventHandler*>(this);
if (handler)
{
handler->Handle(e);
} }
if (root_) void Scene::SetRoot(Node * root)
{ {
root_->Dispatch(e, false); if (root_ == root)
} return;
}
void easy2d::Scene::Dispatch(const KeyEvent & e) if (root_)
{ {
auto handler = dynamic_cast<KeyEventHandler*>(this); root_->SetParentScene(nullptr);
if (handler) root_->Release();
{ }
handler->Handle(e);
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) void Scene::Draw()
{
transform_ = matrix;
if (root_)
{ {
root_->dirty_transform_ = true; if (root_)
{
root_->Visit();
}
} }
}
const D2D1::Matrix3x2F & easy2d::Scene::GetTransform() const void Scene::Dispatch(const MouseEvent & e)
{ {
return transform_; auto handler = dynamic_cast<MouseEventHandler*>(this);
} if (handler)
{
handler->Handle(e);
}
if (root_)
{
root_->Dispatch(e, false);
}
}
void Scene::Dispatch(const KeyEvent & e)
{
auto handler = dynamic_cast<KeyEventHandler*>(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_;
}
}

View File

@ -21,128 +21,131 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
easy2d::Sprite::Sprite() namespace easy2d
: image_(nullptr)
{ {
} Sprite::Sprite()
: image_(nullptr)
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)
{ {
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; if (image_->Load(res))
image_->Retain(); {
Node::SetSize(image_->GetWidth(), image_->GetHeight());
Node::SetSize(image_->GetWidth(), image_->GetHeight()); return true;
return true; }
} return false;
return false;
}
bool easy2d::Sprite::Load(Resource& res)
{
if (!image_)
{
image_ = new Image();
image_->Retain();
} }
if (image_->Load(res)) bool Sprite::Load(const std::wstring & file_name)
{ {
Node::SetSize(image_->GetWidth(), image_->GetHeight()); if (!image_)
return true; {
} image_ = new Image();
return false; image_->Retain();
} }
bool easy2d::Sprite::Load(const std::wstring & file_name) if (image_->Load(file_name))
{ {
if (!image_) Node::SetSize(image_->GetWidth(), image_->GetHeight());
{ return true;
image_ = new Image(); }
image_->Retain(); return false;
} }
if (image_->Load(file_name)) void Sprite::Crop(const Rect& crop_rect)
{ {
Node::SetSize(image_->GetWidth(), image_->GetHeight()); image_->Crop(crop_rect);
return true; Node::SetSize(
} std::min(std::max(crop_rect.size.width, 0.f), image_->GetSourceWidth() - image_->GetCropX()),
return false; std::min(std::max(crop_rect.size.height, 0.f), image_->GetSourceHeight() - image_->GetCropY())
}
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 * 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
)
);
}
}
}

View File

@ -21,89 +21,92 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::Task::Task(const Callback & func, const std::wstring & name) namespace easy2d
: running_(true)
, stopped_(false)
, run_times_(0)
, total_times_(-1)
, delay_()
, callback_(func)
, name_(name)
{ {
} Task::Task(const Callback & func, const std::wstring & name)
: running_(true)
easy2d::Task::Task(const Callback & func, float delay, int times, const std::wstring & name) , stopped_(false)
: running_(true) , run_times_(0)
, stopped_(false) , total_times_(-1)
, run_times_(0) , delay_()
, delay_(Duration::Second * std::max(delay, 0.f)) , callback_(func)
, total_times_(times) , name_(name)
, 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)
{ {
stopped_ = true;
return;
} }
++run_times_; Task::Task(const Callback & func, float delay, int times, const std::wstring & name)
last_time_ += delay_; : running_(true)
, stopped_(false)
if (callback_) , 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; running_ = true;
return; last_time_ = Time::Now();
} }
}
void easy2d::Task::ResetTime() void Task::Stop()
{
last_time_ = Time::Now();
}
bool easy2d::Task::IsReady() const
{
if (running_)
{ {
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 void Task::ResetTime()
{ {
return running_; last_time_ = Time::Now();
} }
const std::wstring& easy2d::Task::GetName() const bool Task::IsReady() const
{ {
return name_; 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_;
}
}

View File

@ -21,449 +21,453 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
//-------------------------------------------------------
// Style
//-------------------------------------------------------
easy2d::Text::Style::Style() namespace easy2d
: 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)
{ {
} //-------------------------------------------------------
// Style
//-------------------------------------------------------
easy2d::Text::Text(const std::wstring & text, const Font & font, const Style & style) Text::Style::Style()
: font_(font) : color(Color::White)
, style_(style) , alignment(Align::Left)
, text_layout_(nullptr) , wrap(false)
, text_format_(nullptr) , wrap_width(0.f)
, text_(text) , line_spacing(0.f)
{ , underline(false)
Reset(); , strikethrough(false)
} , outline(true)
, outline_color(Color(Color::Black, 0.5))
, outline_width(1.f)
, outline_stroke(Stroke::Round)
{}
easy2d::Text::~Text() Text::Style::Style(
{ Color color,
SafeRelease(text_format_); Align alignment,
SafeRelease(text_layout_); 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 //-------------------------------------------------------
{ // Text
return style_; //-------------------------------------------------------
}
const std::wstring& easy2d::Text::GetFontFamily() const Text::Text()
{ : font_()
return font_.family; , style_()
} , text_layout_(nullptr)
, text_format_(nullptr)
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_)
{ {
DWRITE_TEXT_METRICS metrics;
text_layout_->GetMetrics(&metrics);
return static_cast<int>(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(); Reset();
} }
}
void easy2d::Text::SetWrapWidth(float wrap_width) Text::~Text()
{
if (style_.wrap_width != wrap_width)
{ {
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<int>(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(); Reset();
} }
} }
}
void easy2d::Text::SetLineSpacing(float line_spacing) void Text::SetWrapWidth(float wrap_width)
{
if (style_.line_spacing != line_spacing)
{ {
style_.line_spacing = line_spacing; if (style_.wrap_width != wrap_width)
Reset(); {
style_.wrap_width = std::max(wrap_width, 0.f);
if (style_.wrap)
{
Reset();
}
}
} }
}
void easy2d::Text::SetAlignment(Align align) void Text::SetLineSpacing(float line_spacing)
{
if (style_.alignment != align)
{ {
style_.alignment = align; if (style_.line_spacing != line_spacing)
Reset(); {
style_.line_spacing = line_spacing;
Reset();
}
} }
}
void easy2d::Text::SetUnderline(bool underline) void Text::SetAlignment(Align align)
{
if (style_.underline != underline)
{ {
style_.underline = underline; if (style_.alignment != align)
if (!text_format_) {
CreateFormat(); 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(); CreateLayout();
} }
}
void easy2d::Text::SetStrikethrough(bool strikethrough) void Text::CreateFormat()
{
if (style_.strikethrough != strikethrough)
{ {
style_.strikethrough = strikethrough; SafeRelease(text_format_);
if (!text_format_)
CreateFormat();
CreateLayout();
}
}
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<UINT32>(text_.size());
auto writeFactory = Device::GetGraphics()->GetWriteFactory();
// 对文本自动换行情况下进行处理
if (style_.wrap)
{
ThrowIfFailed( ThrowIfFailed(
writeFactory->CreateTextLayout( Device::GetGraphics()->GetWriteFactory()->CreateTextFormat(
text_.c_str(), font_.family.c_str(),
length, nullptr,
text_format_, DWRITE_FONT_WEIGHT(font_.weight),
style_.wrap_width, font_.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
0, DWRITE_FONT_STRETCH_NORMAL,
&text_layout_ font_.size,
) L"",
); &text_format_
// 获取文本布局的宽度和高度
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_format_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT(style_.alignment));
text_layout_->GetMetrics(&metrics);
// 重设文本宽高
this->SetSize(metrics.width, metrics.height);
// 重新创建 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_); 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 (text_.empty())
if (style_.underline) {
{ this->SetSize(0, 0);
text_layout_->SetUnderline(true, Range); return;
}
if (text_format_ == nullptr)
{
E2D_WARNING("Text::CreateLayout failed! text_format_ NULL pointer exception.");
return;
}
UINT32 length = static_cast<UINT32>(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);
}
}

View File

@ -21,126 +21,129 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
easy2d::Data::Data(const std::wstring & key, const std::wstring & field) namespace easy2d
: key_(key)
, field_(field)
, data_path_(Path::GetDataPath())
{ {
} Data::Data(const std::wstring & key, const std::wstring & field)
: key_(key)
, field_(field)
, data_path_(Path::GetDataPath())
{
}
bool easy2d::Data::Exists() const bool Data::Exists() const
{ {
wchar_t temp[256] = { 0 }; wchar_t temp[256] = { 0 };
::GetPrivateProfileStringW( ::GetPrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
L"", L"",
temp, temp,
255, 255,
data_path_.c_str() data_path_.c_str()
); );
return temp[0] == L'\0'; return temp[0] == L'\0';
} }
bool easy2d::Data::SaveInt(int value) bool Data::SaveInt(int value)
{ {
BOOL ret = ::WritePrivateProfileStringW( BOOL ret = ::WritePrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
std::to_wstring(value).c_str(), std::to_wstring(value).c_str(),
data_path_.c_str() data_path_.c_str()
); );
return ret == TRUE; return ret == TRUE;
} }
bool easy2d::Data::SaveFloat(float value) bool Data::SaveFloat(float value)
{ {
BOOL ret = ::WritePrivateProfileStringW( BOOL ret = ::WritePrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
std::to_wstring(value).c_str(), std::to_wstring(value).c_str(),
data_path_.c_str() data_path_.c_str()
); );
return ret == TRUE; return ret == TRUE;
} }
bool easy2d::Data::SaveDouble(double value) bool Data::SaveDouble(double value)
{ {
BOOL ret = ::WritePrivateProfileStringW( BOOL ret = ::WritePrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
std::to_wstring(value).c_str(), std::to_wstring(value).c_str(),
data_path_.c_str() data_path_.c_str()
); );
return ret == TRUE; return ret == TRUE;
} }
bool easy2d::Data::SaveBool(bool value) bool Data::SaveBool(bool value)
{ {
BOOL ret = ::WritePrivateProfileStringW( BOOL ret = ::WritePrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
(value ? L"1" : L"0"), (value ? L"1" : L"0"),
data_path_.c_str() data_path_.c_str()
); );
return ret == TRUE; return ret == TRUE;
} }
bool easy2d::Data::SaveString(const std::wstring& value) bool Data::SaveString(const std::wstring& value)
{ {
BOOL ret = ::WritePrivateProfileStringW( BOOL ret = ::WritePrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
value.c_str(), value.c_str(),
data_path_.c_str() data_path_.c_str()
); );
return ret == TRUE; return ret == TRUE;
} }
int easy2d::Data::GetInt() const int Data::GetInt() const
{ {
return ::GetPrivateProfileIntW( return ::GetPrivateProfileIntW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
0, 0,
data_path_.c_str() data_path_.c_str()
); );
} }
float easy2d::Data::GetFloat() const float Data::GetFloat() const
{ {
wchar_t temp[32] = { 0 }; wchar_t temp[32] = { 0 };
::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str()); ::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str());
return std::stof(temp); return std::stof(temp);
} }
double easy2d::Data::GetDouble() const double Data::GetDouble() const
{ {
wchar_t temp[32] = { 0 }; wchar_t temp[32] = { 0 };
::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str()); ::GetPrivateProfileStringW(field_.c_str(), key_.c_str(), L"0.0", temp, 31, data_path_.c_str());
return std::stod(temp); return std::stod(temp);
} }
bool easy2d::Data::GetBool() const bool Data::GetBool() const
{ {
int nValue = ::GetPrivateProfileIntW( int nValue = ::GetPrivateProfileIntW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
0, 0,
data_path_.c_str()); data_path_.c_str());
return nValue == TRUE; return nValue == TRUE;
} }
std::wstring easy2d::Data::GetString() std::wstring Data::GetString()
{ {
wchar_t temp[256] = { 0 }; wchar_t temp[256] = { 0 };
::GetPrivateProfileStringW( ::GetPrivateProfileStringW(
field_.c_str(), field_.c_str(),
key_.c_str(), key_.c_str(),
L"", L"",
temp, temp,
255, 255,
data_path_.c_str() data_path_.c_str()
); );
return temp; return temp;
} }
}

View File

@ -23,270 +23,273 @@
#include <cwctype> #include <cwctype>
#include <shobjidl.h> #include <shobjidl.h>
std::list<std::wstring> easy2d::File::search_paths_; namespace easy2d
easy2d::File::File()
: file_path_()
{ {
} std::list<std::wstring> File::search_paths_;
easy2d::File::File(const std::wstring & file_name) File::File()
: file_path_(file_name) : file_path_()
{
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
{ {
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; 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 bool 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)
{ {
// 截取扩展名 if (::PathFileExists(file_path_.c_str()))
file_ext = file_path_.substr(pos); return true;
// 转换为小写字母 return false;
std::transform(file_ext.begin(), file_ext.end(), file_ext.begin(), std::towlower);
} }
return file_ext;
}
bool easy2d::File::Delete() const std::wstring& File::GetPath() const
{ {
if (::DeleteFile(file_path_.c_str())) return file_path_;
return true; }
return false;
}
easy2d::File easy2d::File::Extract(Resource& res, const std::wstring& dest_file_name) std::wstring File::GetExtension() const
{ {
File file; std::wstring file_ext;
HANDLE file_handle = ::CreateFile( // 找到文件名中的最后一个 '.' 的位置
dest_file_name.c_str(), size_t pos = file_path_.find_last_of(L'.');
GENERIC_WRITE, // 判断 pos 是否是有效位置
NULL, if (pos != std::wstring::npos)
NULL, {
CREATE_ALWAYS, // 截取扩展名
FILE_ATTRIBUTE_TEMPORARY, file_ext = file_path_.substr(pos);
NULL // 转换为小写字母
); 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; 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 File::AddSearchPath(const std::wstring & path)
}
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)
{ {
tmp.replace(pos, 1, L"\\"); std::wstring tmp = path;
pos++; 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"\\"); std::wstring file_path;
} HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
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<void**>(&file_open));
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (!title.empty()) IFileOpenDialog *file_open;
{
file_open->SetTitle(title.c_str());
}
if (!filter.empty()) hr = ::CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
{ IID_IFileOpenDialog, reinterpret_cast<void**>(&file_open));
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)) if (SUCCEEDED(hr))
{ {
IShellItem *item; if (!title.empty())
hr = file_open->GetResult(&item); {
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)) if (SUCCEEDED(hr))
{ {
PWSTR str_file_path; IShellItem *item;
hr = item->GetDisplayName(SIGDN_FILESYSPATH, &str_file_path); hr = file_open->GetResult(&item);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
file_path = str_file_path; PWSTR str_file_path;
::CoTaskMemFree(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) File 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))
{ {
IFileSaveDialog *file_save; std::wstring file_path;
HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
hr = ::CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL,
IID_IFileSaveDialog, reinterpret_cast<void**>(&file_save));
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (!title.empty()) IFileSaveDialog *file_save;
{
file_save->SetTitle(title.c_str());
}
if (!def_file.empty()) hr = ::CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL,
{ IID_IFileSaveDialog, reinterpret_cast<void**>(&file_save));
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)) if (SUCCEEDED(hr))
{ {
IShellItem *item; if (!title.empty())
hr = file_save->GetResult(&item); {
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)) if (SUCCEEDED(hr))
{ {
PWSTR str_file_path; IShellItem *item;
hr = item->GetDisplayName(SIGDN_FILESYSPATH, &str_file_path); hr = file_save->GetResult(&item);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
file_path = str_file_path; PWSTR str_file_path;
::CoTaskMemFree(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); }
}

View File

@ -22,38 +22,40 @@
#include "..\e2dmodule.h" #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 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 class Transcoder
{ {
WAVEFORMATEX* wave_format_; WAVEFORMATEX* wave_format_;
@ -304,252 +306,255 @@ namespace easy2d
} }
}; };
}
//-------------------------------------------------------
// Music
//-------------------------------------------------------
easy2d::Music::Music() Music::Music()
: opened_(false) : opened_(false)
, playing_(false) , playing_(false)
, wave_data_(nullptr) , wave_data_(nullptr)
, size_(0) , size_(0)
, voice_(nullptr) , voice_(nullptr)
{ {
} }
easy2d::Music::Music(const std::wstring& file_path) Music::Music(const std::wstring& file_path)
: opened_(false) : opened_(false)
, playing_(false) , playing_(false)
, wave_data_(nullptr) , wave_data_(nullptr)
, size_(0) , size_(0)
, voice_(nullptr) , voice_(nullptr)
{ {
Load(file_path); Load(file_path);
} }
easy2d::Music::Music(Resource& res) Music::Music(Resource& res)
: opened_(false) : opened_(false)
, playing_(false) , playing_(false)
, wave_data_(nullptr) , wave_data_(nullptr)
, size_(0) , size_(0)
, voice_(nullptr) , voice_(nullptr)
{ {
Load(res); Load(res);
} }
easy2d::Music::~Music() Music::~Music()
{
Close();
}
bool easy2d::Music::Load(const std::wstring & file_path)
{
if (opened_)
{ {
Close(); Close();
} }
File music_file; bool Music::Load(const std::wstring & file_path)
if (!music_file.Open(file_path))
{ {
E2D_WARNING("Media file not found."); if (opened_)
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_)
{ {
delete[] wave_data_; Close();
wave_data_ = nullptr;
} }
TraceError(L"Create source voice error", hr);
return false;
}
opened_ = true; File music_file;
return true; if (!music_file.Open(file_path))
}
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_)
{ {
delete[] wave_data_; E2D_WARNING("Media file not found.");
wave_data_ = nullptr; return false;
} }
TraceError(L"Create source voice error", hr);
return false;
}
opened_ = true; // 用户输入的路径不一定是完整路径,因为用户可能通过 File::AddSearchPath 添加
return true; // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径
} std::wstring music_file_path = music_file.GetPath();
bool easy2d::Music::Play(int loop_count) Transcoder transcoder;
{ if (!transcoder.LoadMediaFile(music_file_path.c_str(), &wave_data_, &size_))
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()))
{ {
playing_ = false; return false;
} }
}
}
void easy2d::Music::Resume() HRESULT hr = Device::GetAudio()->CreateVoice(&voice_, transcoder.GetWaveFormatEx());
{ if (FAILED(hr))
if (voice_)
{
if (SUCCEEDED(voice_->Start()))
{ {
playing_ = true; if (wave_data_)
{
delete[] wave_data_;
wave_data_ = nullptr;
}
TraceError(L"Create source voice error", hr);
return false;
} }
}
}
void easy2d::Music::Stop() opened_ = true;
{ return true;
if (voice_) }
bool Music::Load(Resource& res)
{ {
if (SUCCEEDED(voice_->Stop())) if (opened_)
{ {
voice_->ExitLoop(); Close();
voice_->FlushSourceBuffers();
playing_ = false;
} }
}
}
void easy2d::Music::Close() Transcoder transcoder;
{ if (!transcoder.LoadMediaResource(res, &wave_data_, &size_))
if (voice_) {
{ return false;
voice_->Stop(); }
voice_->FlushSourceBuffers();
voice_->DestroyVoice(); HRESULT hr = Device::GetAudio()->CreateVoice(&voice_, transcoder.GetWaveFormatEx());
voice_ = nullptr; 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_; if (!opened_)
wave_data_ = nullptr; {
} E2D_WARNING("Music must be opened first!");
return false;
}
opened_ = false; if (voice_ == nullptr)
playing_ = false; {
} E2D_WARNING("IXAudio2SourceVoice Null pointer exception!");
return false;
}
bool easy2d::Music::IsPlaying() const
{
if (opened_ && voice_)
{
XAUDIO2_VOICE_STATE state; XAUDIO2_VOICE_STATE state;
voice_->GetState(&state); voice_->GetState(&state);
if (state.BuffersQueued && playing_) if (state.BuffersQueued)
return true; {
} Stop();
return false; }
}
float easy2d::Music::GetVolume() const if (loop_count < 0)
{ {
if (voice_) 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; if (voice_)
voice_->GetVolume(&volume); {
return volume; if (SUCCEEDED(voice_->Stop()))
{
playing_ = false;
}
}
} }
return 0.f;
}
bool easy2d::Music::SetVolume(float volume) void Music::Resume()
{
if (voice_)
{ {
volume = std::min(std::max(volume, -224.f), 224.f); if (voice_)
return SUCCEEDED(voice_->SetVolume(volume)); {
if (SUCCEEDED(voice_->Start()))
{
playing_ = true;
}
}
} }
return false;
}
IXAudio2SourceVoice * easy2d::Music::GetSourceVoice() const void Music::Stop()
{ {
return voice_; 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_;
}
}

View File

@ -23,115 +23,118 @@
#include <shlobj.h> #include <shlobj.h>
namespace namespace easy2d
{ {
// 创建指定文件夹 namespace
bool CreateFolder(const std::wstring & dir_path)
{ {
if (dir_path.empty() || dir_path.size() >= MAX_PATH) // 创建指定文件夹
return false; bool CreateFolder(const std::wstring & dir_path)
wchar_t tmp_dir_path[MAX_PATH] = { 0 };
size_t length = dir_path.length();
for (size_t i = 0; i < length; ++i)
{ {
tmp_dir_path[i] = dir_path.at(i); if (dir_path.empty() || dir_path.size() >= MAX_PATH)
if (tmp_dir_path[i] == L'\\' || tmp_dir_path[i] == L'/' || i == (length - 1)) 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() const std::wstring& Path::GetDataPath()
{
static std::wstring data_path;
if (data_path.empty())
{ {
// 设置数据的保存路径 static std::wstring data_path;
std::wstring local_app_data_path = Path::GetLocalAppDataPath(); if (data_path.empty())
std::wstring title = Game::GetInstance()->GetTitle();
std::wstring folder_name = std::to_wstring(std::hash<std::wstring>{}(title));
if (!local_app_data_path.empty())
{ {
data_path.append(local_app_data_path) // 设置数据的保存路径
.append(L"\\Easy2DGameData\\") std::wstring local_app_data_path = Path::GetLocalAppDataPath();
.append(folder_name) std::wstring title = Game::GetInstance()->GetTitle();
.append(L"\\"); std::wstring folder_name = std::to_wstring(std::hash<std::wstring>{}(title));
File file(data_path); if (!local_app_data_path.empty())
if (!file.Exists() && !CreateFolder(data_path))
{ {
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<std::wstring>{}(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() const std::wstring& Path::GetLocalAppDataPath()
{
static std::wstring temp_path;
if (temp_path.empty())
{ {
// 设置临时文件保存路径 static std::wstring local_app_data_path;
wchar_t path[_MAX_PATH]; if (local_app_data_path.empty())
std::wstring title = Game::GetInstance()->GetTitle();
std::wstring folder_name = std::to_wstring(std::hash<std::wstring>{}(title));
if (0 != ::GetTempPath(_MAX_PATH, path))
{ {
temp_path.append(path) // 获取 AppData/Local 文件夹的路径
.append(L"\\Easy2DGameTemp\\") wchar_t path[MAX_PATH] = { 0 };
.append(folder_name) ::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
.append(L"\\"); local_app_data_path = path;
}
File file(temp_path); return local_app_data_path;
if (!file.Exists() && !CreateFolder(temp_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;
}

View File

@ -1,212 +1,215 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
std::map<size_t, easy2d::Music*> easy2d::Player::musics_; namespace easy2d
easy2d::Player::Player()
: volume_(1.f)
{ {
} std::map<size_t, Music*> Player::musics_;
easy2d::Player::~Player() Player::Player()
{ : volume_(1.f)
}
bool easy2d::Player::Load(const std::wstring & file_path)
{
if (file_path.empty())
return false;
Music * music = new (std::nothrow) Music();
if (music)
{ {
if (music->Load(file_path))
{
music->SetVolume(volume_);
size_t hash_code = std::hash<std::wstring>{}(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) Player::~Player()
{
if (file_path.empty())
return false;
if (Load(file_path))
{ {
auto music = musics_[std::hash<std::wstring>{}(file_path)];
if (music->Play(loop_count))
{
return true;
}
} }
return false;
}
void easy2d::Player::Pause(const std::wstring & file_path) bool Player::Load(const std::wstring & file_path)
{
if (file_path.empty())
return;
size_t hash_code = std::hash<std::wstring>{}(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<std::wstring>{}(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<std::wstring>{}(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<std::wstring>{}(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)
{ {
if (music->Load(res)) if (file_path.empty())
{ return false;
music->SetVolume(volume_);
musics_.insert(std::make_pair(hash_code, music));
return true;
}
else
{
music->Release();
}
}
return false;
}
bool easy2d::Player::Play(Resource& res, int loop_count) Music * music = new (std::nothrow) Music();
{
if (Load(res)) if (music)
{
if (music->Load(file_path))
{
music->SetVolume(volume_);
size_t hash_code = std::hash<std::wstring>{}(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<std::wstring>{}(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<std::wstring>{}(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<std::wstring>{}(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<std::wstring>{}(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<std::wstring>{}(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(); size_t hash_code = res.GetHashCode();
auto music = musics_[hash_code]; if (musics_.end() != musics_.find(hash_code))
if (music->Play(loop_count))
{
return true; 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) void Player::PauseAll()
{
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_)
{ {
pair.second->SetVolume(volume_); for (const auto& pair : musics_)
{
pair.second->Pause();
}
} }
}
void easy2d::Player::PauseAll() void Player::ResumeAll()
{
for (const auto& pair : musics_)
{ {
pair.second->Pause(); for (const auto& pair : musics_)
{
pair.second->Resume();
}
} }
}
void easy2d::Player::ResumeAll() void Player::StopAll()
{
for (const auto& pair : musics_)
{ {
pair.second->Resume(); for (const auto& pair : musics_)
{
pair.second->Stop();
}
} }
}
void easy2d::Player::StopAll() void Player::ClearCache()
{
for (const auto& pair : musics_)
{ {
pair.second->Stop(); if (musics_.empty())
} return;
}
void easy2d::Player::ClearCache() for (const auto& pair : musics_)
{ {
if (musics_.empty()) pair.second->Release();
return; }
musics_.clear();
for (const auto& pair : musics_)
{
pair.second->Release();
} }
musics_.clear(); }
}

View File

@ -21,40 +21,43 @@
#include "..\e2dtransition.h" #include "..\e2dtransition.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::BoxTransition::BoxTransition(float duration) namespace easy2d
: Transition(duration)
{ {
} BoxTransition::BoxTransition(float duration)
: Transition(duration)
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)
{ {
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; Transition::Init(prev, next, game);
in_layer_param_.opacity = 1;
in_layer_param_.contentBounds = D2D1::RectF( in_layer_param_.opacity = 0;
window_size_.width * (1 - process_),
window_size_.height * (1 - process_),
window_size_.width * process_,
window_size_.height * process_
);
} }
}
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_
);
}
}
}

View File

@ -21,23 +21,26 @@
#include "..\e2dtransition.h" #include "..\e2dtransition.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::EmergeTransition::EmergeTransition(float duration) namespace easy2d
: Transition(duration)
{ {
} EmergeTransition::EmergeTransition(float duration)
: Transition(duration)
{
}
void easy2d::EmergeTransition::Init(Scene * prev, Scene * next, Game * game) void EmergeTransition::Init(Scene * prev, Scene * next, Game * game)
{ {
Transition::Init(prev, next, game); Transition::Init(prev, next, game);
out_layer_param_.opacity = 1;
in_layer_param_.opacity = 0;
}
void easy2d::EmergeTransition::Update() out_layer_param_.opacity = 1;
{ in_layer_param_.opacity = 0;
Transition::Update(); }
out_layer_param_.opacity = 1 - process_; void EmergeTransition::Update()
in_layer_param_.opacity = process_; {
} Transition::Update();
out_layer_param_.opacity = 1 - process_;
in_layer_param_.opacity = process_;
}
}

View File

@ -21,31 +21,34 @@
#include "..\e2dtransition.h" #include "..\e2dtransition.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::FadeTransition::FadeTransition(float duration) namespace easy2d
: Transition(duration)
{ {
} FadeTransition::FadeTransition(float duration)
: Transition(duration)
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)
{ {
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; in_layer_param_.opacity = 0;
} }
else
void FadeTransition::Update()
{ {
out_layer_param_.opacity = 0; Transition::Update();
in_layer_param_.opacity = (process_ - 0.5f) * 2;
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;
}
} }
} }

View File

@ -21,88 +21,91 @@
#include "..\e2dtransition.h" #include "..\e2dtransition.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::MoveTransition::MoveTransition(float duration, Direction direction) namespace easy2d
: Transition(duration)
, direction_(direction)
{ {
} MoveTransition::MoveTransition(float duration, Direction direction)
: Transition(duration)
void easy2d::MoveTransition::Init(Scene * prev, Scene * next, Game * game) , direction_(direction)
{
Transition::Init(prev, next, game);
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_) void MoveTransition::Init(Scene * prev, Scene * next, Game * game)
{ {
out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); Transition::Init(prev, next, game);
}
if (in_scene_)
{
in_scene_->SetTransform(
D2D1::Matrix3x2F::Translation(
start_pos_.x,
start_pos_.y
)
);
}
}
void easy2d::MoveTransition::Update() switch (direction_)
{ {
Transition::Update(); 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_) if (out_scene_)
{ {
auto translation = pos_delta_ * process_; out_scene_->SetTransform(D2D1::Matrix3x2F::Identity());
out_scene_->SetTransform( }
D2D1::Matrix3x2F::Translation(
translation.x, if (in_scene_)
translation.y {
) 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_; Transition::Update();
in_scene_->SetTransform(
D2D1::Matrix3x2F::Translation(
translation.x,
translation.y
)
);
}
}
void easy2d::MoveTransition::Reset() if (out_scene_)
{ {
if (out_scene_) auto translation = pos_delta_ * process_;
{ out_scene_->SetTransform(
out_scene_->SetTransform(D2D1::Matrix3x2F::Identity()); 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());
}
} }
} }

View File

@ -21,84 +21,87 @@
#include "..\e2dtransition.h" #include "..\e2dtransition.h"
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::RotationTransition::RotationTransition(float duration, float rotation) namespace easy2d
: Transition(duration)
, rotation_(rotation)
{ {
} RotationTransition::RotationTransition(float duration, float rotation)
: Transition(duration)
void easy2d::RotationTransition::Init(Scene * prev, Scene * next, Game * game) , rotation_(rotation)
{
Transition::Init(prev, next, game);
if (out_scene_)
{ {
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() auto center_pos = D2D1::Point2F(
{ window_size_.width / 2,
Transition::Update(); window_size_.height / 2
);
auto center_pos = D2D1::Point2F( if (process_ < .5f)
window_size_.width / 2, {
window_size_.height / 2 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_) if (out_scene_)
{ {
out_scene_->SetTransform( out_scene_->SetTransform(D2D1::Matrix3x2F::Identity());
D2D1::Matrix3x2F::Scale(
(.5f - process_) * 2,
(.5f - process_) * 2,
center_pos
) * D2D1::Matrix3x2F::Rotation(
rotation_ * (.5f - process_) * 2,
center_pos
)
);
} }
}
else
{
if (in_scene_) if (in_scene_)
{ {
out_layer_param_.opacity = 0; in_scene_->SetTransform(D2D1::Matrix3x2F::Identity());
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
)
);
} }
} }
} }
void easy2d::RotationTransition::Reset()
{
if (out_scene_)
{
out_scene_->SetTransform(D2D1::Matrix3x2F::Identity());
}
if (in_scene_)
{
in_scene_->SetTransform(D2D1::Matrix3x2F::Identity());
}
}

View File

@ -22,143 +22,146 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
#include "..\e2dmodule.h" #include "..\e2dmodule.h"
easy2d::Transition::Transition(float duration) namespace easy2d
: 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_()
{ {
duration_ = std::max(duration, 0.f); Transition::Transition(float duration)
} : done_(false)
, started_()
easy2d::Transition::~Transition() , process_(0)
{ , window_size_()
SafeRelease(out_layer_); , out_scene_(nullptr)
SafeRelease(in_layer_); , in_scene_(nullptr)
SafeRelease(out_scene_); , out_layer_(nullptr)
SafeRelease(in_scene_); , in_layer_(nullptr)
} , out_layer_param_()
, in_layer_param_()
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_)
{ {
ThrowIfFailed( duration_ = std::max(duration, 0.f);
graphics->GetRenderTarget()->CreateLayer(&in_layer_)
);
} }
if (out_scene_) Transition::~Transition()
{ {
ThrowIfFailed( SafeRelease(out_layer_);
graphics->GetRenderTarget()->CreateLayer(&out_layer_) SafeRelease(in_layer_);
); SafeRelease(out_scene_);
SafeRelease(in_scene_);
} }
window_size_ = game->GetSize(); bool Transition::IsDone()
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)
{ {
process_ = 1; return done_;
}
else
{
process_ = (Time::Now() - started_).Seconds() / duration_;
process_ = std::min(process_, 1.f);
} }
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() if (out_scene_)
{ out_scene_->Retain();
auto render_target = Device::GetGraphics()->GetRenderTarget();
if (out_scene_) if (in_scene_)
{ in_scene_->Retain();
render_target->SetTransform(out_scene_->GetTransform());
render_target->PushAxisAlignedClip( 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( D2D1::RectF(
0.f, 0.f,
0.f, 0.f,
window_size_.width, window_size_.width,
window_size_.height 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()); if (duration_ == 0)
render_target->PushAxisAlignedClip( {
D2D1::RectF( process_ = 1;
0.f, }
0.f, else
window_size_.width, {
window_size_.height process_ = (Time::Now() - started_).Seconds() / duration_;
), process_ = std::min(process_, 1.f);
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE }
);
render_target->PushLayer(in_layer_param_, in_layer_);
in_scene_->Draw(); if (process_ >= 1)
{
render_target->PopLayer(); this->Stop();
render_target->PopAxisAlignedClip(); }
} }
}
void easy2d::Transition::Stop() void Transition::Draw()
{ {
done_ = true; auto render_target = Device::GetGraphics()->GetRenderTarget();
Reset();
} 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();
}
}

View File

@ -20,63 +20,69 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
static const UINT kRedShift = 16; namespace easy2d
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
{
const UINT RED_SHIFT = 16;
const UINT GREEN_SHIFT = 8;
const UINT BLUE_SHIFT = 0;
easy2d::Color::Color(float r, float g, float b) const UINT RED_MASK = 0xff << RED_SHIFT;
: r(r) const UINT GREEN_MASK = 0xff << GREEN_SHIFT;
, g(g) const UINT BLUE_MASK = 0xff << BLUE_SHIFT;
, b(b) }
, a(1.f)
{
}
easy2d::Color::Color(float r, float g, float b, float alpha) Color::Color()
: r(r) : r(0)
, g(g) , g(0)
, b(b) , b(0)
, a(alpha) , a(1.f)
{ {
} }
easy2d::Color::Color(UINT rgb) Color::Color(float r, float g, float b)
: r(((rgb & kRedMask) >> kRedShift) / 255.f) : r(r)
, g(((rgb & kGreenMask) >> kGreenShift) / 255.f) , g(g)
, b(((rgb & kBlueMask) >> kBlueShift) / 255.f) , b(b)
, a(1.f) , a(1.f)
{ {
} }
easy2d::Color::Color(UINT rgb, float alpha) Color::Color(float r, float g, float b, float alpha)
: r(((rgb & kRedMask) >> kRedShift) / 255.f) : r(r)
, g(((rgb & kGreenMask) >> kGreenShift) / 255.f) , g(g)
, b(((rgb & kBlueMask) >> kBlueShift) / 255.f) , b(b)
, a(alpha) , a(alpha)
{ {
} }
easy2d::Color::Color(const D2D1_COLOR_F& color) Color::Color(UINT rgb)
: r(color.r) : r(((rgb & RED_MASK) >> RED_SHIFT) / 255.f)
, g(color.g) , g(((rgb & GREEN_MASK) >> GREEN_SHIFT) / 255.f)
, b(color.b) , b(((rgb & BLUE_MASK) >> BLUE_SHIFT) / 255.f)
, a(color.a) , a(1.f)
{ {
} }
easy2d::Color::operator D2D1_COLOR_F() const Color::Color(UINT rgb, float alpha)
{ : r(((rgb & RED_MASK) >> RED_SHIFT) / 255.f)
return D2D1::ColorF(r, g, b, a); , 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);
}
}

View File

@ -22,275 +22,288 @@
#include <regex> #include <regex>
const easy2d::Duration easy2d::Duration::Millisecond = easy2d::Duration(1); namespace easy2d
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)
{ {
} 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) namespace
: 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<float>(sec) + static_cast<float>(ms) / 1000.f;
}
float easy2d::Duration::Minutes() const
{
int64_t min = milliseconds_ / Minute.milliseconds_;
int64_t ms = milliseconds_ % Minute.milliseconds_;
return static_cast<float>(min) + static_cast<float>(ms) / (60 * 1000.f);
}
float easy2d::Duration::Hours() const
{
int64_t hour = milliseconds_ / Hour.milliseconds_;
int64_t ms = milliseconds_ % Hour.milliseconds_;
return static_cast<float>(hour) + static_cast<float>(ms) / (60 * 60 * 1000.f);
}
easy2d::Duration easy2d::Duration::Parse(const std::wstring & str)
{
typedef std::map<std::wstring, Duration> 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))
{ {
E2D_WARNING("Duration::Parse: invalid duration"); const auto duration_regex = std::wregex(L"[-+]?([0-9]*(\\.[0-9]*)?[a-z]+)+");
typedef std::map<std::wstring, Duration> 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<float>(sec) + static_cast<float>(ms) / 1000.f;
}
float Duration::Minutes() const
{
int64_t min = milliseconds_ / Minute.milliseconds_;
int64_t ms = milliseconds_ % Minute.milliseconds_;
return static_cast<float>(min) + static_cast<float>(ms) / (60 * 1000.f);
}
float Duration::Hours() const
{
int64_t hour = milliseconds_ / Hour.milliseconds_;
int64_t ms = milliseconds_ % Hour.milliseconds_;
return static_cast<float>(hour) + static_cast<float>(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; return d;
} }
if (str.empty() || str == L"0") { return d; } bool Duration::operator==(const Duration & other) const
// ·ûºÅλ
if (str[0] == L'-' || str[0] == L'+')
{ {
negative = (str[0] == L'-'); return milliseconds_ == other.milliseconds_;
pos++;
} }
while (pos < len) bool Duration::operator!=(const Duration & other) const
{ {
// ÊýÖµ return milliseconds_ != other.milliseconds_;
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) 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 bool Duration::operator>=(const Duration & other) const
{ {
return milliseconds_ == other.milliseconds_; return milliseconds_ >= other.milliseconds_;
} }
bool easy2d::Duration::operator!=(const Duration & other) const bool Duration::operator<(const Duration & other) const
{ {
return milliseconds_ != other.milliseconds_; return milliseconds_ < other.milliseconds_;
} }
bool easy2d::Duration::operator>(const Duration & other) const bool Duration::operator<=(const Duration & other) const
{ {
return milliseconds_ > other.milliseconds_; return milliseconds_ <= other.milliseconds_;
} }
bool easy2d::Duration::operator>=(const Duration & other) const Duration Duration::operator+(const Duration & other) const
{ {
return milliseconds_ >= other.milliseconds_; return Duration(milliseconds_ + other.milliseconds_);
} }
bool easy2d::Duration::operator<(const Duration & other) const Duration Duration::operator-(const Duration & other) const
{ {
return milliseconds_ < other.milliseconds_; return Duration(milliseconds_ - other.milliseconds_);
} }
bool easy2d::Duration::operator<=(const Duration & other) const Duration Duration::operator-() const
{ {
return milliseconds_ <= other.milliseconds_; return Duration(-milliseconds_);
} }
easy2d::Duration easy2d::Duration::operator+(const Duration & other) const Duration Duration::operator*(int value) const
{ {
return Duration(milliseconds_ + other.milliseconds_); return Duration(milliseconds_ * value);
} }
easy2d::Duration easy2d::Duration::operator-(const Duration & other) const Duration Duration::operator/(int value) const
{ {
return Duration(milliseconds_ - other.milliseconds_); return Duration(milliseconds_ / value);
} }
easy2d::Duration easy2d::Duration::operator-() const Duration Duration::operator*(float value) const
{ {
return Duration(-milliseconds_); return Duration(static_cast<int>(milliseconds_ * value));
} }
easy2d::Duration easy2d::Duration::operator*(int value) const Duration Duration::operator/(float value) const
{ {
return Duration(milliseconds_ * value); return Duration(static_cast<int>(milliseconds_ / value));
} }
easy2d::Duration easy2d::Duration::operator/(int value) const Duration Duration::operator*(double value) const
{ {
return Duration(milliseconds_ / value); return Duration(static_cast<int>(milliseconds_ * value));
} }
easy2d::Duration easy2d::Duration::operator*(float value) const Duration Duration::operator/(double value) const
{ {
return Duration(static_cast<int>(milliseconds_ * value)); return Duration(static_cast<int>(milliseconds_ / value));
} }
easy2d::Duration easy2d::Duration::operator/(float value) const Duration & Duration::operator+=(const Duration &other)
{ {
return Duration(static_cast<int>(milliseconds_ / value)); milliseconds_ += other.milliseconds_;
} return (*this);
}
easy2d::Duration easy2d::Duration::operator*(double value) const Duration & Duration::operator-=(const Duration &other)
{ {
return Duration(static_cast<int>(milliseconds_ * value)); milliseconds_ -= other.milliseconds_;
} return (*this);
}
easy2d::Duration easy2d::Duration::operator/(double value) const Duration & Duration::operator*=(int value)
{ {
return Duration(static_cast<int>(milliseconds_ / value)); milliseconds_ *= value;
} return (*this);
}
easy2d::Duration & easy2d::Duration::operator+=(const Duration &other) Duration & Duration::operator/=(int value)
{ {
milliseconds_ += other.milliseconds_; milliseconds_ /= value;
return (*this); return (*this);
} }
easy2d::Duration & easy2d::Duration::operator-=(const Duration &other) Duration & Duration::operator*=(float value)
{ {
milliseconds_ -= other.milliseconds_; milliseconds_ = static_cast<int>(milliseconds_ * value);
return (*this); return (*this);
} }
easy2d::Duration & easy2d::Duration::operator*=(int value) Duration & Duration::operator/=(float value)
{ {
milliseconds_ *= value; milliseconds_ = static_cast<int>(milliseconds_ / value);
return (*this); return (*this);
} }
easy2d::Duration & easy2d::Duration::operator/=(int value) Duration & Duration::operator*=(double value)
{ {
milliseconds_ /= value; milliseconds_ = static_cast<int>(milliseconds_ * value);
return (*this); return (*this);
} }
easy2d::Duration & easy2d::Duration::operator*=(float value) Duration & Duration::operator/=(double value)
{ {
milliseconds_ = static_cast<int>(milliseconds_ * value); milliseconds_ = static_cast<int>(milliseconds_ / value);
return (*this); return (*this);
} }
easy2d::Duration & easy2d::Duration::operator/=(float value) Duration operator*(int value, const Duration & dur)
{ {
milliseconds_ = static_cast<int>(milliseconds_ / value); return dur * value;
return (*this); }
}
easy2d::Duration & easy2d::Duration::operator*=(double value) Duration operator/(int value, const Duration & dur)
{ {
milliseconds_ = static_cast<int>(milliseconds_ * value); return dur / value;
return (*this); }
}
easy2d::Duration & easy2d::Duration::operator/=(double value) Duration operator*(float value, const Duration & dur)
{ {
milliseconds_ = static_cast<int>(milliseconds_ / value); return dur * value;
return (*this); }
}
easy2d::Duration easy2d::operator*(int value, const Duration & dur) Duration operator/(float value, const Duration & dur)
{ {
return dur * value; return dur / value;
} }
easy2d::Duration easy2d::operator/(int value, const Duration & dur) Duration operator*(double value, const Duration & dur)
{ {
return dur / value; return dur * value;
} }
easy2d::Duration easy2d::operator*(float value, const Duration & dur) Duration operator/(double value, const Duration & dur)
{ {
return dur * value; 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;
} }

View File

@ -21,10 +21,13 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
easy2d::Font::Font(const std::wstring & family, float size, UINT weight, bool italic) namespace easy2d
: family(family)
, size(size)
, weight(weight)
, italic(italic)
{ {
Font::Font(const std::wstring & family, float size, UINT weight, bool italic)
: family(family)
, size(size)
, weight(weight)
, italic(italic)
{
}
} }

View File

@ -22,63 +22,66 @@
#include <cmath> #include <cmath>
easy2d::Point::Point() namespace easy2d
{ {
x = 0; Point::Point()
y = 0; {
} x = 0;
y = 0;
}
easy2d::Point::Point(float x, float y) Point::Point(float x, float y)
{ {
this->x = x; this->x = x;
this->y = y; this->y = y;
} }
easy2d::Point::Point(const Point & other) Point::Point(const Point & other)
{ {
x = other.x; x = other.x;
y = other.y; y = other.y;
} }
easy2d::Point easy2d::Point::operator+(const Point & p) const Point Point::operator+(const Point & p) const
{ {
return Point(x + p.x, y + p.y); return Point(x + p.x, y + p.y);
} }
easy2d::Point easy2d::Point::operator-(const Point & p) const Point Point::operator-(const Point & p) const
{ {
return Point(x - p.x, y - p.y); return Point(x - p.x, y - p.y);
} }
easy2d::Point easy2d::Point::operator*(float value) const Point Point::operator*(float value) const
{ {
return Point(x * value, y * value); return Point(x * value, y * value);
} }
easy2d::Point easy2d::Point::operator/(float value) const Point Point::operator/(float value) const
{ {
return Point(x / value, y / value); return Point(x / value, y / value);
} }
easy2d::Point::operator easy2d::Size() const Point::operator Size() const
{ {
return Size(x, y); return Size(x, y);
} }
float easy2d::Point::Distance(const Point &p1, const Point &p2) float Point::Distance(const Point &p1, const Point &p2)
{ {
return sqrt( return sqrt(
(p1.x - p2.x) * (p1.x - p2.x) + (p1.x - p2.x) * (p1.x - p2.x) +
(p1.y - p2.y) * (p1.y - p2.y) (p1.y - p2.y) * (p1.y - p2.y)
); );
} }
easy2d::Point easy2d::Point::operator-() const Point Point::operator-() const
{ {
return Point(-x, -y); return Point(-x, -y);
} }
bool easy2d::Point::operator==(const Point & point) const bool Point::operator==(const Point & point) const
{ {
return (x == point.x) && (y == point.y); return (x == point.x) && (y == point.y);
} }
}

View File

@ -20,9 +20,12 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
std::default_random_engine &easy2d::Random::GetEngine() namespace easy2d
{ {
static std::random_device device; std::default_random_engine &Random::GetEngine()
static std::default_random_engine engine(device()); {
return engine; static std::random_device device;
} static std::default_random_engine engine(device());
return engine;
}
}

View File

@ -20,56 +20,59 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
easy2d::Rect::Rect(void) namespace easy2d
: origin()
, size()
{ {
} Rect::Rect(void)
: origin()
easy2d::Rect::Rect(float x, float y, float width, float height) , size()
: 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))
{ {
return true;
} }
return false;
}
bool easy2d::Rect::Intersects(const Rect& rect) const Rect::Rect(float x, float y, float width, float height)
{ : origin(x, y)
return !((origin.x + size.width) < rect.origin.x || , size(width, height)
(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(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);
}
}

View File

@ -20,35 +20,38 @@
#include "..\e2dobject.h" #include "..\e2dobject.h"
easy2d::Ref::Ref() namespace easy2d
{ {
// 当对象被创建时,意味着它已经被引用了一次 Ref::Ref()
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)
{ {
delete this; // 当对象被创建时,意味着它已经被引用了一次
return 0; ref_count_ = 1;
} }
return new_count; Ref::~Ref()
} {
}
LONG easy2d::Ref::GetRefCount() const LONG Ref::Retain()
{ {
return ref_count_; 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_;
}
}

View File

@ -21,77 +21,80 @@
#include "..\e2dtool.h" #include "..\e2dtool.h"
easy2d::Resource::Resource(LPCWSTR name, LPCWSTR type) namespace easy2d
: name_(name)
, type_(type)
, data_(nullptr)
, data_size_(0)
, loaded_(false)
{ {
} Resource::Resource(LPCWSTR name, LPCWSTR type)
: name_(name)
LPCWSTR easy2d::Resource::GetName() const , type_(type)
{ , data_(nullptr)
return name_; , data_size_(0)
} , loaded_(false)
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<LPCWSTR>{}(name_);
}
bool easy2d::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;
} 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<LPCWSTR>{}(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;
}
}

View File

@ -20,55 +20,58 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
easy2d::Size::Size() namespace easy2d
{ {
width = 0; Size::Size()
height = 0; {
} width = 0;
height = 0;
}
easy2d::Size::Size(float width, float height) Size::Size(float width, float height)
{ {
this->width = width; this->width = width;
this->height = height; this->height = height;
} }
easy2d::Size::Size(const Size & other) Size::Size(const Size & other)
{ {
width = other.width; width = other.width;
height = other.height; height = other.height;
} }
easy2d::Size easy2d::Size::operator+(const Size & other) const Size Size::operator+(const Size & other) const
{ {
return Size(width + other.width, height + other.height); return Size(width + other.width, height + other.height);
} }
easy2d::Size easy2d::Size::operator-(const Size & other) const Size Size::operator-(const Size & other) const
{ {
return Size(width - other.width, height - other.height); return Size(width - other.width, height - other.height);
} }
easy2d::Size easy2d::Size::operator*(float value) const Size Size::operator*(float value) const
{ {
return Size(width * value, height * value); return Size(width * value, height * value);
} }
easy2d::Size easy2d::Size::operator/(float value) const Size Size::operator/(float value) const
{ {
return Size(width / value, height / value); return Size(width / value, height / value);
} }
easy2d::Size::operator easy2d::Point() const Size::operator Point() const
{ {
return Point(width, height); return Point(width, height);
} }
easy2d::Size easy2d::Size::operator-() const Size Size::operator-() const
{ {
return Size(-width, -height); return Size(-width, -height);
} }
bool easy2d::Size::operator==(const Size & other) const bool Size::operator==(const Size & other) const
{ {
return (width == other.width) && (height == other.height); return (width == other.width) && (height == other.height);
} }
}

View File

@ -20,86 +20,89 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
using namespace std::chrono; namespace easy2d
easy2d::Time::Time()
{ {
} using namespace std::chrono;
easy2d::Time::Time(std::chrono::steady_clock::time_point time)
: time_(time)
{
}
easy2d::Time::Time(const Time & other) Time::Time()
: time_(other.time_) {
{ }
}
easy2d::Time::Time(Time && other) Time::Time(std::chrono::steady_clock::time_point time)
: time_(std::move(other.time_)) : time_(time)
{ {
} }
time_t easy2d::Time::GetTimeStamp() const Time::Time(const Time & other)
{ : time_(other.time_)
auto& duration = time_point_cast<milliseconds>(time_).time_since_epoch(); {
return static_cast<time_t>(duration.count()); }
}
bool easy2d::Time::IsZero() const Time::Time(Time && other)
{ : time_(std::move(other.time_))
return time_.time_since_epoch().count() == 0LL; {
} }
easy2d::Time easy2d::Time::operator+(const Duration & other) const time_t Time::GetTimeStamp() const
{ {
return Time(time_ + milliseconds(other.Milliseconds())); auto& duration = time_point_cast<milliseconds>(time_).time_since_epoch();
} return static_cast<time_t>(duration.count());
}
easy2d::Time easy2d::Time::operator-(const Duration & other) const bool Time::IsZero() const
{ {
return Time(time_ - milliseconds(other.Milliseconds())); return time_.time_since_epoch().count() == 0LL;
} }
easy2d::Time & easy2d::Time::operator+=(const Duration & other) Time Time::operator+(const Duration & other) const
{ {
time_ += milliseconds(other.Milliseconds()); return Time(time_ + milliseconds(other.Milliseconds()));
return (*this); }
}
easy2d::Time & easy2d::Time::operator-=(const Duration &other) Time Time::operator-(const Duration & other) const
{ {
time_ -= milliseconds(other.Milliseconds()); return Time(time_ - milliseconds(other.Milliseconds()));
return (*this); }
}
easy2d::Duration easy2d::Time::operator-(const Time & other) const Time & Time::operator+=(const Duration & other)
{ {
auto ms = duration_cast<milliseconds>(time_ - other.time_).count(); time_ += milliseconds(other.Milliseconds());
return Duration(static_cast<int>(ms)); return (*this);
} }
easy2d::Time& easy2d::Time::operator=(const Time & other) E2D_NOEXCEPT Time & Time::operator-=(const Duration &other)
{ {
if (this == &other) time_ -= milliseconds(other.Milliseconds());
return (*this);
}
Duration Time::operator-(const Time & other) const
{
auto ms = duration_cast<milliseconds>(time_ - other.time_).count();
return Duration(static_cast<int>(ms));
}
Time& Time::operator=(const Time & other) E2D_NOEXCEPT
{
if (this == &other)
return *this;
time_ = other.time_;
return *this; return *this;
}
time_ = other.time_; Time& Time::operator=(Time && other) E2D_NOEXCEPT
return *this; {
} if (this == &other)
return *this;
easy2d::Time& easy2d::Time::operator=(Time && other) E2D_NOEXCEPT time_ = std::move(other.time_);
{
if (this == &other)
return *this; return *this;
}
time_ = std::move(other.time_); Time Time::Now()
return *this; {
} return Time(steady_clock::now());
}
easy2d::Time easy2d::Time::Now() }
{
return Time(steady_clock::now());
}

View File

@ -21,49 +21,52 @@
#include "..\e2dutil.h" #include "..\e2dutil.h"
easy2d::Transform::Transform() namespace easy2d
: position()
, size()
, scale_x(1.f)
, scale_y(1.f)
, rotation(0)
, skew_x(0)
, skew_y(0)
, pivot_x(0)
, pivot_y(0)
{ {
} 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 Transform::operator D2D1::Matrix3x2F() const
{ {
auto pivot = D2D1::Point2F(size.width * pivot_x, size.height * pivot_y); auto pivot = D2D1::Point2F(size.width * pivot_x, size.height * pivot_y);
auto matrix = D2D1::Matrix3x2F::Scale( auto matrix = D2D1::Matrix3x2F::Scale(
scale_x, scale_x,
scale_y, scale_y,
pivot pivot
) * D2D1::Matrix3x2F::Skew( ) * D2D1::Matrix3x2F::Skew(
skew_x, skew_x,
skew_y, skew_y,
pivot pivot
) * D2D1::Matrix3x2F::Rotation( ) * D2D1::Matrix3x2F::Rotation(
rotation, rotation,
pivot pivot
) * D2D1::Matrix3x2F::Translation( ) * D2D1::Matrix3x2F::Translation(
position.x - pivot.x, position.x - pivot.x,
position.y - pivot.y position.y - pivot.y
); );
return matrix; return matrix;
} }
bool easy2d::Transform::operator==(const Transform & other) const bool Transform::operator==(const Transform & other) const
{ {
return position == other.position && return position == other.position &&
size == other.size && size == other.size &&
scale_x == other.scale_x && scale_x == other.scale_x &&
scale_y == other.scale_y && scale_y == other.scale_y &&
skew_x == other.skew_x && skew_x == other.skew_x &&
skew_y == other.skew_y && skew_y == other.skew_y &&
rotation == other.rotation && rotation == other.rotation &&
pivot_x == other.pivot_x && pivot_x == other.pivot_x &&
pivot_y == other.pivot_y; pivot_y == other.pivot_y;
} }
}