当前位置: 首页 > news >正文

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

    在游戏中,有很多分来飞去的平台,这个平台长短不一。如果每种长度都去创建一张图片那是比较繁琐的事情。实际上,我们只用到3张图。分别是平台的,平台的中间部分,平台的右边。关键是平台的中间部分,两张中间部分放在一起能够很好地衔接起来,这样只要增加中间部分的数量就能创建不同长度的平台。那这种图片该怎么制作呢?我们先找一张平台的完整图

 

 

然后切出中间部分。

 

这时候,我们能够发现,两块中间部分能够无缝的拼在一起。那么我们就把它拼起来。而拼起来的这块中间部分,我们再整体复制一块,发现不用翻转就能无缝拼接了,这样就完成了平台的中间部分。而平台的右边部分只需要用图中平台的左边部分水平翻转就可以得到。

    这样,我们得到了全部的平台文件。

 

 

9.6 创建平台类以及平台工厂类

    从这部分开始,我们就要开始编码平台的相关类了。首先我们来创建平台类。Platform继承自SKNode。这个类不需要载入纹理只实现平台组装功能,所以继承自SKNode。那么我们就需要自己实现宽width和高height:

//宽
var width :CGFloat = 0.0
//高
var height :CGFloat = 10.0

 

    然后我们需要写一个onCreate方法来组装平台的零件。onCreate接受一个SKSpriteNode类型的数组。并将数组内的元素按顺序水平排好,加入当前类中的实例中。

func onCreate(arrSprite:[SKSpriteNode]){
//通过接受SKSpriteNode数组来创建平台
for platform in arrSprite {
//以当前宽度为平台零件的x坐标
platform.position.x = self.width
//加载
self.addChild(platform)
//更新宽度
self.width += platform.size.width
}
}

 完整代码如下:

//平台类
import SpriteKit

class Platform:SKNode{
    //宽
    var width :CGFloat = 0.0
    //高
    var height :CGFloat = 10.0

    func onCreate(arrSprite:[SKSpriteNode]){
        //通过接受SKSpriteNode数组来创建平台
        for platform in arrSprite {
            //以当前宽度为平台零件的x坐标
            platform.position.x = self.width
            //加载
            self.addChild(platform)
            //更新宽度
            self.width += platform.size.width
        }
    }
}

 

    接下来我们要来写一个平台的工厂类,它负责产生平台零件然后传给平台类进行组装。在编码的时候,我们应该根据功能设计不同的类负责不同的功能。这样各司其职结构清晰,也方便日后的扩展修改。

    工厂类名为PlatformFactory,同样继承自SKNode。在工厂类中,存有平台的纹理。

//定义平台左边纹理
let textureLeft = SKTexture(imageNamed: "platform_l")
//定义平台中间纹理
let textureMid = SKTexture(imageNamed: "platform_m")
//定义平台右边纹理
let textureRight = SKTexture(imageNamed: "platform_r")

 

    我们还需要定义一个数组来储存生成的平台:

//定义一个数组来储存组装后的平台
var platforms = [Platform]()

 

    现在开始写生成平台的方法,createPlatform,它接收四个参数。isRandom,用来决定是否生成随机位置的平台,暂时用不到,但是为了后面做扩展做准备。minNum就是生成几个中间部分。x与y就是位置坐标了。

    createPlatform这个方法,会根据需求生成平台零件数组传入到平台中进行组装。最后放入平台数组中。

    平台工厂类不仅负责生成平台,同时自身也是一个容器,这样就能统一控制所有平台。完整代码如下:

import SpriteKit

class PlatformFactory: SKNode {
    //定义平台左边纹理
    let textureLeft = SKTexture(imageNamed: "platform_l")
    //定义平台中间纹理
    let textureMid = SKTexture(imageNamed: "platform_m")
    //定义平台右边纹理
    let textureRight = SKTexture(imageNamed: "platform_r")

    //定义一个数组来储存组装后的平台
    var platforms = [Platform]()

    
    
