From 76762136330614857f29f1d75396305a5e5ec287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=BA=E6=98=8E=20=E6=B2=88?= <2431685932@qq.com> Date: Mon, 24 Jun 2024 00:17:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BA=8C=E7=BB=B4=E5=90=91=E9=87=8F?= =?UTF-8?q?=E7=B1=BB=EF=BC=8CAnimation=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TdGame/TdGame/TdGame.vcxproj | 2 + TdGame/TdGame/TdGame.vcxproj.filters | 6 ++ TdGame/TdGame/animation.h | 109 +++++++++++++++++++++++++++ TdGame/TdGame/timer.h | 7 +- TdGame/TdGame/vector2.h | 88 +++++++++++++++++++++ 5 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 TdGame/TdGame/animation.h create mode 100644 TdGame/TdGame/vector2.h diff --git a/TdGame/TdGame/TdGame.vcxproj b/TdGame/TdGame/TdGame.vcxproj index 6d5aa1c..755509a 100644 --- a/TdGame/TdGame/TdGame.vcxproj +++ b/TdGame/TdGame/TdGame.vcxproj @@ -136,6 +136,7 @@ + @@ -145,6 +146,7 @@ + diff --git a/TdGame/TdGame/TdGame.vcxproj.filters b/TdGame/TdGame/TdGame.vcxproj.filters index dc70d1d..9057f12 100644 --- a/TdGame/TdGame/TdGame.vcxproj.filters +++ b/TdGame/TdGame/TdGame.vcxproj.filters @@ -62,5 +62,11 @@ 头文件 + + 头文件 + + + 头文件 + \ No newline at end of file diff --git a/TdGame/TdGame/animation.h b/TdGame/TdGame/animation.h new file mode 100644 index 0000000..bebccf3 --- /dev/null +++ b/TdGame/TdGame/animation.h @@ -0,0 +1,109 @@ +#pragma once +#ifndef _ANIMATION_H_ +#define _ANIMATION_H_ + +#include "timer.h" + +#include +#include +#include + + +class Animation +{ +public: + //±íʾһ¸ö¿ÉÒÔ´æ´¢ºÍµ÷ÓÃÎÞ²ÎÊýÇÒÎÞ·µ»ØÖµµÄ¿Éµ÷ÓöÔÏóÀàÐÍ¡£ + typedef std::function PlayCallBack; +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; + if (!is_loop && on_finished) + on_finished(); + } + } + ); + } + ~Animation() = default; + + void reset() + { + timer.restart(); + + idx_frame = 0; + } + + void set_frame_data(SDL_Texture* texture, int num_x, int num_y, const std::vector& idx_list) + { + int width_tex, height_tex; + + this->texture = texture; + SDL_QueryTexture(texture, nullptr, nullptr, &width_tex, &height_tex); + width_frame = width_tex / num_x, height_frame = height_tex / num_y; + + rect_src_list.resize(idx_list.size()); + for (size_t i = 0; i < idx_list.size(); i++) + { + int idx = idx_list[i]; + SDL_Rect& rect_src = rect_src_list[i]; + + 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; + }; + } + + void set_loop(bool is_loop) + { + this->is_loop = is_loop; + } + + void set_interval(double interval) + { + timer.set_wait_time(interval); + } + + void set_on_finished(PlayCallBack on_finished) + { + this->on_finished = on_finished; + } + + void on_update(double delta) + { + timer.on_update(delta); + } + //äÖȾÆ÷£¬äÖȾλÖ㬽Ƕȣ¨¿ÉÄÜÊÇÐýת£© + void on_render(SDL_Renderer* renderer, const SDL_Point& pos_dst, double angle = 0)const + { + static SDL_Rect rect_dst; + + 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); + } +private: + Timer timer; + //¶¯»­ÊÇ·ñÑ­»·£¨½ÇÉ«¶¯»­ÄÜÑ­»·£¬ÌØЧ¶¯»­²»ÄÜ£© + bool is_loop = true; + //¼Ç¼µ±Ç°²¥·ÅµÚ¼¸Ö¡ + size_t idx_frame = 0; + PlayCallBack on_finished; + //¶¯»­ËùÓÃÎÆÀí + SDL_Texture* texture = nullptr; + std::vector rect_src_list; + int width_frame = 0, height_frame = 0; +}; + + +#endif // ! _ANIMATION_H_ diff --git a/TdGame/TdGame/timer.h b/TdGame/TdGame/timer.h index 31a9c6e..fd1c9d2 100644 --- a/TdGame/TdGame/timer.h +++ b/TdGame/TdGame/timer.h @@ -50,6 +50,7 @@ public: { bool can_shot = (!one_shot || (one_shot && !shotted)); shotted = true; + //Èç¹ûÄÜ´¥·¢£¬ÇÒ³¬Ê±º¯ÊýÒѾ­ÉèÖà if (can_shot && on_timeout) on_timeout; @@ -59,16 +60,16 @@ public: private: //´´½¨¼ÆʱÆ÷¿ªÊ¼¹ýÈ¥¶àÉÙʱ¼ä double pass_time = 0; - //µÈ´ý¶à¾Ã´¥·¢¶¨Ê±Æ÷ + //´¥·¢¶¨Ê±Æ÷Ç°µÈ´ýʱ¼ä double wait_time = 0; //±ê×¢¼ÆʱÆ÷ÊÇ·ñÔÝÍ£ bool paused = false; - //Èç¹ûÊǵ¥´Î´¥·¢£¬¼Ç¼״̬£¬²»¿ÉÔٴδ¥·¢ + //Èç¹ûÊǵ¥´Î´¥·¢£¬¼Ç¼´¥·¢×´Ì¬£¬²»¿ÉÔٴδ¥·¢ bool shotted = false; //ÊÇ·ñÊǵ¥´Î´¥·¢ bool one_shot = false; - + //»Øµ÷º¯Êý£¬±íʾ³¬Ê±Ó¦¸Ã´¦Àíʲô std::function on_timeout; }; diff --git a/TdGame/TdGame/vector2.h b/TdGame/TdGame/vector2.h new file mode 100644 index 0000000..7074361 --- /dev/null +++ b/TdGame/TdGame/vector2.h @@ -0,0 +1,88 @@ +#pragma once +#ifndef _VECTOR2_H_ +#define _VECTOR2_H_ + +#include + +class Vector2 +{ +public: + double x = 0; + double y = 0; + +public: + Vector2() = default; + ~Vector2() = default; + + Vector2(double x, double y) + :x(x), y(y) {} + + Vector2 operator+(const Vector2& vec) const + { + return Vector2(x + vec.x, y + vec.y); + } + + void operator+=(const Vector2& vec) + { + x += vec.x; y += vec.y; + } + + Vector2 operator-(const Vector2& vec) const + { + return Vector2(x - vec.x, y - vec.y); + } + + void operator-=(const Vector2& vec) + { + x -= vec.x; y -= vec.y; + } + + Vector2 operator*(const Vector2& vec)const + { + return Vector2(x * vec.x , y* vec.y); + } + + void operator*=(double val) + { + x *= val, y *= val; + } + + bool operator==(const Vector2& vec)const + { + return x == vec.x && y == vec.y; + } + + bool operator>(const Vector2& vec)const + { + return length() > vec.length(); + } + + bool operator<(const Vector2& vec)const + { + return length() < vec.length(); + } + + //ÏòÁ¿³¤¶È + double length() const + { + return sqrt(x * x + y * y); + } + + //µ¥Î»ÏòÁ¿ + Vector2 normalize() const + { + double len = length(); + + if (len == 0) + return Vector2(0, 0); + + return Vector2(x / len, y / len); + } + + bool approx_zero() const + { + return length() < 0.00001; + } +}; + +#endif \ No newline at end of file