一,什么是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
FirstScene
class
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
SpriteKit
class
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
SpriteKit
class
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
SpriteKit
class
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
SpriteKit
class
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
SpriteKit
class
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)
}
}
|