iOS.& Swift Books 苹果通过教程增强现实

14
射频& Physics 由克里斯语撰写

在本章中,您将从您在前一篇的位置拾取。您的AR型Spritekit游戏伴奏良好,您已经奠定了很多基础。您现在的目标是添加所有缺失的碎片和完成触摸。

花点时间利用你做了什么,什么未来的升股指。

什么是做了什么?

  • 游戏状态 :游戏有基本的游戏状态到位,您可以轻松地从一个状态切换到另一个状态。这使您可以根据游戏的当前状态控制您的代码。

  • 产卵点 :当播放器点击屏幕时,游戏在相机视图中添加AR锚点。一个小盒子,它也会出现作为表情符号的产卵点。

  • 误差处理:您的游戏足以处理现实世界可以抛弃的东西。它通知玩家的任何跟踪问题,最重要的是,它可以从中断中恢复。

下一步是什么?

  • 产卵表情符号:随着地方重生点,你会在这个位置产生多个表情符号。

  • 运行行动:要添加一些波兰语,您将在Emojis上运行一些自定义操作来播放声音效果,缩放和运行其他代码。

  • 启用物理学:您将启用物理,因此Emojis参与物理模拟。这使每个表情符号为物理形状,并将像重力一样施加力。

  • 申请力量:您将使用基于物理的动画来向Emojis施加力量,从产卵点射出到世界,然后让重力将它们拉回地球。

  • 2D Raycasting.:您将使用2D Raycasting来检查播放器是否触及任何生成的Emojis,以保存它们从某些死亡。

现在你知道接下来是什么,现在是时候破解了!

笔记 :有一个从前面的章节可以在最终项目的副本 起始/表情符号.

产卵表情符号

你的第一步是让Emojis产卵。您将使用Spawn Point作为父节点以产生新的EMOJIS。这确保了emojis在玩家的观点中产生了产卵。

首先创建一个辅助函数,它产生一个单一的表情符号。虽然游戏正在运行,你将每半秒调用这个函数,将新的表情符号产生新的emoji。

打开 场景 , then add the following function to Scene:

func spawnEmoji() {  
  // 1
  let emojiNode = SKLabelNode(
    text:String(emojis.randomElement()!))
  emojiNode.name = " 表情符号 "
  emojiNode.horizontalAlignmentMode = .center
  emojiNode.verticalAlignmentMode = .center
  // 2
  guard let sceneView = self.view as? ARSKView else { return }
  let spawnNode = sceneView.scene?.childNode(
    withName: "SpawnPoint")
  spawnNode?.addChild(emojiNode)
}

This defines a function named spawnEmoji() whose main responsibility is spawning a single emoji.

仔细看看它在做什么:

  1. Creates a new SKLabelNode using a random emoji character from the string of emojis available in emojis. The node is named 表情符号 它垂直和水平居中。

  2. Interrogates the available node in scene, looking for the node named SpawnPoint. It then adds the newly-created emoji as a child of spawnNode. This places the emoji into the scene.

随着辅助功能到位,是时候开始产卵那些表情符号!虽然游戏正在播放,但您将每半秒调用此功能以产生新的表情符号。最佳地点是场景更新,每秒调用60次。

Add the following to update(_:):

// 1
if gameState != .Playing { return }
// 2
if spawnTime == 0 { spawnTime = currentTime + 3 }
// 3   
if spawnTime < currentTime {
  spawnEmoji()
  spawnTime = currentTime + 0.5;
}
//4     
updateHUD("SCORE: " + String(score) + 
  " | LIVES: " + String(lives))

这是这是如何崩溃的:

  1. 你只想在它的时候更新游戏 state.
  2. If spawnTime is 0, the game just started so you give the player a few seconds to prepare for the onslaught of emojis that are about to spawn. This creates a slight delay of 3 seconds before the first emoji spawns.
  3. Once spawnTime is less than currentTime, it’s time to spawn a new emoji. Once spawned, you reset spawnTime to wait for another half a second before spawning the next emoji.
  4. 最后,当前得分和提供生活更新HUD。

很棒,你终于产卵表情符号!欢迎您快速建立并运行来测试事项,但准备不受影响。

到目前为止,Emojis Spawn和你可以看到节点数增加,但你看不到表情符号。那是因为他们隐藏在产卵点后面。

解决问题的快速简便的方法是使物理学能够使Emojis参与物理模拟。一旦生成,重力会向地面拉出表情符号。

启用物理学

Spritekit配备了一个非常强大的2D物理引擎。为了允许物理引擎在生成的Emojis上运行物理模拟,您只需要让物理引擎意识到Emojis。

物理体类型

