diff --git a/kiwano-audio/src/Player.h b/kiwano-audio/src/Player.h index 032aa2c4..3b4dc078 100644 --- a/kiwano-audio/src/Player.h +++ b/kiwano-audio/src/Player.h @@ -37,9 +37,9 @@ namespace kiwano ~Player(); - // 预加载音乐资源 + // 加载音乐资源 bool Load( - Resource const& res /* 音乐资源 */ + Resource const& res /* 音乐资源 */ ); // 播放音乐 diff --git a/kiwano/utils/ResLoader.cpp b/kiwano/utils/ResLoader.cpp index 7496aba9..461361f3 100644 --- a/kiwano/utils/ResLoader.cpp +++ b/kiwano/utils/ResLoader.cpp @@ -28,37 +28,90 @@ namespace kiwano { - namespace + namespace __res_loader_09 { - void LoadJsonData09(Json const& json_data, ResLoader* loader) + struct GlobalData { String path; + }; + + void LoadImageFromData(ResLoader* loader, GlobalData const& global_data, Json const& image_data); + bool CompareJsonWithString(Json const& data, const wchar_t* key, const wchar_t* value); + + void LoadJsonData(ResLoader* loader, Json const& json_data) + { + GlobalData global_data; if (json_data.count(L"path")) { - path = json_data[L"path"]; + global_data.path = json_data[L"path"]; } if (json_data.count(L"images")) { for (const auto& image : json_data[L"images"]) { - String file = image[L"file"]; - String id = image.count(L"id") ? image[L"id"] : file; - - if (image.count(L"type") && image[L"type"].as_string() == L"gif") - loader->AddGifImage(id, Resource(path + file)); - else - loader->AddImage(id, Resource(path + file)); + LoadImageFromData(loader, global_data, image); } } - - /*if (json_data.count(L"sounds")) + } + + void LoadImageFromData(ResLoader* loader, GlobalData const& global_data, Json const& image_data) + { + String id = image_data[L"id"]; + + if (image_data.count(L"file")) { - for (const auto& sound : json_data[L"sounds"]) + String file = image_data[L"file"]; + + // Gif image + if (CompareJsonWithString(image_data, L"type", L"gif")) { - loader->AddObj(); + loader->AddGifImage(id, Resource(global_data.path + file)); + return; } - }*/ + + if (!file.empty()) + { + if (image_data.count(L"rows") || image_data.count(L"cols")) + { + // Image slices + int rows = 1, cols = 1; + if (image_data.count(L"rows")) rows = image_data[L"rows"]; + if (image_data.count(L"cols")) cols = image_data[L"cols"]; + loader->AddFrames(id, Resource(global_data.path + file), cols, rows); + return; + } + else + { + // Simple image + loader->AddImage(id, Resource(global_data.path + file)); + return; + } + } + } + + // Frames + if (image_data.count(L"files")) + { + Array images; + images.reserve(image_data[L"files"].size()); + for (const auto& file : image_data[L"files"]) + { + auto filePath = file.as_string(); + ImagePtr image = new Image(global_data.path + file.as_string()); + if (image->IsValid()) + { + images.push_back(image); + } + } + loader->AddFrames(id, images); + } + + } + + bool CompareJsonWithString(Json const& data, const wchar_t* key, const wchar_t* value) + { + return data.count(key) && data[key].as_string() == value; } } @@ -96,7 +149,7 @@ namespace kiwano String version = json_data[L"version"]; if (version.empty() || version == L"0.9") { - LoadJsonData09(json_data, this); + __res_loader_09::LoadJsonData(this, json_data); } else { @@ -158,7 +211,7 @@ namespace kiwano return false; } - size_t ResLoader::AddFrames(String const& id, Array const& images) + bool ResLoader::AddFrames(String const& id, Array const& images) { if (images.empty()) return 0; @@ -181,11 +234,7 @@ namespace kiwano if (!image_arr.empty()) { FramesPtr frames = new (std::nothrow) Frames(image_arr); - if (frames) - { - res_.insert(std::make_pair(id, frames)); - return frames->GetFrames().size(); - } + return AddFrames(id, frames); } return 0; } @@ -196,12 +245,7 @@ namespace kiwano return 0; FramesPtr frames = new (std::nothrow) Frames(images); - if (frames) - { - res_.insert(std::make_pair(id, frames)); - return frames->GetFrames().size(); - } - return 0; + return AddFrames(id, frames); } size_t ResLoader::AddFrames(String const & id, Resource const & image, int cols, int rows) @@ -211,7 +255,7 @@ namespace kiwano ImagePtr raw = new (std::nothrow) Image; if (!raw || !raw->Load(image)) - return 0; + return false; float raw_width = raw->GetSourceWidth(); float raw_height = raw->GetSourceHeight(); @@ -228,19 +272,14 @@ namespace kiwano ImagePtr ptr = new (std::nothrow) Image(raw->GetBitmap()); if (ptr) { - ptr->Crop(Rect{ i * width, j * height, width, height }); + ptr->Crop(Rect{ j * width, i * height, width, height }); image_arr.push_back(ptr); } } } FramesPtr frames = new (std::nothrow) Frames(image_arr); - if (frames) - { - res_.insert(std::make_pair(id, frames)); - return frames->GetFrames().size(); - } - return 0; + return AddFrames(id, frames); } size_t ResLoader::AddFrames(String const & id, Resource const & image, Array const & crop_rects) @@ -263,6 +302,11 @@ namespace kiwano } FramesPtr frames = new (std::nothrow) Frames(image_arr); + return AddFrames(id, frames); + } + + size_t ResLoader::AddFrames(String const & id, FramesPtr frames) + { if (frames) { res_.insert(std::make_pair(id, frames)); @@ -271,16 +315,6 @@ namespace kiwano return 0; } - bool ResLoader::AddFrames(String const & id, FramesPtr frames) - { - if (frames) - { - res_.insert(std::make_pair(id, frames)); - return true; - } - return false; - } - bool ResLoader::AddObj(String const& id, ObjectPtr obj) { if (obj) @@ -321,4 +355,13 @@ namespace kiwano res_.clear(); } + ResLoader::ResLoader() + { + } + + ResLoader::~ResLoader() + { + Destroy(); + } + } \ No newline at end of file diff --git a/kiwano/utils/ResLoader.h b/kiwano/utils/ResLoader.h index 145e6aab..557b990e 100644 --- a/kiwano/utils/ResLoader.h +++ b/kiwano/utils/ResLoader.h @@ -27,6 +27,7 @@ namespace kiwano { + // 资源加载器 class KGE_API ResLoader { public: @@ -49,7 +50,7 @@ namespace kiwano bool AddGifImage(String const& id, GifImagePtr image); // 添加帧集合 - size_t AddFrames(String const& id, Array const& images); + bool AddFrames(String const& id, Array const& images); // 添加帧集合 size_t AddFrames(String const& id, Array const& images); @@ -63,17 +64,21 @@ namespace kiwano size_t AddFrames(String const& id, Resource const& image, Array const& crop_rects); // 添加帧集合 - bool AddFrames(String const& id, FramesPtr frames); + size_t AddFrames(String const& id, FramesPtr frames); // 添加对象 bool AddObj(String const& id, ObjectPtr obj); + // 获取图片资源 ImagePtr GetImage(String const& id) const; + // 获取 GIF 图片资源 GifImagePtr GetGifImage(String const& id) const; + // 获取序列帧 FramesPtr GetFrames(String const& id) const; + // 获取对象 ObjectPtr GetObj(String const& id) const; // 删除指定资源 @@ -91,6 +96,11 @@ namespace kiwano return dynamic_cast<_Ty*>((*iter).second.Get()); } + public: + ResLoader(); + + virtual ~ResLoader(); + protected: UnorderedMap res_; }; diff --git a/samples/Samples/Demo1.h b/samples/Samples/Demo1.h index 38ef868b..4bc7472d 100644 --- a/samples/Samples/Demo1.h +++ b/samples/Samples/Demo1.h @@ -7,15 +7,15 @@ class Demo1 : public Scene { public: - static ScenePtr Create(ResLoader* loader) + static ScenePtr Create() { - return new Demo1(loader); + return new Demo1; } - Demo1(ResLoader* loader) + Demo1() { // 获取人物图片 - ImagePtr man_image = loader->GetImage(L"man"); + ImagePtr man_image = g_Loader.GetImage(L"man"); // 缓动方程 auto ease_functions = { diff --git a/samples/Samples/Demo2.h b/samples/Samples/Demo2.h index 1495731e..1cc1832e 100644 --- a/samples/Samples/Demo2.h +++ b/samples/Samples/Demo2.h @@ -67,15 +67,15 @@ class Demo2 : public Scene { public: - static ScenePtr Create(ResLoader* loader) + static ScenePtr Create() { - return new Demo2(loader); + return new Demo2; } - Demo2(ResLoader* loader) + Demo2() { // 创建角色 - HeroPtr hero = new Hero(loader->GetGifImage(L"Kusanagi")); + HeroPtr hero = new Hero(g_Loader.GetGifImage(L"Kusanagi")); // 在屏幕上居中显示 hero->SetAnchor(0.5f, 0.5f); hero->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2); diff --git a/samples/Samples/Demo3.h b/samples/Samples/Demo3.h index b791897d..2ea0073f 100644 --- a/samples/Samples/Demo3.h +++ b/samples/Samples/Demo3.h @@ -11,7 +11,7 @@ class Demo3 TextPtr state_text; // 播放状态文字 public: - static ScenePtr Create(ResLoader* loader) + static ScenePtr Create() { return new Demo3; } diff --git a/samples/Samples/Demo4.h b/samples/Samples/Demo4.h index 6ef74780..132e09fc 100644 --- a/samples/Samples/Demo4.h +++ b/samples/Samples/Demo4.h @@ -17,28 +17,9 @@ class Tiger public: Tiger() { - // 获取图片原始大小 - ImagePtr image = new Image(L"res/tiger.png"); - Size source_size = image->GetSize(); - // 计算每帧图片大小 - Size frame_size = { source_size.x / 5, source_size.y / 3 }; - // 加载帧动画 - run_frames = new Frames; - for (int i = 0; i < 6; ++i) - { - Point pos = { (i % 5) * frame_size.x, (i / 5) * frame_size.y }; - ImagePtr frame = new Image(L"res/tiger.png", Rect{ pos, frame_size }); - run_frames->Add(frame); - } - - stand_frames = new Frames; - for (int i = 0; i < 6; ++i) - { - Point pos = { ((i + 1) % 5) * frame_size.x, ((i + 1) / 5 + 1) * frame_size.y }; - ImagePtr frame = new Image(L"res/tiger.png", Rect{ pos, frame_size }); - stand_frames->Add(frame); - } + run_frames = g_Loader.GetFrames(L"tiger_running"); + stand_frames = g_Loader.GetFrames(L"tiger_standing"); // 执行动画 AddAction( @@ -163,7 +144,7 @@ class Demo4 : public Scene { public: - static ScenePtr Create(ResLoader* loader) + static ScenePtr Create() { return new Demo4; } diff --git a/samples/Samples/Demo5.h b/samples/Samples/Demo5.h index 8f5a9b84..63b5cddd 100644 --- a/samples/Samples/Demo5.h +++ b/samples/Samples/Demo5.h @@ -8,7 +8,7 @@ class Demo5 : public Scene { public: - static ScenePtr Create(ResLoader* loader) + static ScenePtr Create() { return new Demo5; } diff --git a/samples/Samples/Samples.vcxproj b/samples/Samples/Samples.vcxproj index c05de61c..bc6c896c 100644 --- a/samples/Samples/Samples.vcxproj +++ b/samples/Samples/Samples.vcxproj @@ -214,7 +214,7 @@ - + diff --git a/samples/Samples/Samples.vcxproj.filters b/samples/Samples/Samples.vcxproj.filters index fdf10a3d..8d7c1556 100644 --- a/samples/Samples/Samples.vcxproj.filters +++ b/samples/Samples/Samples.vcxproj.filters @@ -4,14 +4,31 @@ - - - - - - + + src + + + src + + + src + + + src + + + src + + + src + - + + + + + {4460eeec-9e2f-46b6-909a-5ff4443075ce} + \ No newline at end of file diff --git a/samples/Samples/common.h b/samples/Samples/common.h index cf98daff..93c3750a 100644 --- a/samples/Samples/common.h +++ b/samples/Samples/common.h @@ -11,3 +11,6 @@ using namespace kiwano::network; const int WINDOW_WIDTH = 640; const int WINDOW_HEIGHT = 480; + +// 资源加载工具 +extern ResLoader g_Loader; diff --git a/samples/Samples/main.cpp b/samples/Samples/main.cpp index 8dbb0997..b8796125 100644 --- a/samples/Samples/main.cpp +++ b/samples/Samples/main.cpp @@ -11,7 +11,7 @@ namespace struct Demo { String title; - ScenePtr(*Create)(ResLoader*); + ScenePtr(*Create)(); }; Demo s_Demos[] = { @@ -25,11 +25,12 @@ namespace int s_DemoNum = sizeof(s_Demos) / sizeof(Demo); } +// 资源加载工具 +ResLoader g_Loader; + class DemoApp : public Application { - ResLoader loader_; - public: DemoApp() { @@ -46,12 +47,18 @@ public: void OnStart() override { // 从 JSON 文件中加载资源 - loader_.LoadFromJsonFile(L"res/res.json"); + g_Loader.LoadFromJsonFile(L"res/index.json"); // 切换到第一个场景 ChangeDemoScene(0); } + void OnDestroy() override + { + // 退出游戏时销毁资源 + g_Loader.Destroy(); + } + void ChangeDemoScene(int index) { if (s_CurrIndex != index) @@ -61,7 +68,7 @@ public: String title = s_Demos[index].title; Window::Instance()->SetTitle(L"Kiwano示例程序 - " + title); - ScenePtr scene = s_Demos[index].Create(&loader_); + ScenePtr scene = s_Demos[index].Create(); EnterScene(scene); // 添加按键监听 diff --git a/samples/Samples/res/res.json b/samples/Samples/res/index.json similarity index 51% rename from samples/Samples/res/res.json rename to samples/Samples/res/index.json index c5774f4f..5355d9c5 100644 --- a/samples/Samples/res/res.json +++ b/samples/Samples/res/index.json @@ -15,21 +15,26 @@ "file": "spring_forest.jpg" }, { - "id": "tiger", - "file": "tiger.png", - "rows": 3, - "cols": 5 + "id": "tiger_running", + "files": [ + "tiger/run/run01.png", + "tiger/run/run02.png", + "tiger/run/run03.png", + "tiger/run/run04.png", + "tiger/run/run05.png", + "tiger/run/run06.png" + ] + }, + { + "id": "tiger_standing", + "file": "tiger/stand.png", + "rows": 2, + "cols": 3 }, { "id": "Kusanagi", "file": "Kusanagi.gif", "type": "gif" } - ], - "sounds": [ - { - "id": "bg_music", - "file": "splash.mp3" - } ] } \ No newline at end of file diff --git a/samples/Samples/res/tiger.png b/samples/Samples/res/tiger.png deleted file mode 100644 index 4ddffcde..00000000 Binary files a/samples/Samples/res/tiger.png and /dev/null differ diff --git a/samples/Samples/res/tiger/run/run01.png b/samples/Samples/res/tiger/run/run01.png new file mode 100644 index 00000000..c9edf27e Binary files /dev/null and b/samples/Samples/res/tiger/run/run01.png differ diff --git a/samples/Samples/res/tiger/run/run02.png b/samples/Samples/res/tiger/run/run02.png new file mode 100644 index 00000000..b4be56bb Binary files /dev/null and b/samples/Samples/res/tiger/run/run02.png differ diff --git a/samples/Samples/res/tiger/run/run03.png b/samples/Samples/res/tiger/run/run03.png new file mode 100644 index 00000000..a6ec3549 Binary files /dev/null and b/samples/Samples/res/tiger/run/run03.png differ diff --git a/samples/Samples/res/tiger/run/run04.png b/samples/Samples/res/tiger/run/run04.png new file mode 100644 index 00000000..005680c4 Binary files /dev/null and b/samples/Samples/res/tiger/run/run04.png differ diff --git a/samples/Samples/res/tiger/run/run05.png b/samples/Samples/res/tiger/run/run05.png new file mode 100644 index 00000000..e0c71b7a Binary files /dev/null and b/samples/Samples/res/tiger/run/run05.png differ diff --git a/samples/Samples/res/tiger/run/run06.png b/samples/Samples/res/tiger/run/run06.png new file mode 100644 index 00000000..af3c5546 Binary files /dev/null and b/samples/Samples/res/tiger/run/run06.png differ diff --git a/samples/Samples/res/tiger/shock.png b/samples/Samples/res/tiger/shock.png new file mode 100644 index 00000000..41809eb8 Binary files /dev/null and b/samples/Samples/res/tiger/shock.png differ diff --git a/samples/Samples/res/tiger/stand.png b/samples/Samples/res/tiger/stand.png new file mode 100644 index 00000000..1c6868eb Binary files /dev/null and b/samples/Samples/res/tiger/stand.png differ diff --git a/samples/Samples/res/tiger/stand/stand01.png b/samples/Samples/res/tiger/stand/stand01.png new file mode 100644 index 00000000..864dcb95 Binary files /dev/null and b/samples/Samples/res/tiger/stand/stand01.png differ diff --git a/samples/Samples/res/tiger/stand/stand02.png b/samples/Samples/res/tiger/stand/stand02.png new file mode 100644 index 00000000..503f7c23 Binary files /dev/null and b/samples/Samples/res/tiger/stand/stand02.png differ diff --git a/samples/Samples/res/tiger/stand/stand03.png b/samples/Samples/res/tiger/stand/stand03.png new file mode 100644 index 00000000..a1d7cf9a Binary files /dev/null and b/samples/Samples/res/tiger/stand/stand03.png differ diff --git a/samples/Samples/res/tiger/stand/stand04.png b/samples/Samples/res/tiger/stand/stand04.png new file mode 100644 index 00000000..d8c6b8c1 Binary files /dev/null and b/samples/Samples/res/tiger/stand/stand04.png differ diff --git a/samples/Samples/res/tiger/stand/stand05.png b/samples/Samples/res/tiger/stand/stand05.png new file mode 100644 index 00000000..e4756cd4 Binary files /dev/null and b/samples/Samples/res/tiger/stand/stand05.png differ diff --git a/samples/Samples/res/tiger/stand/stand06.png b/samples/Samples/res/tiger/stand/stand06.png new file mode 100644 index 00000000..b5337f8d Binary files /dev/null and b/samples/Samples/res/tiger/stand/stand06.png differ