SDL3_API分类参考_扫描码(CategoryScancode)

2026-3-6 / 0 评论 / 3 阅读

扫描码子系统(CategoryScancode)

该模块定义了键盘扫描码(Scancode)的核心枚举类型,扫描码用于标识键盘上物理按键的位置,而非按键上的符号。

关于扫描码的具体含义和最佳使用方式,请参考官方键盘使用最佳实践文档:
https://wiki.libsdl.org/SDL3/BestKeyboardPractices


函数

  • (无)

数据类型

  • (无)

结构体

  • (无)

枚举

  • SDL_Scancode:键盘扫描码枚举(每个值对应键盘上一个固定的物理位置,参考美式 QWERTY 键盘布局,与按键符号/键盘布局无关)

  • (无)

FreeBASIC 示例代码

' 引入 SDL 相关声明(需确保 FreeBASIC 已链接 SDL3 库)
#Include "SDL.bi"

' 辅助函数:打印扫描码详细信息
Sub PrintScancodeInfo(ByVal scancode As SDL_Scancode)
    ' 获取扫描码名称
    Dim As ZString Ptr scName = SDL_GetScancodeName(scancode)
    ' 扫描码转按键码(体现布局差异)
    Dim As SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode)
    Dim As ZString Ptr keyName = SDL_GetKeyName(keycode)

    SDL_LogInfo(SDL_LOG_CATEGORY_INPUT, _
        "扫描码:%d (0x%X) | 扫描码名称:%s | 对应按键码:0x%X | 按键名称:%s", _
        scancode, scancode, scName, keycode, keyName)

    ' 释放字符串资源
    SDL_free(scName)
    SDL_free(keyName)
End Sub

' 模拟 WASD 移动(核心场景:基于物理位置的输入)
Sub HandleWASDMovement()
    Static As Integer lastDirX = 0, lastDirY = 0
    Dim As UByte Ptr keyStates = SDL_GetKeyboardState(NULL)

    ' 基于扫描码的物理位置检测(与布局无关)
    Dim As Integer dirX = 0, dirY = 0
    If (keyStates[SDL_SCANCODE_A]) Then dirX -= 1  ' A 键位置:左
    If (keyStates[SDL_SCANCODE_D]) Then dirX += 1  ' D 键位置:右
    If (keyStates[SDL_SCANCODE_W]) Then dirY -= 1  ' W 键位置:上
    If (keyStates[SDL_SCANCODE_S]) Then dirY += 1  ' S 键位置:下

    ' 仅在方向变化时打印日志
    If (dirX <> lastDirX Or dirY <> lastDirY) Then
        If (dirX = 0 And dirY = 0) Then
            SDL_LogInfo(SDL_LOG_CATEGORY_GAME, "停止移动")
        Else
            Dim As String dirStr = ""
            If (dirY < 0) Then dirStr &= "上 "
            If (dirY > 0) Then dirStr &= "下 "
            If (dirX < 0) Then dirStr &= "左 "
            If (dirX > 0) Then dirStr &= "右 "
            SDL_LogInfo(SDL_LOG_CATEGORY_GAME, "移动方向:%s", dirStr)
        End If
        lastDirX = dirX
        lastDirY = dirY
    End If
End Sub

' 主程序
Dim As SDL_Window Ptr window = NULL
Dim As SDL_Event evt
Dim As Boolean quit = False

' 1. 初始化 SDL
If (SDL_Init(SDL_INIT_VIDEO) < 0) Then
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL 初始化失败:%s", SDL_GetError())
    End 1
End If

' 2. 创建窗口
window = SDL_CreateWindow("SDL Scancode 示例", _
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, _
    800, 600, SDL_WINDOW_SHOWN)
If (window = NULL) Then
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "创建窗口失败:%s", SDL_GetError())
    SDL_Quit()
    End 1
End If

SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "=== SDL_Scancode 核心示例 ===")
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "WASD:移动(基于物理位置)| 按任意键查看扫描码信息 | ESC:退出")

' 3. 主循环
While (Not quit)
    ' 每帧处理 WASD 移动(状态查询)
    HandleWASDMovement()

    ' 处理事件队列
    While (SDL_PollEvent(@evt))
        Select Case evt.type
            Case SDL_QUITEVENT
                quit = True

            Case SDL_EVENT_KEY_DOWN
                ' ESC 退出
                If (evt.key.scancode = SDL_SCANCODE_ESCAPE) Then
                    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "按下 ESC 键(扫描码),退出程序")
                    quit = True
                Else
                    ' 打印当前按键的扫描码信息
                    SDL_LogInfo(SDL_LOG_CATEGORY_INPUT, "==== 按键物理位置信息 ====")
                    PrintScancodeInfo(evt.key.scancode)
                End If

                ' 演示:扫描码转名称(自定义绑定场景)
                If (evt.key.scancode = SDL_SCANCODE_SPACE) Then
                    Dim As ZString Ptr spaceName = SDL_GetScancodeName(SDL_SCANCODE_SPACE)
                    SDL_LogInfo(SDL_LOG_CATEGORY_GAME, "按下 %s 键(物理位置),触发跳跃", spaceName)
                    SDL_free(spaceName)
                End If
        End Select
    Wend

    SDL_Delay(10)  ' 降低 CPU 占用
Wend

' 4. 清理资源
SDL_DestroyWindow(window)
SDL_Quit()

SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "程序正常退出")
End 0

核心扫描码枚举说明

SDL_Scancode 枚举值完全对应美式 QWERTY 键盘的物理位置,以下是游戏开发中最常用的核心值:

扫描码常量 物理位置(美式键盘) 典型用途
SDL_SCANCODE_W W 键 上/前进
SDL_SCANCODE_A A 键
SDL_SCANCODE_S S 键 下/后退
SDL_SCANCODE_D D 键
SDL_SCANCODE_SPACE 空格键 跳跃/确认
SDL_SCANCODE_ESCAPE ESC 键 取消/退出
SDL_SCANCODE_SHIFT Shift 键(左右均可) 加速/大写
SDL_SCANCODE_CTRL Ctrl 键(左右均可) 特殊操作
SDL_SCANCODE_R R 键 换弹/刷新
SDL_SCANCODE_F1-F12 F1-F12 功能键 功能快捷键
SDL_SCANCODE_UP/DOWN/LEFT/RIGHT 方向键 菜单导航/移动

扫描码 vs 按键码 核心区别

特性 SDL_Scancode(扫描码) SDL_Keycode(按键码)
绑定对象 物理按键位置(与布局无关) 按键符号(与布局相关)
核心场景 游戏移动(WASD)、快捷键(物理位置) 文本输入、通用按键(ESC/Enter)
示例 法语键盘按 Z 键 → SDL_SCANCODE_W 法语键盘按 Z 键 → SDLK_z
稳定性 跨布局稳定(位置不变) 跨布局变化(符号不变)

总结

  1. SDL_Scancode 核心价值:绑定键盘物理位置,是游戏中「设备无关输入」的基础(如 WASD 移动在任何布局的键盘上都对应相同的手指位置);
  2. 使用场景:所有基于「物理按键位置」的输入(移动、射击、快捷键)都应优先使用扫描码;
  3. 关键配合函数
    • SDL_GetKeyboardState:通过扫描码查询实时按键状态;
    • SDL_GetScancodeName:获取扫描码的可读名称(用于配置界面);
    • SDL_GetKeyFromScancode:扫描码转按键码(适配布局的符号显示)。

评论一下?

OωO
取消