swift语言实战晋级-第9章 游戏实战-跑酷熊猫-9-10 移除平台与视差滚动

原文:swift语言实战晋级-第9章 游戏实战-跑酷熊猫-9-10 移除平台与视差滚动

9.9 移除场景之外的平台

 

    用为平台是源源不断的产生的,如果不注意销毁,平台就将越积越多,虽然在游戏场景中看不到。几十个还看不出问题,那几万个呢?几百万个呢?

    所以我们来看看怎么移除平台,那什么样的平台需要移除呢?又如何移除呢?之前我们也说过,当平台完全移除游戏场景的时候就可以进行移除操作了。需要做两个操作,1从平台工厂类中移除,2从平台数组中移除。

而且,因为平台是一个接一个出现的,所以我们不需要每次都遍历平台数组去对每个平台都做判断。只需要对最左边也就是第一个平台做这种检测就可以了。这种检测放在move方法中是最适合不过的了。

 

func move(speed:CGFloat){
//遍历所有
for p in platforms{
//x坐标的变化长生水平移动的动画
p.position.x -= speed
}
//移除平台
if platforms[0].position.x < -platforms[0].width {
platforms[0].removeFromParent()
platforms.removeAtIndex(0)
}
}

9.10 视差滚动背景

 

    什么是视差滚动?它指的是让多层背景以不同的速度移动,形成立体的运动效果,从而带来非常出色的视觉体验。

 

    而我们的游戏中也运用到了这个技术。如下图:

 

    在跑酷熊猫这个游戏中,我们的背景分为两层。第一层更靠近游戏窗口的色彩更鲜艳,移动速度也更快一些。第二层由于要模拟远处的场景,所以颜色更淡一些,对比度更弱一些,移动速度也就更慢一些。

    于是,在我们的编码中,我们可以利用GameScene中定义的移动速度moveSpeed,给第一层背景1/5的moveSpeed的值,给第二层背景1/20的moveSeed的值。这样就形成了视察滚动。

   

    视差滚动讲完,我们还要理解一种循环滚动的算法。因为我们不可能像产生平台那样,源源不断的生成新的背景。我们要用一种循环滚动的算法来实现。

    首先,我们的背景图片是可以收尾无缝衔接的。那么该需要多少张无缝衔接图来组成背景呢?判断标准是:当第一张图移除屏幕外,剩下的图在x轴方向上还能够填满游戏屏幕就够了。看下图:

 

 

    像上图这样的情况,只需要两张背景图就够了。那么我们就用两张无缝衔接的背景图来做说明什么是循环滚动。下图是初始情况:

 

当移动到再上一张图9-17的位置时,直接跳回图9-18的位置,再继续向左移动就形成了循环滚动。我们从下图能看到,回跳的时候,在游戏场景中,背景在视觉上是没有变化的,但实际上已经开始了新的滚动。

 

原理讲完,我们来看看具体的编码。我们新建一个背景类,类名是BackGround,继承自SKNode。

    在背景类中我们定义两个数组,一个用来存放近景,另一个用来存放远景:

//近处背景数组
ar arrBG = [SKSpriteNode]()
//远处背景数组
var arrFar = [SKSpriteNode]()

 

    我们在构造方法init内些生成背景的代码。由于远景图片比较小,所以要完成循环滚动要3张图。

    循环滚动的算法卸写在了move方法中,move方法和平台工厂类的move方法一样,接收一个表示速度的参数,这个参数是GameScene中moveSpeed的1/5。因为远景速度移动要更慢,所以它的x坐标的变化值是近景的四分之一。

    看看完整代码:

import SpriteKit

class BackGround :SKNode {
    //近处背景数组
    var arrBG = [SKSpriteNode]()
    //远处背景数组
    var arrFar = [SKSpriteNode]()

