一,什么是SpriteKit

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)       
    }
}

Swift - 一步步教你使用SpriteKit创建开发游戏项目的更多相关文章

  1. 一步步教你轻松学支持向量机SVM算法之案例篇2

    一步步教你轻松学支持向量机SVM算法之案例篇2 (白宁超 2018年10月22日10:09:07) 摘要:支持向量机即SVM(Support Vector Machine) ,是一种监督学习算法,属于 ...

  2. 一步步教你轻松学关联规则Apriori算法

    一步步教你轻松学关联规则Apriori算法 (白宁超 2018年10月22日09:51:05) 摘要:先验算法(Apriori Algorithm)是关联规则学习的经典算法之一,常常应用在商业等诸多领 ...

  3. 一步步教你轻松学K-means聚类算法

    一步步教你轻松学K-means聚类算法(白宁超  2018年9月13日09:10:33) 导读:k-均值算法(英文:k-means clustering),属于比较常用的算法之一,文本首先介绍聚类的理 ...

  4. 一步步教你轻松学朴素贝叶斯模型算法Sklearn深度篇3

    一步步教你轻松学朴素贝叶斯深度篇3(白宁超   2018年9月4日14:18:14) 导读:朴素贝叶斯模型是机器学习常用的模型算法之一,其在文本分类方面简单易行,且取得不错的分类效果.所以很受欢迎,对 ...

  5. 一步步教你轻松学KNN模型算法

    一步步教你轻松学KNN模型算法( 白宁超 2018年7月24日08:52:16 ) 导读:机器学习算法中KNN属于比较简单的典型算法,既可以做聚类又可以做分类使用.本文通过一个模拟的实际案例进行讲解. ...

  6. Swift: 在Swift中桥接OC文件(自己创建的类文件、第三方库文件)

    一.介绍 随着Swift的逐渐成熟,使用swift开发或者混合开发已经成为了一个趋势,本身苹果公司也十分推荐使用Swift这门新语言.目前Swift已经更新到了3.0,估计没有多久4.0就要出来了.那 ...

  7. 一步步教你搭建VS环境下用C#写WebDriver脚本

    一步步教你搭建VS环境下用C#写WebDriver脚本http://www.automationqa.com/forum.php?mod=viewthread&tid=3529&fro ...

  8. 我写了个教程《一步步教你把ubuntu安装到U盘》

    一步步教你把ubuntu安装到U盘 作者 Val 2452013147@qq.com 原因: 由于某些原因(学生党),需要把ubuntu安装到U盘到处走,百度了一下,教程都不是很好,要么很复杂,要么不 ...

  9. 一步步教你读懂NET中IL(附带图)

    一步步教你读懂NET中IL(附带图) 接触NET也有1年左右的时间了,NET的内部实现对我产生了很大的吸引力,在msdn上找到一篇关于NET的IL代码的图解说明,写的挺不错的.个人觉得:能对这些底部的 ...

随机推荐

  1. BZOJ 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草( dp )

    dp... dp( l , r , k )  , 表示 吃了[ l , r ] 的草 , k = 1 表示最后在 r 处 , k = 0 表示最后在 l 处 . ------------------- ...

  2. ubuntu学习: apt-get命令

    1.apt-get update 更新软件源本地缓存文件 2.apt-cache search 查找软件包,找到想要安装的包,如 sudo apt-cache search mysql-server ...

  3. matlab绘图方法汇总

    Matlab画图 强大的画图功能是Matlab的特点之中的一个,Matlab提供了一系列的画图函数,用户不须要过多的考虑画图的细节,仅仅须要给出一些基本參数就能得到所需图形,这类函数称为高层画图函数. ...

  4. yii框架网址解析问题

    转载请注明来自souldak,微博:@evagle 首先如果你在config/main.php里面没有配置urlManager的话,那么流程如下(摘自yii官网) 用户发出了访问 URL http:/ ...

  5. 解决Android Activity切换时出现白屏问题

    有些性能低的机器,在切换activity时候出现白屏一段时候后才显示正确的视图 高性能的机器可能太快看不到,但是事实是存在的, 特别是当你新开一个进程的时候,A进程的activity跳转到B进程的Ac ...

  6. Case of the Zeros and Ones

    Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Description Andrew ...

  7. 百度网盘自动上传脚本-bpcs_uploader

    安装jsonpear install pecl/json 一.bpcs_uploader下载和使用: 1.下载地址:http://oott123.github.com/bpcs_uploader/ 2 ...

  8. SuperSocket源码解析之会话生命周期

    一 基本概念 会话(Session)是客户端与服务器进行通信的基本单元,也是一个Socket的封装,在http协议中也有Session机制,其主要作用封装一个通信单元socket,负责服务器与客户端消 ...

  9. Spring源码解析——如何阅读源码(转)

    最近没什么实质性的工作,正好有点时间,就想学学别人的代码.也看过一点源码,算是有了点阅读的经验,于是下定决心看下spring这种大型的项目的源码,学学它的设计思想. 手码不易,转载请注明:xingoo ...

  10. Boost::filesystem 使用小笔记

    今天拿起手要用C++写个小工具,从指定的目录递归遍历文件,然后做一下处理.又翻了一下boost的filesystem库.小结一下,希望能加深印象,免得下次又要查看文档. 1. path对象就是一个跨平 ...