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(
  •         width: 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(width: 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人!

iOS Sprite Kit教程之滚动场景的更多相关文章

  1. iOS Sprite Kit教程之真机测试以及场景的添加与展示

    iOS Sprite Kit教程之真机测试以及场景的添加与展示 IOS实现真机测试 在进行真机测试之前,首先需要确保设备已经连在了Mac(或者Mac虚拟机)上,在第1.9.1小节开始,设备就一直连接在 ...

  2. iOS Sprite Kit教程之场景的切换

    iOS Sprite Kit教程之场景的切换 Sprite Kit中切换场景 每一个场景都不是单独存在的.玩家可以从一个场景中切换到另外一个场景中.本小节,我们来讲解场景切换.在每一个游戏中都会使用到 ...

  3. iOS Sprite Kit教程之场景的设置

    iOS Sprite Kit教程之场景的设置 Sprite Kit中设置场景 在图2.8所示的效果中,可以看到新增的场景是没有任何内容的,本节将讲解对场景的三个设置,即颜色的设置.显示模式的设置以及测 ...

  4. iOS Sprite Kit教程之编写程序以及Xcode的介绍

    iOS Sprite Kit教程之编写程序以及Xcode的介绍 Xcode界面介绍 一个Xcode项目由很多的文件组成,例如代码文件.资源文件等.Xcode会帮助开发者对这些文件进行管理.所以,Xco ...

  5. iOS Sprite Kit教程之编敲代码以及Xcode的介绍

    iOS Sprite Kit教程之编敲代码以及Xcode的介绍 Xcode界面介绍 一个Xcode项目由非常多的文件组成,比如代码文件.资源文件等.Xcode会帮助开发人员对这些文件进行管理.所以,X ...

  6. iOS Sprite Kit教程之申请和下载证书

    iOS Sprite Kit教程之申请和下载证书 模拟器虽然可以实现真机上的一些功能,但是它是有局限的.例如,在模拟器上没有重力感应.相机机等.如果想要进行此方面的游戏的开发,进行程序测试时,模拟器显 ...

  7. iOS Sprite Kit教程之使用帮助文档以及调试程序

    iOS Sprite Kit教程之使用帮助文档以及调试程序 IOS中使用帮助文档 在编写代码的时候,可能会遇到很多的方法.如果开发者对这些方法的功能,以及参数不是很了解,就可以使用帮助文档.那么帮助文 ...

  8. ios游戏开发 Sprite Kit教程:初学者 1

    注:本文译自Sprite Kit Tutorial for Beginners 目录 Sprite Kit的优点和缺点 Sprite Kit vs Cocos2D-iPhone vs Cocos2D- ...

  9. Sprite Kit教程:初学者

    作者:Ray Wenderlich 原文出处:点击打开链接 http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 转自 ...

随机推荐

  1. 49、多线程创建的三种方式之继承Thread类

    继承Thread类创建线程 在java里面,开发者可以创建线程,这样在程序执行过程中,如果CPU空闲了,就会执行线程中的内容. 使用Thread创建线程的步骤: 1.自定义一个类,继承java.lan ...

  2. 【树】ztree

    ztree前端参见官网http://www.ztree.me/v3/main.php Action示例 public String initLabServerTree(){ return SUCCES ...

  3. 关于 jQuery 中的 $.data() 方法和 jQuery 对象上的data 方法

    参见文章:http://www.it165.net/pro/html/201404/11922.html

  4. 【黑客免杀攻防】读书笔记14 - 面向对象逆向-虚函数、MFC逆向

    虚函数存在是为了克服类型域解决方案的缺陷,以使程序员可以在基类里声明一些能够在各个派生类里重新定义的函数. 1 识别简单的虚函数 代码示例: #include "stdafx.h" ...

  5. Android调试大法 自定义IDE默认签名文件==>微信支付、微信登录、微信分享,debug时调试通过,release时调不起微信

    转载地址:http://blog.yanzhenjie.com Android调试大法之自定义IDE默认签名文件,你是否为调试第三方SDK时debug签名和release签名发生冲突而烦恼?你是否在d ...

  6. docker强制关闭命令

    删除容器: 优雅的关闭容器:docker stop  容器id/容器名字 强制关闭容器:docker kill 容器id/容器名字 删除镜像: docker rmi 容器id/容器名字

  7. netstat-ll-grep-nohup-df-supervisord

    ============http://man.linuxde.net/=========== 0 vi / n是查找下一个,alt+n是上一个  u撤销上一步,回到上一步 1. 根据进程号(4974) ...

  8. iconfont-矢量图标字体

    二.矢量图标使用 1.进入:http://www.iconfont.cn/  搜索你图标的关键字,然后将需要的图标字体加入购物车 加入购物车之后,添加到项目 2.点击查看在线连接,生成css代码,把代 ...

  9. activiti源码分析学习

    activiti源码分析学习导语 目前项目中用activiti来做工作流的相关工作,最近遇到一些情况下,公司二次开发的流程图渲染出现了问题,会造成流程图出不来的情况.初步分析数据库中记录以及简单的代码 ...

  10. Java Http接口加签、验签操作方法

    1.业务背景 最近接触了一些电商业务,发现在处理电商业务接口时,比如淘宝.支付类接口,接口双方为了确保数据参数在传输过程中未经过篡改,都需要对接口数据进行加签,然后在接口服务器端对接口参数进行验签,确 ...