在 Corona 中,创建支持手柄/摇杆的应用既容易又具有互动性。本指南概述了游戏手柄 API 和事件如何协同工作。
游戏手柄在 Corona Simulator for macOS 或 Windows、Win32 桌面应用程序以及 Android 设备上受支持。
受支持的游戏手柄。Corona Simulator for macOS 支持大多数游戏手柄,但有些手柄需要额外的设置。测试过的游戏手柄包括
本指南配套“Pew Pew!”示例应用,它利用了所有游戏手柄 API。你可以从我们的 GitHub 存储库 下载它。
首先要使用的 API 是 system.getInputDevices(),它返回所有检测到的输入设备的列表。不过,请注意平台之间的以下差异
基本上,当一个应用程序启动时,你可以检查设备的按键绑定是否已存储
local inputDevices = system.getInputDevices() for i = 1,#inputDevices do local device = inputDevices[i] print( device.descriptor ) end
实际上,system.getInputDevices() 返回的列表中的每个条目都是 InputDevice 的一个实例。你可以查询它以获取有关设备的信息,例如
object.descriptor 属性指示会话/运行期间的手柄标识符。如果断开了相同设备然后又重新连接,它将具有相同的 descriptor
值,但这并不意味着 descriptor
在会话/运行之间保持不变。在后续的会话/运行中,手柄可能会具有不同的 descriptor
值。
object.displayName 由操作系统报告。你可以显示此信息,以便用户可以识别正在使用的游戏手柄。
你还可以通过 object:getAxes() 方法查询 InputDevice 对象的状态,或使用 object:vibrate() 函数使其振动。请参阅 文档 以获取完整属性和方法列表。
每当控制器连接或断开连接时,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
表格包含有关收到状态更改的设备的以下属性
"inputDeviceStatus"
。作为输入结果,游戏手柄会产生两类事件:axis 和 key。
在 macOS 和 Windows 中,key 事件的 event.device
属性将为 nil
。如果此事件来自虚拟输入设备(例如虚拟键盘),则在 Android 中它也可能为 nil
。
以下示例显示了如何检测特定手柄。当触发 axis
或 key
事件时,会调用 setDevice()
函数来设置 event.device
和 InputDevice 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.normalizedValue
与 0.5
进行了比较。这意味着摇杆旋转了一个“可读”的量,或者超过了一半。
一些游戏手柄在按下模拟触发器时会产生 axis
和 key
事件,因此你可能需要有条件地处理这种可能性。
按键使用 key 事件处理。每当用户按下游戏手柄/操纵杆上的按钮或键盘上的键时,都会触发此事件。要识别按下了哪个按钮/键,请参考 event.keyName 文档。此外,当 key
事件发生时,如果按下按钮/键,则 event.phase
等于 "down"
;如果释放按钮/键, event.phase
等于 "up"
。
axis 事件会在手柄的轴值发生任何变化时触发。这可能会产生大量事件,因此游戏开发者应考虑累积轴状态。每个事件都有几个有用的属性
axis
字段中的值对其进行解释。处理 axis
事件时的通常工作流是累积值。在这种方法中,event.normalizedValue 通常最为有用。
与设备一样,轴可以提供有关其自身的有用信息。InputAxis 表格由 object:getAxes() 和 axis
事件中的 axis 返回。可能最有用的属性是 type,它尝试描述轴的效用。
游戏手柄在 Corona Simulator for macOS 或 Windows、Win32 桌面应用程序以及 Android 设备上受支持。
可以使用以下事件来实现游戏手柄支持
"down"
或 "up"
的 event.phase
。event.device
访问。event.device
可为 nil
。要列出已知游戏控制器,请使用 system.getInputDevices() 函数。
最好累计轴变化并在稍后执行操作,例如在运行时 "enterFrame"
侦听器中,类似于 示例应用程序 方法。