VirtualGameController 0.0.14

VirtualGameController 0.0.14

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布最新发布2016年1月
SPM支持 SPM

Jakub KnejzlikRob Reuss 维护。



虚拟游戏控制器

特性

  • 封装了苹果的 GameController 框架 API (GCController)
  • 创建软件控制器(使用 MFi 配置文件)
  • 控制器转发
  • 软件控制器和游戏之间的双向通信,包括像图像这样的较大数据文件(作为独立的通道表示为 NSData)
  • 支持设备运动
  • 自定义控制器元素
  • 自定义元素映射
  • 基于 WiFi,如有需要支持蓝牙回退
  • 与 Apple TV 模拟器兼容
  • 在 Apple TV 上(使用控制器转发)支持无限数量的硬件控制器
  • 能够通过运动、扩展配置文件元素和自定义元素增强廉价的滑动式/贴合式控制器
  • 支持 iCade 控制器(通过 MFi 配置文件映射,因此它们显示为 MFi 硬件)
  • 软件控制器上易于实现的 3D Touch
  • 使用软件控制器(包括 Apple TV)利用屏幕和蓝牙键盘
  • 支持快照(与苹果的快照格式兼容)
  • Swift 2.1 或 Objective C
  • 基于框架

要求

  • iOS 9.0+ / Mac OS X 10.9+
  • Xcode 7 / Swift 2.0 / Objective C

平台支持

  • iOS
  • tvOS
  • OS X
  • watchOS

一些用例

