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,9 +37,9 @@ namespace kiwano
~Player();
// 속潼稜있栗都
// 속潼稜있栗都
bool Load(
Resource const& res /* 稜있栗都 */
Resource const& res /* 稜있栗都 */
);
// 꺄렴稜있

View File

@ -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<ImagePtr> 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<Resource> const& images)
bool ResLoader::AddFrames(String const& id, Array<Resource> 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<Rect> 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();
}
}

View File

@ -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<Resource> const& images);
bool AddFrames(String const& id, Array<Resource> 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);
// Ìí¼ÓÖ¡¼¯ºÏ
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<String, ObjectPtr> res_;
};

View File

@ -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 = {

View File

@ -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);

View File

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

View File

@ -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;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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);
// 添加按键监听

View File

@ -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"
}
]
}

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