ResLoader supports image slices now

minor
This commit is contained in:
Nomango 2019-08-01 13:07:48 +08:00 committed by Nomango
parent 249e3a0b91
commit 4b1a2921e4
28 changed files with 171 additions and 105 deletions

View File

@ -37,7 +37,7 @@ namespace kiwano
~Player(); ~Player();
// 속潼稜있栗都 // 속潼稜있栗都
bool Load( bool Load(
Resource const& res /* 稜있栗都 */ Resource const& res /* 稜있栗都 */
); );

View File

@ -28,37 +28,90 @@
namespace kiwano namespace kiwano
{ {
namespace namespace __res_loader_09
{ {
void LoadJsonData09(Json const& json_data, ResLoader* loader) struct GlobalData
{ {
String path; 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")) if (json_data.count(L"path"))
{ {
path = json_data[L"path"]; global_data.path = json_data[L"path"];
} }
if (json_data.count(L"images")) if (json_data.count(L"images"))
{ {
for (const auto& image : json_data[L"images"]) for (const auto& image : json_data[L"images"])
{ {
String file = image[L"file"]; LoadImageFromData(loader, global_data, image);
String id = image.count(L"id") ? image[L"id"] : file; }
}
}
if (image.count(L"type") && image[L"type"].as_string() == L"gif") void LoadImageFromData(ResLoader* loader, GlobalData const& global_data, Json const& image_data)
loader->AddGifImage(id, Resource(path + file)); {
String id = image_data[L"id"];
if (image_data.count(L"file"))
{
String file = image_data[L"file"];
// Gif image
if (CompareJsonWithString(image_data, L"type", L"gif"))
{
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 else
loader->AddImage(id, Resource(path + file)); {
// Simple image
loader->AddImage(id, Resource(global_data.path + file));
return;
}
} }
} }
/*if (json_data.count(L"sounds")) // Frames
if (image_data.count(L"files"))
{ {
for (const auto& sound : json_data[L"sounds"]) Array<ImagePtr> images;
images.reserve(image_data[L"files"].size());
for (const auto& file : image_data[L"files"])
{ {
loader->AddObj(); 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"]; String version = json_data[L"version"];
if (version.empty() || version == L"0.9") if (version.empty() || version == L"0.9")
{ {
LoadJsonData09(json_data, this); __res_loader_09::LoadJsonData(this, json_data);
} }
else else
{ {
@ -158,7 +211,7 @@ namespace kiwano
return false; return false;
} }
size_t ResLoader::AddFrames(String const& id, Array<Resource> const& images) bool ResLoader::AddFrames(String const& id, Array<Resource> const& images)
{ {
if (images.empty()) if (images.empty())
return 0; return 0;
@ -181,11 +234,7 @@ namespace kiwano
if (!image_arr.empty()) if (!image_arr.empty())
{ {
FramesPtr frames = new (std::nothrow) Frames(image_arr); FramesPtr frames = new (std::nothrow) Frames(image_arr);
if (frames) return AddFrames(id, frames);
{
res_.insert(std::make_pair(id, frames));
return frames->GetFrames().size();
}
} }
return 0; return 0;
} }
@ -196,12 +245,7 @@ namespace kiwano
return 0; return 0;
FramesPtr frames = new (std::nothrow) Frames(images); FramesPtr frames = new (std::nothrow) Frames(images);
if (frames) return AddFrames(id, frames);
{
res_.insert(std::make_pair(id, frames));
return frames->GetFrames().size();
}
return 0;
} }
size_t ResLoader::AddFrames(String const & id, Resource const & image, int cols, int rows) 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; ImagePtr raw = new (std::nothrow) Image;
if (!raw || !raw->Load(image)) if (!raw || !raw->Load(image))
return 0; return false;
float raw_width = raw->GetSourceWidth(); float raw_width = raw->GetSourceWidth();
float raw_height = raw->GetSourceHeight(); float raw_height = raw->GetSourceHeight();
@ -228,19 +272,14 @@ namespace kiwano
ImagePtr ptr = new (std::nothrow) Image(raw->GetBitmap()); ImagePtr ptr = new (std::nothrow) Image(raw->GetBitmap());
if (ptr) 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); image_arr.push_back(ptr);
} }
} }
} }
FramesPtr frames = new (std::nothrow) Frames(image_arr); FramesPtr frames = new (std::nothrow) Frames(image_arr);
if (frames) return AddFrames(id, frames);
{
res_.insert(std::make_pair(id, frames));
return frames->GetFrames().size();
}
return 0;
} }
size_t ResLoader::AddFrames(String const & id, Resource const & image, Array<Rect> const & crop_rects) size_t ResLoader::AddFrames(String const & id, Resource const & image, Array<Rect> const & crop_rects)
@ -263,6 +302,11 @@ namespace kiwano
} }
FramesPtr frames = new (std::nothrow) Frames(image_arr); FramesPtr frames = new (std::nothrow) Frames(image_arr);
return AddFrames(id, frames);
}
size_t ResLoader::AddFrames(String const & id, FramesPtr frames)
{
if (frames) if (frames)
{ {
res_.insert(std::make_pair(id, frames)); res_.insert(std::make_pair(id, frames));
@ -271,16 +315,6 @@ namespace kiwano
return 0; 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) bool ResLoader::AddObj(String const& id, ObjectPtr obj)
{ {
if (obj) if (obj)
@ -321,4 +355,13 @@ namespace kiwano
res_.clear(); res_.clear();
} }
ResLoader::ResLoader()
{
}
ResLoader::~ResLoader()
{
Destroy();
}
} }

View File

@ -27,6 +27,7 @@
namespace kiwano namespace kiwano
{ {
// 资源加载器
class KGE_API ResLoader class KGE_API ResLoader
{ {
public: public:
@ -49,7 +50,7 @@ namespace kiwano
bool AddGifImage(String const& id, GifImagePtr image); bool AddGifImage(String const& id, GifImagePtr image);
// Ìí¼ÓÖ¡¼¯ºÏ // Ìí¼ÓÖ¡¼¯ºÏ
size_t AddFrames(String const& id, Array<Resource> const& images); bool AddFrames(String const& id, Array<Resource> const& images);
// Ìí¼ÓÖ¡¼¯ºÏ // Ìí¼ÓÖ¡¼¯ºÏ
size_t AddFrames(String const& id, Array<ImagePtr> const& images); size_t AddFrames(String const& id, Array<ImagePtr> const& images);
@ -63,17 +64,21 @@ namespace kiwano
size_t AddFrames(String const& id, Resource const& image, Array<Rect> const& crop_rects); size_t AddFrames(String const& id, Resource const& image, Array<Rect> 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); bool AddObj(String const& id, ObjectPtr obj);
// 获取图片资源
ImagePtr GetImage(String const& id) const; ImagePtr GetImage(String const& id) const;
// 获取 GIF 图片资源
GifImagePtr GetGifImage(String const& id) const; GifImagePtr GetGifImage(String const& id) const;
// 获取序列帧
FramesPtr GetFrames(String const& id) const; FramesPtr GetFrames(String const& id) const;
// 获取对象
ObjectPtr GetObj(String const& id) const; ObjectPtr GetObj(String const& id) const;
// ɾ³ýÖ¸¶¨×ÊÔ´ // ɾ³ýÖ¸¶¨×ÊÔ´
@ -91,6 +96,11 @@ namespace kiwano
return dynamic_cast<_Ty*>((*iter).second.Get()); return dynamic_cast<_Ty*>((*iter).second.Get());
} }
public:
ResLoader();
virtual ~ResLoader();
protected: protected:
UnorderedMap<String, ObjectPtr> res_; UnorderedMap<String, ObjectPtr> res_;
}; };

View File

@ -7,15 +7,15 @@ class Demo1
: public Scene : public Scene
{ {
public: 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 = { auto ease_functions = {

View File

@ -67,15 +67,15 @@ class Demo2
: public Scene : public Scene
{ {
public: 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->SetAnchor(0.5f, 0.5f);
hero->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2); hero->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);

View File

@ -11,7 +11,7 @@ class Demo3
TextPtr state_text; // 播放状态文字 TextPtr state_text; // 播放状态文字
public: public:
static ScenePtr Create(ResLoader* loader) static ScenePtr Create()
{ {
return new Demo3; return new Demo3;
} }

View File

@ -17,28 +17,9 @@ class Tiger
public: public:
Tiger() 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; run_frames = g_Loader.GetFrames(L"tiger_running");
for (int i = 0; i < 6; ++i) stand_frames = g_Loader.GetFrames(L"tiger_standing");
{
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);
}
// 执行动画 // 执行动画
AddAction( AddAction(
@ -163,7 +144,7 @@ class Demo4
: public Scene : public Scene
{ {
public: public:
static ScenePtr Create(ResLoader* loader) static ScenePtr Create()
{ {
return new Demo4; return new Demo4;
} }

View File

@ -8,7 +8,7 @@ class Demo5
: public Scene : public Scene
{ {
public: public:
static ScenePtr Create(ResLoader* loader) static ScenePtr Create()
{ {
return new Demo5; return new Demo5;
} }

View File

@ -214,7 +214,7 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="res\res.json" /> <None Include="res\index.json" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -4,14 +4,31 @@
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Demo1.h" /> <ClInclude Include="Demo1.h">
<ClInclude Include="common.h" /> <Filter>src</Filter>
<ClInclude Include="Demo2.h" /> </ClInclude>
<ClInclude Include="Demo3.h" /> <ClInclude Include="Demo2.h">
<ClInclude Include="Demo4.h" /> <Filter>src</Filter>
<ClInclude Include="Demo5.h" /> </ClInclude>
<ClInclude Include="Demo3.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="Demo4.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="Demo5.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="common.h">
<Filter>src</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="res\res.json" /> <None Include="res\index.json" />
</ItemGroup>
<ItemGroup>
<Filter Include="src">
<UniqueIdentifier>{4460eeec-9e2f-46b6-909a-5ff4443075ce}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -11,3 +11,6 @@ using namespace kiwano::network;
const int WINDOW_WIDTH = 640; const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480; const int WINDOW_HEIGHT = 480;
// 栗都속潼묏야
extern ResLoader g_Loader;

View File

@ -11,7 +11,7 @@ namespace
struct Demo struct Demo
{ {
String title; String title;
ScenePtr(*Create)(ResLoader*); ScenePtr(*Create)();
}; };
Demo s_Demos[] = { Demo s_Demos[] = {
@ -25,11 +25,12 @@ namespace
int s_DemoNum = sizeof(s_Demos) / sizeof(Demo); int s_DemoNum = sizeof(s_Demos) / sizeof(Demo);
} }
// 资源加载工具
ResLoader g_Loader;
class DemoApp class DemoApp
: public Application : public Application
{ {
ResLoader loader_;
public: public:
DemoApp() DemoApp()
{ {
@ -46,12 +47,18 @@ public:
void OnStart() override void OnStart() override
{ {
// 从 JSON 文件中加载资源 // 从 JSON 文件中加载资源
loader_.LoadFromJsonFile(L"res/res.json"); g_Loader.LoadFromJsonFile(L"res/index.json");
// 切换到第一个场景 // 切换到第一个场景
ChangeDemoScene(0); ChangeDemoScene(0);
} }
void OnDestroy() override
{
// 退出游戏时销毁资源
g_Loader.Destroy();
}
void ChangeDemoScene(int index) void ChangeDemoScene(int index)
{ {
if (s_CurrIndex != index) if (s_CurrIndex != index)
@ -61,7 +68,7 @@ public:
String title = s_Demos[index].title; String title = s_Demos[index].title;
Window::Instance()->SetTitle(L"Kiwano示例程序 - " + title); Window::Instance()->SetTitle(L"Kiwano示例程序 - " + title);
ScenePtr scene = s_Demos[index].Create(&loader_); ScenePtr scene = s_Demos[index].Create();
EnterScene(scene); EnterScene(scene);
// 添加按键监听 // 添加按键监听

View File

@ -15,21 +15,26 @@
"file": "spring_forest.jpg" "file": "spring_forest.jpg"
}, },
{ {
"id": "tiger", "id": "tiger_running",
"file": "tiger.png", "files": [
"rows": 3, "tiger/run/run01.png",
"cols": 5 "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", "id": "Kusanagi",
"file": "Kusanagi.gif", "file": "Kusanagi.gif",
"type": "gif" "type": "gif"
} }
],
"sounds": [
{
"id": "bg_music",
"file": "splash.mp3"
}
] ]
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB