一,什么是SpriteKit


4,修改场景背景色,添加文本标签,点击屏幕给标签添加动画效果
5,跳转到新场景
6,使用SKSpriteNode创建一个飞船
7,定时生成陨石(并设置物理碰撞)
四,最终完整的代码
--- FirstScene.swift ---
--- SecondScene.swift ---
SpriteKit是苹果公司官方出品,用于制作2D游戏的框架。这个框架具备了图形渲染和动画的功能。可以使图像或者精灵(sprite)动 起来。SpriteKit的渲染方式是传统的环形渲染,允许在渲染前处理每一帧点的内容。例如定义场景中的元素,以及这些内容在每一帧中是如何变化的。尤 其重要的是,苹果官方出品的这个SpriteKit能够很有效地利用图形硬件来渲染。
除了图形渲染,SpriteKit还包括了声音播放和物理系统。在Xcode中,我们可以很轻易地创建复杂的特效和纹理集。
二,SpriteKit支持的内容
(1)无纹理或者有纹理的矩形
(2)文本
(3)基于CGPath的形状
(4)音频,视频
(5)动画特效
(6)物理系统
三,从零开始开发一个游戏项目
1,在Xcode中创建一个Game项目

2,当项目创建完毕后,系统会自动生成一个场景,叫GameScene.swift。我们不用它,使用自己新创建的场景。

