在 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" 侦听器中,类似于 示例应用程序 方法。