一,你创建一个物理体时必须指定的关键特性是它的 类型 。物理学体类型定义如何与物理模拟部队和其他机构身体相互作用。

物理形状

除了类型, 形状 是您必须在创建物理机构时指定的另一个重要属性。这定义了物理引擎用于检测冲突的2D形状。

启用物理学

In SpriteKit, all physics bodies are SKPhysicsBody objects. Once you create a physics body, you assign it to the physicsBody property of the SKNode.

// Enable Physics
emojiNode.physicsBody = SKPhysicsBody(circleOfRadius: 15)
emojiNode.physicsBody?.mass = 0.01

力量

在现实生活中,当你想制作球移动时,你必须对它施加力量 - 例如,通过踢它来施加力量。同样,为了使动态对象移动,您必须应用某种力量。

添加一些随机性

为游戏添加一些随机性将使游戏更具挑战性并提高重放值。而不是沿着y轴向上向上推emojis,而是您也会在x轴上添加一些随机性。

func randomCGFloat() -> CGFloat {
  return CGFloat(Float(arc4random()) / Float(UINT32_MAX))
}

应用冲动

你将把力量作为冲动施加力量而不是施加恒力。例如,重力是恒定的力量,而踢是一种冲动。

// Add Impulse
emojiNode.physicsBody?.applyImpulse(CGVector(
  dx: -5 + 10 * randomCGFloat(), dy: 10))

扭矩

扭矩是您可以应用于物理体的另一种力量 - 一种旋转力。它仅影响物理体的角动量(旋转)而不是线性动量。

施加扭矩

You can use applyTorque(), which is available on the physicsBody, to apply torque to a SKNode.

// Add Torque
emojiNode.physicsBody?.applyTorque(-0.2 + 0.4 * randomCGFloat())

行动

行动 allow you to perform basic animations to manipulate a node’s position, scale, rotation and opacity within a scene. To perform an SKAction on a SKNode, you simply need to 跑步 节点上的动作。

顺序& group actions

You can run only run a single SKAction on a SKNode at a time, but there are two special types of actions you can use to run multiple actions in a 顺序 或者在A. 团体 .

添加声音文件

在下一节中,您将使用播放声音操作来为您的游戏添加一些有趣的声音。为此,您需要为项目添加一些声音文件。

运行行动

现在,你知道所有关于动作,你会加入一些动作给它带来的游戏生活。

// 1
let spawnSoundAction = SKAction.playSoundFileNamed(
      "SoundEffects/Spawn.wav", waitForCompletion: false)
let dieSoundAction = SKAction.playSoundFileNamed(
      "SoundEffects/Die.wav", waitForCompletion: false)
let waitAction = SKAction.wait(forDuration: 3)
let removeAction = SKAction.removeFromParent()
// 2
let runAction = SKAction.run({
  self.lives -= 1
  if self.lives <= 0 {
    self.stopGame()
  }
})
// 3
let sequenceAction = SKAction.sequence(
  [spawnSoundAction, waitAction, dieSoundAction, runAction,
    removeAction])    
emojiNode.run(sequenceAction)

了解2D Raycasting.

可怜的表情符号,有办法,现在保存。这只是这么残暴满足! :]

处理触摸

接下来,您将添加触摸功能在游戏中玩家可以保存这些可怜的表情符号。

func checkTouches(_ touches: Set<UITouch>) {
  // 1
  guard let touch = touches.first else { return }
  let touchLocation = touch.location(in: self)
  let touchedNode = self.atPoint(touchLocation)
  // 2
  if touchedNode.name != " 表情符号 " { return }
  score += 1
  // 3     
  let collectSoundAction = SKAction.playSoundFileNamed(
      "SoundEffects/Collect.wav", waitForCompletion: false)
  let removeAction = SKAction.removeFromParent()
  let sequenceAction = SKAction.sequence(
    [collectSoundAction, removeAction]) 
  touchedNode.run(sequenceAction)
}
checkTouches(touches)

添加完成触摸

当游戏开始时,Spawn Point刚刚弹出。这感觉有点突然和未溶血。如果产生的发出动画,那么它看起来很酷。

boxNode.setScale(0)
let startSoundAction = SKAction.playSoundFileNamed(
  "SoundEffects/GameStart.wav", waitForCompletion: false)
let scaleInAction = SKAction.scale(to: 1.5, duration: 0.8)
boxNode.run(SKAction.sequence(
  [startSoundAction, scaleInAction]))

关键点

恭喜,您已到达章节和部分结尾。

有一个技术问题?想报告一个错误吗? 你可以问的问题和bug报告本书的作者在我们的官书论坛 这里 .

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

为了突出或做笔记,你需要通过自己拥有这本书的订阅或能力。