TIL:如何在SpriteKit游戏中使用SKCameraNode
在过去的好时光中,过去常常需要花费大量的数学才能产生一种幻觉,即玩家正在向更大的“世界”移动。 我最近一直在玩SpriteKit,今天我了解了使用SKCameraNode
实际创建该效果有多么容易。
什么是SKCameraNode
苹果的文档很好地解释了这一点。 SKCameraNode
对象用于指定场景中可以从中渲染场景的位置。 换句话说,它可以用于在游戏世界中滚动玩家的视图。
如何使用它
俗话说,一张图片值得一千个字。 通过一个示例,了解SKCameraNode
工作方式将更加容易。
我们将建立一个游戏场景,让玩家能够通过点击屏幕来浏览世界。 世界观将始终以主角为中心。 为了给事情增添趣味,我们还将添加一个得分计数器叠加层。
让我们首先使用SpriteKit创建一个新的iOS游戏。 默认项目模板包括带有一些示例行为的GameScene
。 由于我们专注于相机行为,因此我们将从头开始创建自己的SpriteKit Scene
。
让我们在场景编辑器中放置一些Color Sprites
:
我将其中一个尺寸缩小(50×50),并给它命名一个名称player
,以后我们可以用它来从代码中引用该对象。 这将是精灵对象,它将响应触摸事件并在世界范围内移动。 我们的“相机”(播放器的视图)将以该对象为中心。
通过足够的拖放操作,让我们打开游戏场景swift文件并开始编写一些代码。
声明类型为SKCameraNode
的可选变量:
var cam: SKCameraNode?
这将是我们对相机的参考。 场景进入视野后,我们将初始化变量:
覆盖func didMove(以查看:SKView){
super.didMove(查看)
cam = SKCameraNode()
self.camera =凸轮
self.addChild(cam!)
}
这里要注意的重要一点是,相机节点具有自己的框架,该框架占据屏幕的大小。 设置相机效果的位置会转换为设置可见屏幕的中心。
为了演示这一点,让我们首先尝试让我们的“玩家”在屏幕上移动以响应触摸事件。 为此,我们将在场景首次进入视野时获得对玩家对象的引用,并在触摸屏幕后使其移动:
var cam:SKCameraNode?
var播放器:SKSpriteNode?
覆盖func didMove(以查看:SKView){
super.didMove(查看)
cam = SKCameraNode()
self.camera =凸轮
self.addChild(cam!)
玩家= self.childNode(withName:“玩家”)为? SKSpriteNode
}
然后覆盖touchesBegan
以获取我们必须移动到的位置:
覆盖func touchesBegan(_ touches:Set ,事件:UIEvent?){
super.touchesBegan(touches,with:event)
如果让location = touches.first?.location(in:self){
播放器?.run(SKAction.move(收件人:位置,时长:1.0))
}
}
继续尝试一下,当我们点击屏幕上的附近位置时,玩家方格应该正在移动。 但是,我们还没有让相机跟随。
在更新阶段是更新相机位置的好时机:
覆盖功能更新(_ currentTime:TimeInterval){
super.update(currentTime)
如果让camera = cam,则让pl = player {
camera.position = pl.position
}
}
再次运行游戏,现在摄影机似乎位于我们的玩家对象的中心。 在每个游戏循环之后,都将调整摄像机的位置以匹配玩家的位置。 如前所述,相机的位置始终与其视觉中心相对应。
现在,最后一点-显示得分叠加。 当玩家移动时,分数计数器(和其他界面控件)很可能不应该随世界“滚动”。 我们将添加一个标签,该标签将始终固定在屏幕的左上方。
首先,让我们在场景进入视图时初始化类型为SKLabelNode
的得分变量:
var cam:SKCameraNode?
var播放器:SKSpriteNode?
var得分:SKLabelNode?
覆盖func didMove(以查看:SKView){
super.didMove(查看)
cam = SKCameraNode()
self.camera =凸轮
self.addChild(cam!)
分数= SKLabelNode(字体名称:“ ArialHebrew-Bold”)
得分?.text =“ 000”
分数?。颜色= UIColor.white
score?.position = CGPoint(x:-self.size.width / 2 + 50,y:self.size.height / 2-50)
self.camera?.addChild(得分!)
玩家= self.childNode(withName:“玩家”)为? SKSpriteNode
}
我们没有将得分标签添加到self
( SKScene
),而是将其添加为camera节点的后代。 即使相机本身改变位置,相机节点的所有子节点仍保持固定在相机框架中。