3,将新创建的场景代替默认的GameScene
打开GameViewController.swift,将相关的地方进行替换
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
extension SKNode { class func unarchiveFromFile(file : NSString) -> SKNode? { ..... let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as FirstSceneclass GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() if let scene = FirstScene.unarchiveFromFile("GameScene") as? FirstScene { ......... |
4,修改场景背景色,添加文本标签,点击屏幕给标签添加动画效果
这里我们使用了SpriteKit的动作(Action)。当点击屏幕时,文字依次向上移动、放大、暂停并淡出屏幕,最后从场景中移除。

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
import SpriteKitclass FirstScene: SKScene { //当切换到这个场景视图后后 override func didMoveToView(view: SKView) { createScene() } func createScene(){ //改变背景颜色 self.backgroundColor = SKColor.blueColor() //创建一个显示文本的节点 let myLabel = SKLabelNode(fontNamed:"Chalkduster") //添加name属性 myLabel.name = "label" //设置文本内容 myLabel.text = "Hello, hangge.com"; //设置字体大小 myLabel.fontSize = 46; //设置文本节点的位置 myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame)); //将文本节点加入场景中 self.addChild(myLabel) } //响应屏幕点击时间的方法 override func touchesBegan(touches:NSSet, withEvent event: UIEvent) { //获取文本节点 let labelNode = self.childNodeWithName("label") //向上移动的动作 let moveUp = SKAction.moveByX(0, y: 100, duration: 0.5) //放大动作 let zoom = SKAction.scaleTo(2.0, duration: 0.25) //暂停的动作 let pause = SKAction.waitForDuration(0.5) //淡出的动作 let fadeAway = SKAction.fadeOutWithDuration(0.25) //从父对象移除的动作 let remove = SKAction.removeFromParent() //动作序列 let moveSequence = SKAction.sequence([moveUp,zoom,pause,fadeAway,remove]) //文本节点执行动作序列 labelNode?.runAction(moveSequence) }} |
5,跳转到新场景
对文本节点的动作序列做如下修改,当文本节点消失的时候,会创建一个新的场景SecondScene,并以开门的方式过渡到新场景,而之前的场景会被移除
|
1
2
3
4
5
6
7
8
9
|
//执行完动作序列之后调用闭包函数labelNode?.runAction(moveSequence, completion: { //声明下一个场景的实例 let secondScene = SecondScene(size: self.size) //场景过渡动画 let doors = SKTransition.doorsOpenVerticalWithDuration(0.5) //带动画的场景跳转 self.view?.presentScene(secondScene,transition:doors)}) |
6,使用SKSpriteNode创建一个飞船
下面通过创建一个椭圆充当飞船,飞船两侧还添加了忽明忽暗的灯光。同时,飞船设置了一个重复的动作序列自动进行移动。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import SpriteKitclass SecondScene: SKScene { //当切换到这个场景视图后后 override func didMoveToView(view: SKView) { createScene() } func createScene(){ let spaceship = newSpaceship() //设置飞船的位置 spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)-150) //加入到场景中 self.addChild(spaceship) } //创建飞创的类 func newSpaceship()->SKShapeNode{ //创建一个椭圆,充当飞船 let ship = SKShapeNode() ship.path = CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 15, 15, nil) ship.strokeColor = SKColor.whiteColor() ship.fillColor = SKColor.grayColor() //创建一组动作,暂停1秒,位移,暂停1秒,位移 let hover = SKAction.sequence([ SKAction.waitForDuration(1.0), SKAction.moveByX(100, y: 50, duration: 1), SKAction.waitForDuration(1.0), SKAction.moveByX(-100, y: -50, duration: 1.0) ]) //以重复的方式执行序列动作 ship.runAction(SKAction.repeatActionForever(hover)) //创建灯光 let light1 = newLight() //设置灯光位置 light1.position = CGPointMake(-28, 6.0) //加载灯光 ship.addChild(light1) //创建灯光2,步骤同上 let light2 = newLight() light2.position = CGPointMake(28, 6.0) ship.addChild(light2) //物理系统 ship.physicsBody = SKPhysicsBody(circleOfRadius: 15) ship.physicsBody?.dynamic = false //返回飞船 return ship } //创建灯光方法 func newLight()->SKShapeNode{ //创建一个黄色椭圆充当灯光 let light = SKShapeNode() light.path = CGPathCreateWithRoundedRect(CGRectMake(-4, -4, 8, 8), 4, 4, nil) light.strokeColor = SKColor.whiteColor() light.fillColor = SKColor.yellowColor() //创建忽明忽暗的动作 let blink = SKAction.sequence([ SKAction.fadeOutWithDuration(0.25), SKAction.fadeInWithDuration(0.25) ]) //创建一直重复的动作 let blinkForever = SKAction.repeatActionForever(blink) //执行动作 light.runAction(blinkForever) //返回灯光 return light }} |
7,定时生成陨石(并设置物理碰撞)
下面代码会每隔0.1秒在屏幕上方随机的生成一个陨石。由于添加了物理体,所以陨石会做向下的自由落体运动。同时陨石砸在飞船上会停住,并像有弹性似的跳了跳,等飞船离开后才又落下来。

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
import SpriteKitclass SecondScene: SKScene { //当切换到这个场景视图后后 override func didMoveToView(view: SKView) { createScene() } func createScene(){ //..... //生成陨石(每隔 0.1秒生成1个) NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "addRock", userInfo: nil, repeats: true) } //创建陨石的方法 func addRock(){ //小椭圆充当陨石 let rock = SKShapeNode() rock.path = CGPathCreateWithRoundedRect(CGRectMake(-4, -4, 8, 8), 4, 4, nil) rock.strokeColor = SKColor.whiteColor() rock.fillColor = SKColor.brownColor() //获取场景宽,高 let w = self.size.width let h = self.size.height //随机出现在场景的xy位置 let x = CGFloat(arc4random())%w let y = CGFloat(arc4random())%h //设置陨石的位置 rock.position = CGPointMake(x,y) //设置陨石的name属性 rock.name = "rock" //给陨石设置物理体 rock.physicsBody = SKPhysicsBody(circleOfRadius: 4) //物理体允许检测碰撞 rock.physicsBody?.usesPreciseCollisionDetection = true //场景加入陨石 self.addChild(rock) }} |
四,最终完整的代码
--- FirstScene.swift ---
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
import SpriteKitclass FirstScene: SKScene { //当切换到这个场景视图后后 override func didMoveToView(view: SKView) { createScene() } func createScene(){ //改变背景颜色 self.backgroundColor = SKColor.blueColor() //创建一个显示文本的节点 let myLabel = SKLabelNode(fontNamed:"Chalkduster") //添加name属性 myLabel.name = "label" //设置文本内容 myLabel.text = "Hello, hangge.com"; //设置字体大小 myLabel.fontSize = 46; //设置文本节点的位置 myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame)); //将文本节点加入场景中 self.addChild(myLabel) } //响应屏幕点击时间的方法 override func touchesBegan(touches:NSSet, withEvent event: UIEvent) { //获取文本节点 let labelNode = self.childNodeWithName("label") //向上移动的动作 let moveUp = SKAction.moveByX(0, y: 100, duration: 0.5) //放大动作 let zoom = SKAction.scaleTo(2.0, duration: 0.25) //暂停的动作 let pause = SKAction.waitForDuration(0.5) //淡出的动作 let fadeAway = SKAction.fadeOutWithDuration(0.25) //从父对象移除的动作 let remove = SKAction.removeFromParent() //动作序列 let moveSequence = SKAction.sequence([moveUp,zoom,pause,fadeAway,remove]) //执行完动作序列之后调用闭包函数 labelNode?.runAction(moveSequence, completion: { //声明下一个场景的实例 let secondScene = SecondScene(size: self.size) //场景过渡动画 let doors = SKTransition.doorsOpenVerticalWithDuration(0.5) //带动画的场景跳转 self.view?.presentScene(secondScene,transition:doors) }) }} |
--- SecondScene.swift ---
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
import SpriteKitclass SecondScene: SKScene { //当切换到这个场景视图后后 override func didMoveToView(view: SKView) { createScene() } func createScene(){ let spaceship = newSpaceship() //设置飞船的位置 spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)-150) //加入到场景中 self.addChild(spaceship) //生成陨石(每隔 0.1秒生成1个) NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "addRock", userInfo: nil, repeats: true) } //创建飞创的类 func newSpaceship()->SKShapeNode{ //创建一个椭圆,充当飞船 let ship = SKShapeNode() ship.path = CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 15, 15, nil) ship.strokeColor = SKColor.whiteColor() ship.fillColor = SKColor.grayColor() //创建一组动作,暂停1秒,位移,暂停1秒,位移 let hover = SKAction.sequence([ SKAction.waitForDuration(1.0), SKAction.moveByX(100, y: 50, duration: 1), SKAction.waitForDuration(1.0), SKAction.moveByX(-100, y: -50, duration: 1.0) ]) //以重复的方式执行序列动作 ship.runAction(SKAction.repeatActionForever(hover)) //创建灯光 let light1 = newLight() //设置灯光位置 light1.position = CGPointMake(-28, 6.0) //加载灯光 ship.addChild(light1) //创建灯光2,步骤同上 let light2 = newLight() light2.position = CGPointMake(28, 6.0) ship.addChild(light2) //物理系统 ship.physicsBody = SKPhysicsBody(circleOfRadius: 15) ship.physicsBody?.dynamic = false //返回飞船 return ship } //创建灯光方法 func newLight()->SKShapeNode{ //创建一个黄色椭圆充当灯光 let light = SKShapeNode() light.path = CGPathCreateWithRoundedRect(CGRectMake(-4, -4, 8, 8), 4, 4, nil) light.strokeColor = SKColor.whiteColor() light.fillColor = SKColor.yellowColor() //创建忽明忽暗的动作 let blink = SKAction.sequence([ SKAction.fadeOutWithDuration(0.25), SKAction.fadeInWithDuration(0.25) ]) //创建一直重复的动作 let blinkForever = SKAction.repeatActionForever(blink) //执行动作 light.runAction(blinkForever) //返回灯光 return light } //创建陨石的方法 func addRock(){ //小椭圆充当陨石 let rock = SKShapeNode() rock.path = CGPathCreateWithRoundedRect(CGRectMake(-4, -4, 8, 8), 4, 4, nil) rock.strokeColor = SKColor.whiteColor() rock.fillColor = SKColor.brownColor() //获取场景宽,高 let w = self.size.width let h = self.size.height //随机出现在场景的xy位置 let x = CGFloat(arc4random())%w let y = CGFloat(arc4random())%h //设置陨石的位置 rock.position = CGPointMake(x,y) //设置陨石的name属性 rock.name = "rock" //给陨石设置物理体 rock.physicsBody = SKPhysicsBody(circleOfRadius: 4) //物理体允许检测碰撞 rock.physicsBody?.usesPreciseCollisionDetection = true //场景加入陨石 self.addChild(rock) }} |