Hazel游戏引擎(019)输入事件轮询

文章介绍了如何在引擎程序中实现任意位置检测输入事件,如按键和鼠标点击。方法是利用GLFW的输入事件检测函数,封装成静态单例类,提供统一的接口供全局使用。具体实现包括键盘按键和鼠标按钮的状态检查以及鼠标位置的获取。
摘要由CSDN通过智能技术生成

文中若有代码、术语等错误,欢迎指正

前言

  • 此节目的

    在引擎程序中任何位置都能询问本应用是否有输入事件(按键是否按下、鼠标是否点击、鼠标位置等)。

  • 分析

    目前引擎程序已能获得GLFW窗口事件,但是通过Application的OnEvent分发给所属的Layer层,

    这并不能实现在程序任何位置都能知道此时是否有输入事件。

  • 如何实现

    • 方法一

      自己写一套检测输入事件系统,因为现在能接收GLFW窗口事件,当检测到一个按键按下事件时,将这个按键设置为按下,当检测到按键松开时,将这个按键设置为释放。

      这是一个方式,但是自己根据GLFW窗口事件来实现,有点麻烦

    • 方法二

      通过GLFW已经提供的输入事件检测函数来检测输入事件,并封装为一个类供引擎程序全局使用(代表此类应是单例静态的对象)。

      此节用方法二

项目相关

代码

  • Input

    #pragma once
    #include "Hazel/Core.h"
    namespace Hazel {
    	class HAZEL_API Input{
    	public:
    		inline static bool IsKeyPressed(int keycode) { return s_Instance->IsKeyPressedImpl(keycode); }
    		inline static bool IsMouseButtonPressed(int button) { return s_Instance->IsMouseButtonPressedImpl(button); }
    		inline static std::pair<float, float> GetMousePosition() { return s_Instance->GetMousePositionImpl(); }
    		inline static float GetMouseX() { return s_Instance->GetMouseXImpl(); }
    		inline static float GetMouseY() { return s_Instance->GetMouseYImpl(); }
    	protected:
    		virtual bool IsKeyPressedImpl(int keycode) = 0;
    
    		virtual bool IsMouseButtonPressedImpl(int button) = 0;
    		virtual std::pair<float, float> GetMousePositionImpl() = 0;
    		virtual float GetMouseXImpl() = 0;
    		virtual float GetMouseYImpl() = 0;
    	private:
    		static Input* s_Instance;// 声明静态单例全局对象
    	};
    }
    
  • WindowsInput

    #pragma once
    #include "Hazel/Input.h"
    namespace Hazel {
    	class WindowsInput : public Input{
    	protected:
    		virtual bool IsKeyPressedImpl(int keycode) override;
    
    		virtual bool IsMouseButtonPressedImpl(int button) override;
    		virtual std::pair<float, float> GetMousePositionImpl() override;
    		virtual float GetMouseXImpl() override;
    		virtual float GetMouseYImpl() override;
    	};
    }
    
    #include "hzpch.h"
    #include "WindowsInput.h"
    #include "Hazel/Application.h"
    #include <GLFW/glfw3.h>
    namespace Hazel {
    	// 父类指针指向子类对象
    	Input* Input::s_Instance = new WindowsInput();// 定义静态单例全局对象
    	bool WindowsInput::IsKeyPressedImpl(int keycode){
    		// 获取GLFW原生窗口void*,转为GLFWwindow*
    		auto window = static_cast<GLFWwindow*>(Application::Get().GetWindow().GetNativeWindow());
    		// 用已有的GLFW函数来获取按键状态
    		auto state = glfwGetKey(window, keycode);
    		return state == GLFW_PRESS || state == GLFW_REPEAT;
    	}
    	bool WindowsInput::IsMouseButtonPressedImpl(int button){
    		auto window = static_cast<GLFWwindow*>(Application::Get().GetWindow().GetNativeWindow());
    		auto state = glfwGetMouseButton(window, button);
    		return state == GLFW_PRESS;
    	}
    	std::pair<float, float> WindowsInput::GetMousePositionImpl(){
    		auto window = static_cast<GLFWwindow*>(Application::Get().GetWindow().GetNativeWindow());
    		double xpos, ypos;
    		glfwGetCursorPos(window, &xpos, &ypos);
    
    		return { (float)xpos, (float)ypos };
    	}
    	float WindowsInput::GetMouseXImpl(){
    		// C++17写法
    		auto [x, y] = GetMousePositionImpl();
    		return x;
    		// C++14以下
    		//auto x = GetMousePositionImpl();
    		//return std::get<0>(x);
    	}
    	float WindowsInput::GetMouseYImpl(){
    		auto [x, y] = GetMousePositionImpl();
    		return y;
    	}
    }
    

测试效果

  • Application

    void Application::Run()
    {
        while (m_Running)
        {
            glClearColor(1, 0, 1, 1);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // 从前往后顺序更新层
            for (Layer* layer : m_LayerStack)
                layer->OnUpdate();
    		//
            // 测试:全局输入事件检测
            /
            auto [x, y] = Input::GetMousePosition();
    			HZ_CORE_TRACE("{0}, {1}", x, y);
            m_Window->OnUpdate();	// 更新glfw
        }
    }
    

    请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘建杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值