【2D平台跳跃游戏 - 04】工具
定时器类
思路
定时器是一个记录游戏时间流逝的对象
若使用回调函数实现,那么就设置set_callback()
方法,使用定时器时注册自己的回调函数,并由定时器存储
当流逝的时间到达预定的那一帧时,就执行回调函数的逻辑
定时器还支持暂停与循环计时,所以拥有两个布尔变量,分别记录是否暂停和循环计时
定时器类中有以下方法:
- 重新启动:重置存储时间并设置未触发过
- 设置等待时间
- 设置单次触发
- 设置回调函数
- 暂停
- 恢复
- 更新方法:首先判断是否暂停;然后累加时间,如果超过设定时间,并且存在回调函数,就尝试调用回调函数,同时将存储时间归零,然后设置触发状态为已触发
具体实现
#include <functional>
class Timer
{
public:
Timer() = default;
~Timer() = default;
// 重新启动
void restart()
{
pass_time = 0;
shotted = false;
}
// 设置等待时间
void set_wait_time(int val)
{
wait_time = val;
}
// 设置单次触发
void set_one_shot(bool flag)
{
one_shot = flag;
}
// 设置回调函数
void set_callback(std::function<void()> callback)
{
this->callback = callback;
}
// 暂停
void pause()
{
paused = true;
}
// 重新启动
void resume()
{
paused = false;
}
// 更新方法
void on_update(int delta)
{
if (paused)
return;
pass_time += delta;
if (pass_time >= wait_time)
{
if ((!one_shot || (one_shot && !shotted)) && callback)
callback();
shotted = true;
pass_time = 0;
}
}
private:
int pass_time = 0; // 已过时间
int wait_time = 0; // 等待时间
bool paused = false; // 是否暂停
bool shotted = false; // 是否触发
bool one_shot = false; // 单次触发
std::function<void()> callback; // 回调函数
};
另一种思路
第二种思路是使用继承实现,类似于场景
首先实现一个定时器基类,同时将回调函数设定为虚函数,每个地方使用时,需要创建自己的定时器子类,并且实现回调函数即可
二维向量类
二维向量类不同于系统自带的POINT
类,由于在数据计算时需要更高精度的浮点计算,所以封装了二维向量类
思路
向量类中有两个浮点型共有变量x,y
向量类中重载了常用的运算符
向量类中提供了两个额外方法:
获取向量长度和标准化向量
具体实现
#include <cmath>
// 向量类
class Vector2
{
public:
float x = 0;
float y = 0;
public:
Vector2() = default;
~Vector2() = default;
Vector2(float x, float 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;
}
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);
}
float operator*(const Vector2& vec) const
{
return x * vec.x + y * vec.y;
}
Vector2 operator*(float val) const
{
return Vector2(x * val, y * val);
}
void operator*=(float val)
{
x *= val, y *= val;
}
// 获取向量长度
float length()
{
return sqrt(x * x + y * y);
}
// 标准化向量
Vector2 normalize()
{
float len = length();
if (len == 0)
return Vector2(0, 0);
return Vector2(x / len, y / len);
}
};
评论区