diff --git a/TdGame/TdGame/TdGame.vcxproj b/TdGame/TdGame/TdGame.vcxproj index 755509a..e1fbe71 100644 --- a/TdGame/TdGame/TdGame.vcxproj +++ b/TdGame/TdGame/TdGame.vcxproj @@ -138,12 +138,14 @@ + + diff --git a/TdGame/TdGame/TdGame.vcxproj.filters b/TdGame/TdGame/TdGame.vcxproj.filters index 9057f12..0a681fd 100644 --- a/TdGame/TdGame/TdGame.vcxproj.filters +++ b/TdGame/TdGame/TdGame.vcxproj.filters @@ -68,5 +68,11 @@ 头文件 + + 头文件\enemy + + + 头文件\enemy + \ No newline at end of file diff --git a/TdGame/TdGame/animation.h b/TdGame/TdGame/animation.h index bebccf3..48a9e8c 100644 --- a/TdGame/TdGame/animation.h +++ b/TdGame/TdGame/animation.h @@ -12,7 +12,7 @@ class Animation { public: - //±íʾһ¸ö¿ÉÒÔ´æ´¢ºÍµ÷ÓÃÎÞ²ÎÊýÇÒÎÞ·µ»ØÖµµÄ¿Éµ÷ÓöÔÏóÀàÐÍ¡£ + //±íʾһ¸ö,¿ÉÒÔ´æ´¢ºÍµ÷ÓÃÎÞ²ÎÊýÇÒÎÞ·µ»ØÖµµÄ,¿Éµ÷ÓöÔÏóÀàÐÍ¡£ typedef std::function PlayCallBack; public: Animation() diff --git a/TdGame/TdGame/enemy.h b/TdGame/TdGame/enemy.h new file mode 100644 index 0000000..69b19a0 --- /dev/null +++ b/TdGame/TdGame/enemy.h @@ -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 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_ diff --git a/TdGame/TdGame/map.h b/TdGame/TdGame/map.h index 9bd3f33..709ae26 100644 --- a/TdGame/TdGame/map.h +++ b/TdGame/TdGame/map.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 ""; diff --git a/TdGame/TdGame/route.h b/TdGame/TdGame/route.h index a8b1093..0174cf3 100644 --- a/TdGame/TdGame/route.h +++ b/TdGame/TdGame/route.h @@ -10,7 +10,7 @@ class Route { public: - typedef std::vector Idxlist; + typedef std::vector 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) diff --git a/TdGame/TdGame/slime_enemy.h b/TdGame/TdGame/slime_enemy.h new file mode 100644 index 0000000..cbc4856 --- /dev/null +++ b/TdGame/TdGame/slime_enemy.h @@ -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_ diff --git a/TdGame/TdGame/vector2.h b/TdGame/TdGame/vector2.h index 7074361..92e09e9 100644 --- a/TdGame/TdGame/vector2.h +++ b/TdGame/TdGame/vector2.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; } };