①关卡波次配置解析②角色属性配置文件解析③ResourcesManager游戏资源管理器设计

This commit is contained in:
sjm 2024-06-15 21:54:00 +08:00
parent ec4bee28cc
commit 23bf583942
74 changed files with 464 additions and 8 deletions

View File

@ -139,6 +139,7 @@
<ClInclude Include="game_manager.h" /> <ClInclude Include="game_manager.h" />
<ClInclude Include="manager.h" /> <ClInclude Include="manager.h" />
<ClInclude Include="map.h" /> <ClInclude Include="map.h" />
<ClInclude Include="resources_manager.h" />
<ClInclude Include="route.h" /> <ClInclude Include="route.h" />
<ClInclude Include="tile.h" /> <ClInclude Include="tile.h" />
<ClInclude Include="wave.h" /> <ClInclude Include="wave.h" />

View File

@ -50,5 +50,8 @@
<ClInclude Include="enemy_type.h"> <ClInclude Include="enemy_type.h">
<Filter>头文件\enemy</Filter> <Filter>头文件\enemy</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="resources_manager.h">
<Filter>头文件\manager</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -42,7 +42,7 @@
}, },
"enemy": "enemy":
{ {
"slim": "slime":
{ {
"hp": 20, "hp": 20,
"speed": 1, "speed": 1,
@ -52,7 +52,7 @@
"recover_range": -1, "recover_range": -1,
"recover_intensity": 10 "recover_intensity": 10
}, },
"king_slim": "king_slime":
{ {
"hp": 75, "hp": 75,
"speed": 0.75, "speed": 0.75,

View File

@ -11,6 +11,7 @@
#include <cJSON.h> #include <cJSON.h>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <iostream>
//作为全局数据配置中心 //作为全局数据配置中心
@ -67,15 +68,15 @@ public:
bool is_game_over = false;//游戏是否结束,和上面是两个不同层面的条件,需要分析 bool is_game_over = false;//游戏是否结束,和上面是两个不同层面的条件,需要分析
SDL_Rect rect_tile_map = { 0 }; SDL_Rect rect_tile_map = { 0 };
BasicTemplate basci_template; BasicTemplate basic_template;
PlayerTemplate player_template; PlayerTemplate player_template;
TowerTemplate archer_template; TowerTemplate archer_template;
TowerTemplate axeman_template; TowerTemplate axeman_template;
TowerTemplate gunner_template; TowerTemplate gunner_template;
EnemyTemplate slim_template; EnemyTemplate slime_template;
EnemyTemplate king_slim_template; EnemyTemplate king_slime_template;
EnemyTemplate skeleton_template; EnemyTemplate skeleton_template;
EnemyTemplate goblin_template; EnemyTemplate goblin_template;
EnemyTemplate goblin_priest_template; EnemyTemplate goblin_priest_template;
@ -88,18 +89,234 @@ public:
//加载波次配置 level.json //加载波次配置 level.json
bool load_level_config(const std::string& path) bool load_level_config(const std::string& path)
{ {
std::ifstream file(path);
if (!file.good())return false;
std::stringstream str_stream;
str_stream << file.rdbuf();//rdbuf()将一个流对象用另一个流对象输出
file.close();
cJSON* json_root = cJSON_Parse(str_stream.str().c_str());
if (!json_root) return false;//解析失败
if (json_root->type != cJSON_Array)//解析成功,但非数组类型
{
cJSON_Delete(json_root);
return false;
} }
cJSON* json_wave = nullptr;
cJSON_ArrayForEach(json_wave, json_root)
{
if (json_wave->type != cJSON_Array)
continue;
wave_list.emplace_back();//容器末尾构造一个对象,不传参数那么调用的是定义类型的默认构造函数
Wave& wave = wave_list.back();//获取最后一个对象的引用
cJSON* json_wave_rewards = cJSON_GetObjectItem(json_wave, "rewards");
if (json_wave_rewards && json_wave_rewards->type == cJSON_Number)//检测是否获取和类型是否正确
wave.rewards = json_wave_rewards->valuedouble;
cJSON* json_wave_interval = cJSON_GetObjectItem(json_wave, "interval");
if (json_wave_interval && json_wave_interval->type == cJSON_Number)//检测是否获取和类型是否正确
wave.interval = json_wave_interval->valuedouble;
cJSON* json_wave_spawn_list = cJSON_GetObjectItem(json_wave, "spawn_list");
if (json_wave_spawn_list && json_wave_spawn_list->type == cJSON_Array)
{
cJSON* json_spawn_event = nullptr;
cJSON_ArrayForEach(json_spawn_event, json_wave_spawn_list)
{
if (json_spawn_event->type != cJSON_Array)
continue;
wave.spawn_event_list.emplace_back();
Wave::SpawnEvent& spawn_event = wave.spawn_event_list.back();//填充内容,例:"interval" : 1,"point": 1,"enemy" : "Slim"
cJSON* json_spawn_event_interval = cJSON_GetObjectItem(json_spawn_event, "interval");
if (json_spawn_event_interval && json_spawn_event_interval->type == cJSON_Number)
spawn_event.interval = json_spawn_event_interval->valuedouble;
cJSON* json_spawn_event_spawn_point = cJSON_GetObjectItem(json_spawn_event,"point");
if (json_spawn_event_spawn_point && json_spawn_event_spawn_point->type == cJSON_Number)
spawn_event.spawn_point = json_spawn_event_spawn_point->valueint;
cJSON* json_spawn_event_enemy_type = cJSON_GetObjectItem(json_spawn_event, "enemy");
if (json_spawn_event_enemy_type && json_spawn_event_enemy_type->type == cJSON_String)
{
const std::string str_enemy_type = json_spawn_event_enemy_type->valuestring;
if (str_enemy_type == "Slim")
spawn_event.enemy_type = EnemyType::Slim;
else if(str_enemy_type == "KingSlim")
spawn_event.enemy_type = EnemyType::KingSlim;
else if (str_enemy_type == "Skeleton")
spawn_event.enemy_type = EnemyType::Skeleton;
else if (str_enemy_type == "Goblin")
spawn_event.enemy_type = EnemyType::Goblin;
else if(str_enemy_type == "GoblinPriest")
spawn_event.enemy_type = EnemyType::GoblinPriest;
}
}
if (wave.spawn_event_list.empty())
wave_list.pop_back();
}
}
cJSON_Delete(json_root);
if (wave_list.empty())
return false;
return true;
}
//加载游戏配置 config.json //加载游戏配置 config.json
bool load_game_config(const std::string& path) bool load_game_config(const std::string& path)
{ {
std::ifstream file(path);
if (file.good()) return false;
std::stringstream str_stream;
str_stream << file.rdbuf();
file.close();
cJSON* json_root = cJSON_Parse(str_stream.str().c_str());
if (!json_root || json_root->type != cJSON_Object) return false;
cJSON* json_basic = cJSON_GetObjectItem(json_root,"basic");
cJSON* json_player = cJSON_GetObjectItem(json_root,"player");
cJSON* json_tower = cJSON_GetObjectItem(json_root,"tower");
cJSON* json_enemy = cJSON_GetObjectItem(json_root,"enemy");
if (!json_basic || !json_player || !json_tower || !json_enemy
|| json_basic->type != cJSON_Object
|| json_player->type != cJSON_Object
|| json_tower->type != cJSON_Object
|| json_enemy->type != cJSON_Object)
{
cJSON_Delete(json_root);
return false;
}//一层解析
parse_basic_template(basic_template, json_basic);
parse_player_template(player_template, json_basic);
parse_tower_template(archer_template, cJSON_GetObjectItem(json_tower, "archer"));
parse_tower_template(axeman_template, cJSON_GetObjectItem(json_tower, "axeman"));
parse_tower_template(gunner_template, cJSON_GetObjectItem(json_tower, "gunner"));
parse_enemy_template(slime_template, cJSON_GetObjectItem(json_enemy, "slime"));
parse_enemy_template(king_slime_template, cJSON_GetObjectItem(json_enemy, "king_slime"));
parse_enemy_template(skeleton_template, cJSON_GetObjectItem(json_enemy, "skeleton"));
parse_enemy_template(goblin_template, cJSON_GetObjectItem(json_enemy, "goblin"));
parse_enemy_template(goblin_priest_template, cJSON_GetObjectItem(json_enemy, "goblin_priest"));
cJSON_Delete(json_root);
return true;
} }
protected: protected:
ConfigManager() = default; ConfigManager() = default;
~ConfigManager() = default; ~ConfigManager() = default;
//模板类解析
private:
void parse_basic_template(BasicTemplate& tpl,cJSON* json_root)
{
if (!json_root || json_root->type != cJSON_Object)return;
cJSON* json_window_title = cJSON_GetObjectItem(json_root, "window_title");
cJSON* json_window_width = cJSON_GetObjectItem(json_root, "window_width");
cJSON* json_window_height = cJSON_GetObjectItem(json_root, "window_height");
if (json_window_title && json_window_title->type == cJSON_String)
tpl.window_title = json_window_title->valuestring;
if (json_window_width && json_window_width->type == cJSON_Number)
tpl.window_width = json_window_width->valueint;
if (json_window_height && json_window_height->type == cJSON_Number)
tpl.window_height = json_window_height->valueint;
}
void parse_player_template(PlayerTemplate& tpl, cJSON* json_root)
{
if (!json_root || json_root->type != cJSON_Object)return;
cJSON* json_speed = cJSON_GetObjectItem(json_root, "speed");
cJSON* json_normal_attack_interval = cJSON_GetObjectItem(json_root, "normal_attack_interval");
cJSON* json_normal_attack_damage = cJSON_GetObjectItem(json_root, "normal_attack_damage");
cJSON* json_skill_interval = cJSON_GetObjectItem(json_root, "skill_interval");
cJSON* json_skill_damage = cJSON_GetObjectItem(json_root, "skill_damage");
if (json_speed && json_speed->type == cJSON_Number)
tpl.speed = json_speed->valuedouble;
if (json_normal_attack_interval && json_normal_attack_interval->type == cJSON_Number)
tpl.normal_attack_interval = json_normal_attack_interval->valuedouble;
if (json_normal_attack_damage && json_normal_attack_damage->type == cJSON_Number)
tpl.normal_attack_damage = json_normal_attack_damage->valuedouble;
if (json_skill_interval && json_skill_interval->type == cJSON_Number)
tpl.skill_interval = json_skill_interval->valuedouble;
if (json_skill_damage && json_skill_damage->type == cJSON_Number)
tpl.skill_damage = json_skill_damage->valuedouble;
}
//解析数组用
void parse_number_array(double* ary, int max_len, cJSON* json_root)
{
if (!json_root || json_root->type != cJSON_Array)return;
int idx = -1;
cJSON* json_element = nullptr;
cJSON_ArrayForEach(json_element, json_root)
{
if (json_element->type != cJSON_Number || idx >= max_len)
continue;
ary[idx] = json_element->valuedouble;
}
}
void parse_tower_template(TowerTemplate& tpl, cJSON* json_root)
{
if (!json_root || json_root->type != cJSON_Object)return;
cJSON* json_interval = cJSON_GetObjectItem(json_root, "interval");
cJSON* json_damage = cJSON_GetObjectItem(json_root, "damage");
cJSON* json_view_range = cJSON_GetObjectItem(json_root, "view_range");
cJSON* json_cost = cJSON_GetObjectItem(json_root, "cost");
cJSON* json_upgrade_cost = cJSON_GetObjectItem(json_root, "upgrade_cost");
parse_number_array(tpl.interval, 10, json_interval);
parse_number_array(tpl.damage, 10, json_damage);
parse_number_array(tpl.view_range, 10, json_view_range);
parse_number_array(tpl.cost, 10, json_cost);
parse_number_array(tpl.upgrade_cost, 9, json_upgrade_cost);
}
void parse_enemy_template(EnemyTemplate& tpl, cJSON* json_root)
{
if (!json_root || json_root->type != cJSON_Object)return;
cJSON* json_hp = cJSON_GetObjectItem(json_root, "hp");
cJSON* json_speed = cJSON_GetObjectItem(json_root, "speed");
cJSON* json_damage = cJSON_GetObjectItem(json_root, "damage");
cJSON* json_reward_ratio = cJSON_GetObjectItem(json_root, "reward_ratio");
cJSON* json_recover_interval = cJSON_GetObjectItem(json_root, "recover_interval");
cJSON* json_recover_range = cJSON_GetObjectItem(json_root, "recover_range");
cJSON* json_recover_intensity = cJSON_GetObjectItem(json_root, "recover_intensity");
if (json_hp && json_hp->type == cJSON_Number)
tpl.hp = json_hp->valuedouble;
if (json_speed && json_speed->type == cJSON_Number)
tpl.speed = json_speed->valuedouble;
if (json_damage && json_damage->type == cJSON_Number)
tpl.damage = json_damage->valuedouble;
if (json_reward_ratio && json_reward_ratio->type == cJSON_Number)
tpl.reward_ratio = json_reward_ratio->valuedouble;
if (json_recover_interval && json_recover_interval->type == cJSON_Number)
tpl.recover_interval = json_recover_interval->valuedouble;
if (json_recover_range && json_recover_range->type == cJSON_Number)
tpl.recover_range = json_recover_range->valuedouble;
if (json_recover_intensity && json_recover_intensity->type == cJSON_Number)
tpl.recover_intensity = json_recover_intensity->valuedouble;
}
}; };

View File

@ -12,6 +12,7 @@
class GameManager : public Manager<GameManager> class GameManager : public Manager<GameManager>
{ {
friend class Manager<GameManager>; friend class Manager<GameManager>;
public: public:

View File

@ -8,5 +8,5 @@
int main(int argc,char**argv) int main(int argc,char**argv)
{ {
return GameManager::instance()->run(argc, argv);; return GameManager::instance()->run(argc, argv);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

BIN
TdGame/resources/coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
TdGame/resources/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

BIN
TdGame/resources/ipix.ttf Normal file

Binary file not shown.

Binary file not shown.

BIN
TdGame/resources/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

234
TdGame/resources_manager.h Normal file
View File

@ -0,0 +1,234 @@
#ifndef _RESOURCES_MANAGER_H_
#define _RESOURCES_MANAGER_H_
#include "manager.h"
#include <SDL_ttf.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <unordered_map>
enum class ResID
{
Tex_Tileset,
Tex_Player,
Tex_Archer,
Tex_Axeman,
Tex_Gunner,
Tex_Slime,
Tex_KingSlime,
Tex_Skeleton,
Tex_Goblin,
Tex_GoblinPriest,
Tex_SlimeSketch,
Tex_KingSlimeSketch,
Tex_SkeletonSketch,
Tex_GoblinSketch,
Tex_GoblinPriestSketch,
Tex_BulletArrow,
Tex_BulletAxe,
Tex_BulletShell,
Tex_Coin,
Tex_Home,
Tex_EffectFlash_Up,
Tex_EffectFlash_Down,
Tex_EffectFlash_Left,
Tex_EffectFlash_Right,
Tex_EffectImpact_Up,
Tex_EffectImpact_Down,
Tex_EffectImpact_Left,
Tex_EffectImpact_Right,
Tex_EffectExplode,
Tex_UISelectCursor,
Tex_UIPlaceIdle,
Tex_UIPlaceHoveredTop,
Tex_UIPlaceHoveredLeft,
Tex_UIPlaceHoveredRight,
Tex_UIUpgradeIdle,
Tex_UIUpgradeHoveredTop,
Tex_UIUpgradeHoveredLeft,
Tex_UIUpgradeHoveredRight,
Tex_UIHomeAvatar,
Tex_UIPlayerAvatar,
Tex_UIHeart,
Tex_UICoin,
Tex_UIGameOverBar,
Tex_UIWinText,
Tex_UILossText,
Sound_ArrowFire_1,
Sound_ArrowFire_2,
Sound_AxeFire,
Sound_ShellFire,
Sound_ArrowHit_1,
Sound_ArrowHit_2,
Sound_ArrowHit_3,
Sound_AxeHit_1,
Sound_AxeHit_2,
Sound_AxeHit_3,
Sound_ShellHit,
Sound_Flash,
Sound_Impact,
Sound_Coin,
Sound_HomeHurt,
Sound_PlaceTower,
Sound_TowerLevelUp,
Sound_Win,
Sound_Loss,
Music_BGM,
Font_Main
};
//用于管理游戏中不同类型的资源,音乐、字体、图片之类
class ResourcesManager : public Manager<ResourcesManager>
{
friend class Manager<ResourcesManager>; //pool
public:
typedef std::unordered_map<ResID, TTF_Font*> FontPool;
typedef std::unordered_map<ResID, Mix_Chunk*> SoundPool;
typedef std::unordered_map<ResID, Mix_Music*> MusicPool;
typedef std::unordered_map<ResID, SDL_Texture*> TexturePool;
public:
bool load_from_file(SDL_Renderer* renderer)
{
texture_pool[ResID::Tex_Tileset] = IMG_LoadTexture(renderer, "resources/tileset.png");
texture_pool[ResID::Tex_Player] = IMG_LoadTexture(renderer, "resources/player.png");
texture_pool[ResID::Tex_Archer] = IMG_LoadTexture(renderer, "resources/tower_archer.png");
texture_pool[ResID::Tex_Axeman] = IMG_LoadTexture(renderer, "resources/tower_axeman.png");
texture_pool[ResID::Tex_Gunner] = IMG_LoadTexture(renderer, "resources/tower_gunner.png");
texture_pool[ResID::Tex_Slime] = IMG_LoadTexture(renderer, "resources/enemy_slime.png");
texture_pool[ResID::Tex_KingSlime] = IMG_LoadTexture(renderer, "resources/enemy_king_slime.png");
texture_pool[ResID::Tex_Skeleton] = IMG_LoadTexture(renderer, "resources/enemy_skeleton.png");
texture_pool[ResID::Tex_Goblin] = IMG_LoadTexture(renderer, "resources/enenmy_goblin.png");
texture_pool[ResID::Tex_GoblinPriest] = IMG_LoadTexture(renderer, "resources/enenmy_goblin_priest.png");
texture_pool[ResID::Tex_SlimeSketch] = IMG_LoadTexture(renderer, "resources/enenmy_slime_sketch.png");
texture_pool[ResID::Tex_KingSlimeSketch] = IMG_LoadTexture(renderer, "resources/enenmy_king_slime_sketch.png");
texture_pool[ResID::Tex_SkeletonSketch] = IMG_LoadTexture(renderer, "resources/enenmy_skeleton_sketch.png");
texture_pool[ResID::Tex_GoblinSketch] = IMG_LoadTexture(renderer, "resources/enenmy_goblin_sketch.png");
texture_pool[ResID::Tex_GoblinPriestSketch] = IMG_LoadTexture(renderer, "resources/enenmy_goblin_priest_sketch.png");
texture_pool[ResID::Tex_BulletArrow] = IMG_LoadTexture(renderer, "resources/bullet_arrow.png");
texture_pool[ResID::Tex_BulletAxe] = IMG_LoadTexture(renderer, "resources/bullet_axe.png");
texture_pool[ResID::Tex_BulletShell] = IMG_LoadTexture(renderer, "resources/bullet_shell.png");
texture_pool[ResID::Tex_Coin] = IMG_LoadTexture(renderer, "resources/coin.png");
texture_pool[ResID::Tex_Home] = IMG_LoadTexture(renderer, "resources/home.png");
texture_pool[ResID::Tex_EffectFlash_Up] = IMG_LoadTexture(renderer, "resources/effect_flash_up.png");
texture_pool[ResID::Tex_EffectFlash_Down] = IMG_LoadTexture(renderer, "resources/effect_flash_down.png");
texture_pool[ResID::Tex_EffectFlash_Left] = IMG_LoadTexture(renderer, "resources/effect_flash_left.png");
texture_pool[ResID::Tex_EffectFlash_Right] = IMG_LoadTexture(renderer, "resources/effect_flash_right.png");
texture_pool[ResID::Tex_EffectImpact_Up] = IMG_LoadTexture(renderer, "resources/effect_impact_up.png");
texture_pool[ResID::Tex_EffectImpact_Down] = IMG_LoadTexture(renderer, "resources/effect_impact_down.png");
texture_pool[ResID::Tex_EffectImpact_Left] = IMG_LoadTexture(renderer, "resources/effect_impact_left.png");
texture_pool[ResID::Tex_EffectImpact_Right] = IMG_LoadTexture(renderer, "resources/effect_impact_right.png");
texture_pool[ResID::Tex_EffectExplode] = IMG_LoadTexture(renderer, "resources/effect_explode.png");
texture_pool[ResID::Tex_UISelectCursor] = IMG_LoadTexture(renderer, "resources/ui_select_cursor.png");
texture_pool[ResID::Tex_UIPlaceIdle] = IMG_LoadTexture(renderer, "resources/ui_place_idle.png");
texture_pool[ResID::Tex_UIPlaceHoveredTop] = IMG_LoadTexture(renderer, "resources/ui_place_hovered_top.png");
texture_pool[ResID::Tex_UIPlaceHoveredLeft] = IMG_LoadTexture(renderer, "resources/ui_place_hovered_left.png");
texture_pool[ResID::Tex_UIPlaceHoveredRight] = IMG_LoadTexture(renderer, "resources/ui_place_hovered_right.png");
texture_pool[ResID::Tex_UIUpgradeIdle] = IMG_LoadTexture(renderer, "resources/ui_upgrade_idle.png");
texture_pool[ResID::Tex_UIUpgradeHoveredTop] = IMG_LoadTexture(renderer, "resources/ui_upgrade_hovered_top.png");
texture_pool[ResID::Tex_UIUpgradeHoveredLeft] = IMG_LoadTexture(renderer, "resources/ui_upgrade_hovered_left.png");
texture_pool[ResID::Tex_UIUpgradeHoveredRight] = IMG_LoadTexture(renderer, "resources/ui_upgrade_hovered_right.png");
texture_pool[ResID::Tex_UIHomeAvatar] = IMG_LoadTexture(renderer, "resources/ui_home_avatar.png");
texture_pool[ResID::Tex_UIPlayerAvatar] = IMG_LoadTexture(renderer, "resources/ui_player_avatar.png");
texture_pool[ResID::Tex_UIHeart] = IMG_LoadTexture(renderer, "resources/ui_heart.png");
texture_pool[ResID::Tex_UICoin] = IMG_LoadTexture(renderer, "resources/ui_coin.png");
texture_pool[ResID::Tex_UIGameOverBar] = IMG_LoadTexture(renderer, "resources/ui_game_over_bar.png");
texture_pool[ResID::Tex_UIWinText] = IMG_LoadTexture(renderer, "resources/ui_win_text.png");
texture_pool[ResID::Tex_UILossText] = IMG_LoadTexture(renderer, "resources/ui_loss_text.png");
for (const auto& pair : texture_pool)
if (!pair.second) return false;
sound_pool[ResID::Sound_ArrowFire_1] = Mix_LoadWAV("resources/sound_arrow_fire_1.mp3");
sound_pool[ResID::Sound_ArrowFire_2] = Mix_LoadWAV("resources/sound_arrow_fire_2.mp3");
sound_pool[ResID::Sound_AxeFire] = Mix_LoadWAV("resources/sound_axe_fire.wav");
sound_pool[ResID::Sound_ShellFire] = Mix_LoadWAV("resources/sound_shell_fire.wav");
sound_pool[ResID::Sound_ArrowHit_1] = Mix_LoadWAV("resources/sound_arrow_hit_1.mp3");
sound_pool[ResID::Sound_ArrowHit_2] = Mix_LoadWAV("resources/sound_arrow_hit_2.mp3");
sound_pool[ResID::Sound_ArrowHit_3] = Mix_LoadWAV("resources/sound_arrow_hit_3.mp3");
sound_pool[ResID::Sound_AxeHit_1] = Mix_LoadWAV("resources/sound_axe_hit_1.mp3");
sound_pool[ResID::Sound_AxeHit_2] = Mix_LoadWAV("resources/sound_axe_hit_2.mp3");
sound_pool[ResID::Sound_AxeHit_3] = Mix_LoadWAV("resources/sound_axe_hit_3.mp3");
sound_pool[ResID::Sound_ShellHit] = Mix_LoadWAV("resources/sound_shell_hit.mp3");
sound_pool[ResID::Sound_Flash] = Mix_LoadWAV("resources/sound_flash.wav");
sound_pool[ResID::Sound_Impact] = Mix_LoadWAV("resources/sound_impact.wav");
sound_pool[ResID::Sound_Coin] = Mix_LoadWAV("resources/sound_coin.mp3");
sound_pool[ResID::Sound_HomeHurt] = Mix_LoadWAV("resources/sound_home_hurt.wav");
sound_pool[ResID::Sound_PlaceTower] = Mix_LoadWAV("resources/sound_place_tower.mp3");
sound_pool[ResID::Sound_TowerLevelUp] = Mix_LoadWAV("resources/sound_tower_level_up.mp3");
sound_pool[ResID::Sound_Win] = Mix_LoadWAV("resources/sound_win.wav");
sound_pool[ResID::Sound_Loss] = Mix_LoadWAV("resources/sound_loss.mp3");
for (const auto& pair : sound_pool)
if (!pair.second) return false;
music_pool[ResID::Music_BGM] = Mix_LoadMUS("resources/music_bgm.mp3");
for (const auto& pair : music_pool)
if (!pair.second) return false;
font_pool[ResID::Font_Main] = TTF_OpenFont("resources/ipix.ttf", 25);
for (const auto& pair : font_pool)
if (!pair.second) return false;
return true;
}
const FontPool& get_font_pool()
{
return font_pool;
}
const SoundPool& get_sound_pool()
{
return sound_pool;
}
const MusicPool& get_music_pool()
{
return music_pool;
}
const TexturePool& get_texture_pool()
{
return texture_pool;
}
protected:
ResourcesManager() = default;
~ResourcesManager() = default;
private:
//避免外部对资源池进行修改,设计成私有
FontPool font_pool;
SoundPool sound_pool;
MusicPool music_pool;
TexturePool texture_pool;
};
#endif