zoukankan      html  css  js  c++  java
  • iOS Sprite Kit教程之滚动场景

    iOS Sprite Kit教程之滚动场景

    滚动场景

    在很多的游戏中,场景都不是静止的,而是滚动的,如在植物大战僵尸的游戏中,它的场景如图2.26所示。

     

    图2.26  植物大战僵尸

    在图2.26中,用黑色框框住的部分是在屏幕上显示的,即玩家是可以看到的。右边的这些内容玩家就看不到了,为了让玩家可以熟悉场景中的内容,此游戏在开始时,首先对屏幕中的场景进行滚动。本节将为开发者实现场景滚动的功能。

    Sprite Kit中让场景进行滚动

    以下是如何让一个场景进行滚动的具体实现方法。

    1.创建项目以及添加图像

    从上文的内容中可以看到场景的背景颜色具有单一性,即场景的背景颜色是红色,场景就为红色。一般所说的滚动场景其实就是滚动背景,所以在滚动场景时,场景的滚动效果是看不出来的。为了可以看到滚动效果,背景需要使用图像实现。首先我们需要添加图像background1.png和background2.png到创建的项目中。添加图像的具体步骤如下:

    (1创建一个Game类型的项目,命名为2-2。

    (2右击2-2项目中的Supporting Files文件夹,弹出快捷菜单,如图2.27所示。

     

    图2.27  添加图像1

    (3选择Add Files to "2-2"…命令,弹出选择文件对话框,如图2.28所示。

     

     

    图2.28  添加图像2

    (4选择需要添加的图像后,单击Add按钮,实现图像的添加。添加后的图像就会显示在Supporting Files文件夹中。

    2.修改设备的方向

    单击项目名称,打开目标窗口,选择General选项,打开General面板,在其中找到Device Orientation,选择其中的Landscape Left和Landscape Right单选框。让运行的模拟器方向变为横向,如图2.29所示。

     

     

    图2.29  修改设备方向

    3.删除多余的代码

    打开GameScene.swift文件,删除多余代码,剩余的代码如下:

     

    • import SpriteKit
    • class GameScene: SKScene {
    • override func didMoveToView(view: SKView) {
    •    
    •     }
    •     override func update(currentTime: CFTimeInterval) {
    •       
    •     }
    • }

    打开GameViewController.swift文件,删除多余代码,剩余的代码如下:

     

    • import UIKit
    • import SpriteKit
    • class GameViewController: UIViewController {
    •     override func viewDidLoad() {
    •         super.viewDidLoad()
    •     }
    • }

    4.编写实现滚动场景的代码

    (1打开GameScene.swift文件,添加一个新的框架,以及实现运算符的重载,使其可以实现两个点的加法赋值运算以及乘法运算。代码如下:

     

    • import CoreGraphics
    • //“+”加法运算符的重载
    • func + (left: CGPoint, right: CGPoint) -> CGPoint {
    •     return CGPoint(x: left.x + right.x, y: left.y + right.y)
    • }
    • //“+=”赋值加法运算符的重载
    • func += (inout left: CGPoint, right: CGPoint) {
    •     left = left + right
    • }
    • //“*”乘法运算符的重载
    • func * (point: CGPoint, scalar: CGFloat) -> CGPoint {
    •     return CGPoint(x: point.x * scalar, y: point.y * scalar)
    • }

    (2添加一个backgroundNode()方法,此方法实现的功能是将两个图像作为场景中的背景,如图2.30所示。代码如下:

     

    • func backgroundNode() -> SKSpriteNode {
    •     //创建并设置backgroundNode对象
    •     let backgroundNode = SKSpriteNode()
    •     backgroundNode.anchorPoint = CGPointZero
    • backgroundNode.name = "background"
    • //创建并设置backgroundNode1对象
    •     let background1 = SKSpriteNode(imageNamed: "background1")
    •     background1.anchorPoint = CGPointZero
    •     background1.position = CGPoint(x: 0, y: 0)
    • backgroundNode.addChild(background1)
    • //创建并设置backgroundNode2对象
    •     let background2 = SKSpriteNode(imageNamed: "background2")
    •     background2.anchorPoint = CGPointZero
    •     background2.position = CGPoint(x: background1.size.width, y: 0)
    • backgroundNode.addChild(background2)
    • //设置backgroundNode对象的尺寸
    •     backgroundNode.size = CGSize(
    •         background1.size.width + background2.size.width,
    •         height: background1.size.height)
    •     return backgroundNode
    • }

     

    图2.30  场景的背景

    注意,在此代码中的背景添加使用的是SKSpriteNode类实现的,对于此类,我们会在后面进行讲解。

    (3在didMoveToView(view: SKView方法中编写代码,将设置的背景添加到场景中,代码如下:

     

    • override func didMoveToView(view: SKView) {
    •     let background = backgroundNode()                                                //实例化对象
    •     background.anchorPoint = CGPointZero                                         //设置描点
    •     background.position = CGPointZero                                                //设置位置
    •     background.name = "background"
    •     addChild(background)
    • }

    (4添加变量到GameScene.swift文件中,代码如下:

     

    • let backgroundMovePointsPerSec: CGFloat = 200.0                            //背景在每秒中移动的点
    • var dt: NSTimeInterval = 0                                                                          //时间间距
    • var lastUpdateTime: NSTimeInterval = 0                                       //上一次更新的时间

    (5添加一个moveBackground()的方法,在此方法中编写代码,使其实现背景的移动,代码如下:

     

    • func moveBackground() {
    •     enumerateChildNodesWithName("background") { node, _ in
    •         let background = node as SKSpriteNode                                          //将node转换为SKSpriteNode
    •         let backgroundVelocity =CGPoint(x: -self.backgroundMovePointsPerSec, y: 0)  //背景的速度
    •         let amountToMove = backgroundVelocity * CGFloat(self.dt)                                         //偏移量
    •         background.position += amountToMove                                                                    //背景的位置
    •     }
    • }

    (6在update(currentTime: NSTimeInterval)方法中编写代码,实现数据的更新,进而实现场景的滚动,代码如下:

     

    • override func update(currentTime: NSTimeInterval) {
    •     //判断lastUpdateTime是否大于0
    •     if lastUpdateTime > 0 {
    •         dt = currentTime - lastUpdateTime
    •     } else {
    •         dt = 0
    •     }
    •     lastUpdateTime = currentTime
    •     moveBackground()                                                          //调用
    • }

    (7打开GameViewController.swift文件,编写代码,实现场景的显示,代码如下:

     

    • override func viewDidLoad() {
    •     super.viewDidLoad()
    •     let scene = GameScene(size:CGSize( 2048, height: 1536))
    •     let skView = self.view as SKView
    •     skView.showsFPS = true
    •     skView.showsNodeCount = true
    •     skView.ignoresSiblingOrder = true
    •     scene.scaleMode = .AspectFill
    •     skView.presentScene(scene)
    • }

    此时运行程序,会看到如图2.31所示的效果。

     

     

    图2.31  运行效果

    Sprite Kit中的永无休止的滚动场景

    在2.5.1小节中,当单击运行按钮后,可以看到场景中的背景图像实现了滚动,进而实现了场景的滚动,但是,将这两个图像都滚动完毕后,场景还在进行滚动,此时背景图像就慢慢的退出了场景,如图2.32所示。本小节将为开发者解决在上一小节中的不足。实现一个永无休止的滚动场景功能,即背景循环滚动。具体的操作步骤如下:

     

     

    图2.32  滚动场景

    (1打开GameScene.swift文件,添加一个变量,代码如下:

    let backgroundLayer = SKNode()            //实例化一个节点

    (2修改didMoveToView(view: SKView)方法中的代码,修改后的代码如下“

     

    • override func didMoveToView(view: SKView) {
    •     //变量0到1的范围
    • for i in 0...1 {
    •     //设置并添加背景
    •         let background = backgroundNode()
    •         background.anchorPoint = CGPointZero
    •         background.position =CGPoint(x: CGFloat(i)*background.size.width, y: 0)
    •         background.name = "background"
    •         addChild(background)
    •     }
    • }

    (3修改moveBackground()方法中的代码,修改后的代码如下:

     

    • func moveBackground() {
    •     enumerateChildNodesWithName("background") { node, _ in
    •         let background = node as SKSpriteNode
    •         let backgroundVelocity =CGPoint(x: -self.backgroundMovePointsPerSec, y: 0)
    •         let amountToMove = backgroundVelocity * CGFloat(self.dt)
    •         background.position += amountToMove
    •         let backgroundScreenPos = self.backgroundLayer.convertPoint(background.position, toNode: self)
    •         //判断x的值是否小于背景的-width的值
    •         if backgroundScreenPos.x <= -background.size.width {
    •             //设置背景的位置
    •             background.position = CGPoint(
    •                 x: background.position.x + background.size.width*2,
    •                 y: background.position.y)
    •         }
    •     }
    • }

    此时运行程序,会看到如图2.33所示的效果。

     

     

    图2.33  运行效果

    本文选自:iOS游戏框架Sprite Kit基础教程——Swift版大学霸内部资料,转载请注明出处,尊重技术尊重IT人!

  • 相关阅读:
    The bean 'xxx' could not be injected as a 'xxx'because it is a JDK dynamic proxy that implements
    JQuery对象选择详细说明
    C#将image中的显示的图片转换成二进制
    选择一个图片文件,并且用PictureBox表示在Form上
    Android推送方案分析(MQTT/XMPP/GCM)
    [转载]什么是 Design Hackathon?
    脚本启动MySql服务
    Mysql数据库插入数据乱码问题,解决方案!
    MySQL自动备份脚本
    读取Excel模板,写入数据,并别输出另存为Excel文件
  • 原文地址:https://www.cnblogs.com/daxueba-ITdaren/p/4682904.html
Copyright © 2011-2022 走看看