游戏引擎从零开始(4)-input event

作者:狼烟四起2024.01.29 16:33浏览量:138

简介:在游戏引擎开发中,处理用户输入事件是至关重要的。本文将介绍如何从零开始实现一个基本的输入事件系统,包括键盘、鼠标和游戏控制器等输入设备的处理。

游戏引擎开发中,处理用户输入事件是至关重要的。玩家需要通过键盘、鼠标或游戏控制器等设备与游戏进行交互,因此一个高效的输入事件系统是必不可少的。在本篇文章中,我们将从零开始实现一个基本的输入事件系统,包括键盘、鼠标和游戏控制器等输入设备的处理。
一、输入事件概述
输入事件是指用户通过键盘、鼠标、游戏控制器等设备与应用程序进行交互时产生的事件。在游戏引擎中,这些事件通常包括按键按下、按键释放、鼠标移动、鼠标点击等。处理这些事件可以帮助我们控制角色的移动、射击或其他交互行为。
二、实现输入事件系统

  1. 创建事件类
    首先,我们需要创建一个事件类来存储输入事件的相关信息。这个类应该包含事件类型(如按键按下、鼠标移动等)、事件发生的时间以及与事件相关的数据(如按键码、鼠标位置等)。
    1. class InputEvent {
    2. public:
    3. enum class Type { KEYBOARD, MOUSE, GAMEPAD };
    4. InputEvent(Type type, float time, int keycode, int x, int y);
    5. InputEvent(Type type, float time, int x, int y);
    6. InputEvent(Type type, float time, GamePad::Button button);
    7. Type getType() const;
    8. float getTime() const;
    9. int getKeyCode() const;
    10. int getX() const;
    11. int getY() const;
    12. GamePad::Button getGamePadButton() const;
    13. };
  2. 注册输入事件监听器
    接下来,我们需要创建一个输入事件监听器类,让其他对象能够注册成为事件的接收者。这个类应该包含一个监听器列表,用于存储注册的监听器对象。当发生输入事件时,这个类会遍历监听器列表,将事件传递给每个监听器对象进行处理。
    1. class InputEventListener {
    2. public:
    3. virtual void onInputEvent(const InputEvent& event) = 0;
    4. };
    5. class InputEventDispatcher {
    6. public:
    7. void registerListener(InputEventListener* listener);
    8. void unregisterListener(InputEventListener* listener);
    9. void dispatchEvent(const InputEvent& event);
    10. };
  3. 处理输入事件
    在我们的游戏循环中,我们需要不断地检查是否有新的输入事件发生,并将它们分发给注册的监听器对象进行处理。具体实现可以参考以下代码:
    1. void InputEventDispatcher::update(float deltaTime) {
    2. std::vector<InputEvent> events = getInputEvents(); // 获取所有输入事件
    3. for (const auto& event : events) {
    4. dispatchEvent(event); // 分发事件给所有监听器对象
    5. }
    6. }
  4. 实现监听器对象
    最后,我们需要实现具体的监听器对象来处理不同类型的输入事件。这些监听器对象应该继承自InputEventListener类,并重写onInputEvent方法来处理特定的事件类型。例如,我们可以创建一个键盘监听器来处理按键按下和释放事件:
    ```cpp
    class KeyboardListener : public InputEventListener {
    public:
    void onInputEvent(const InputEvent& event) override {
    if (event.getType() == InputEvent::Type::KEYBOARD) {
    switch (event.getKeyCode()) {
    case GLFW_KEY_W: // 按键W被按下时执行相应的操作…} break; // …处理W键按下事件…} break;