测试已测试 | ✗ |
Lang语言 | SwiftSwift |
许可证 | MIT |
发布最新发布 | 2016年1月 |
SPM支持 SPM | ✗ |
由 Jakub Knejzlik,Rob Reuss 维护。
VirtualGameController 是苹果的 Game Controller 框架的替代品,因此它可以轻松集成到现有游戏中,在您需要回退到使用苹果的框架时提供保护,并且允许实现超出 Game Controller 但使用 MFi 配置文件的功能。单个游戏端实现可以与广泛的控制器场景一起工作。以下情况下VirtualGameController 可能对您很有用:
示例项目的用户界面是为文档、测试和调试目的而设计的,而不是用于游戏。
工作区中包含特定平台的框架项目。单个框架文件支持外设(基于软件的控制器)和中心(即,您的游戏)。
import VirtualGameController
请注意,您目前还需要导入GameController
。
有关使用Objective C的说明,请查看Wiki上的说明。
已实现对CocoaPods和Carthage的支持。
包含了一系列示例项目,演示了不同平台(iOS、tvOS、OS X、watchOS)的应用程序角色(外设、桥接和中心),以及演示Objective C和SceneKit使用的项目。它们通过将框架文件复制到项目中来提供,而不是引用框架项目的生成产品。要切换到使用框架文件的生成产品,请遵循Wiki中的这些说明。
有关示例项目的其他说明
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,并禁用游戏中未使用的运动输入。
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震动,如果与手表应用程序集成了该手机,振动请求也会转发到手表,从而产生触觉反馈(手腕点击)。
请参阅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 示例项目以及维基页面。
查看维基文章。
您可以随时通过LinkedIn或[email protected]与我联系。
MIT 许可协议 (MIT)
版权所有 © [2015] [Rob Reuss]
任何人自由地获得此软件及其相关文档文件(“软件”)的副本,均可不受限制地处理软件,包括但不限于使用、复制、修改、合并、出版、分发、再许可和/或销售软件副本,并允许将软件提供给他人,使他们也可以这样做,但前提是以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
本软件“按原样提供”,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论源于合同行为、侵权或其他,无论源于或有关于软件或软件的使用或其它。