feat: 瓦片类实现,Map类地图数据加载,地图缓存生成
This commit is contained in:
parent
fa0770dfae
commit
3c10a01c69
@ -136,6 +136,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="game_manager.h" />
|
<ClInclude Include="game_manager.h" />
|
||||||
<ClInclude Include="manager.h" />
|
<ClInclude Include="manager.h" />
|
||||||
|
<ClInclude Include="map.h" />
|
||||||
|
<ClInclude Include="tile.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -29,5 +29,11 @@
|
|||||||
<ClInclude Include="manager.h">
|
<ClInclude Include="manager.h">
|
||||||
<Filter>头文件\manager</Filter>
|
<Filter>头文件\manager</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="tile.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="map.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
96
TdGame/config.json
Normal file
96
TdGame/config.json
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
{
|
||||||
|
"basic":
|
||||||
|
{
|
||||||
|
"window_title": "村庄保卫战!",
|
||||||
|
"window_width": 1280,
|
||||||
|
"window_height": 720
|
||||||
|
},
|
||||||
|
"player":
|
||||||
|
{
|
||||||
|
"speed": 5,
|
||||||
|
"normal_attack_interval": 0.5,
|
||||||
|
"normal_attack_damage": 10,
|
||||||
|
"skill_interval": 10,
|
||||||
|
"skill_damage": 5
|
||||||
|
},
|
||||||
|
"tower":
|
||||||
|
{
|
||||||
|
"archer":
|
||||||
|
{
|
||||||
|
"interval": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
"damage": [5, 1, 1, 1, 10, 10, 10, 10, 10, 10],
|
||||||
|
"view_range": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
|
||||||
|
"cost": [10, 2, 2, 10, 10, 10, 10, 10, 10, 10],
|
||||||
|
"upgrade_cost": [10, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||||
|
},
|
||||||
|
"axeman":
|
||||||
|
{
|
||||||
|
"interval": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||||
|
"damage": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
||||||
|
"view_range": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
|
||||||
|
"cost": [20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
|
||||||
|
"upgrade_cost": [10, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||||
|
},
|
||||||
|
"gunner":
|
||||||
|
{
|
||||||
|
"interval": [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
|
||||||
|
"damage": [20, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
||||||
|
"view_range": [5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
|
||||||
|
"cost": [30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
|
||||||
|
"upgrade_cost": [10, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enemy":
|
||||||
|
{
|
||||||
|
"slim":
|
||||||
|
{
|
||||||
|
"hp": 20,
|
||||||
|
"speed": 1,
|
||||||
|
"damage": 1,
|
||||||
|
"reward_ratio": 0.8,
|
||||||
|
"recover_interval": 100,
|
||||||
|
"recover_range": -1,
|
||||||
|
"recover_intensity": 10
|
||||||
|
},
|
||||||
|
"king_slim":
|
||||||
|
{
|
||||||
|
"hp": 75,
|
||||||
|
"speed": 0.75,
|
||||||
|
"damage": 1,
|
||||||
|
"reward_ratio": 1,
|
||||||
|
"recover_interval": 100,
|
||||||
|
"recover_range": -1,
|
||||||
|
"recover_intensity": 10
|
||||||
|
},
|
||||||
|
"skeleton":
|
||||||
|
{
|
||||||
|
"hp": 40,
|
||||||
|
"speed": 1.5,
|
||||||
|
"damage": 1,
|
||||||
|
"reward_ratio": 1,
|
||||||
|
"recover_interval": 100,
|
||||||
|
"recover_range": -1,
|
||||||
|
"recover_intensity": 10
|
||||||
|
},
|
||||||
|
"goblin":
|
||||||
|
{
|
||||||
|
"hp": 50,
|
||||||
|
"speed": 1.5,
|
||||||
|
"damage": 1,
|
||||||
|
"reward_ratio": 1,
|
||||||
|
"recover_interval": 100,
|
||||||
|
"recover_range": -1,
|
||||||
|
"recover_intensity": 10
|
||||||
|
},
|
||||||
|
"goblin_priest":
|
||||||
|
{
|
||||||
|
"hp": 100,
|
||||||
|
"speed": 0.75,
|
||||||
|
"damage": 1,
|
||||||
|
"reward_ratio": 1,
|
||||||
|
"recover_interval": 10,
|
||||||
|
"recover_range": 5,
|
||||||
|
"recover_intensity": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,19 +4,109 @@
|
|||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_ttf.h>
|
||||||
|
#include<SDL_image.h>
|
||||||
|
#include<SDL_mixer.h>
|
||||||
|
|
||||||
|
|
||||||
class GameManager : public Manager<GameManager>
|
class GameManager : public Manager<GameManager>
|
||||||
{
|
{
|
||||||
friend class Manager<GameManager>;
|
friend class Manager<GameManager>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int run(int argc,char** argv)
|
||||||
|
{
|
||||||
|
Uint64 last_counter = SDL_GetPerformanceCounter();
|
||||||
|
const Uint64 counter_freq = SDL_GetPerformanceFrequency();
|
||||||
|
|
||||||
|
while (!is_quit)
|
||||||
|
{
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
on_input();
|
||||||
|
|
||||||
|
|
||||||
|
Uint64 current_counter = SDL_GetPerformanceCounter();
|
||||||
|
double delta = (double)(current_counter - last_counter) / counter_freq;
|
||||||
|
last_counter = current_counter;
|
||||||
|
if (delta * 1000 < 1000.0 / 60)
|
||||||
|
SDL_Delay(Uint32(1000.0 / 60 - delta * 1000));
|
||||||
|
|
||||||
|
//更新数据
|
||||||
|
on_update(delta);
|
||||||
|
|
||||||
|
//绘制画面
|
||||||
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
on_render();
|
||||||
|
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GameManager()
|
GameManager()
|
||||||
{
|
{
|
||||||
|
init_assert(!SDL_Init(SDL_INIT_EVERYTHING),u8"SDL2 初始化失败!");
|
||||||
|
init_assert(IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG), u8"SDL_image 初始化失败!");
|
||||||
|
init_assert(Mix_Init(MIX_INIT_MP3), u8"SDL_mixer 初始化失败!");
|
||||||
|
init_assert(!TTF_Init(), u8"SDL_ttf 初始化失败!");
|
||||||
|
|
||||||
|
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_IME_SHOW_UI,"1");
|
||||||
|
|
||||||
|
window = SDL_CreateWindow(u8"村庄保卫战", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, 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"创建渲染器失败!");
|
||||||
|
|
||||||
}
|
}
|
||||||
~GameManager()
|
~GameManager()
|
||||||
{
|
{
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
|
||||||
|
TTF_Quit();
|
||||||
|
Mix_Quit();
|
||||||
|
IMG_Quit();
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDL_Event event;
|
||||||
|
bool is_quit = false;
|
||||||
|
|
||||||
|
SDL_Window* window = nullptr;
|
||||||
|
SDL_Renderer* renderer = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init_assert(bool flag, const char* err_msg)
|
||||||
|
{
|
||||||
|
if (flag) return;
|
||||||
|
|
||||||
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, u8"游戏启动失败!", err_msg, window);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_input()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_update(double delta)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_render()
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
35
TdGame/level.json
Normal file
35
TdGame/level.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[{
|
||||||
|
"interval": 1,
|
||||||
|
"rewards": 100,
|
||||||
|
"spawn_list": [{
|
||||||
|
"interval": 1,
|
||||||
|
"point": 1,
|
||||||
|
"enemy": "Slim"
|
||||||
|
}, {
|
||||||
|
"interval": 1,
|
||||||
|
"point": 2,
|
||||||
|
"enemy": "KingSlim"
|
||||||
|
}, {
|
||||||
|
"interval": 1,
|
||||||
|
"point": 1,
|
||||||
|
"enemy": "Goblin"
|
||||||
|
}, {
|
||||||
|
"interval": 1,
|
||||||
|
"point": 2,
|
||||||
|
"enemy": "GoblinPriest"
|
||||||
|
}, {
|
||||||
|
"interval": 1,
|
||||||
|
"point": 1,
|
||||||
|
"enemy": "Skeleton"
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"interval": 3,
|
||||||
|
"rewards": 100,
|
||||||
|
"spawn_list": [{
|
||||||
|
"interval": 3,
|
||||||
|
"point": 2,
|
||||||
|
"enemy": "KingSlim"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
|||||||
|
#define SDL_MAIN_HANDLED
|
||||||
#include<iostream>
|
#include<iostream>
|
||||||
|
|
||||||
#include "manager.h"
|
|
||||||
#include "game_manager.h"
|
#include "game_manager.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main(int argc,char**argv)
|
||||||
{
|
{
|
||||||
GameManager* instance = GameManager::instance();
|
return GameManager::instance()->run(argc, argv);;
|
||||||
|
|
||||||
std::cout << "Hello World!" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
15
TdGame/map.csv
Normal file
15
TdGame/map.csv
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,3\-1\4\1,3\-1\4\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\4\-1,3\-1\4\-1,3\-1\4\-1,3\-1\4\-1,3\-1\4\-1,3\-1\4\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,4\-1\2\-1,3\-1\3\-1,3\-1\3\-1,4\-1\3\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\54\0\-1,0\54\0\-1,0\29\0\-1,4\-1\2\-1,0\29\0\-1,0\54\0\-1,0\54\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\54\0\-1,4\128\0\-1,5\-1\0\-1,3\-1\2\-1,5\-1\0\-1,4\128\0\-1,0\54\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\53\0\-1,3\-1\0\-1,3\-1\0\-1,5\-1\0\0,3\-1\0\-1,3\-1\0\-1,0\53\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\53\0\-1,0\53\0\-1,5\-1\0\-1,4\-1\1\-1,5\-1\0\-1,0\53\0\-1,0\53\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\285\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,3\-1\3\-1,3\-1\3\-1,3\-1\3\-1,3\-1\3\-1,3\-1\3\-1,4\-1\3\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\2\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,26\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\4\-1,3\-1\4\-1,3\-1\4\-1,4\-1\1\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,27\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,4\-1\1\-1,3\-1\3\-1,3\-1\3\2,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
||||||
|
0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1,0\-1\0\-1
|
|
142
TdGame/map.h
Normal file
142
TdGame/map.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _MAP_H_
|
||||||
|
#define _MAP_H_
|
||||||
|
|
||||||
|
#include "tile.h"
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
class Map
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Map() = default;
|
||||||
|
~Map() = default;
|
||||||
|
|
||||||
|
bool load(const std::string& path)
|
||||||
|
{
|
||||||
|
std::ifstream file(path);
|
||||||
|
if (!file.good())return false;
|
||||||
|
|
||||||
|
TileMap tile_map_temp;
|
||||||
|
|
||||||
|
int idx_x = -1, idx_y = -1;//瓦片位置索引
|
||||||
|
|
||||||
|
std::string str_line;
|
||||||
|
while (std::getline(file, str_line))
|
||||||
|
{
|
||||||
|
str_line = trim_str(str_line);
|
||||||
|
if (str_line.empty())
|
||||||
|
continue;
|
||||||
|
//如果不为空,则进入下一行,将idx_x置-1
|
||||||
|
idx_x = -1, idx_y++;
|
||||||
|
tile_map_temp.emplace_back();//在二维容器添加新行
|
||||||
|
|
||||||
|
std::string str_tile;
|
||||||
|
std::stringstream str_stream(str_line);
|
||||||
|
while (std::getline(str_stream, str_tile, ','))//按逗号分隔符处理单个瓦片数据
|
||||||
|
{
|
||||||
|
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() 以便后续操作。
|
||||||
|
|
||||||
|
load_tile_from_string(tile,str_tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
//解决极端情况,地图空空
|
||||||
|
if (tile_map_temp.empty() || tile_map_temp[0].empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tile_map = tile_map_temp;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_width() const //const不会对类内进行修改
|
||||||
|
{
|
||||||
|
if (tile_map.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return tile_map[0].size();//一行大小(宽度)
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_height() const
|
||||||
|
{
|
||||||
|
return tile_map.size();//行数量(高度)
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TileMap tile_map;
|
||||||
|
SDL_Point idx_home = { 0 };
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//一个去除字符串前后空格和制表符的函数
|
||||||
|
std::string trim_str(const std::string& str)
|
||||||
|
{
|
||||||
|
size_t begin_idx = str.find_first_not_of(" \t");
|
||||||
|
if (begin_idx == std::string::npos)
|
||||||
|
return "";
|
||||||
|
size_t end_idx = str.find_last_not_of(" \t");
|
||||||
|
size_t idx_range = end_idx - begin_idx + 1;
|
||||||
|
|
||||||
|
return str.substr(begin_idx, idx_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
//解析单元格中字符串的内容
|
||||||
|
void load_tile_from_string(Tile& tile, const std::string& str)
|
||||||
|
{
|
||||||
|
std::string str_tidy = trim_str(str);
|
||||||
|
|
||||||
|
std::string str_value;
|
||||||
|
std::vector<int> values;
|
||||||
|
std::stringstream str_stream(str_tidy);
|
||||||
|
|
||||||
|
while (std::getline(str_stream, str_value, '\\'))
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = std::stoi(str_value); //将n进制的字符串转化为十进制, 遇到非数字字符报错
|
||||||
|
} //例如,stoi(str, 0, 2); 将字符串 str 从 0 位置之后的数字的 2 进制数,转换为十进制
|
||||||
|
catch (const std::invalid_argument&)
|
||||||
|
{
|
||||||
|
value = -1;
|
||||||
|
}
|
||||||
|
values.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.terrian = (values.size() < 1 || values[0] < 0) ? 0 : values[0];
|
||||||
|
tile.decoration = (values.size() < 2) ? -1 : values[1];
|
||||||
|
tile.direction = (Tile::Direction)((values.size() < 3 || values[2] < 0) ? 0 : values[2]);
|
||||||
|
tile.special_flag = (values.size() <= 3) ? -1 : values[3];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//生成地图缓存
|
||||||
|
void generate_map_cache()
|
||||||
|
{
|
||||||
|
for (int y = 0; y < get_height(); y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < get_width(); x++)
|
||||||
|
{
|
||||||
|
const Tile& tile = tile_map[y][x];
|
||||||
|
if (tile.special_flag < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tile.special_flag == 0)
|
||||||
|
{
|
||||||
|
idx_home.x == x;
|
||||||
|
idx_home.y == y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
30
TdGame/tile.h
Normal file
30
TdGame/tile.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _TILE_H_
|
||||||
|
#define _TILE_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define SIZE_TILE = 48
|
||||||
|
|
||||||
|
//只有数据没有方法,结构体比较好
|
||||||
|
struct Tile
|
||||||
|
{
|
||||||
|
enum class Direction
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
};
|
||||||
|
|
||||||
|
int terrian = 0;
|
||||||
|
int decoration = -1;
|
||||||
|
int special_flag = -1;
|
||||||
|
bool has_tower = false;
|
||||||
|
Direction direction = Direction::None;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<std::vector<Tile>> TileMap;
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user