目 录CONTENT

文章目录

【2D平台跳跃游戏 - 04】工具

千年的霜雪
2024-09-17 / 0 评论 / 0 点赞 / 6 阅读 / 0 字 / 正在检测是否收录...

【2D平台跳跃游戏 - 04】工具

定时器类

思路

定时器是一个记录游戏时间流逝的对象

若使用回调函数实现,那么就设置set_callback()方法,使用定时器时注册自己的回调函数,并由定时器存储
当流逝的时间到达预定的那一帧时,就执行回调函数的逻辑

定时器还支持暂停与循环计时,所以拥有两个布尔变量,分别记录是否暂停和循环计时

定时器类中有以下方法:

  1. 重新启动:重置存储时间并设置未触发过
  2. 设置等待时间
  3. 设置单次触发
  4. 设置回调函数
  5. 暂停
  6. 恢复
  7. 更新方法:首先判断是否暂停;然后累加时间,如果超过设定时间,并且存在回调函数,就尝试调用回调函数,同时将存储时间归零,然后设置触发状态为已触发

具体实现

#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);
	}
};
0

评论区