feat: enemy敌人基类实现
This commit is contained in:
@@ -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:
|
||||
//<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;
|
||||
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()
|
||||
{
|
||||
//<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>
|
||||
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");
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user