    override init() {
        super.init()
        //获取远处背景的纹理
        var farTexture = SKTexture(imageNamed: "background_f1")
        //远处背景由3章无缝图衔接而成
        var farBg0 = SKSpriteNode(texture: farTexture)
        farBg0.anchorPoint = CGPointMake(0, 0)
        farBg0.zPosition = 9
        farBg0.position.y = 150

        var farBg1 = SKSpriteNode(texture: farTexture)
        farBg1.anchorPoint = CGPointMake(0, 0)
        farBg1.zPosition = 9
        farBg1.position.x = farBg0.frame.width
        farBg1.position.y = farBg0.position.y

        var farBg2 = SKSpriteNode(texture: farTexture)
        farBg2.anchorPoint = CGPointMake(0, 0)
        farBg2.zPosition = 9
        farBg2.position.x = farBg0.frame.width * 2
        farBg2.position.y = farBg0.position.y

        self.addChild(farBg0)
        self.addChild(farBg1)
        self.addChild(farBg2)
        arrFar.append(farBg0)
        arrFar.append(farBg1)
        arrFar.append(farBg2)

        //近处背景纹理
        var texture = SKTexture(imageNamed: "background_f0")
        //近处背景由2章无缝衔接图组成
        var bg0 = SKSpriteNode(texture: texture)
        bg0.anchorPoint = CGPointMake(0, 0)
        var bg1 = SKSpriteNode(texture: texture)
        bg1.anchorPoint = CGPointMake(0, 0)
        bg1.position.x = bg0.frame.width
        bg0.zPosition = 10
        bg1.zPosition = 10
        bg0.position.y = 70
        bg1.position.y = bg0.position.y
        self.addChild(bg0)
        self.addChild(bg1)
        arrBG.append(bg0)
        arrBG.append(bg1)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //移动方法
    func move(speed:CGFloat){
        //通过遍历获取背景,然后做x方向的改变
        for bg in arrBG {
            bg.position.x -= speed
        }
        //循环滚动算法
        if arrBG[0].position.x + arrBG[0].frame.width < speed {
            arrBG[0].position.x = 0
            arrBG[1].position.x = arrBG[0].frame.width
        }
        //远景同上

        for far in arrFar {
            far.position.x -= speed/4
        }
        if arrFar[0].position.x + arrFar[0].frame.width < speed/4 {
            arrFar[0].position.x = 0
            arrFar[1].position.x = arrFar[0].frame.width
            arrFar[2].position.x = arrFar[0].frame.width * 2
        }
    }
}

 

    和平台工厂类与熊猫类一样,我们需要在GameScene里申明一个bg变量。

lazy var bg = BackGround()

    然后在didMoveToView方法中加载,要比熊猫panda早一些。

self.addChild(bg)

    背景的滚动也需要在GameScene的update中实现

bg.move(moveSpeed/5)

 

    此时GameScene已经发生了很大的改变,让我们看看完整的代码:

import SpriteKit

class GameScene: SKScene,ProtocolMainScene{
    lazy var panda = Panda()
    lazy var platformFactory = PlatformFactory()
    lazy var bg = BackGround()

    //移动速度
    var moveSpeed:CGFloat = 15
    //判断最后一个平台还有多远完全进入游戏场景
    var lastDis:CGFloat = 0.0
    override func didMoveToView(view: SKView) {
        //场景的背景颜色
        let skyColor = SKColor(red:113/255,green:197/255,blue:207/255,alpha:1)
        self.backgroundColor = skyColor

        //设置背景
        self.addChild(bg)

        //给熊猫定一个初始位置
        panda.position = CGPointMake(200, 400)
        //将熊猫显示在场景中
        self.addChild(panda)
        //将平台工厂加入视图
        self.addChild(platformFactory)
        //将屏幕的宽度传到平台工厂类中
        platformFactory.sceneWidth = self.frame.width
        //设置代理
        platformFactory.delegate = self

    }
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        //当熊猫状态为跑的时候播放跳的动作
        if panda.status == Status.run {
            panda.jump()
        }else if panda.status == Status.jump {
            //当状态为跳的时候,执行打滚动画
            panda.roll()
        }

    }
    override func update(currentTime: CFTimeInterval) {
        lastDis -= moveSpeed
        if lastDis <= 0 {
            println("生成新平台")
            platformFactory.createPlatformRandom()
        }
        platformFactory.move(self.moveSpeed)
        bg.move(moveSpeed/5)
    }

    func onGetData(dist:CGFloat){
        self.lastDis = dist

    }

}

 

    最后我们运行一下,看看效果。嗯,一切都非常完美。wait,平台好像有点不对劲,跑到背景后面去了。

好吧,通过检查代码我们发现,背景都设置了zPosition,数值在9,10。这个属性决定了渲染顺序。越小越先渲染,也就是越小越在后面。那么解决这个bug的方法也很简单。只要把平台的在Position设的大一些,例如20,就能解决。

所以我们切换到Platform类,在onCreate方法的最后一行添加一句:

self.zPosition = 20

 

    再运行一下,这回正常了。

 

我的微信公众号

我写的破书:《Swift语言实战晋级》http://item.jd.com/11641501.html

 

 

时间: 2024-12-04 00:47:25

swift语言实战晋级-第9章 游戏实战-跑酷熊猫-9-10 移除平台与视差滚动的相关文章

Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-1

原文:Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-1 学习目标 一.进一步学习Swift的游戏制作 二.掌握SKNode,SKSpriteNode的运用 三.了解SpriteKit的物理系统 四.掌握动作(SKAction)的运用   在这一章,我们要通过制作跑酷熊猫这个游戏来进一步学习Swift的游戏开发.首先我们要知道自己将要编写的是一个什么样的游戏.先来看一下游戏截图.   跑酷熊猫是一个跑酷类的游戏.我们将操控熊猫这个胖纸施展轻功,在或长或短的平台上飞奔,同时还要收集小苹果.跑的

Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-3 显示一个动态的熊猫