VirtualGameController 是苹果的 Game Controller 框架的替代品,因此它可以轻松集成到现有游戏中,在您需要回退到使用苹果的框架时提供保护,并且允许实现超出 Game Controller 但使用 MFi 配置文件的功能。单个游戏端实现可以与广泛的控制器场景一起工作。以下情况下VirtualGameController 可能对您很有用:

  • 开发和支持基于软件的控制器。使您的用户能够使用iPhone、iPad或Apple Watch控制您的游戏,利用3D触感和运动输入。输入通过GCController API(即,通过MFi配置文件)流动,因此您的基于软件的控制器将显示为基于硬件的控制器。轻松将信息从您的游戏发送到您的软件控制器(双向通信)。创建基于软件的控制器API简单易用。
  • 使用控制器中继创建混合硬件/软件控制器。Apple在2014年WWDC的会议中描述了一个名为“控制器中继”的功能(大约在29:00https://developer.apple.com/videos/play/wwdc2014-611/),但据我所知,该功能从未出现。《VirtualGameController》支持会议中描述的中继控制器中继,使您能够通过完整配置文件和运动输入增强适合形状的硬件控制器。
  • 支持大量控制器用于社交游戏。对与游戏一起使用的硬件或软件控制器的数量没有限制。可以使用控制器中继(桥接)、混合控制器和基于软件的控制器来超过Apple TV上的第三方控制器限制。
  • 创建基于文本的游戏。支持基于字符串的自定义输入,使得创建面向文本的游戏变得简单。在示例项目中展示了语音输入的使用。

截图

示例项目的用户界面是为文档、测试和调试目的而设计的,而不是用于游戏。

Selector Peripheral Central

术语

  • 外设:基于软件的控制器。
  • 中心:通常是一个支持硬件和软件控制器的游戏。中心使用VirtualGameController作为Apple Game Controller框架的替代品。
  • 桥接:在外设和中心之间充当中继,代表两者的混合。主要用例是“控制器中继”。

集成

工作区中包含特定平台的框架项目。单个框架文件支持外设(基于软件的控制器)和中心(即,您的游戏)。

import VirtualGameController

请注意,您目前还需要导入GameController

有关使用Objective C的说明,请查看Wiki上的说明

已实现对CocoaPods和Carthage的支持。

使用示例项目

包含了一系列示例项目,演示了不同平台(iOS、tvOS、OS X、watchOS)的应用程序角色(外设、桥接和中心),以及演示Objective C和SceneKit使用的项目。它们通过将框架文件复制到项目中来提供,而不是引用框架项目的生成产品。要切换到使用框架文件的生成产品,请遵循Wiki中的这些说明

有关示例项目的其他说明

  • 要探索使用您的Apple Watch作为控制器,请使用设置为watchOS项目的iOS Bridge示例。手表可以与其配对的手机交互,作为桥接(将值中继到其他中心)或作为中心(直接在配对的iPhone上显示游戏界面)。配对手表的发现是自动的。
  • 查看SceneKit示例项目是一种评估框架运动能力的好方法,同时也很有趣。它作为一个单一项目实现,拥有用于针对iOS、OSX和tvOS的共享代码。
  • Wiki上也有使用DemoBots(Swift语言)和SceneKitVehicle(Objective C语言)示例项目的测试说明。

使用基于MFi硬件的控制器

VirtualGameController设计为与苹果的Game Controller框架兼容的界面,因此使用VGC与硬件控制器的工作方式与使用Game Controller框架基本相同。请参见下文的游戏集成部分和示例项目以获取更多信息。

创建基于软件的外设

初始化

请注意,在下面的示例中,没有设置自定义元素或自定义映射。请参阅本文件其他部分了解如何处理这些内容(或请参阅示例项目)。

 VgcManager.startAs(.Peripheral, appIdentifier: "MyAppID", customElements: CustomElements(), customMappings: CustomMappings(), includesPeerToPeer: true)

appIdentifier参数用于Bonjour,应是一个简短、唯一的标识符。

如果没有使用自定义映射和自定义元素,则可以提供一个简化的形式。

VgcManager.startAs(.Peripheral, appIdentifier: "MyAppID", includesPeerToPeer: true)

关于自定义映射和自定义元素功能的文档即将推出,尽管示例项目和类文件的组合可能足以让您开始使用。

includesPeerToPeer参数传递给NSNetServices。它提供了连接回蓝牙或WiFi的点对点功能。有关更多信息,请参阅NSNetServices文档。

调用startAs方法后,可以通过设置deviceInfo属性来定义外围设备。这样做不是必需的,因为默认值(如下所示)应适用于大多数情况。

VgcManager.peripheral.deviceInfo = DeviceInfo(deviceUID: "", vendorName: "", attachedToDevice: false, profileType: .ExtendedGamepad, controllerType: .Software, supportsMotion: true)

将空字符串传递给deviceUID,以便系统使用NSUUID()创建它,并将其存储到用户默认设置中。

将空字符串传递给vendorName,设备网络名称将被用于标识外围设备。

查找中心服务

开始搜索网桥和中心

VgcManager.peripheral.browseForServices()

访问找到的当前服务集合

VgcManager.peripheral.availableServices

相关通知 - 两个通知都携带一个包含VgcService的参考作为其有效载荷

NSNotificationCenter.defaultCenter().addObserver(self, selector: "foundService:", name: VgcPeripheralFoundService, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "lostService:", name: VgcPeripheralLostService, object: nil)

在简单实现中,您将连接到您找到的第一个中心服务,而如果您始终使用网桥,则您将连接到您找到的第一个网桥。在这些情况下,您需要开始搜索,并使用VgcPeripheralFoundService通知调用connectToService方法。

如果您选择实现更复杂的场景,其中多个外围设备连接到网桥或中心,上述方法和通知的组合应该可以满足您的需求。示例项目实现了此类灵活场景。

连接到和从中心断开连接

一旦获得对服务(中心或网桥)的引用,就可以将其传递给以下方法

VgcManager.peripheral.connectToService(service)

要与服务断开连接

VgcManager.peripheral.disconnectFromService()

相关通知

NSNotificationCenter.defaultCenter().addObserver(self, selector: "peripheralDidConnect:", name: VgcPeripheralDidConnectNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "peripheralDidDisconnect:", name: VgcPeripheralDidDisconnectNotification, object: nil)

向中心发送值

提供了一种Element类,每个实例代表一个硬件或软件控制器元素。为每个支持的配置文件(微型游戏手柄、游戏手柄、扩展游戏手柄和运动)都提供了元素集合。要向中央发送一个值,需要将该Element对象的value属性设置为该值,然后将元素传递给sendElementState方法。

let leftShoulder = VgcManager.elements.leftShoulder
leftShoulder.value = 1.0
VgcManager.peripheral.sendElementState(leftShoulder)

玩家索引

当中央分配一个玩家索引时,它将触发以下通知,该通知携带新的玩家索引值作为负载。

NSNotificationCenter.defaultCenter().addObserver(self, selector: "receivedPlayerIndex:", name: VgcNewPlayerIndexNotification, object: nil)

设备运动

对运动更新的支持取决于特定平台对Core Motion的支持(例如,在OS X上不支持)。当尝试在不受支持的平台上启动运动更新时,框架应检测到。

以下是一些应该一目了然的主要方法。

VgcManager.peripheral.motion.start()
VgcManager.peripheral.motion.stop()

VgcManager.peripheral.motion.enableUserAcceleration = true
VgcManager.peripheral.motion.enableGravity = true
VgcManager.peripheral.motion.enableRotationRate = true
VgcManager.peripheral.motion.enableAttitude = true

VgcManager.peripheral.motion.updateInterval = 1/60

VgcManager.peripheral.motion.enableAdaptiveFilter = true
VgcManager.peripheral.motion.enableLowPassFilter = true

出于性能原因,应尽可能地减少updateInterval,并禁用游戏中未使用的运动输入。

游戏集成(中央)

GCController替换

VirtualGameController的设计是为了作为Apple框架GameController的替代品(尽管两个框架都应该包含,因为需要一些GameController头文件引用)

import GameController

变成...

import GameController
import VirtualGameController

必须使用针对您的目标平台特定的框架文件,并为每个平台提供了框架文件。

控制器类VgcController的接口与GCController的接口相同,大多数现有的游戏可以通过全局搜索将"GCC"替换为"VgcC"来实现过渡。存在一些例外,其中使用了GameController结构,这些可以保留为GC引用。

GCControllerButtonValueChangedHandler
GCControllerDirectionPadValueChangedHandler
GCControllerElement
GCMicroGamepad
GCGamepad
GCExtendedGamepad
GCMotion

如果您希望测试框架的集成,证明它与Apple DemoBots 示例项目配合工作。一个限制是,当使用Apple TV版本时,由于与DemoBots实现此功能相关的问题,您必须使用遥控器来启动游戏(查看该页面最后一段)。

有关使用DemoBots进行深度测试的详细说明,请参阅Wiki文章,该文章还提供了有关将VirtualGameController集成到现有项目中的有用提示。

中央与桥

存在两种类型的中央应用程序集成,这会导致截然不同的结果:中央

中央正如同您预期的那样,关于游戏集成:您的中央就是您的游戏,一次只应实现一个。

结合了中央和外设的行为;对于您的中央来说,它是一个外设,对于您的外设来说,它是一个中央。它的另一个名字是“控制器转发器”,因为它的主要功能是将一个或多个外设发送到中央的值转发/中继。外设可以是MFi硬件控制器、iCade硬件控制器、Apple Watch或基于软件的虚拟控制器(假设桥部署在连接到手表的iPhone上)。如果在支持设备运动的设备(iOS设备)上实现桥,桥可以扩展外设的功能,包括运动支持。例如,MFi或iCade控制器可以对中央实现运动配置文件。

扩展功能

中心支持的某些功能超出了Apple GameController框架的能力

其他

在VgcController实例上提供了一个名为controller.vibrateDevice的方法,它可以使iPhone震动,如果与手表应用程序集成了该手机,振动请求也会转发到手表,从而产生触觉反馈(手腕点击)。

整合Apple Watch

示例项目

请参阅iOS外围设备示例项目以获取更多指导。

项目设置

为了在您的项目中集成手表功能,建议您使用Apple的“iOS App with WatchKit App”模板开始项目。这将使您能够为您的应用程序创建一个WatchKit扩展。

您的iOS项目必须导入iOS版本的框架,而WatchKit扩展必须导入watchOS版本。

启动您的手表扩展

您的手表扩展应使用startAs方法以外围设备的身份启动,并为VgcWatchConnectivity类设置一个实例变量,这是watchOS框架发布的

    VgcManager.startAs(.Peripheral, appIdentifier: "", customElements: CustomElements(), customMappings: CustomMappings())
    watchConnectivity = VgcWatchConnectivity()    

从手表发送值

在您的手表扩展内部,请在您的VgcWatchConnectivity实例变量上使用以下方法将元素值发送到您的iOS应用程序(存在于您的手机上)以及中心(自动从iOS应用程序转发)

let element = watchConnectivity.elements.rightShoulder
element.value = 1.0
watchConnectivity.sendElementState(element)
element.value = 0.0
watchConnectivity.sendElementState(element)

从手表接收值

当您的手表以上一节中描述的方式发送值时,有两种处理这些消息的方法。如果您不采取任何行动,这些值将自动转发到中心。如果要在外围设备上进行处理,并转发或不再转发,您可以设置valuChangedHandler,如下所示

VgcManager.peripheral.watch.valueChangedHandler = { (element: Element) in
    print("iOS iPhone watch handler fired for \(element.name) with value \(element.value)")
}

如果valuChangedHandler不为空,值就不会自动转发到中心,因此如果您希望这些值被转发,您必须自己执行此操作

VgcManager.peripheral.sendElementState(element)

向手表发送值

要从外围iOS应用程序向手表发送一个值,您可以使用以下方法

VgcManager.peripheral.watch.sendElementState(element)

在手表上接收值

如果手表与您的iPhone iOS应用程序配对,从中心接收到的值将转发到手表,您可以通过设置watchConnectivity实例上的valueChangedHandler来对那些值做出反应

watchConnectivity.valueChangedHandler = { (element: Element) in
    print("Watch handler fired for \(element.name) with value \(element.value)")
}

请注意,如果外围设备如上所述向手表发送一个值,则相同的处理程序将被触发。

从手表开始运动

您可以从手表发送运动值,但请注意性能并不出色

watchConnectivity.motion.start()
watchConnectivity.motion.stop()

自定义元素

请参阅维基文章

自定义映射

查看维基文章

双向通信

查看维基文章

Objective-C 支持

查看附带的 Objective C 示例项目以及维基页面

iCade 控制器支持

查看维基文章

联系和支持

您可以随时通过LinkedIn[email protected]与我联系。

许可协议

MIT 许可协议 (MIT)

版权所有 © [2015] [Rob Reuss]

任何人自由地获得此软件及其相关文档文件(“软件”)的副本,均可不受限制地处理软件,包括但不限于使用、复制、修改、合并、出版、分发、再许可和/或销售软件副本,并允许将软件提供给他人,使他们也可以这样做,但前提是以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

本软件“按原样提供”,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论源于合同行为、侵权或其他,无论源于或有关于软件或软件的使用或其它。