    func createPlatform(isRandom:Bool,midNum:UInt32,x:CGFloat,y:CGFloat)->Platform{
        //声明一个平台类,用来组装平台。
        var platform = Platform()
        //生成平台的左边零件
        let platform_left = SKSpriteNode(texture: textureLeft)
        //设置中心点
        platform_left.anchorPoint = CGPoint(x: 0, y: 0.9)
        //生成平台的右边零件
        let platform_right = SKSpriteNode(texture: textureRight)
        //设置中心点
        platform_right.anchorPoint = CGPoint(x: 0, y: 0.9)
        
        //声明一个数组来存放平台的零件
        var arrPlatform = [SKSpriteNode]()
        //将左边零件加入零件数组
        arrPlatform.append(platform_left)
        
        //根据传入的参数来决定要组装几个平台的中间零件
        //然后将中间的零件加入零件数组
        for i in 1...midNum {
            let platform_mid = SKSpriteNode(texture: textureMid)
            platform_mid.anchorPoint = CGPoint(x: 0, y: 0.9)
            arrPlatform.append(platform_mid)
        }
        //将右边零件加入零件数组
        arrPlatform.append(platform_right)
        //将零件数组传入
        platform.onCreate(arrPlatform)
        platform.name="platform"
        //设置平台的位置
        platform.position = CGPoint(x: x, y: y)
        //放到当前实例中
        self.addChild(platform)
        //将平台加入平台数组
        platforms.append(platform)
        return platform
    }
}

 

写完了平台工厂类和平台类,我们迫不及待的测试一下。我们可以切换到GameScene中添加代码测试一下:

    先声明一个平台工厂:

lazy var platformFactory = PlatformFactory()

 

然后在didMoveToView方法中将平台工厂加入当前视图中。

self.addChild(platformFactory)

 之后是一行临时的测试代码:

let platform = platformFactory.createPlatform(false, midNum: 1, x: 100, y: 300)

 运行代码测试一下,效果如下:

Good,搞定。

 

我的微信公众号

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

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/sandal1980/p/4286057.html

相关文章:

  • FireDAC 之FDMetaInfoQuery
  • GIT操作笔记
  • DevExpress随笔系列
  • 4.2 HTML Canvas标签
  • java对象占用内存大小计算方式
  • iOS开发之oc(六)--点语法
  • Sample SecondarySort 浅析
  • 导入项目时Loading descriptor ...
  • 【BZOJ】【2940】【POI2000】条纹
  • IOS开发基础知识--碎片8
  • 远程debug WebSphere 和 Watch时提示error(s)_during_the_evaluation
  • javascirpt怎样模仿块级作用域(js高程笔记)
  • python 多线程编程
  • 一:Html基本结构
  • ETL的考虑
  • Gradle 5.0 正式版发布
  • Laravel 中的一个后期静态绑定
  • PHP 的 SAPI 是个什么东西
  • SpingCloudBus整合RabbitMQ
  • VUE es6技巧写法(持续更新中~~~)
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 从重复到重用
  • 使用 Docker 部署 Spring Boot项目
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #define用法
  • (poj1.2.1)1970(筛选法模拟)
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (七)c52学习之旅-中断
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .Net Remoting(分离服务程序实现) - Part.3
  • .Net 路由处理厉害了
  • .netcore如何运行环境安装到Linux服务器
  • .net打印*三角形
  • .net访问oracle数据库性能问题
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • .NET业务框架的构建
  • []串口通信 零星笔记
  • [20171101]rman to destination.txt
  • [AI]ChatGPT4 与 ChatGPT3.5 区别有多大
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [HDU]2161Primes
  • [Linux]如何理解kernel、shell、bash
  • [Lucas定理]【学习笔记】
  • [MRCTF2020]Ez_bypass1
  • [Nginx]反向代理Node将3000端口访问转换成80端口
  • [node] Node.js的全局对象Global
  • [oeasy]python0004_游乐场_和python一起玩耍_python解释器_数学运算
  • [OIDC in Action] 3. 基于OIDC(OpenID Connect)的SSO(添加Github OAuth 2.0的支持)
  • [one_demo_11]二分查找法
  • [PHP]加密解密函数
  • [RK3568][Android12.0]--- 系统自带预置第三方APK方法