feat: enemy敌人基类实现
This commit is contained in:
@@ -138,12 +138,14 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="animation.h" />
|
<ClInclude Include="animation.h" />
|
||||||
<ClInclude Include="config_manager.h" />
|
<ClInclude Include="config_manager.h" />
|
||||||
|
<ClInclude Include="enemy.h" />
|
||||||
<ClInclude Include="enemy_type.h" />
|
<ClInclude Include="enemy_type.h" />
|
||||||
<ClInclude Include="game_manager.h" />
|
<ClInclude Include="game_manager.h" />
|
||||||
<ClInclude Include="manager.h" />
|
<ClInclude Include="manager.h" />
|
||||||
<ClInclude Include="map.h" />
|
<ClInclude Include="map.h" />
|
||||||
<ClInclude Include="resources_manager.h" />
|
<ClInclude Include="resources_manager.h" />
|
||||||
<ClInclude Include="route.h" />
|
<ClInclude Include="route.h" />
|
||||||
|
<ClInclude Include="slime_enemy.h" />
|
||||||
<ClInclude Include="tile.h" />
|
<ClInclude Include="tile.h" />
|
||||||
<ClInclude Include="timer.h" />
|
<ClInclude Include="timer.h" />
|
||||||
<ClInclude Include="vector2.h" />
|
<ClInclude Include="vector2.h" />
|
||||||
|
|||||||
@@ -68,5 +68,11 @@
|
|||||||
<ClInclude Include="vector2.h">
|
<ClInclude Include="vector2.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="enemy.h">
|
||||||
|
<Filter>头文件\enemy</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="slime_enemy.h">
|
||||||
|
<Filter>头文件\enemy</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
class Animation
|
class Animation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//<2F><>ʾһ<CABE><D2BB><EFBFBD><EFBFBD><EFBFBD>Դ洢<D4B4>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><DEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB7><EFBFBD>ֵ<EFBFBD>Ŀɵ<EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD>
|
//<2F><>ʾһ<CABE><D2BB>,<EFBFBD><EFBFBD><EFBFBD>Դ洢<EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>,<2C>ɵ<EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD>
|
||||||
typedef std::function<void()> PlayCallBack;
|
typedef std::function<void()> PlayCallBack;
|
||||||
public:
|
public:
|
||||||
Animation()
|
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()
|
||||||
|
{
|
||||||
|
//<2F><><EFBFBD>ܼ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
timer_skill.set_one_shot(false);
|
||||||
|
timer_skill.set_on_timeout([&]() {on_skill_released(this); });
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
timer_sketch.set_one_shot(true);
|
||||||
|
timer_sketch.set_wait_time(0.075);
|
||||||
|
timer_sketch.set_on_timeout([&]() {is_show_sketch = false; });
|
||||||
|
|
||||||
|
//<2F>ٶȻָ<C8BB><D6B8><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
timer_restore_speed.set_one_shot(true);
|
||||||
|
timer_restore_speed.set_on_timeout([&]() {speed = max_speed;});
|
||||||
|
}
|
||||||
|
~Enemy() = default;
|
||||||
|
|
||||||
|
//֡<><D6A1><EFBFBD><EFBFBD>
|
||||||
|
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;
|
||||||
|
|
||||||
|
//<2F>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
||||||
|
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;
|
||||||
|
|
||||||
|
//<2F>Ƿ<EFBFBD>չʾˮƽ<CBAE><C6BD><EFBFBD><EFBFBD>
|
||||||
|
bool is_show_x_anim = (velocity.x) >= abs(velocity.y);
|
||||||
|
|
||||||
|
//1.<2E>Ƿ<EFBFBD>չʾ<D5B9><CABE>Ӱ 2.<2E>Ƿ<EFBFBD>չʾˮƽ<CBAE><C6BD><EFBFBD><EFBFBD>
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//Ѫ<><D1AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA1A2><EFBFBD>߿<DFBF><F2A3ACB8><EFBFBD>)
|
||||||
|
static SDL_Rect rect;
|
||||||
|
static SDL_Point point;
|
||||||
|
static const int offset_y = 2;
|
||||||
|
static Vector2 size_hp_bar = { 40,8 };
|
||||||
|
//Ѫ<><D1AA><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>ɫ
|
||||||
|
static const SDL_Color color_border = { 116,185,124,255 };
|
||||||
|
//Ѫ<><D1AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//<2F><><EFBFBD><EFBFBD>Ѫ<EFBFBD><D1AA>
|
||||||
|
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);
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD>Ѫ<EFBFBD><D1AA><EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//<2F><>ȡ<EFBFBD>ָ<EFBFBD><D6B8>뾶
|
||||||
|
double get_recover_radius()const
|
||||||
|
{
|
||||||
|
//ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
return recover_range * SIZE_TILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_recover_intensity()const
|
||||||
|
{
|
||||||
|
return recover_intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
//<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƴ<EFBFBD>enemy
|
||||||
|
bool can_move()
|
||||||
|
{
|
||||||
|
return !is_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//<2F><>ȡenemy<6D><79>·<EFBFBD><C2B7><EFBFBD>ϵĽ<CFB5><C4BD><EFBFBD>
|
||||||
|
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;
|
||||||
|
//<2F><><EFBFBD>ٺ<EFBFBD><D9BA>ٶ<EFBFBD>
|
||||||
|
double speed = 0;
|
||||||
|
double max_speed = 0;
|
||||||
|
//<2F>Է<EFBFBD><D4B7><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>˺<EFBFBD>
|
||||||
|
double damage = 0;
|
||||||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ҹ<EFBFBD><D2B8><EFBFBD>
|
||||||
|
double reward_ratio = 0;
|
||||||
|
//<2F>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ܵļ<DCB5><C4BC><EFBFBD>
|
||||||
|
double recover_interval = 0;
|
||||||
|
//<2F>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ܵķ<DCB5>Χ
|
||||||
|
double recover_range = 0;
|
||||||
|
//<2F>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ܵ<EFBFBD>ǿ<EFBFBD><C7BF>
|
||||||
|
double recover_intensity = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//λ<><CEBB>
|
||||||
|
Vector2 position;
|
||||||
|
//<2F>ٶ<EFBFBD>
|
||||||
|
Vector2 velocity;
|
||||||
|
//<2F><><EFBFBD><EFBFBD>
|
||||||
|
Vector2 direction;
|
||||||
|
|
||||||
|
bool is_valid = true;
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>չʾ<D5B9><CABE><EFBFBD><EFBFBD>
|
||||||
|
Timer timer_sketch;
|
||||||
|
bool is_show_sketch = false;
|
||||||
|
|
||||||
|
//<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>֡
|
||||||
|
Animation* anim_current = nullptr;
|
||||||
|
|
||||||
|
SkillCallback on_skill_released;
|
||||||
|
|
||||||
|
//<2F>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
Timer timer_restore_speed;
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
|
||||||
|
const Route* route = nullptr;
|
||||||
|
|
||||||
|
//<2F><>ǰ<EFBFBD><C7B0>Ŀ<EFBFBD>굥Ԫ<EAB5A5><D4AA>
|
||||||
|
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:
|
|||||||
//һ<><D2BB>ȥ<EFBFBD><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ո<EFBFBD><D5B8><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD>
|
//һ<><D2BB>ȥ<EFBFBD><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ո<EFBFBD><D5B8><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD>
|
||||||
std::string trim_str(const std::string& str)
|
std::string trim_str(const std::string& str)
|
||||||
{
|
{
|
||||||
|
//<2F>ҵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ǿո<C7BF><D5B8><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸλ<C4B8>ã<EFBFBD><C3A3>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ->nops
|
||||||
size_t begin_idx = str.find_first_not_of(" \t");
|
size_t begin_idx = str.find_first_not_of(" \t");
|
||||||
if (begin_idx == std::string::npos)
|
if (begin_idx == std::string::npos)
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
class Route
|
class Route
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<SDL_Point> Idxlist;
|
typedef std::vector<SDL_Point> IdxList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Route() = default;
|
Route() = default;
|
||||||
@@ -63,13 +63,13 @@ public:
|
|||||||
|
|
||||||
~Route() = default;
|
~Route() = default;
|
||||||
|
|
||||||
const Idxlist& get_idx_list() const
|
const IdxList& get_idx_list() const
|
||||||
{
|
{
|
||||||
return idx_list;
|
return idx_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Idxlist idx_list;
|
IdxList idx_list;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool check_duplicate_idx(const SDL_Point& target_idx)
|
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;
|
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)
|
void operator*=(double val)
|
||||||
@@ -81,7 +86,7 @@ public:
|
|||||||
|
|
||||||
bool approx_zero() const
|
bool approx_zero() const
|
||||||
{
|
{
|
||||||
return length() < 0.00001;
|
return length() < 0.0001;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user