iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

翻車機率極高的2D平台遊戲(2D Platformer)製作系列 第 6

[Day6] 初見輸入系統

今日目標

  • 鍵盤滑鼠輸入

GLFW Input Callback

第一篇的時候,有簡單的介紹glfw管理的一系列輸入callback,,我只用了KeyCallback而已,但也只是做了一個簡單的ESC離開功能。在源始碼的資料夾裡,可以看到除了PC電腦的輸入裝置的處理,glfw還有搖桿的處理

今天會完成幾個常用的鍵盤輸入功能,會用到以下這幾種Callback

  • Key Callback (鍵盤輸入)
  • Mouse Button Callback (滑鼠按鍵輸入)
  • Mouse Cursor Position Callback (滑鼠游標位置)
  • Mouse Scroll Callback (滑鼠滾輪)

建立簡單的Input System

輸入功能的方向很簡單,尤其是單純製作最上層遊戲邏輯的部分,就是

按了甚麼按鍵,做甚麼事情;滑鼠移到哪裡,做甚麼事情

所以開了幾個關於「確定這個輸入是按下還是放開」的函式

// [iron_window] check is key pressed
int IsKeyPressed(KeyCode keycode);

// [iron_window] check is key released after pressed
int IsKeyReleased(KeyCode keycode);

// [iron_window] check is mouse button pressed
int IsMouseButtonPressed(MouseButton mouse_button);

// [iron_window] check is mouse button released
int IsMouseButtonReleased(MouseButton mouse_button);

// [iron_window] get mouse cursor position
V2f GetMousePosition();

// [iron_window] get mouse scroll roll
float GetScrollYOffset();

然後在WINDOW這個結構存取使用者的狀態。關於KeyCodeMouseButton這兩個enum,我在iron_types.hglfw定義的按鍵ID再複製一份到enum裡面,ID的定義可以參考glfw3.h的363行開始,然後利用這兩個enum定義出兩個這個陣列存在WINDOW裡,用於紀錄每個按鍵的狀態。

之後再依照glfw文件上處理callback的方式,完成這些功能了。

正要測試的時候發現到一點,我的KeyReleasedMouseButtonReleased如果沒按下去,就會一直觸發狀態(這不是廢話嗎~),但我想要的是按下之後,放開時要觸發。

於是我的處理方法也很簡單,直接加上一個跟按鍵狀態同大小的陣列,每一個GameLoop都去比較之前是有按過還是沒按過。最後當Game Loop結束的時候,在EndScene函式裡面更新按鍵的狀態。

// iron_window.EndScene

    glfwSwapBuffers(WINDOW.wnd);

    // reset input state
    // must put before call `glfwPollEvents`

    // keyboard
    for (int i = 0; i < MAX_KEY_CODE; i++) {
        WINDOW.Keyboard.key_previous_state[i] = WINDOW.Keyboard.key_current_state[i];
    }

    // mouse
    for (int i = 0; i < MAX_MOUSE_BUTTON; i++) {
        WINDOW.Mouse.mouse_btn_previous_state[i] = WINDOW.Mouse.mouse_btn_current_state[i];
    }
    WINDOW.Mouse.scroll_offset = 0.0f;

    glfwPollEvents();

這樣基本上就大功告成了...

參考

這是今天的成果


上一篇
[Day5] 第一章貼圖
下一篇
[Day7] 簡單的Log
系列文
翻車機率極高的2D平台遊戲(2D Platformer)製作33

尚未有邦友留言

立即登入留言