error:错误版本,无法成成敌人
This commit is contained in:
parent
b165dd9c9b
commit
da08160625
@ -121,6 +121,7 @@
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\ThirdParty\cJSON\include;..\ThirdParty\SDL2\include;..\ThirdParty\SDL2_gfx\include;..\ThirdParty\SDL2_image\include;..\ThirdParty\SDL2_mixer\include;..\ThirdParty\SDL2_ttf\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -137,6 +138,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="animation.h" />
|
||||
<ClInclude Include="coin_manager.h" />
|
||||
<ClInclude Include="config_manager.h" />
|
||||
<ClInclude Include="enemy.h" />
|
||||
<ClInclude Include="enemy_manager.h" />
|
||||
@ -156,6 +158,7 @@
|
||||
<ClInclude Include="timer.h" />
|
||||
<ClInclude Include="vector2.h" />
|
||||
<ClInclude Include="wave.h" />
|
||||
<ClInclude Include="wave_manager.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -92,5 +92,11 @@
|
||||
<ClInclude Include="home_manager.h">
|
||||
<Filter>头文件\manager</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="wave_manager.h">
|
||||
<Filter>头文件\manager</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="coin_manager.h">
|
||||
<Filter>头文件\manager</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -8,7 +8,6 @@
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
|
||||
class Animation
|
||||
{
|
||||
public:
|
||||
@ -18,12 +17,14 @@ public:
|
||||
Animation()
|
||||
{
|
||||
timer.set_one_shot(false);
|
||||
|
||||
timer.set_on_timeout
|
||||
(
|
||||
//[&]表示 lambda 表达式按引用捕获外部作用域的所有变量。这样,可以在 lambda 表达式中使用并修改这些变量。
|
||||
[&]()
|
||||
{
|
||||
idx_frame++;
|
||||
|
||||
if (idx_frame >= rect_src_list.size())
|
||||
{
|
||||
idx_frame = is_loop ? 0 : rect_src_list.size() - 1;
|
||||
@ -58,7 +59,8 @@ public:
|
||||
|
||||
rect_src.x = (idx % num_x) * width_frame;
|
||||
rect_src.y = (idx / num_x) * height_frame;
|
||||
rect_src.w = width_frame; rect_src.h = height_frame;
|
||||
rect_src.w = width_frame;
|
||||
rect_src.h = height_frame;
|
||||
};
|
||||
}
|
||||
|
||||
@ -81,6 +83,7 @@ public:
|
||||
{
|
||||
timer.on_update(delta);
|
||||
}
|
||||
|
||||
//渲染器,渲染位置,角度(可能是旋转)
|
||||
void on_render(SDL_Renderer* renderer, const SDL_Point& pos_dst, double angle = 0) const
|
||||
{
|
||||
@ -89,8 +92,8 @@ public:
|
||||
rect_dst.x = pos_dst.x; rect_dst.y = pos_dst.y;
|
||||
rect_dst.w = width_frame; rect_dst.h = height_frame;
|
||||
|
||||
//渲染器,纹理,裁剪矩形,目标矩形,角度,旋转中心点(默认1/2),翻转
|
||||
SDL_RenderCopyEx(renderer, texture, &rect_src_list[idx_frame], &rect_dst, 0, nullptr, SDL_RendererFlip::SDL_FLIP_NONE);
|
||||
//渲染器,纹理,裁剪矩形,目标矩形,角度,旋转中心点(默认1/2),翻转。 纹理绘制
|
||||
SDL_RenderCopyEx(renderer, texture, &rect_src_list[idx_frame], &rect_dst, angle, nullptr, SDL_RendererFlip::SDL_FLIP_NONE);
|
||||
}
|
||||
private:
|
||||
Timer timer;
|
||||
|
39
TdGame/TdGame/coin_manager.h
Normal file
39
TdGame/TdGame/coin_manager.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#ifndef _COIN_MANAGER_H_
|
||||
#define _COIN_MANAGER_H_
|
||||
|
||||
#include"manager.h"
|
||||
|
||||
class CoinManager:public Manager<CoinManager>
|
||||
{
|
||||
friend class Manager<CoinManager>;
|
||||
public:
|
||||
void increase_coin(double val)
|
||||
{
|
||||
num_coin += val;
|
||||
}
|
||||
|
||||
void decrease_coin(double val)
|
||||
{
|
||||
num_coin -= val;
|
||||
|
||||
if (num_coin < 0)
|
||||
num_coin = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
CoinManager()
|
||||
{
|
||||
num_coin = ConfigManager::instance()->num_initial_coin;
|
||||
}
|
||||
~CoinManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
double num_coin = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // _COINMANAGER_H_
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"basic":
|
||||
{
|
||||
"window_title": "村庄保卫战!",
|
||||
"window_title": "村庄保卫战",
|
||||
"window_width": 1280,
|
||||
"window_height": 720
|
||||
},
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
int level_axeman = 0;//斧头兵等级
|
||||
int level_gunner = 0;//枪兵等级
|
||||
|
||||
bool is_game_win =true;//游戏是否获胜
|
||||
bool is_game_win =false;//游戏是否获胜
|
||||
bool is_game_over = false;//游戏是否结束,和上面是两个不同层面的条件,需要分析
|
||||
SDL_Rect rect_tile_map = { 0 };
|
||||
|
||||
@ -94,8 +94,8 @@ public:
|
||||
if (!file.good())return false;
|
||||
|
||||
std::stringstream str_stream;
|
||||
str_stream << file.rdbuf();//rdbuf()将一个流对象用另一个流对象输出
|
||||
file.close();
|
||||
//rdbuf()将一个流对象用另一个流对象输出
|
||||
str_stream << file.rdbuf(); file.close();
|
||||
|
||||
cJSON* json_root = cJSON_Parse(str_stream.str().c_str());
|
||||
if (!json_root) return false;//解析失败
|
||||
@ -133,14 +133,17 @@ public:
|
||||
continue;
|
||||
|
||||
wave.spawn_event_list.emplace_back();
|
||||
Wave::SpawnEvent& spawn_event = wave.spawn_event_list.back();//填充内容,例:"interval" : 1,"point": 1,"enemy" : "Slim"
|
||||
//填充内容,例:"interval" : 1,"point": 1,"enemy" : "Slime"
|
||||
Wave::SpawnEvent& spawn_event = wave.spawn_event_list.back();
|
||||
|
||||
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)
|
||||
{
|
||||
@ -157,7 +160,6 @@ public:
|
||||
spawn_event.enemy_type = EnemyType::GoblinPriest;
|
||||
}
|
||||
}
|
||||
|
||||
if (wave.spawn_event_list.empty())
|
||||
wave_list.pop_back();
|
||||
}
|
||||
@ -179,9 +181,7 @@ public:
|
||||
if (!file.good()) return false;
|
||||
|
||||
std::stringstream str_stream;
|
||||
str_stream << file.rdbuf();
|
||||
|
||||
file.close();
|
||||
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;
|
||||
@ -296,6 +296,7 @@ private:
|
||||
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");
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
|
||||
//闪白计时器
|
||||
timer_sketch.set_one_shot(true);
|
||||
timer_sketch.set_wait_time(0.075);
|
||||
timer_sketch.set_wait_time(0.001);
|
||||
timer_sketch.set_on_timeout([&]() {is_show_sketch = false; });
|
||||
|
||||
//速度恢复计时器
|
||||
@ -59,7 +59,7 @@ public:
|
||||
//是否展示水平动画
|
||||
bool is_show_x_anim = (velocity.x) >= abs(velocity.y);
|
||||
|
||||
//1.是否展示剪影 2.是否展示水平动画
|
||||
//1.是否展示剪影 2.展示动画左右
|
||||
if (is_show_sketch)
|
||||
{
|
||||
if (is_show_x_anim)
|
||||
@ -102,7 +102,7 @@ public:
|
||||
//绘制血条
|
||||
rect.x = (int)(position.x - size_hp_bar.x / 2);
|
||||
rect.y = (int)(position.y - size.y / 2 - size_hp_bar.y - offset_y);
|
||||
rect.w = (int)size_hp_bar.x * (hp / max_hp);
|
||||
rect.w = (int)(size_hp_bar.x * (hp / max_hp));
|
||||
rect.h = (int)size_hp_bar.y;
|
||||
SDL_SetRenderDrawColor(renderer, color_content.r, color_content.g, color_content.b, color_content.a);
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
@ -159,7 +159,7 @@ public:
|
||||
|
||||
void make_invalid()
|
||||
{
|
||||
is_valid = true;
|
||||
is_valid = false;
|
||||
}
|
||||
|
||||
double get_hp()const
|
||||
@ -216,7 +216,7 @@ public:
|
||||
if (route->get_idx_list().size() == 1)
|
||||
return 1;
|
||||
|
||||
return (double)idx_target / route->get_idx_list().size() - 1;
|
||||
return (double)idx_target / (route->get_idx_list().size() - 1);
|
||||
}
|
||||
protected:
|
||||
Vector2 size;
|
||||
@ -285,8 +285,8 @@ private:
|
||||
if (idx_target < idx_list.size())
|
||||
{
|
||||
const SDL_Point& point = idx_list[idx_target];
|
||||
|
||||
static const SDL_Rect& rect_tile_map = ConfigManager::instance()->rect_tile_map;
|
||||
|
||||
position.x = rect_tile_map.x + point.x * SIZE_TILE + SIZE_TILE / 2;
|
||||
position.y = rect_tile_map.y + point.y * SIZE_TILE + SIZE_TILE / 2;
|
||||
}
|
||||
|
@ -5,8 +5,12 @@
|
||||
#include "enemy.h"
|
||||
#include "manager.h"
|
||||
#include "config_manager.h"
|
||||
#include "Vector2.h"
|
||||
#include "home_manager.h"
|
||||
#include "slime_enemy.h"
|
||||
#include "king_slime_enemy.h"
|
||||
#include "skeleton_enemy.h"
|
||||
#include "goblin_enemy.h"
|
||||
#include "goblin_priest_enemy.h"
|
||||
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
@ -17,6 +21,7 @@ class EnemyManager: public Manager<EnemyManager>
|
||||
friend class Manager<EnemyManager>;
|
||||
|
||||
public:
|
||||
//类型:vector<Enemy*>
|
||||
typedef std::vector<Enemy*> EnemyList;
|
||||
|
||||
public:
|
||||
@ -38,8 +43,89 @@ public:
|
||||
enemy->on_render(renderer);
|
||||
}
|
||||
|
||||
/*
|
||||
敌人生成
|
||||
param2:敌人生成点
|
||||
*/
|
||||
void spawn_enemy(EnemyType type, int idx_spawn_point)
|
||||
{
|
||||
static Vector2 position;
|
||||
static const SDL_Rect& rect_tile_map = ConfigManager::instance()->rect_tile_map;
|
||||
|
||||
//获取路径池
|
||||
static const Map::SpawnerRoutePool& spawner_route_pool
|
||||
= ConfigManager::instance()->map.get_idx_spawner_pool();
|
||||
|
||||
/*
|
||||
* 返回迭代器,如果未找到则返回最后一个元素的下一个位置
|
||||
*/
|
||||
const auto& iter = spawner_route_pool.find(idx_spawn_point);
|
||||
if(iter == spawner_route_pool.end())
|
||||
return;
|
||||
|
||||
Enemy* enemy = nullptr;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EnemyType::Slime:
|
||||
enemy = new SlimeEnemy();
|
||||
break;
|
||||
case EnemyType::KingSlime:
|
||||
enemy = new KingSlimeEnemy();
|
||||
break;
|
||||
case EnemyType::Skeleton:
|
||||
enemy = new SkeletonEnemy();
|
||||
break;
|
||||
case EnemyType::Goblin:
|
||||
enemy = new GoblinEnemy();
|
||||
break;
|
||||
case EnemyType::GoblinPriest:
|
||||
enemy = new GoblinPriestEnemy();
|
||||
break;
|
||||
default:
|
||||
enemy = new SlimeEnemy();
|
||||
break;
|
||||
}
|
||||
|
||||
//技能释放
|
||||
enemy->set_on_skill_released
|
||||
(
|
||||
[&](Enemy* enemy_src)
|
||||
{
|
||||
double revocer_radius = enemy_src->get_recover_radius();
|
||||
if (revocer_radius < 0) return;
|
||||
|
||||
const Vector2 pos_src = enemy_src->get_position();
|
||||
for (Enemy* enemy_dst : enemy_list)
|
||||
{
|
||||
const Vector2& pos_dst = enemy_dst->get_position();
|
||||
double distance = (pos_dst - pos_src).length();
|
||||
if (distance <= revocer_radius)
|
||||
enemy_dst->increase_hp(enemy_src->get_recover_intensity());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
//寻路
|
||||
const Route::IdxList& idx_list = iter->second.get_idx_list();
|
||||
position.x = rect_tile_map.x + idx_list[0].x * SIZE_TILE + SIZE_TILE / 2;
|
||||
position.y = rect_tile_map.y + idx_list[0].y * SIZE_TILE + SIZE_TILE / 2;
|
||||
|
||||
enemy->set_position(position);
|
||||
enemy->set_route(&iter->second);
|
||||
|
||||
enemy_list.push_back(enemy);
|
||||
|
||||
}
|
||||
|
||||
bool check_cleared()
|
||||
{
|
||||
return enemy_list.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
EnemyManager() = default;
|
||||
|
||||
~EnemyManager()
|
||||
{
|
||||
for (Enemy* enemy : enemy_list)
|
||||
@ -67,6 +153,7 @@ private:
|
||||
if (enemy->can_remove()) continue;
|
||||
|
||||
const Vector2& position = enemy->get_position();
|
||||
|
||||
if (position.x >= position_home_tile.x
|
||||
&& position.y >= position_home_tile.y
|
||||
&& position.x <= position_home_tile.x + SIZE_TILE
|
||||
@ -75,7 +162,6 @@ private:
|
||||
enemy->make_invalid();
|
||||
|
||||
HomeManager::instance()->decrease_hp(enemy->get_damage());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +177,7 @@ private:
|
||||
[](const Enemy* enemy)
|
||||
{
|
||||
bool deletable = enemy->can_remove();
|
||||
if (deletable) delete(enemy);
|
||||
if (deletable) delete enemy;
|
||||
return deletable;
|
||||
}), enemy_list.end());
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "manager.h"
|
||||
#include "config_manager.h"
|
||||
#include "resources_manager.h"
|
||||
#include "enemy_manager.h"
|
||||
#include "wave_manager.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
@ -33,7 +35,7 @@ public:
|
||||
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));
|
||||
SDL_Delay((Uint32)(1000.0 / 60 - delta * 1000));
|
||||
|
||||
//¸üÐÂÊý¾Ý
|
||||
on_update(delta);
|
||||
@ -119,7 +121,15 @@ private:
|
||||
|
||||
void on_update(double delta)
|
||||
{
|
||||
static ConfigManager* instance = ConfigManager::instance();
|
||||
|
||||
if (!instance->is_game_over)
|
||||
{
|
||||
WaveManager::instance()->on_update(delta);
|
||||
EnemyManager::instance()->on_update(delta);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void on_render()
|
||||
@ -127,6 +137,8 @@ private:
|
||||
static ConfigManager* instance = ConfigManager::instance();
|
||||
static SDL_Rect& rect_dst = instance->rect_tile_map;
|
||||
SDL_RenderCopy(renderer, tex_tile_map, nullptr, &rect_dst);
|
||||
|
||||
EnemyManager::instance()->on_render(renderer);
|
||||
}
|
||||
|
||||
bool generate_tile_map_texture()
|
||||
@ -145,7 +157,7 @@ private:
|
||||
width_tex_tile_map = (int)map.get_width() * SIZE_TILE;
|
||||
height_tex_tile_map = (int)map.get_height() * SIZE_TILE;
|
||||
|
||||
//第三个参数说明这张纹理可以被renderer绘制,并且格式是第二个参数
|
||||
//第三个参数说明这张纹理可以被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;
|
||||
|
@ -20,40 +20,39 @@ public:
|
||||
static ConfigManager::EnemyTemplate& goblin_template = ConfigManager::instance()->goblin_template;
|
||||
|
||||
|
||||
static const std::vector<int> idx_list_up = { 6,7,8,9,10,11 };
|
||||
static const std::vector<int> idx_list_down = { 0,1,2,3,4,5 };
|
||||
static const std::vector<int> idx_list_left = { 18,19,20,21,22,23 };
|
||||
static const std::vector<int> idx_list_right = { 12,13,14,15,16,17 };
|
||||
static const std::vector<int> idx_list_up = { 5, 6, 7, 8, 9 };
|
||||
static const std::vector<int> idx_list_down = { 0, 1, 2, 3, 4 };
|
||||
static const std::vector<int> idx_list_left = { 15, 16, 17, 18, 19 };
|
||||
static const std::vector<int> idx_list_right = { 10, 11, 12, 13, 14 };
|
||||
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.1);
|
||||
anim_up.set_frame_data(tex_goblin, 6, 4, idx_list_up);
|
||||
anim_down.set_loop(true); anim_down.set_interval(0.1);
|
||||
anim_down.set_frame_data(tex_goblin, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_goblin, 6, 4, idx_list_left);
|
||||
anim_right.set_loop(true); anim_right.set_interval(0.1);
|
||||
anim_right.set_frame_data(tex_goblin, 6, 4, idx_list_right);
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.15);
|
||||
anim_up.set_frame_data(tex_goblin, 5, 4, idx_list_up);
|
||||
anim_down.set_loop(true); anim_down.set_interval(0.15);
|
||||
anim_down.set_frame_data(tex_goblin, 5, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.15);
|
||||
anim_left.set_frame_data(tex_goblin, 5, 4, idx_list_left);
|
||||
anim_right.set_loop(true); anim_right.set_interval(0.15);
|
||||
anim_right.set_frame_data(tex_goblin, 5, 4, idx_list_right);
|
||||
|
||||
anim_up_sketch.set_loop(true); anim_up_sketch.set_interval(0.1);
|
||||
anim_up_sketch.set_frame_data(tex_goblin_sketch, 6, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.1);
|
||||
anim_down_sketch.set_frame_data(tex_goblin_sketch, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_goblin_sketch, 6, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.1);
|
||||
anim_right_sketch.set_frame_data(tex_goblin_sketch, 6, 4, idx_list_right);
|
||||
anim_up_sketch.set_loop(true); anim_up_sketch.set_interval(0.15);
|
||||
anim_up_sketch.set_frame_data(tex_goblin_sketch, 5, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.15);
|
||||
anim_down_sketch.set_frame_data(tex_goblin_sketch, 5, 4, idx_list_down);
|
||||
anim_left_sketch.set_loop(true); anim_left_sketch.set_interval(0.15);
|
||||
anim_left_sketch.set_frame_data(tex_goblin_sketch, 5, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.15);
|
||||
anim_right_sketch.set_frame_data(tex_goblin_sketch, 5, 4, idx_list_right);
|
||||
|
||||
max_hp = king_slime_template.hp;
|
||||
max_speed = king_slime_template.speed;
|
||||
damage = king_slime_template.damage;
|
||||
reward_ratio = king_slime_template.reward_ratio;
|
||||
recover_interval = king_slime_template.recover_interval;
|
||||
recover_range = king_slime_template.recover_range;
|
||||
recover_intensity = king_slime_template.recover_intensity;
|
||||
max_hp = goblin_template.hp;
|
||||
max_speed = goblin_template.speed;
|
||||
damage = goblin_template.damage;
|
||||
reward_ratio = goblin_template.reward_ratio;
|
||||
recover_interval = goblin_template.recover_interval;
|
||||
recover_range = goblin_template.recover_range;
|
||||
recover_intensity = goblin_template.recover_intensity;
|
||||
|
||||
size.x = 48, size.y = 48;
|
||||
hp = max_hp;
|
||||
speed = max_speed;
|
||||
hp = max_hp,speed = max_speed;
|
||||
}
|
||||
|
||||
~GoblinEnemy() = default;
|
||||
|
@ -21,28 +21,28 @@ public:
|
||||
static ConfigManager::EnemyTemplate& goblin_priest_template = ConfigManager::instance()->goblin_priest_template;
|
||||
|
||||
|
||||
static const std::vector<int> idx_list_up = { 6,7,8,9,10,11 };
|
||||
static const std::vector<int> idx_list_down = { 0,1,2,3,4,5 };
|
||||
static const std::vector<int> idx_list_left = { 18,19,20,21,22,23 };
|
||||
static const std::vector<int> idx_list_right = { 12,13,14,15,16,17 };
|
||||
static const std::vector<int> idx_list_up = { 5, 6, 7, 8, 9 };
|
||||
static const std::vector<int> idx_list_down = { 0, 1, 2, 3, 4 };
|
||||
static const std::vector<int> idx_list_left = { 15, 16, 17, 18, 19 };
|
||||
static const std::vector<int> idx_list_right = { 10, 11, 12, 13, 14 };
|
||||
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.1);
|
||||
anim_up.set_frame_data(tex_goblin_priest, 6, 4, idx_list_up);
|
||||
anim_down.set_loop(true); anim_down.set_interval(0.1);
|
||||
anim_down.set_frame_data(tex_goblin_priest, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_goblin_priest, 6, 4, idx_list_left);
|
||||
anim_right.set_loop(true); anim_right.set_interval(0.1);
|
||||
anim_right.set_frame_data(tex_goblin_priest, 6, 4, idx_list_right);
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.15);
|
||||
anim_up.set_frame_data(tex_goblin_priest, 5, 4, idx_list_up);
|
||||
anim_down.set_loop(true); anim_down.set_interval(0.15);
|
||||
anim_down.set_frame_data(tex_goblin_priest, 5, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.15);
|
||||
anim_left.set_frame_data(tex_goblin_priest, 5, 4, idx_list_left);
|
||||
anim_right.set_loop(true); anim_right.set_interval(0.15);
|
||||
anim_right.set_frame_data(tex_goblin_priest, 5, 4, idx_list_right);
|
||||
|
||||
anim_up_sketch.set_loop(true); anim_up_sketch.set_interval(0.1);
|
||||
anim_up_sketch.set_frame_data(tex_goblin_priest_sketch, 6, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.1);
|
||||
anim_down_sketch.set_frame_data(tex_goblin_priest_sketch, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_goblin_priest_sketch, 6, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.1);
|
||||
anim_right_sketch.set_frame_data(tex_goblin_priest_sketch, 6, 4, idx_list_right);
|
||||
anim_up_sketch.set_loop(true); anim_up_sketch.set_interval(0.15);
|
||||
anim_up_sketch.set_frame_data(tex_goblin_priest_sketch, 5, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.15);
|
||||
anim_down_sketch.set_frame_data(tex_goblin_priest_sketch, 5, 4, idx_list_down);
|
||||
anim_left_sketch.set_loop(true); anim_left_sketch.set_interval(0.15);
|
||||
anim_left_sketch.set_frame_data(tex_goblin_priest_sketch, 5, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.15);
|
||||
anim_right_sketch.set_frame_data(tex_goblin_priest_sketch, 5, 4, idx_list_right);
|
||||
|
||||
max_hp = goblin_priest_template.hp;
|
||||
max_speed = goblin_priest_template.speed;
|
||||
@ -53,8 +53,7 @@ public:
|
||||
recover_intensity = goblin_priest_template.recover_intensity;
|
||||
|
||||
size.x = 48, size.y = 48;
|
||||
hp = max_hp;
|
||||
speed = max_speed;
|
||||
hp = max_hp,speed = max_speed;
|
||||
}
|
||||
~GoblinPriestEnemy() = default;
|
||||
|
||||
|
@ -20,9 +20,9 @@ public:
|
||||
static ConfigManager::EnemyTemplate& king_slime_template = ConfigManager::instance()->king_slime_template;
|
||||
|
||||
|
||||
static const std::vector<int> idx_list_up = { 6,7,8,9,10,11 };
|
||||
static const std::vector<int> idx_list_up = { 18, 19, 20, 21, 22, 23 };
|
||||
static const std::vector<int> idx_list_down = { 0, 1, 2, 3, 4, 5 };
|
||||
static const std::vector<int> idx_list_left = { 18,19,20,21,22,23 };
|
||||
static const std::vector<int> idx_list_left = { 6, 7, 8, 9, 10, 11 };
|
||||
static const std::vector<int> idx_list_right = { 12, 13, 14, 15, 16, 17 };
|
||||
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.1);
|
||||
@ -38,8 +38,8 @@ public:
|
||||
anim_up_sketch.set_frame_data(tex_king_slime_sketch, 6, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.1);
|
||||
anim_down_sketch.set_frame_data(tex_king_slime_sketch, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_king_slime_sketch, 6, 4, idx_list_left);
|
||||
anim_left_sketch.set_loop(true); anim_left_sketch.set_interval(0.1);
|
||||
anim_left_sketch.set_frame_data(tex_king_slime_sketch, 6, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.1);
|
||||
anim_right_sketch.set_frame_data(tex_king_slime_sketch, 6, 4, idx_list_right);
|
||||
|
||||
@ -52,8 +52,7 @@ public:
|
||||
recover_intensity = king_slime_template.recover_intensity;
|
||||
|
||||
size.x = 48, size.y = 48;
|
||||
hp = max_hp;
|
||||
speed = max_speed;
|
||||
hp = max_hp,speed = max_speed;
|
||||
}
|
||||
|
||||
~KingSlimeEnemy() = default;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#define SDL_MAIN_HANDLED
|
||||
#include<iostream>
|
||||
|
||||
|
||||
#include "game_manager.h"
|
||||
|
||||
|
||||
|
@ -64,8 +64,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t get_width() const //const不会对类内进行修改
|
||||
{
|
||||
if (tile_map.empty())
|
||||
|
@ -20,28 +20,28 @@ public:
|
||||
static ConfigManager::EnemyTemplate& skeleton_template = ConfigManager::instance()->skeleton_template;
|
||||
|
||||
//向上行动的动画帧索引(根据resource中skeleton的资源图)
|
||||
static const std::vector<int> idx_list_up = { 6,7,8,9,10,11 };
|
||||
static const std::vector<int> idx_list_down = { 0,1,2,3,4,5 };
|
||||
static const std::vector<int> idx_list_left = { 18,19,20,21,22,23 };
|
||||
static const std::vector<int> idx_list_right = { 12,13,14,15,16,17 };
|
||||
static const std::vector<int> idx_list_up = { 5, 6, 7, 8, 9 };
|
||||
static const std::vector<int> idx_list_down = { 0, 1, 2, 3, 4 };
|
||||
static const std::vector<int> idx_list_left = { 15, 16, 17, 18, 19 };
|
||||
static const std::vector<int> idx_list_right = { 10, 11, 12, 13, 14 };
|
||||
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.1);
|
||||
anim_up.set_loop(true); anim_up.set_interval(0.15);
|
||||
anim_up.set_frame_data(tex_skeleton, 6, 4, idx_list_up);
|
||||
anim_down.set_loop(true); anim_down.set_interval(0.1);
|
||||
anim_down.set_loop(true); anim_down.set_interval(0.15);
|
||||
anim_down.set_frame_data(tex_skeleton, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.15);
|
||||
anim_left.set_frame_data(tex_skeleton, 6, 4, idx_list_left);
|
||||
anim_right.set_loop(true); anim_right.set_interval(0.1);
|
||||
anim_right.set_loop(true); anim_right.set_interval(0.15);
|
||||
anim_right.set_frame_data(tex_skeleton, 6, 4, idx_list_right);
|
||||
|
||||
anim_up_sketch.set_loop(true); anim_up_sketch.set_interval(0.1);
|
||||
anim_up_sketch.set_frame_data(tex_skeleton_sketch, 6, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.1);
|
||||
anim_down_sketch.set_frame_data(tex_skeleton_sketch, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_skeleton_sketch, 6, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.1);
|
||||
anim_right_sketch.set_frame_data(tex_skeleton_sketch, 6, 4, idx_list_right);
|
||||
anim_up_sketch.set_loop(true); anim_up_sketch.set_interval(0.15);
|
||||
anim_up_sketch.set_frame_data(tex_skeleton_sketch, 5, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.15);
|
||||
anim_down_sketch.set_frame_data(tex_skeleton_sketch, 5, 4, idx_list_down);
|
||||
anim_left_sketch.set_loop(true); anim_left_sketch.set_interval(0.15);
|
||||
anim_left_sketch.set_frame_data(tex_skeleton_sketch, 5, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.15);
|
||||
anim_right_sketch.set_frame_data(tex_skeleton_sketch, 5, 4, idx_list_right);
|
||||
|
||||
max_hp = skeleton_template.hp;
|
||||
max_speed = skeleton_template.speed;
|
||||
@ -52,8 +52,7 @@ public:
|
||||
recover_intensity = skeleton_template.recover_intensity;
|
||||
|
||||
size.x = 48, size.y = 48;
|
||||
hp = max_hp;
|
||||
speed = max_speed;
|
||||
hp = max_hp,speed = max_speed;
|
||||
}
|
||||
|
||||
~SkeletonEnemy() = default;
|
||||
|
@ -38,8 +38,8 @@ public:
|
||||
anim_up_sketch.set_frame_data(tex_slime_sketch, 6, 4, idx_list_up);
|
||||
anim_down_sketch.set_loop(true); anim_down_sketch.set_interval(0.1);
|
||||
anim_down_sketch.set_frame_data(tex_slime_sketch, 6, 4, idx_list_down);
|
||||
anim_left.set_loop(true); anim_left.set_interval(0.1);
|
||||
anim_left.set_frame_data(tex_slime_sketch, 6, 4, idx_list_left);
|
||||
anim_left_sketch.set_loop(true); anim_left_sketch.set_interval(0.1);
|
||||
anim_left_sketch.set_frame_data(tex_slime_sketch, 6, 4, idx_list_left);
|
||||
anim_right_sketch.set_loop(true); anim_right_sketch.set_interval(0.1);
|
||||
anim_right_sketch.set_frame_data(tex_slime_sketch, 6, 4, idx_list_right);
|
||||
|
||||
@ -52,11 +52,9 @@ public:
|
||||
recover_intensity = slime_template.recover_intensity;
|
||||
|
||||
size.x = 48, size.y = 48;
|
||||
hp = max_hp;
|
||||
speed = max_speed;
|
||||
hp = max_hp, speed = max_speed;
|
||||
}
|
||||
~SlimeEnemy() = default;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
void on_update(double delta)
|
||||
{
|
||||
if (paused) return;
|
||||
|
||||
pass_time += delta;
|
||||
if (pass_time >= wait_time)
|
||||
{
|
||||
@ -73,5 +74,4 @@ private:
|
||||
std::function<void()> on_timeout;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -13,7 +13,7 @@ struct Wave
|
||||
{
|
||||
double interval = 0;
|
||||
int spawn_point = 1;
|
||||
EnemyType enemy_type = EnemyType::Slime;//在level.json文件中见格式,波次序列配置文件
|
||||
EnemyType enemy_type = EnemyType::Goblin;//在level.json文件中见格式,波次序列配置文件
|
||||
};
|
||||
|
||||
double rewards = 0;
|
||||
|
110
TdGame/TdGame/wave_manager.h
Normal file
110
TdGame/TdGame/wave_manager.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef _WAVE_MANAGER_H
|
||||
#define _WAVE_MANAGER_H
|
||||
|
||||
#include"timer.h"
|
||||
#include "manager.h"
|
||||
#include "config_manager.h"
|
||||
#include "enemy_manager.h"
|
||||
#include "coin_manager.h"
|
||||
|
||||
class WaveManager : public Manager<WaveManager>
|
||||
{
|
||||
friend class Manager<WaveManager>;
|
||||
|
||||
public:
|
||||
void on_update(double delta)
|
||||
{
|
||||
static ConfigManager* instance = ConfigManager::instance();
|
||||
|
||||
if (instance->is_game_over)
|
||||
return;
|
||||
|
||||
if (!is_wave_started)
|
||||
timer_start_wave.on_update(delta);
|
||||
else
|
||||
timer_spawn_enemy.on_update(delta);
|
||||
|
||||
//如果最后一个敌人已经生成&&敌人列表为空
|
||||
if (is_spawned_last_enemy && EnemyManager::instance()->check_cleared())
|
||||
{
|
||||
CoinManager::instance()->increase_coin(instance->wave_list[idx_wave].rewards);
|
||||
|
||||
idx_wave++;
|
||||
|
||||
//如果最后一波
|
||||
if (idx_wave >= instance->wave_list.size())
|
||||
{
|
||||
instance->is_game_win = true;
|
||||
instance->is_game_over = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
idx_spawn_event = 0;
|
||||
is_wave_started = true;
|
||||
is_spawned_last_enemy = false;
|
||||
|
||||
const Wave& wave = instance->wave_list[idx_wave];
|
||||
timer_start_wave.set_wait_time(wave.interval);
|
||||
timer_start_wave.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
WaveManager()
|
||||
{
|
||||
static const std::vector<Wave>& wave_list = ConfigManager::instance()->wave_list;
|
||||
|
||||
timer_start_wave.set_one_shot(true);
|
||||
timer_start_wave.set_wait_time(wave_list[0].interval);
|
||||
timer_start_wave.set_on_timeout(
|
||||
[&]()
|
||||
{
|
||||
is_wave_started = true;
|
||||
timer_spawn_enemy.set_wait_time(wave_list[idx_wave].spawn_event_list[0].interval);
|
||||
timer_spawn_enemy.restart();
|
||||
}
|
||||
);
|
||||
|
||||
timer_spawn_enemy.set_one_shot(true);
|
||||
timer_spawn_enemy.set_on_timeout(
|
||||
[&]()
|
||||
{
|
||||
const std::vector<Wave::SpawnEvent>& spawn_event_list = wave_list[idx_wave].spawn_event_list;
|
||||
const Wave::SpawnEvent& spawn_event = spawn_event_list[idx_spawn_event];
|
||||
|
||||
EnemyManager::instance()->spawn_enemy(spawn_event.enemy_type, spawn_event.spawn_point);
|
||||
|
||||
idx_spawn_event++;
|
||||
|
||||
if (idx_spawn_event >= spawn_event_list.size())
|
||||
{
|
||||
is_spawned_last_enemy = true;
|
||||
return;
|
||||
}
|
||||
|
||||
timer_spawn_enemy.set_wait_time(spawn_event_list[idx_spawn_event].interval);
|
||||
timer_spawn_enemy.restart();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
~WaveManager() = default;
|
||||
|
||||
private:
|
||||
//波次
|
||||
int idx_wave = 0;
|
||||
//生成事件次,一波有很多次生成
|
||||
int idx_spawn_event = 0;
|
||||
//第一波开始计时器
|
||||
Timer timer_start_wave;
|
||||
//敌人生成计时器
|
||||
Timer timer_spawn_enemy;
|
||||
//是否开始
|
||||
bool is_wave_started = false;
|
||||
//是否生成最后一个敌人
|
||||
bool is_spawned_last_enemy = false;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user