diff --git a/TdGame/TdGame.vcxproj b/TdGame/TdGame.vcxproj index 540f032..30ea2dd 100644 --- a/TdGame/TdGame.vcxproj +++ b/TdGame/TdGame.vcxproj @@ -120,6 +120,7 @@ true MultiThreaded ..\ThirdParty\cJSON\include;..\ThirdParty\SDL2\include;..\ThirdParty\SDL2_gfx\include;..\ThirdParty\SDL2_image\include;..\ThirdParty\SDL2_mixer\include;..\ThirdParty\SDL2_ttf\include;%(AdditionalIncludeDirectories) + ProgramDatabase Console @@ -131,6 +132,7 @@ + diff --git a/TdGame/TdGame.vcxproj.filters b/TdGame/TdGame.vcxproj.filters index 4a0717c..bf9807c 100644 --- a/TdGame/TdGame.vcxproj.filters +++ b/TdGame/TdGame.vcxproj.filters @@ -19,11 +19,17 @@ {d16b420a-6329-4705-af2a-57caf4eee0e9} + + {26456ec2-6d40-4a7f-9935-8248edc2bef2} + 源文件 + + 源文件\cJSON + diff --git a/TdGame/config_manager.h b/TdGame/config_manager.h index c72a839..79b8f98 100644 --- a/TdGame/config_manager.h +++ b/TdGame/config_manager.h @@ -90,6 +90,7 @@ public: bool load_level_config(const std::string& path) { std::ifstream file(path); + if (!file.good())return false; std::stringstream str_stream; @@ -97,8 +98,8 @@ public: 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); @@ -108,7 +109,7 @@ public: cJSON* json_wave = nullptr; cJSON_ArrayForEach(json_wave, json_root) { - if (json_wave->type != cJSON_Array) + if (json_wave->type != cJSON_Object) continue; wave_list.emplace_back();//ĩβһ󣬲ôõǶ͵ĬϹ캯 @@ -128,7 +129,7 @@ public: cJSON* json_spawn_event = nullptr; cJSON_ArrayForEach(json_spawn_event, json_wave_spawn_list) { - if (json_spawn_event->type != cJSON_Array) + if (json_spawn_event->type != cJSON_Object) continue; wave.spawn_event_list.emplace_back(); @@ -144,10 +145,10 @@ public: 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; + if (str_enemy_type == "Slime") + spawn_event.enemy_type = EnemyType::Slime; + else if(str_enemy_type == "KingSlime") + spawn_event.enemy_type = EnemyType::KingSlime; else if (str_enemy_type == "Skeleton") spawn_event.enemy_type = EnemyType::Skeleton; else if (str_enemy_type == "Goblin") @@ -163,6 +164,7 @@ public: } cJSON_Delete(json_root); + if (wave_list.empty()) return false; @@ -174,7 +176,7 @@ public: bool load_game_config(const std::string& path) { std::ifstream file(path); - if (file.good()) return false; + if (!file.good()) return false; std::stringstream str_stream; str_stream << file.rdbuf(); diff --git a/TdGame/enemy_type.h b/TdGame/enemy_type.h index 07fb959..62c8912 100644 --- a/TdGame/enemy_type.h +++ b/TdGame/enemy_type.h @@ -4,8 +4,8 @@ enum class EnemyType { - Slim, - KingSlim, + Slime, + KingSlime, Skeleton, Goblin, GoblinPriest diff --git a/TdGame/game_manager.h b/TdGame/game_manager.h index e75dd4e..49e3e85 100644 --- a/TdGame/game_manager.h +++ b/TdGame/game_manager.h @@ -3,6 +3,8 @@ #define _GAME_MANAGER_H_ #include "manager.h" +#include "config_manager.h" +#include "resources_manager.h" #include #include @@ -61,13 +63,25 @@ protected: SDL_SetHint(SDL_HINT_IME_SHOW_UI,"1"); - window = SDL_CreateWindow(u8"ׯս", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_SHOWN); + ConfigManager* config = ConfigManager::instance(); + + init_assert(config->map.load("map.csv"), u8"Ϸͼʧܣ"); + init_assert(config->load_level_config("level.json"), u8"عؿʧܣ"); + init_assert(config->load_game_config("config.json"), u8"Ϸʧܣ"); + + window = SDL_CreateWindow(config->basic_template.window_title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + config->basic_template.window_width, config->basic_template.window_height, SDL_WINDOW_SHOWN); init_assert(window, u8"Ϸʧܣ"); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE); init_assert(renderer, u8"Ⱦʧܣ"); + init_assert(ResourcesManager::instance()->load_from_file(renderer), u8"ϷԴʧܣ"); + + init_assert(generate_tile_map_texture(),u8"Ƭͼʧܣ"); + } + ~GameManager() { SDL_DestroyRenderer(renderer); @@ -86,6 +100,8 @@ private: SDL_Window* window = nullptr; SDL_Renderer* renderer = nullptr; + SDL_Texture* tex_tile_map = nullptr; + private: void init_assert(bool flag, const char* err_msg) { @@ -107,7 +123,94 @@ private: void on_render() { + static ConfigManager* instance = ConfigManager::instance(); + static SDL_Rect& rect_dst = instance->rect_tile_map; + SDL_RenderCopy(renderer, tex_tile_map, nullptr, &rect_dst); + } + bool generate_tile_map_texture() + { + const Map& map = ConfigManager::instance()->map; + const TileMap& tile_map = map.get_tile_map(); + SDL_Rect& rect_tile_map = ConfigManager::instance()->rect_tile_map; + SDL_Texture* tex_tile_set = ResourcesManager::instance()->get_texture_pool().find(ResID::Tex_Tileset)->second; + + int width_tex_tile_set, height_tex_tile_set; + SDL_QueryTexture(tex_tile_set, nullptr, nullptr, &width_tex_tile_set, &height_tex_tile_set);//Ⱥ͸߶ȴ洢ȥ + int num_tile_single_line = (int)std::ceil((double)width_tex_tile_set / SIZE_TILE);//ȡһжٵԪ + + //ͼ + int width_tex_tile_map, height_tex_tile_map; + width_tex_tile_map = (int)map.get_width() * SIZE_TILE; + height_tex_tile_map = (int)map.get_height() * SIZE_TILE; + + //˵ԱrendererƣҸʽǵڶ + tex_tile_map = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, + SDL_TEXTUREACCESS_TARGET, width_tex_tile_map, height_tex_tile_map); + if (!tex_tile_map)return false; + + //ɵͼƬrect_tile_map + ConfigManager* config = ConfigManager::instance(); + rect_tile_map.x = (config->basic_template.window_width - width_tex_tile_map) / 2;//ϽǶ꣬Ϊϣڴм䣡 + rect_tile_map.y = (config->basic_template.window_height - height_tex_tile_map) / 2; + rect_tile_map.w = width_tex_tile_map; + rect_tile_map.h = height_tex_tile_map;//ȾĿreact; + + //Ļģʽ + SDL_SetTextureBlendMode(tex_tile_map, SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(renderer, tex_tile_map); + + for (int y = 0; y < map.get_height(); y++) + { + for (int x = 0; x < map.get_width(); x++) + { + //Դزľ + SDL_Rect rect_src; + const Tile& tile = tile_map[y][x]; + + //Ŀλþ + const SDL_Rect& rect_dst = + { + x * SIZE_TILE,y * SIZE_TILE, //x,y + SIZE_TILE,SIZE_TILE // + }; + + //ҪüزĿ + rect_src = + { + (tile.terrian % num_tile_single_line) * SIZE_TILE,//ƹ + (tile.terrian / num_tile_single_line) * SIZE_TILE, + SIZE_TILE,SIZE_TILE + }; + SDL_RenderCopy(renderer, tex_tile_set, &rect_src, &rect_dst);//β + + //жװǷ + if (tile.decoration >= 0) + { + rect_src = + { + (tile.decoration % num_tile_single_line) * SIZE_TILE, + (tile.decoration / num_tile_single_line) * SIZE_TILE, + SIZE_TILE,SIZE_TILE + }; + SDL_RenderCopy(renderer, tex_tile_set, &rect_src, &rect_dst);//װ + } + } + } + + //Ŀ꣨ӣ + const SDL_Point& idx_home = map.get_idx_home(); + const SDL_Rect& rect_dst = + { + idx_home.x * SIZE_TILE, idx_home.y * SIZE_TILE, + SIZE_TILE,SIZE_TILE + }; + SDL_RenderCopy(renderer, ResourcesManager::instance()->get_texture_pool().find(ResID::Tex_Home)->second, nullptr, &rect_dst); + + //һҪûؿ + SDL_SetRenderTarget(renderer, nullptr); + + return true; } }; diff --git a/TdGame/level.json b/TdGame/level.json index fe2be1e..dd52a0c 100644 --- a/TdGame/level.json +++ b/TdGame/level.json @@ -4,11 +4,11 @@ "spawn_list": [{ "interval": 1, "point": 1, - "enemy": "Slim" + "enemy": "Slime" }, { "interval": 1, "point": 2, - "enemy": "KingSlim" + "enemy": "KingSlime" }, { "interval": 1, "point": 1, @@ -28,7 +28,7 @@ "spawn_list": [{ "interval": 3, "point": 2, - "enemy": "KingSlim" + "enemy": "KingSlime" }] }] diff --git a/TdGame/map.h b/TdGame/map.h index 533e9eb..9bd3f33 100644 --- a/TdGame/map.h +++ b/TdGame/map.h @@ -32,7 +32,7 @@ public: std::string str_line; while (std::getline(file, str_line)) { - str_line = trim_str(str_line); + str_line = trim_str(str_line);//ȥ˿հַԶ庯 if (str_line.empty()) continue; //ΪգһУidx_x-1 @@ -45,7 +45,7 @@ public: { idx_x++;//idx_x++ȥұһƬ tile_map_temp[idx_y].emplace_back();//idx_yƬ - Tile& tile = tile_map_temp[idx_y].back();//ȡƬ Tile& tile = tile_map_temp[idx_y].back() Ա + Tile& tile = tile_map_temp[idx_y].back();//ȡƬ,Ա load_tile_from_string(tile,str_tile); } @@ -162,12 +162,12 @@ private: if (tile.special_flag == 0)//Ƿݣ1234ˢֵ { - idx_home.x == x; - idx_home.y == y; + idx_home.x = x; + idx_home.y = y; } else { - spawner_route_pool[tile.special_flag] = Route(tile_map, { x, y }); + spawner_route_pool[tile.special_flag] = Route(tile_map, { x,y }); } } } diff --git a/TdGame/resources_manager.h b/TdGame/resources_manager.h index b019756..14aa290 100644 --- a/TdGame/resources_manager.h +++ b/TdGame/resources_manager.h @@ -1,3 +1,4 @@ +#pragma once #ifndef _RESOURCES_MANAGER_H_ #define _RESOURCES_MANAGER_H_ @@ -116,13 +117,13 @@ public: 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_Goblin] = IMG_LoadTexture(renderer, "resources/enemy_goblin.png"); + texture_pool[ResID::Tex_GoblinPriest] = IMG_LoadTexture(renderer, "resources/enemy_goblin_priest.png"); + texture_pool[ResID::Tex_SlimeSketch] = IMG_LoadTexture(renderer, "resources/enemy_slime_sketch.png"); + texture_pool[ResID::Tex_KingSlimeSketch] = IMG_LoadTexture(renderer, "resources/enemy_king_slime_sketch.png"); + texture_pool[ResID::Tex_SkeletonSketch] = IMG_LoadTexture(renderer, "resources/enemy_skeleton_sketch.png"); + texture_pool[ResID::Tex_GoblinSketch] = IMG_LoadTexture(renderer, "resources/enemy_goblin_sketch.png"); + texture_pool[ResID::Tex_GoblinPriestSketch] = IMG_LoadTexture(renderer, "resources/enemy_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"); @@ -195,10 +196,9 @@ public: font_pool[ResID::Font_Main] = TTF_OpenFont("resources/ipix.ttf", 25); for (const auto& pair : font_pool) - if (!pair.second) return false; + if (!pair.second) return false; return true; - } const FontPool& get_font_pool() diff --git a/TdGame/route.h b/TdGame/route.h index e5da78d..a8b1093 100644 --- a/TdGame/route.h +++ b/TdGame/route.h @@ -16,7 +16,7 @@ public: Route() = default; //вι캯 - Route(const TileMap& map,SDL_Point& idx_origin) + Route(const TileMap& map,const SDL_Point& idx_origin) { size_t width_map = map[0].size(); size_t height_map = map.size(); @@ -83,4 +83,5 @@ private: return false; } }; + #endif \ No newline at end of file diff --git a/TdGame/tile.h b/TdGame/tile.h index fa52c88..d1b308d 100644 --- a/TdGame/tile.h +++ b/TdGame/tile.h @@ -4,7 +4,7 @@ #include -#define SIZE_TILE = 48 +#define SIZE_TILE 48 //ֻûзṹȽϺ struct Tile diff --git a/TdGame/wave.h b/TdGame/wave.h index e16fd11..4537d93 100644 --- a/TdGame/wave.h +++ b/TdGame/wave.h @@ -13,7 +13,7 @@ struct Wave { double interval = 0; int spawn_point = 1; - EnemyType enemy_type = EnemyType::Slim;//level.jsonļмʽ,ļ + EnemyType enemy_type = EnemyType::Slime;//level.jsonļмʽ,ļ }; double rewards = 0;