diff --git a/core/actions/Animate.cpp b/core/actions/Animate.cpp index d71260d9..d4b5e146 100644 --- a/core/actions/Animate.cpp +++ b/core/actions/Animate.cpp @@ -65,7 +65,7 @@ void e2d::Animate::Init() auto target = dynamic_cast(target_); if (target && animation_) { - target->Open(animation_->GetFrames()[frame_index_]); + target->Load(animation_->GetFrames()[frame_index_]); ++frame_index_; } } @@ -87,7 +87,7 @@ void e2d::Animate::Update() if (target) { - target->Open(frames[frame_index_]); + target->Load(frames[frame_index_]); } started_ += Duration(animation_->GetInterval()); diff --git a/core/e2dobject.h b/core/e2dobject.h index aa762f87..42b7f224 100644 --- a/core/e2dobject.h +++ b/core/e2dobject.h @@ -55,12 +55,12 @@ namespace e2d virtual ~Image(); // 加载图片资源 - bool Open( + bool Load( const Resource& res ); // 加载图片资源 - bool Open( + bool Load( const String& file_name ); @@ -108,13 +108,13 @@ namespace e2d protected: E2D_DISABLE_COPY(Image); - // 加载图片资源 - bool Load( + // 缓存 Bitmap 资源 + static bool CacheBitmap( const String& file_name ); - // 加载图片资源 - bool Load( + // 缓存 Bitmap 资源 + static bool CacheBitmap( const Resource& res ); @@ -729,17 +729,17 @@ namespace e2d virtual ~Sprite(); // 加载图片文件 - bool Open( + bool Load( const Resource& res ); // 加载图片文件 - bool Open( + bool Load( const String& file_name ); // 加载图片 - bool Open( + bool Load( Image * image ); diff --git a/core/e2dtool.h b/core/e2dtool.h index 7a3e1148..aedb7c85 100644 --- a/core/e2dtool.h +++ b/core/e2dtool.h @@ -86,12 +86,12 @@ namespace e2d virtual ~Music(); // 打开音乐文件 - bool Open( + bool Load( const e2d::String& file_path /* 音乐文件路径 */ ); // 打开音乐资源 - bool Open( + bool Load( const Resource& res ); @@ -134,6 +134,8 @@ namespace e2d IXAudio2SourceVoice * GetSourceVoice() const; protected: + E2D_DISABLE_COPY(Music); + bool ReadMMIO(); bool ResetFile(); @@ -163,6 +165,106 @@ namespace e2d }; + // 音乐播放器 + class Player + { + public: + Player(); + + ~Player(); + + // 预加载音乐资源 + bool Load( + const String& file_path /* 音乐文件路径 */ + ); + + // 播放音乐 + bool Play( + const String& file_path, /* 音乐文件路径 */ + int loop_count = 0 /* 重复播放次数,设置 -1 为循环播放 */ + ); + + // 暂停音乐 + void Pause( + const String& file_path /* 音乐文件路径 */ + ); + + // 继续播放音乐 + void Resume( + const String& file_path /* 音乐文件路径 */ + ); + + // 停止音乐 + void Stop( + const String& file_path /* 音乐文件路径 */ + ); + + // 获取音乐播放状态 + bool IsPlaying( + const String& file_path /* 音乐文件路径 */ + ); + + // 预加载音乐资源 + bool Load( + const Resource& res /* 音乐资源 */ + ); + + // 播放音乐 + bool Play( + const Resource& res, /* 音乐资源 */ + int loop_count = 0 /* 重复播放次数,设置 -1 为循环播放 */ + ); + + // 暂停音乐 + void Pause( + const Resource& res /* 音乐资源 */ + ); + + // 继续播放音乐 + void Resume( + const Resource& res /* 音乐资源 */ + ); + + // 停止音乐 + void Stop( + const Resource& res /* 音乐资源 */ + ); + + // 获取音乐播放状态 + bool IsPlaying( + const Resource& res /* 音乐资源 */ + ); + + // 获取音量 + float GetVolume(); + + // 设置音量 + void SetVolume( + float volume /* 音量范围为 -224 ~ 224,0 是静音,1 是正常音量 */ + ); + + // 暂停所有音乐 + void PauseAll(); + + // 继续播放所有音乐 + void ResumeAll(); + + // 停止所有音乐 + void StopAll(); + + // 清除缓存 + static void ClearCache(); + + protected: + E2D_DISABLE_COPY(Player); + + protected: + float volume_; + + static std::map musics_; + }; + + // 数据管理工具 class Data { diff --git a/core/modules/Game.cpp b/core/modules/Game.cpp index 77bc5192..c6a83835 100644 --- a/core/modules/Game.cpp +++ b/core/modules/Game.cpp @@ -60,6 +60,7 @@ e2d::Game::~Game() SafeRelease(next_scene_); Image::ClearCache(); + Player::ClearCache(); Device::Destroy(); if (hwnd_) diff --git a/core/objects/Image.cpp b/core/objects/Image.cpp index 2b4e0d78..3e6662ee 100644 --- a/core/objects/Image.cpp +++ b/core/objects/Image.cpp @@ -34,14 +34,14 @@ e2d::Image::Image(const Resource& res) : bitmap_(nullptr) , crop_rect_() { - this->Open(res); + this->Load(res); } e2d::Image::Image(const Resource& res, const Rect& crop_rect) : bitmap_(nullptr) , crop_rect_() { - this->Open(res); + this->Load(res); this->Crop(crop_rect); } @@ -49,14 +49,14 @@ e2d::Image::Image(const String & file_name) : bitmap_(nullptr) , crop_rect_() { - this->Open(file_name); + this->Load(file_name); } e2d::Image::Image(const String & file_name, const Rect & crop_rect) : bitmap_(nullptr) , crop_rect_() { - this->Open(file_name); + this->Load(file_name); this->Crop(crop_rect); } @@ -65,9 +65,9 @@ e2d::Image::~Image() SafeRelease(bitmap_); } -bool e2d::Image::Open(const Resource& res) +bool e2d::Image::Load(const Resource& res) { - if (!Image::Load(res)) + if (!Image::CacheBitmap(res)) { WARN("Load Image from file failed!"); return false; @@ -77,14 +77,14 @@ bool e2d::Image::Open(const Resource& res) return true; } -bool e2d::Image::Open(const String & file_name) +bool e2d::Image::Load(const String & file_name) { - WARN_IF(file_name.IsEmpty(), "Image Open failed! Invalid file name."); + WARN_IF(file_name.IsEmpty(), "Image Load failed! Invalid file name."); if (file_name.IsEmpty()) return false; - if (!Image::Load(file_name)) + if (!Image::CacheBitmap(file_name)) { WARN("Load Image from file failed!"); return false; @@ -182,7 +182,7 @@ ID2D1Bitmap * e2d::Image::GetBitmap() const return bitmap_; } -bool e2d::Image::Load(const Resource& res) +bool e2d::Image::CacheBitmap(const Resource& res) { if (bitmap_cache_.find(res.id) != bitmap_cache_.end()) { @@ -308,7 +308,7 @@ bool e2d::Image::Load(const Resource& res) return SUCCEEDED(hr); } -bool e2d::Image::Load(const String & file_name) +bool e2d::Image::CacheBitmap(const String & file_name) { size_t hash = file_name.GetHash(); if (bitmap_cache_.find(hash) != bitmap_cache_.end()) @@ -322,8 +322,9 @@ bool e2d::Image::Load(const String & file_name) // 默认搜索路径,所以需要通过 File::GetPath 获取完整路径 String image_file_path = image_file.GetPath(); - IWICImagingFactory *imaging_factory = Device::GetGraphics()->GetImagingFactory(); - ID2D1HwndRenderTarget* render_target = Device::GetGraphics()->GetRenderTarget(); + 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; diff --git a/core/objects/Sprite.cpp b/core/objects/Sprite.cpp index 3f0ac152..26d26977 100644 --- a/core/objects/Sprite.cpp +++ b/core/objects/Sprite.cpp @@ -29,32 +29,32 @@ e2d::Sprite::Sprite() e2d::Sprite::Sprite(Image * image) : image_(nullptr) { - Open(image); + Load(image); } e2d::Sprite::Sprite(const Resource& res) : image_(nullptr) { - Open(res); + Load(res); } e2d::Sprite::Sprite(const Resource& res, const Rect& crop_rect) : image_(nullptr) { - Open(res); + Load(res); Crop(crop_rect); } e2d::Sprite::Sprite(const String & file_name) : image_(nullptr) { - Open(file_name); + Load(file_name); } e2d::Sprite::Sprite(const String & file_name, const Rect & crop_rect) : image_(nullptr) { - Open(file_name); + Load(file_name); Crop(crop_rect); } @@ -63,7 +63,7 @@ e2d::Sprite::~Sprite() SafeRelease(image_); } -bool e2d::Sprite::Open(Image * image) +bool e2d::Sprite::Load(Image * image) { if (image) { @@ -81,7 +81,7 @@ bool e2d::Sprite::Open(Image * image) return false; } -bool e2d::Sprite::Open(const Resource& res) +bool e2d::Sprite::Load(const Resource& res) { if (!image_) { @@ -89,7 +89,7 @@ bool e2d::Sprite::Open(const Resource& res) image_->Retain(); } - if (image_->Open(res)) + if (image_->Load(res)) { Node::SetSize(image_->GetWidth(), image_->GetHeight()); return true; @@ -97,7 +97,7 @@ bool e2d::Sprite::Open(const Resource& res) return false; } -bool e2d::Sprite::Open(const String & file_name) +bool e2d::Sprite::Load(const String & file_name) { if (!image_) { @@ -105,7 +105,7 @@ bool e2d::Sprite::Open(const String & file_name) image_->Retain(); } - if (image_->Open(file_name)) + if (image_->Load(file_name)) { Node::SetSize(image_->GetWidth(), image_->GetHeight()); return true; diff --git a/core/tools/Music.cpp b/core/tools/Music.cpp index dd907d07..53585741 100644 --- a/core/tools/Music.cpp +++ b/core/tools/Music.cpp @@ -65,7 +65,7 @@ e2d::Music::Music(const e2d::String & file_path) , voice_(nullptr) , callback_() { - this->Open(file_path); + this->Load(file_path); } e2d::Music::Music(const Resource& res) @@ -78,7 +78,7 @@ e2d::Music::Music(const Resource& res) , voice_(nullptr) , callback_() { - this->Open(res); + this->Load(res); } e2d::Music::~Music() @@ -86,7 +86,7 @@ e2d::Music::~Music() Close(); } -bool e2d::Music::Open(const e2d::String & file_path) +bool e2d::Music::Load(const e2d::String & file_path) { if (opened_) { @@ -95,14 +95,14 @@ bool e2d::Music::Open(const e2d::String & file_path) if (file_path.IsEmpty()) { - WARN("Music::Open error: Invalid file name."); + WARN("Music::Load error: Invalid file name."); return false; } File music_file; if (!music_file.Open(file_path)) { - WARN("Music::Open error: File not found."); + WARN("Music::Load error: File not found."); return false; } @@ -160,7 +160,7 @@ bool e2d::Music::Open(const e2d::String & file_path) return true; } -bool e2d::Music::Open(const Resource& res) +bool e2d::Music::Load(const Resource& res) { if (opened_) { diff --git a/core/tools/Player.cpp b/core/tools/Player.cpp new file mode 100644 index 00000000..ea1e5356 --- /dev/null +++ b/core/tools/Player.cpp @@ -0,0 +1,204 @@ +#include "..\e2dtool.h" + + +std::map e2d::Player::musics_; + +e2d::Player::Player() + : volume_(1.f) +{ +} + +e2d::Player::~Player() +{ +} + +bool e2d::Player::Load(const String & file_path) +{ + if (file_path.IsEmpty()) + return false; + + Music * music = new (std::nothrow) Music(); + + if (music) + { + if (music->Load(file_path)) + { + music->SetVolume(volume_); + musics_.insert(std::make_pair(file_path.GetHash(), music)); + return true; + } + else + { + delete music; + } + } + return false; +} + +bool e2d::Player::Play(const String & file_path, int loop_count) +{ + if (file_path.IsEmpty()) + return false; + + if (Load(file_path)) + { + auto music = musics_[file_path.GetHash()]; + if (music->Play(loop_count)) + { + return true; + } + } + return false; +} + +void e2d::Player::Pause(const String & file_path) +{ + if (file_path.IsEmpty()) + return; + + size_t hash = file_path.GetHash(); + if (musics_.end() != musics_.find(hash)) + musics_[hash]->Pause(); +} + +void e2d::Player::Resume(const String & file_path) +{ + if (file_path.IsEmpty()) + return; + + size_t hash = file_path.GetHash(); + if (musics_.end() != musics_.find(hash)) + musics_[hash]->Resume(); +} + +void e2d::Player::Stop(const String & file_path) +{ + if (file_path.IsEmpty()) + return; + + size_t hash = file_path.GetHash(); + if (musics_.end() != musics_.find(hash)) + musics_[hash]->Stop(); +} + +bool e2d::Player::IsPlaying(const String & file_path) +{ + if (file_path.IsEmpty()) + return false; + + size_t hash = file_path.GetHash(); + if (musics_.end() != musics_.find(hash)) + return musics_[hash]->IsPlaying(); + return false; +} + +bool e2d::Player::Load(const Resource& res) +{ + if (musics_.end() != musics_.find(res.id)) + return true; + + Music * music = new (std::nothrow) Music(); + + if (music) + { + if (music->Load(res)) + { + music->SetVolume(volume_); + musics_.insert(std::make_pair(res.id, music)); + return true; + } + else + { + delete music; + } + } + return false; +} + +bool e2d::Player::Play(const Resource& res, int loop_count) +{ + if (Load(res)) + { + auto music = musics_[res.id]; + if (music->Play(loop_count)) + { + return true; + } + } + return false; +} + +void e2d::Player::Pause(const Resource& res) +{ + if (musics_.end() != musics_.find(res.id)) + musics_[res.id]->Pause(); +} + +void e2d::Player::Resume(const Resource& res) +{ + if (musics_.end() != musics_.find(res.id)) + musics_[res.id]->Resume(); +} + +void e2d::Player::Stop(const Resource& res) +{ + if (musics_.end() != musics_.find(res.id)) + musics_[res.id]->Stop(); +} + +bool e2d::Player::IsPlaying(const Resource& res) +{ + if (musics_.end() != musics_.find(res.id)) + return musics_[res.id]->IsPlaying(); + return false; +} + +float e2d::Player::GetVolume() +{ + return volume_; +} + +void e2d::Player::SetVolume(float volume) +{ + volume_ = std::min(std::max(volume, -224.f), 224.f); + for (const auto& pair : musics_) + { + pair.second->SetVolume(volume_); + } +} + +void e2d::Player::PauseAll() +{ + for (const auto& pair : musics_) + { + pair.second->Pause(); + } +} + +void e2d::Player::ResumeAll() +{ + for (const auto& pair : musics_) + { + pair.second->Resume(); + } +} + +void e2d::Player::StopAll() +{ + for (const auto& pair : musics_) + { + pair.second->Stop(); + } +} + +void e2d::Player::ClearCache() +{ + if (musics_.empty()) + return; + + for (const auto& pair : musics_) + { + delete pair.second; + } + musics_.clear(); +} diff --git a/project/vs2012/Easy2D.vcxproj b/project/vs2012/Easy2D.vcxproj index d933ca27..c7b5f618 100644 --- a/project/vs2012/Easy2D.vcxproj +++ b/project/vs2012/Easy2D.vcxproj @@ -62,6 +62,7 @@ + diff --git a/project/vs2012/Easy2D.vcxproj.filters b/project/vs2012/Easy2D.vcxproj.filters index 00020b43..f1ef1fdf 100644 --- a/project/vs2012/Easy2D.vcxproj.filters +++ b/project/vs2012/Easy2D.vcxproj.filters @@ -162,6 +162,9 @@ tools + + tools + tools diff --git a/project/vs2013/Easy2D.vcxproj b/project/vs2013/Easy2D.vcxproj index 2e36bc9d..f1c46bcb 100644 --- a/project/vs2013/Easy2D.vcxproj +++ b/project/vs2013/Easy2D.vcxproj @@ -206,6 +206,7 @@ + diff --git a/project/vs2013/Easy2D.vcxproj.filters b/project/vs2013/Easy2D.vcxproj.filters index 00020b43..f1ef1fdf 100644 --- a/project/vs2013/Easy2D.vcxproj.filters +++ b/project/vs2013/Easy2D.vcxproj.filters @@ -162,6 +162,9 @@ tools + + tools + tools diff --git a/project/vs2017/Easy2D.vcxproj b/project/vs2017/Easy2D.vcxproj index cb3b0103..59ed4360 100644 --- a/project/vs2017/Easy2D.vcxproj +++ b/project/vs2017/Easy2D.vcxproj @@ -239,6 +239,7 @@ + diff --git a/project/vs2017/Easy2D.vcxproj.filters b/project/vs2017/Easy2D.vcxproj.filters index 00020b43..f1ef1fdf 100644 --- a/project/vs2017/Easy2D.vcxproj.filters +++ b/project/vs2017/Easy2D.vcxproj.filters @@ -162,6 +162,9 @@ tools + + tools + tools