feat: enemy敌人基类实现
This commit is contained in:
parent
46a7b25970
commit
677a7d9a61
@ -138,12 +138,14 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="animation.h" />
|
||||
<ClInclude Include="config_manager.h" />
|
||||
<ClInclude Include="enemy.h" />
|
||||
<ClInclude Include="enemy_type.h" />
|
||||
<ClInclude Include="game_manager.h" />
|
||||
<ClInclude Include="manager.h" />
|
||||
<ClInclude Include="map.h" />
|
||||
<ClInclude Include="resources_manager.h" />
|
||||
<ClInclude Include="route.h" />
|
||||
<ClInclude Include="slime_enemy.h" />
|
||||
<ClInclude Include="tile.h" />
|
||||
<ClInclude Include="timer.h" />
|
||||
<ClInclude Include="vector2.h" />
|
||||
|
@ -68,5 +68,11 @@
|
||||
<ClInclude Include="vector2.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="enemy.h">
|
||||
<Filter>头文件\enemy</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="slime_enemy.h">
|
||||
<Filter>头文件\enemy</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -12,7 +12,7 @@
|
||||
class Animation
|
||||
{
|
||||
public:
|
||||
//表示一个可以存储和调用无参数且无返回值的可调用对象类型。
|
||||
//表示一个,可以存储和调用无参数且无返回值的,可调用对象类型。
|
||||
typedef std::function<void()> PlayCallBack;
|
||||
public:
|
||||
Animation()
|
||||
|
297
TdGame/TdGame/enemy.h
Normal file
297
TdGame/TdGame/enemy.h
Normal file
@ -0,0 +1,297 @@
|
||||
#pragma once
|
||||
#ifndef _ENEMY_H_
|
||||
#define _ENEMY_H_
|
||||
|
||||
#include "config_manager.h"
|
||||
|
||||
#include "vector2.h"
|
||||
#include "timer.h"
|
||||
#include "animation.h"
|
||||
#include "route.h"
|
||||
|
||||
class Enemy
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(Enemy* enemy)> SkillCallback;
|
||||
|
||||
public:
|
||||
Enemy()
|
||||
{
|
||||
//技能计时器
|
||||
timer_skill.set_one_shot(false);
|
||||
timer_skill.set_on_timeout([&]() {on_skill_released(this); });
|
||||
|
||||
//闪白计时器
|
||||
timer_sketch.set_one_shot(true);
|
||||
timer_sketch.set_wait_time(0.075);
|
||||
timer_sketch.set_on_timeout([&]() {is_show_sketch = false; });
|
||||
|
||||
//速度恢复计时器
|
||||
timer_restore_speed.set_one_shot(true);
|
||||
timer_restore_speed.set_on_timeout([&]() {speed = max_speed;});
|
||||
}
|
||||
~Enemy() = default;
|
||||
|
||||
//帧更新
|
||||
void on_update(double delta)
|
||||
{
|
||||
timer_skill.on_update(delta);
|
||||
timer_sketch.on_update(delta);
|
||||
timer_restore_speed.on_update(delta);
|
||||
|
||||
Vector2 move_distance = velocity * delta;
|
||||
Vector2 target_distance = position_target - position;
|
||||
position += move_distance < target_distance ? move_distance : target_distance;
|
||||
|
||||
//移动距离很小
|
||||
if (target_distance.approx_zero())
|
||||
{
|
||||
idx_target++;
|
||||
refresh_position_target();
|
||||
|
||||
direction = (position_target - position).normalize();
|
||||
|
||||
}
|
||||
|
||||
velocity.x = direction.x * speed * SIZE_TILE;
|
||||
velocity.y = direction.y * speed * SIZE_TILE;
|
||||
|
||||
//是否展示水平动画
|
||||
bool is_show_x_anim = (velocity.x) >= abs(velocity.y);
|
||||
|
||||
//1.是否展示剪影 2.是否展示水平动画
|
||||
if (is_show_sketch)
|
||||
{
|
||||
if (is_show_x_anim)
|
||||
anim_current = velocity.x > 0 ? &anim_right_sketch : &anim_left_sketch;
|
||||
else
|
||||
anim_current = velocity.y > 0 ? &anim_down_sketch : &anim_up_sketch;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_show_x_anim)
|
||||
anim_current = velocity.x > 0 ? &anim_right : &anim_left;
|
||||
else
|
||||
anim_current = velocity.y > 0 ? &anim_down : &anim_up;
|
||||
}
|
||||
|
||||
anim_current->on_update(delta);
|
||||
}
|
||||
|
||||
|
||||
void on_render(SDL_Renderer* renderer)
|
||||
{
|
||||
//血条矩形(内容物、外边框,复用)
|
||||
static SDL_Rect rect;
|
||||
static SDL_Point point;
|
||||
static const int offset_y = 2;
|
||||
static Vector2 size_hp_bar = { 40,8 };
|
||||
//血条外边框颜色
|
||||
static const SDL_Color color_border = { 116,185,124,255 };
|
||||
//血条内容物颜色
|
||||
static const SDL_Color color_content = { 226,255,194,255 };
|
||||
|
||||
|
||||
point.x = (int)(position.x - size.x / 2);
|
||||
point.y = (int)(position.y - size.y / 2);
|
||||
|
||||
anim_current->on_render(renderer, point);
|
||||
|
||||
if (hp < max_hp)
|
||||
{
|
||||
//绘制血条
|
||||
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.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);
|
||||
|
||||
//绘制血条外边框
|
||||
rect.w = (int)size_hp_bar.x;
|
||||
SDL_SetRenderDrawColor(renderer, color_border.r, color_border.g, color_border.b, color_border.a);
|
||||
SDL_RenderDrawRect(renderer, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
void set_on_skill_released(SkillCallback on_skill_released)
|
||||
{
|
||||
this->on_skill_released = on_skill_released;
|
||||
}
|
||||
|
||||
void increase_hp(double val)
|
||||
{
|
||||
hp += val;
|
||||
|
||||
if (hp > max_hp)
|
||||
hp = max_hp;
|
||||
}
|
||||
|
||||
void decrease_hp(double val)
|
||||
{
|
||||
hp -= val;
|
||||
if (hp < 0)
|
||||
{
|
||||
hp = 0;
|
||||
is_valid = false;
|
||||
}
|
||||
is_show_sketch = true;
|
||||
timer_sketch.restart();
|
||||
}
|
||||
void slow_down()
|
||||
{
|
||||
speed = max_speed - 0.5;
|
||||
timer_restore_speed.set_wait_time(1);
|
||||
timer_restore_speed.restart();
|
||||
}
|
||||
|
||||
void set_position(const Vector2& position)
|
||||
{
|
||||
this->position = position;
|
||||
}
|
||||
|
||||
void set_route(const Route* route)
|
||||
{
|
||||
this->route = route;
|
||||
|
||||
refresh_position_target();
|
||||
}
|
||||
|
||||
void make_invalid()
|
||||
{
|
||||
is_valid = true;
|
||||
}
|
||||
|
||||
double get_hp()const
|
||||
{
|
||||
return hp;
|
||||
}
|
||||
|
||||
const Vector2& get_size()const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
const Vector2& get_position()const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
const Vector2& get_velocity()const
|
||||
{
|
||||
return velocity;
|
||||
}
|
||||
|
||||
double get_damage()const
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
double get_reward_ratio()const
|
||||
{
|
||||
return reward_ratio;
|
||||
}
|
||||
|
||||
//获取恢复半径
|
||||
double get_recover_radius()const
|
||||
{
|
||||
//转化世界坐标
|
||||
return recover_range * SIZE_TILE;
|
||||
}
|
||||
|
||||
double get_recover_intensity()const
|
||||
{
|
||||
return recover_intensity;
|
||||
}
|
||||
|
||||
//是否可以移除enemy
|
||||
bool can_move()
|
||||
{
|
||||
return !is_valid;
|
||||
}
|
||||
|
||||
//获取enemy在路径上的进度
|
||||
double get_route_process()const
|
||||
{
|
||||
if (route->get_idx_list().size() == 1)
|
||||
return 1;
|
||||
|
||||
return (double)idx_target / route->get_idx_list().size() - 1;
|
||||
}
|
||||
protected:
|
||||
Vector2 size;
|
||||
|
||||
Timer timer_skill;
|
||||
|
||||
Animation anim_up;
|
||||
Animation anim_down;
|
||||
Animation anim_left;
|
||||
Animation anim_right;
|
||||
Animation anim_up_sketch;
|
||||
Animation anim_down_sketch;
|
||||
Animation anim_left_sketch;
|
||||
Animation anim_right_sketch;
|
||||
|
||||
double hp = 0;
|
||||
double max_hp = 0;
|
||||
//减速后速度
|
||||
double speed = 0;
|
||||
double max_speed = 0;
|
||||
//对防守目标伤害
|
||||
double damage = 0;
|
||||
//爆金币概率
|
||||
double reward_ratio = 0;
|
||||
//恢复技能的间隔
|
||||
double recover_interval = 0;
|
||||
//恢复技能的范围
|
||||
double recover_range = 0;
|
||||
//恢复技能的强度
|
||||
double recover_intensity = 0;
|
||||
|
||||
private:
|
||||
//位置
|
||||
Vector2 position;
|
||||
//速度
|
||||
Vector2 velocity;
|
||||
//方向
|
||||
Vector2 direction;
|
||||
|
||||
bool is_valid = true;
|
||||
|
||||
//闪白效果计时器和是否展示闪白
|
||||
Timer timer_sketch;
|
||||
bool is_show_sketch = false;
|
||||
|
||||
//当前动画帧
|
||||
Animation* anim_current = nullptr;
|
||||
|
||||
SkillCallback on_skill_released;
|
||||
|
||||
//速度受损回复时间
|
||||
Timer timer_restore_speed;
|
||||
|
||||
//行走路径
|
||||
const Route* route = nullptr;
|
||||
|
||||
//当前和目标单元格
|
||||
int idx_target = 0;
|
||||
Vector2 position_target;
|
||||
|
||||
private:
|
||||
void refresh_position_target()
|
||||
{
|
||||
const Route::IdxList& idx_list = route->get_idx_list();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // ! _ENEMY_H_
|
@ -110,6 +110,7 @@ private:
|
||||
//一个去除字符串前后空格和制表符的函数
|
||||
std::string trim_str(const std::string& str)
|
||||
{
|
||||
//找第一个不是空格和制表符的字母位置,找不到返回这个值->nops
|
||||
size_t begin_idx = str.find_first_not_of(" \t");
|
||||
if (begin_idx == std::string::npos)
|
||||
return "";
|
||||
|
@ -10,7 +10,7 @@
|
||||
class Route
|
||||
{
|
||||
public:
|
||||
typedef std::vector<SDL_Point> Idxlist;
|
||||
typedef std::vector<SDL_Point> IdxList;
|
||||
|
||||
public:
|
||||
Route() = default;
|
||||
@ -63,13 +63,13 @@ public:
|
||||
|
||||
~Route() = default;
|
||||
|
||||
const Idxlist& get_idx_list() const
|
||||
const IdxList& get_idx_list() const
|
||||
{
|
||||
return idx_list;
|
||||
}
|
||||
|
||||
private:
|
||||
Idxlist idx_list;
|
||||
IdxList idx_list;
|
||||
|
||||
private:
|
||||
bool check_duplicate_idx(const SDL_Point& target_idx)
|
||||
|
20
TdGame/TdGame/slime_enemy.h
Normal file
20
TdGame/TdGame/slime_enemy.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#ifndef _SLIME_ENEMY_H_
|
||||
#define _SLIME_ENEMY_H_
|
||||
|
||||
#include "enemy.h"
|
||||
#include "config_manager.h"
|
||||
#include "resources_manager.h"
|
||||
|
||||
class SlimeEnemy
|
||||
{
|
||||
public:
|
||||
SlimeEnemy();
|
||||
~SlimeEnemy();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // !_SLIME_ENEMY_H_
|
@ -37,9 +37,14 @@ public:
|
||||
x -= vec.x; y -= vec.y;
|
||||
}
|
||||
|
||||
Vector2 operator*(const Vector2& vec)const
|
||||
double operator*(const Vector2& vec) const
|
||||
{
|
||||
return Vector2(x * vec.x , y* vec.y);
|
||||
return x * vec.x + y * vec.y;
|
||||
}
|
||||
|
||||
Vector2 operator*(double val)const
|
||||
{
|
||||
return Vector2(x * val , y* val);
|
||||
}
|
||||
|
||||
void operator*=(double val)
|
||||
@ -81,7 +86,7 @@ public:
|
||||
|
||||
bool approx_zero() const
|
||||
{
|
||||
return length() < 0.00001;
|
||||
return length() < 0.0001;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user