游戏手柄

在 Corona 中,创建支持手柄/摇杆的应用既容易又具有互动性。本指南概述了游戏手柄 API 和事件如何协同工作。

要求

查询设备

首先要使用的 API 是 system.getInputDevices(),它返回所有检测到的输入设备的列表。不过,请注意平台之间的以下差异

基本上,当一个应用程序启动时,你可以检查设备的按键绑定是否已存储

local inputDevices = system.getInputDevices()

for i = 1,#inputDevices do
    local device = inputDevices[i]
    print( device.descriptor )
end

实际上,system.getInputDevices() 返回的列表中的每个条目都是 InputDevice 的一个实例。你可以查询它以获取有关设备的信息,例如

连接/断开手柄

每当控制器连接或断开连接时,inputDeviceStatus 事件便会被触发。以下示例显示如何处理此事件

local function onInputDeviceStatusChanged( event )
    
    if ( event.connectionStateChanged ) then
        if ( event.device.isConnected ) then
            -- Device has been connected
        else
            -- Connection has been lost
        end
    end
end

Runtime:addEventListener( "inputDeviceStatus", onInputDeviceStatusChanged )

在侦听器函数中,event 表格包含有关收到状态更改的设备的以下属性

处理手柄输入

作为输入结果,游戏手柄会产生两类事件:axiskey

在 macOS 和 Windows 中,key 事件的 event.device 属性将为 nil。如果此事件来自虚拟输入设备(例如虚拟键盘),则在 Android 中它也可能为 nil

以下示例显示了如何检测特定手柄。当触发 axiskey 事件时,会调用 setDevice() 函数来设置 event.deviceInputDevice displayName

local controller = { device="", displayName="" }

--Predeclare
local onKeyEvent
local onAxisEvent

local function setDevice( device, displayName )

    -- Set current controller
    controller["device"] = device
    controller["displayName"] = displayName

    -- Remove event listeners
    Runtime:removeEventListener( "axis", onAxisEvent )
    Runtime:removeEventListener( "key", onKeyEvent )
end

function onKeyEvent( event )
    setDevice( event.device, event.device.displayName )
end

function onAxisEvent( event )
    if ( math.abs(event.normalizedValue) > 0.5 ) then
        setDevice( event.device, event.device.displayName )
    end
end

Runtime:addEventListener( "axis", onAxisEvent )
Runtime:addEventListener( "key", onKeyEvent )
注意
  • 在上述示例中,将 onAxisEvent() 侦听器函数的 event.normalizedValue0.5 进行了比较。这意味着摇杆旋转了一个“可读”的量,或者超过了一半。

  • 一些游戏手柄在按下模拟触发器时会产生 axiskey 事件,因此你可能需要有条件地处理这种可能性。

处理键

按键使用 key 事件处理。每当用户按下游戏手柄/操纵杆上的按钮或键盘上的键时,都会触发此事件。要识别按下了哪个按钮/键,请参考 event.keyName 文档。此外,当 key 事件发生时,如果按下按钮/键,则 event.phase 等于 "down";如果释放按钮/键, event.phase 等于 "up"

处理轴

axis 事件会在手柄的轴值发生任何变化时触发。这可能会产生大量事件,因此游戏开发者应考虑累积轴状态。每个事件都有几个有用的属性

重要提示
  • 处理 axis 事件时的通常工作流是累积值。在这种方法中,event.normalizedValue 通常最为有用。

  • 与设备一样,轴可以提供有关其自身的有用信息。InputAxis 表格由 object:getAxes()axis 事件中的 axis 返回。可能最有用的属性是 type,它尝试描述轴的效用。

总结

参考

文档

第三方驱动程序

示例代码