原文:Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-3 显示一个动态的熊猫     一个静态的熊猫明显不能满足我们的欲望,接下来我们就让熊猫跑起来.序列帧动画的原理就是不停的切换不同的图片.当我们将一张一张的切换Panda类的跑动文理后,熊猫就跑起来了.那么首先我们需要一个数组常量来储存跑动动画文理,还有一个变量来记录熊猫当前的动作状态. let runFrames = [SKTexture]()   //动作状态,默认值为枚举中的跑 var status = Status.run    

Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-2 创建熊猫类

原文:Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-2 创建熊猫类 当我们创建好项目文件后我们就可以开始一步一步的按照我们之前列入的清单来编写我们的游戏.现在就让我们来创建一个熊猫这个类Panda.swift.我们将采取分解的方式,一步一步的完成Panda.swift的编写       首先,我们要导入SpriteKit框架 import SpriteKit   接着我们创建一个枚举值,用来记录熊猫的不同状态,分别是跑,跳,二段跳,打滚.   enum Status:Int{ case r

Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-4 熊猫的跳和打滚

原文:Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-4 熊猫的跳和打滚 之前我们学会了跑的动作,现在我们可以利用同样的方法来实现了跳和打滚的动画.   -- class Panda : SKSpriteNode { -- //跳的纹理集合 let jumpAtlas = SKTextureAtlas(named: "jump.atlas") //存储跳的文理的数组 let jumpFrames = [SKTexture](); //打滚的文理集合 let rollAtlas =

swift语言实战晋级-第9章 游戏实战-跑酷熊猫-7-8 移动平台的算法

原文:swift语言实战晋级-第9章 游戏实战-跑酷熊猫-7-8 移动平台的算法 在上个小节,我们完成了平台的产生.那么我们来实现一下让平台移动.平台的移动,我们只需要在平台工厂类中写好移动的方法,然后在GameScene类中统一控制就行了. 在GameScene类中,有个update方法会每隔一定的时间调用,用来控制平台的移动再适合不过了. 首先,我们在GameScene类中定义一个移动速度:   //移动速度 var moveSpeed:CGFloat = 15   然后在update方法方

Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-5-6 踩踏平台是怎么炼成的

原文:Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-5-6 踩踏平台是怎么炼成的     在游戏中,有很多分来飞去的平台,这个平台长短不一.如果每种长度都去创建一张图片那是比较繁琐的事情.实际上,我们只用到3张图.分别是平台的,平台的中间部分,平台的右边.关键是平台的中间部分,两张中间部分放在一起能够很好地衔接起来,这样只要增加中间部分的数量就能创建不同长度的平台.那这种图片该怎么制作呢?我们先找一张平台的完整图     然后切出中间部分.   这时候,我们能够发现,两块中间部分能够无缝的

《Splunk智能运维实战》——第1章 游戏时间——导入数据 1.1 简介

第1章 游戏时间--导入数据 1.1 简介 加快运维智能的机器数据有很多不同的形式,来源也各不相同.Splunk可从多种来源收集并索引数据,其中包括Web服务器或商业应用程序创建的日志文件,网络设备生成的系统日志数据,及自定义开发脚本输出的数据.即便数据一开始看上去很复杂,我们也可以借助Splunk轻松地实时收集.索引.转化和呈现数据. 本章将学习一些基本的技巧,掌握如何将所需的数据导入Splunk,介绍如何使用样本数据集来构建自己的Splunk智能运维应用程序.该数据集是由一个虚拟的三层式电子

Swift游戏实战-跑酷熊猫(一) 简介 (含源代码)

原文:Swift游戏实战-跑酷熊猫(一) 简介 (含源代码)   优酷观看地址:http://v.youku.com/v_show/id_XNzM2Nzc2MTIw.html   通过这个小游戏,我们能够接触到物理系统(SKPhysicsBody,physicsWorld),动作(SKAction),声音素材的播放,文本标签(SKLabelNode)   我们实现的功能有 熊猫动作的切换,跑,跳,滚 落点平台的生成,移动 熊猫吃的竹子的生成和移动 熊猫跑了多长时间和吃了多少根竹子   一些细节

swift语言实战晋级-1 Swift开发环境的搭建

原文:swift语言实战晋级-1 Swift开发环境的搭建     想要进行Swift的学习,必须要有个开发环境.简单的说就是装好了Xcode的Mac系统.那么接下来我们就简单了解一下这方面的内容.   1.1 下载Xcode        Xcode是苹果公司出的编程工具,类似于微软出品的visual studio,编写Java的eclipse,开发Flash的Flash IDE.所谓工欲善其事必先利其器,所以我们首先要知道的事情就是该去哪里下载Xcode,有以下几个途径.        途径