文章选自掘金苹果API搬运工的文章[SceneKit专题]23-跨平台游戏(macOS,tvOS,watchOS)
主要记录自己在学习ARKit的过程中看到的好的文章,避免到时候链接失效无法找到原文的情况,非常感谢原博主的辛勤付出,也在此分享出来跟大家一起学习。
以前面的游戏为例,将其改为跨平台版本:
-
macOS游戏Geometry Fighter
-
tvOS游戏Breaker
-
watchOS游戏Geometry Fighter
创建项目
打开Xcode创建新项目,选择macOS平台,选择Game类型,点击Next继续.
输入游戏名SceneKitGame,选择Swift语言,SceneKit游戏技术,取消Unit和UI Tests,点击Finish.
生成的项目类似于iOS项目,但不完全相同:
- GameView.swift:继承于SCNView,可以响应鼠标键盘事件但不能触摸.
- GameViewController.swift:继承于NSViewController.
- MainMenu.xib:控制器的xib.
选择My Mac,运行一下游戏:
转换SceneKit游戏
可以在projects/ starter/GeometryFighter/ 中打到原iOS版的项目.
打开iOS版项目,点击GeometryFighter,添加新的target:
选择Add Target...
选择macOS平台,然后选择Game
输入项目名GeometryFighterMac,选择SceneKit,取消Unit Tests和UI Tests,点击Finish:
选择GeometryFighterMac > My Mac作为Active Scheme.
运行后,看到的还是默认的飞机场景,那是因为还需要其他步骤.
多个target内容共享
可以在iOS和macOS之间共享原来的代码和资源.创建一个Shared分组
将下列文件和文件夹移动到Shared下面:
按住Shift键,选中GeometryFighter/ Shared/Particles下面的全部文件,打开右侧的属性检查器,勾选Target Membership下面的GeometryFighterMac;这样就能在iOS target和macOS target之间共享了.
Shared下面的其他几个也是类似操作.
为了解决跨平台带来的问题,还需要添加下列代码:
#if os(iOS)
import UIKit
#endif
#if os(macOS)
import Cocoa
#endif
当然了,我们不需要每个文件都去添加,只需要将已创建好的resources/ GameUtils/ 文件导入进来就可以了.首先,删除一些旧文件,选中GameHelper.swift和UIColor+Extensions.swift. 右键--删除--Move to Trash. 将resources/ GameUtils/ 下面的所有文件拖放到Shared/ GameUtils/ 文件夹下
!](https://img.haomeiwen.com/i1521229/71dd6422f776f77c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
清理
还需要清理一下项目.选中GameView.swift, GameViewController.swift和art.scnassets.右键删除--Move to Trash.
然后从示例代码中本章节的resources/GameViewController文件夹下拖放GameView.swift和GameViewController.swift到项目中,选中Copy items if needed和GeometryFighterMac,点击Finish完成.
还要做的是恢复新的GameViewController与MainMenu.xib之间的联系.
鼠标输入
选中MainMenu.xib,从右侧对象库中拖放一个Click Gesture Recognizer到Game View中.
添加连接函数:
现在还差最后一步,添加AppIcon,你可以从本章节的resources/AppIcon/文件夹中找到,拖放到Assets.xcassets中的AppIcon下:
运行一下程序:
本项目的最终完成版代码可以在对应章节的projects/ final/GeometryFighter/ 下找到.
创建项目
创建项目
在Active Scheme中选择SceneKitGame > tvOS Simulator > Apple TV 1080p:
运行一下,可以看到默认的飞机模型.但是真实的Apple TV是要用遥控器操作的,怎么用呢?在模拟器的Hardware > Show Apple TV Remote中,就可以调出遥控器了:
移植到tvOS
在代码中找到本章节的projects/ starter/Breaker/ 文件夹接着处理.
和前面类似,选中Breaker,添加新的target,在弹出窗中选择tvOS和Game.
targets间内容共享
添加一个Shared分组,并将原来的文件拖放进来:
逐一选中文件夹下的所有文件,添加Target Membership:
还需要清理一下代码. 选中BreakerTV/art.scnassets和BreakerTV/GameViewController.swift,删除--Move To Trash:
添加专用代码
打开GameViewController.swift,在setupNodes()
末尾添加代码:
#if os(tvOS)
scnView.pointOfView = horizontalCameraNode
#endif
还有shouldAutorotate
, prefersStatusBarHidden
和viewWillTransition()
也不需要了:
#if os(iOS)
override var shouldAutorotate: Bool {
... }
override var prefersStatusBarHidden: Bool {
... }
override func viewWillTransition(to size: CGSize, with coordinator:
UIViewControllerTransitionCoordinator) {
... }
#endif
遥控触摸事件
和iOS的触摸事件不同,遥控上更接近MacBook的触摸板的逻辑,touchesBegin()
的初始位置总是(x:960, y: 540)
,即1080p显示器的中心,touchesMoved()
时的位置则是相对于初始点的位置.
另外还有一个问题:tvOS遥控器的触摸板太灵敏了,轻微移动就是很长距离.我们需要在GameViewController
中找到下面的代码:
paddleNode.position.x = paddleX +
(Float(location.x - touchX) * 0.1)
将其更改为:
#if os(iOS)
paddleNode.position.x = paddleX +
(Float(location.x - touchX) * 0.1)
#elseif os(tvOS)
paddleNode.position.x = paddleX +
(Float(location.x - touchX) * 0.01)
#endif
图标
图标资源在本章节对应的resources文件夹下.
打开BreakerTV/Assets.xcassets,选中App Icon & Top Shelf Image,将图片拖放进去:
运行一下,看到图标出现在Apple TV首页上了:
点击进入游戏,开始玩吧:
在Xcode中,并没有专门的watchOS版游戏的模板,我们需要做的是创建一个iOS的游戏,再给它添加watchOS的支持.
添加watchOS支持
我们直接在原iOS项目基础上添加watchOS的target:
在Active Scheme中选择GeometryFighterWatch > iPhone 6s Plus + Apple Watch - 42mm
运行一下,看看效果:
targets间内容共享
创建Shared文件夹,移动需要的文件
然后依次选中各个文件夹下面的所有文件,添加Target Membership:
添加界面控制器
首先清理项目,选中InterfaceController.swift和art.scnassets.右键--删除--Move to Trash.
现在需要添加新的InterfaceController.swift.在本章节对应代码的resources/source文件夹下,拖放到Xcode中.
然后建立连接:
添加触摸输入
选中Interface.storyboard,拖放一个Tap Gesture Recognizer过来.
建立手势的连接:
现在已经基本完成了.
图标
所需图片资源在本章节对应的resource/AppIcon文件夹下.
选中Assets.xcassets下面的AppIcon,将图片拖放到其中:
运行一下,可以愉快地玩耍了!
项目的最终完成版本章节对应的projects/ final/GeometryFighter/ 文件夹下.
网友评论