【游戏引擎】事件系统

事件的注册

在这里插入图片描述
引擎支持多种窗口,如glfw窗口,Win窗口。每个都有自己的事件系统。
希望引进统一事件的管理,并且方便把事件分发到我们游戏中的各个部分,就需要自己实现一套事件系统,这样事件系统可以跟窗口类解耦。
本节解决事件如何产生与分发。

1、事件系统的实现主要是设计各种事件类

事件注册,

在事件发生那一刻,最先是由window类中注册的回调函数捕捉到事件,这个回调函数要做的事情是创建对应的事件类,并把类交给Application,这样是为让了Application将事件分发给各个Layer。
那么如何实现?
首先Application和window类是包含关系,在Application的初始化中创建了具体的Window,另外我们需要在Window类中添加一个回调函数,在创建Window时,Application立马将这个Window的回调函数注册为自己的Application::OnEvent(Event& e)。然后Window类的每个事件的回调函数只做两个事情:1-创建事件类对象。2-执行OnEvent(e)。
以glfw窗口为例,主要代码如下。

class WindowsWindow : public Window
{
public:
void WindowsWindow::Init(const WindowProps& props)
{
	glfwSetWindowUserPointer(m_Window, &m_Data);	//注意这个函数是为了glfw的回调中获取WindowData指针
...
	//这里注册了glfw的键盘事件
	glfwSetKeyCallback(m_Window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
	{
		WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);

		switch (action)
		{
		case GLFW_PRESS:
		{
			KeyPressedEvent event(key, 0);	//1-创建事件类
			data.EventCallback(event);		//2-执行Application的OnEvent
			break;
		}
		case GLFW_RELEASE:
		{
			KeyReleasedEvent event(key);
			data.EventCallback(event);
			break;
		}
		case GLFW_REPEAT:
		{
			KeyPressedEvent event(key, 1);
			data.EventCallback(event);
			break;
		}
		}
	});
...
}
private:
	GLFWwindow* m_Window;
	struct WindowData
	{
		std::string Title;
		unsigned int Width, Height;
		bool VSync;

		EventCallbackFn EventCallback;	//这个就是Application:OnEvent的回调
	};

	WindowData m_Data;
};

class HAZEL_API Application
{
public:
Application::Application()
{
	m_Window = std::unique_ptr<Window>(Window::Create());	//创建Window
	m_Window->SetEventCallback(HZ_BIND_EVENT_FN(Application::OnEvent));	//注册回调
}
void Application::OnEvent(Event& e)
{
	EventDispatcher dispatcher(e);
	dispatcher.Dispatch<WindowCloseEvent>(HZ_BIND_EVENT_FN(Application::OnWindowClose));

	for (auto it = m_LayerStack.end(); it != m_LayerStack.begin(); )
	{
		(*--it)->OnEvent(e);
		//避免事件往下派发,例如 防止UI层和游戏层同时响应点击
		if (e.Handled)
			break;
	}
}
private:
	bool OnWindowClose(WindowCloseEvent& e);

	std::unique_ptr<Window> m_Window;
	LayerStack m_LayerStack;
	bool m_Running = true;
};

事件注册:
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值