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 
  } 

我们没有将得分标签添加到selfSKScene ),而是将其添加为camera节点的后代。 即使相机本身改变位置,相机节点的所有子节点仍保持固定在相机框架中。