①关卡波次配置解析②角色属性配置文件解析③ResourcesManager游戏资源管理器设计
@ -87,7 +87,7 @@ int main()
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
|
||||
|
||||
//加载图像并创建纹理
|
||||
SDL_Surface* suf_img = IMG_Load("avatar.jpg");
|
||||
SDL_Surface* suf_img = IMG_Load("avatar.jpg");
|
||||
SDL_Texture* tex_img = SDL_CreateTextureFromSurface(renderer,suf_img);
|
||||
|
||||
TTF_Font* font = TTF_OpenFont("ipix.ttf", 32);
|
||||
|
@ -139,6 +139,7 @@
|
||||
<ClInclude Include="game_manager.h" />
|
||||
<ClInclude Include="manager.h" />
|
||||
<ClInclude Include="map.h" />
|
||||
<ClInclude Include="resources_manager.h" />
|
||||
<ClInclude Include="route.h" />
|
||||
<ClInclude Include="tile.h" />
|
||||
<ClInclude Include="wave.h" />
|
||||
|
@ -50,5 +50,8 @@
|
||||
<ClInclude Include="enemy_type.h">
|
||||
<Filter>头文件\enemy</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resources_manager.h">
|
||||
<Filter>头文件\manager</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -42,7 +42,7 @@
|
||||
},
|
||||
"enemy":
|
||||
{
|
||||
"slim":
|
||||
"slime":
|
||||
{
|
||||
"hp": 20,
|
||||
"speed": 1,
|
||||
@ -52,7 +52,7 @@
|
||||
"recover_range": -1,
|
||||
"recover_intensity": 10
|
||||
},
|
||||
"king_slim":
|
||||
"king_slime":
|
||||
{
|
||||
"hp": 75,
|
||||
"speed": 0.75,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <cJSON.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
//作为全局数据配置中心
|
||||
|
||||
@ -67,15 +68,15 @@ public:
|
||||
bool is_game_over = false;//游戏是否结束,和上面是两个不同层面的条件,需要分析
|
||||
SDL_Rect rect_tile_map = { 0 };
|
||||
|
||||
BasicTemplate basci_template;
|
||||
BasicTemplate basic_template;
|
||||
PlayerTemplate player_template;
|
||||
|
||||
TowerTemplate archer_template;
|
||||
TowerTemplate axeman_template;
|
||||
TowerTemplate gunner_template;
|
||||
|
||||
EnemyTemplate slim_template;
|
||||
EnemyTemplate king_slim_template;
|
||||
EnemyTemplate slime_template;
|
||||
EnemyTemplate king_slime_template;
|
||||
EnemyTemplate skeleton_template;
|
||||
EnemyTemplate goblin_template;
|
||||
EnemyTemplate goblin_priest_template;
|
||||
@ -88,20 +89,236 @@ public:
|
||||
//加载波次配置 level.json
|
||||
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
|
||||
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:
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // !_CONFIG_MANAGER_H_
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
class GameManager : public Manager<GameManager>
|
||||
{
|
||||
|
||||
friend class Manager<GameManager>;
|
||||
|
||||
public:
|
||||
|
@ -8,5 +8,5 @@
|
||||
|
||||
int main(int argc,char**argv)
|
||||
{
|
||||
return GameManager::instance()->run(argc, argv);;
|
||||
return GameManager::instance()->run(argc, argv);
|
||||
}
|
BIN
TdGame/resources/bullet_arrow.png
Normal file
After Width: | Height: | Size: 668 B |
BIN
TdGame/resources/bullet_axe.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
TdGame/resources/bullet_shell.png
Normal file
After Width: | Height: | Size: 634 B |
BIN
TdGame/resources/coin.png
Normal file
After Width: | Height: | Size: 422 B |
BIN
TdGame/resources/effect_explode.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
TdGame/resources/effect_flash_down.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
TdGame/resources/effect_flash_left.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
TdGame/resources/effect_flash_right.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
TdGame/resources/effect_flash_up.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
TdGame/resources/effect_impact_down.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
TdGame/resources/effect_impact_left.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
TdGame/resources/effect_impact_right.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
TdGame/resources/effect_impact_up.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
TdGame/resources/enemy_goblin.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
TdGame/resources/enemy_goblin_priest.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
TdGame/resources/enemy_goblin_priest_sketch.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
TdGame/resources/enemy_goblin_sketch.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
TdGame/resources/enemy_king_slime.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
TdGame/resources/enemy_king_slime_sketch.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
TdGame/resources/enemy_skeleton.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
TdGame/resources/enemy_skeleton_sketch.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
TdGame/resources/enemy_slime.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
TdGame/resources/enemy_slime_sketch.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
TdGame/resources/home.png
Normal file
After Width: | Height: | Size: 610 B |
BIN
TdGame/resources/ipix.ttf
Normal file
BIN
TdGame/resources/music_bgm.mp3
Normal file
BIN
TdGame/resources/player.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
TdGame/resources/sound_arrow_fire_1.mp3
Normal file
BIN
TdGame/resources/sound_arrow_fire_2.mp3
Normal file
BIN
TdGame/resources/sound_arrow_hit_1.mp3
Normal file
BIN
TdGame/resources/sound_arrow_hit_2.mp3
Normal file
BIN
TdGame/resources/sound_arrow_hit_3.mp3
Normal file
BIN
TdGame/resources/sound_axe_fire.wav
Normal file
BIN
TdGame/resources/sound_axe_hit_1.mp3
Normal file
BIN
TdGame/resources/sound_axe_hit_2.mp3
Normal file
BIN
TdGame/resources/sound_axe_hit_3.mp3
Normal file
BIN
TdGame/resources/sound_coin.mp3
Normal file
BIN
TdGame/resources/sound_flash.wav
Normal file
BIN
TdGame/resources/sound_home_hurt.wav
Normal file
BIN
TdGame/resources/sound_impact.wav
Normal file
BIN
TdGame/resources/sound_loss.mp3
Normal file
BIN
TdGame/resources/sound_place_tower.mp3
Normal file
BIN
TdGame/resources/sound_shell_fire.wav
Normal file
BIN
TdGame/resources/sound_shell_hit.mp3
Normal file
BIN
TdGame/resources/sound_tower_level_up.mp3
Normal file
BIN
TdGame/resources/sound_win.wav
Normal file
BIN
TdGame/resources/tileset.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
TdGame/resources/tower_archer.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
TdGame/resources/tower_axeman.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
TdGame/resources/tower_gunner.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
TdGame/resources/ui_coin.png
Normal file
After Width: | Height: | Size: 554 B |
BIN
TdGame/resources/ui_game_over_bar.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
TdGame/resources/ui_heart.png
Normal file
After Width: | Height: | Size: 477 B |
BIN
TdGame/resources/ui_home_avatar.png
Normal file
After Width: | Height: | Size: 834 B |
BIN
TdGame/resources/ui_loss_text.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
TdGame/resources/ui_place_hovered_left.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
TdGame/resources/ui_place_hovered_right.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
TdGame/resources/ui_place_hovered_top.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
TdGame/resources/ui_place_idle.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
TdGame/resources/ui_player_avatar.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
TdGame/resources/ui_select_cursor.png
Normal file
After Width: | Height: | Size: 386 B |
BIN
TdGame/resources/ui_upgrade_hovered_left.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
TdGame/resources/ui_upgrade_hovered_right.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
TdGame/resources/ui_upgrade_hovered_top.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
TdGame/resources/ui_upgrade_idle.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
TdGame/resources/ui_win_text.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
234
TdGame/resources_manager.h
Normal 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
|