feat:二维向量类,Animation类

This commit is contained in:
sjm 2024-06-24 00:17:55 +08:00
parent 49a2c6beeb
commit 7676213633
5 changed files with 209 additions and 3 deletions

View File

@ -136,6 +136,7 @@
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="animation.h" />
<ClInclude Include="config_manager.h" />
<ClInclude Include="enemy_type.h" />
<ClInclude Include="game_manager.h" />
@ -145,6 +146,7 @@
<ClInclude Include="route.h" />
<ClInclude Include="tile.h" />
<ClInclude Include="timer.h" />
<ClInclude Include="vector2.h" />
<ClInclude Include="wave.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -62,5 +62,11 @@
<ClInclude Include="timer.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="animation.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="vector2.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
</Project>

109
TdGame/TdGame/animation.h Normal file
View File

@ -0,0 +1,109 @@
#pragma once
#ifndef _ANIMATION_H_
#define _ANIMATION_H_
#include "timer.h"
#include <SDL.h>
#include <vector>
#include <functional>
class Animation
{
public:
//表示一个可以存储和调用无参数且无返回值的可调用对象类型。
typedef std::function<void()> 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<int>& 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<SDL_Rect> rect_src_list;
int width_frame = 0, height_frame = 0;
};
#endif // ! _ANIMATION_H_

View File

@ -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<void()> on_timeout;
};

88
TdGame/TdGame/vector2.h Normal file
View File

@ -0,0 +1,88 @@
#pragma once
#ifndef _VECTOR2_H_
#define _VECTOR2_H_
#include <cmath>
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