在本系列中,我们将学习如何使用SpriteKit来为iOS构建2D游戏。 在本文中,我们将继续探索SpriteKit节点,并了解一种称为“ sprite”的特殊节点SKSpriteNode
。
要继续学习本教程,只需下载随附的GitHub repo即可 。 它有一个名为ExampleProject Starter的文件夹。 在Xcode的该文件夹中打开项目,就可以开始了!
精灵节点
SKSpriteNode
可以绘制为在其上映射了纹理的矩形,也可以绘制为彩色的无纹理矩形。 创建映射有纹理的SKSpriteNode
是最常见的方法,因为这是使游戏的SKSpriteNode
作品栩栩如生的方式。
将以下内容添加到GameScene.swift中的didMove(to:)
方法中。
override func didMove(to view: SKView) {
let startGameLabel = SKLabelNode(text: "Start Game")
startGameLabel.name = "startgame"
startGameLabel.position = CGPoint(x: size.width/2, y: size.height/2)
addChild(startGameLabel)
let redSprite = SKSpriteNode(color: .red, size: CGSize(width: 200, height: 200))
addChild(redSprite)
}
在这里,我们使用便捷的intiailizer init(color:size:)
绘制一个矩形精灵,其颜色和大小作为您传入的参数。 如果现在测试项目,您将看到红色方块的一半显示。
您可能想知道为什么为什么只显示精灵的一半,因为我们已经确定SKNode
的起源是( 0,0 )。 这是因为SKSpriteNode
的框架及其纹理位于其位置的中心。 若要更改此行为,可以更改子画面的anchorPoint
属性,该属性确定框架所处的点。 下图显示了anchorPoint
工作方式。
anchorPoint
在单位坐标系中指定,将( 0,0 )放置在框架的左下角,将( 1,1 )放置在框架的右上角。 SKSpriteNode
的默认值为( 0.5,0.5 )。
继续,将anchorPoint
属性更改为( 0,0 ),请注意它的区别。
override func didMove(to view: SKView) {
let startGameLabel = SKLabelNode(text: "Start Game")
startGameLabel.name = "startgame"
startGameLabel.position = CGPoint(x: size.width/2, y: size.height/2)
addChild(startGameLabel)
let redSprite = SKSpriteNode(color: .red, size: CGSize(width: 200, height: 200))
redSprite.anchorPoint = CGPoint(x: 0, y:0)
addChild(redSprite)
}
现在,如果进行测试,您将看到精灵与场景的左下角完美对齐。
现在,通过更改其position属性,将其移至场景的顶部中心。 将您的didMove(to:)
函数替换为以下内容:
override func didMove(to view: SKView) {
let startGameLabel = SKLabelNode(text: "Start Game")
startGameLabel.name = "startgame"
startGameLabel.position = CGPoint(x: size.width/2, y: size.height/2)
addChild(startGameLabel)
let redSprite = SKSpriteNode(color: .red, size: CGSize(width: 200, height: 200))
redSprite.anchorPoint = CGPoint(x: 0, y:0)
redSprite.position = CGPoint(x: size.width/2 - 100, y: size.height - 210)
addChild(redSprite)
}
请注意,我们必须同时从x
和y
值中减去以使精灵居中。 如果我们将anchorPoint
保留为默认值,则该anchorPoint
将已经在x
轴上居中。 重要的是要记住,当您更改锚点时,可能必须对位置进行一些调整。
质感的精灵
该红色框适合进行定位练习,但是您通常需要在游戏中使用艺术品为子画面纹理化。
让我们创建一个带纹理的SKSpriteNode
。 在didMove(to:)
方法的底部添加以下代码。
override func didMove(to view: SKView) {
...
let player = SKSpriteNode(imageNamed: "player")
player.position = CGPoint(x: size.width/2 , y: 300)
addChild(player)
}
在这里,我们使用便捷的初始化程序init(imageNamed:)
,它将没有扩展名的图像名称作为参数。 这是创建带纹理的精灵的最简单方法,因为它可以根据传入的图像为您创建纹理。
创建带纹理的SKSpriteNode
的另一种方法是预先创建一个SKTexture
,并使用将纹理作为参数的初始化器之一。
让我们再创建几个SKSpriteNode
并更改它们的一些属性。 同样,将它们添加到didMove(to:)
函数的底部。
override func didMove(to view: SKView) {
...
let enemy1 = SKSpriteNode(imageNamed: "enemy1")
enemy1.position = CGPoint(x: 100 , y: 300)
enemy1.xScale = 2
addChild(enemy1)
let enemy2 = SKSpriteNode(imageNamed: "enemy2")
enemy2.position = CGPoint(x: size.width - 100 , y: 300)
enemy2.zRotation = 3.14 * 90 / 180
addChild(enemy2)
}
在这里,我们创建两个SKSpriteNode
, enemy1
和enemy2
。 我们设定的xScale
上enemy1
2,改变zRotation
上enemy2
90度旋转。 ( zRotation
属性采用弧度表示其值,正值表示逆时针旋转。)
我们已经尝试过更改精灵上的一些属性。 查看SKNodes和SKSpriteNodes的文档,并尝试更改其他一些属性以查看它们的效果。
Sprite节点非常适合基本的矩形和纹理,但有时需要更复杂的形状。 在这些情况下,您都可以使用SKShapeNode
。 接下来,我们将看看形状节点。
形状节点
另一个有用的节点是SKShapeNode
。 该节点渲染由Core Graphics路径定义的形状。 SKShapeNode
对于无法使用SKSpriteNode
轻松实现的内容很有用。 与使用SKSpriteNode
,此类需要更多的内存,并且性能较低,因此您SKSpriteNode
用。
要将形状分配给SKShapeNode
,可以将CGPath
设置为节点的path
属性。 但是,有一些初始化程序提供预定义的形状,例如矩形,圆形和椭圆形。 让我们使用便捷的初始化程序init(circleOfRadius:)
创建一个圆。
然后,将以下内容添加到didMove(to:)
方法的底部。
override func didMove(to view: SKView) {
...
let circle = SKShapeNode(circleOfRadius: 50)
circle.strokeColor = SKColor.green
circle.fillColor = SKColor.blue
circle.lineWidth = 8
circle.position = CGPoint(x: size.width/2, y: 400)
addChild(circle)
}
我们在形状节点上更改一些属性,将其定位,然后将其添加到场景中。 使用预定义的形状初始化器非常容易。 但是,手动创建一个复杂的CGPath
会花费大量的时间,而且通常会涉及一些复杂的数学运算,因此这并不是很容易的事情。
值得庆幸的是,有一个工具可以让您直观地绘制形状并将其CGPath
导出为Swift代码。 如果您想了解更多信息,请查看PaintCode 。
Sprite节点和Shape节点将涵盖大多数情况,但有时您可能希望在应用程序中显示视频。 SKVideoNode
,我们将介绍SKVideoNode
。
视频节点
我们要看的最后一个节点是SKVideoNode
。 顾名思义,该节点允许您在游戏中播放视频。
创建SKVideoNode
方法有SKVideoNode
。 一种使用AVPlayer
的实例,另一种仅使用存储在应用程序捆绑包中的视频文件的名称,第三种方法使用URL
。
要记住的一件事是,视频的size
属性最初将与目标视频的大小相同。 不过,您可以更改此size
属性,视频将被拉伸到新的尺寸。
要注意的另一件事是, SKVideoNode
提供play()
和pause()
方法。 如果要对视频进行更多控制,则可以使用现有的AVPlayer
初始化SKVideoNode
并使用它来控制视频。
让我们使用最简单的方法来创建SKVideoNode
。 将以下内容添加到didMove(to:)
方法的底部。
override func didMove(to view: SKView) {
...
let video = SKVideoNode(fileNamed: "video.mov")
video.position = CGPoint(x: size.width/2,y: 600)
addChild(video)
video.play()
}
在这里,我们使用了intiailizer init(fileNamed:)
来创建视频。 您传递视频的名称以及扩展名。 我没有在项目的源代码中附带视频,但是如果您想看一下这项工作,可以在项目中添加一个名为“ video.mov ”的视频。
结论
这样就完成了我们对节点的研究。 阅读这篇文章和上一篇文章之后,您应该对SKNode
及其子类有很好的了解。 在本系列的下一部分中,我们将研究SKActions
并在游戏中使用物理。 感谢您的阅读,我在那里见!
另外,请查看我们的SpriteKit课程! 即使您以前从未使用SpriteKit进行编码,这些操作也将带您完成构建第一个iOS版SpriteKit游戏的所有步骤。
翻译自: https://code.tutsplus.com/tutorials/spritekit-basics-sprites--cms-28816