zoukankan      html  css  js  c++  java
  • Swift

    一,什么是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)       
        }
    }
  • 相关阅读:
    数据结构 队列
    数据结构 堆栈
    UNP学习 广播
    UNP学习 路由套接口
    QTcpSocket发送结构体
    线性表及实现
    [转]理解WSRF之一 使用WS-ResourceProperties (整理自IBM网站)
    详解x86、IA-32、IA-64等CPU系列
    gsoap框架下的onvif程序流程分析
    【LeetCode】从contest-21开始。(一般是10个contest写一篇文章)
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4841089.html
Copyright © 2011-2022 走看看