春节这段时间,社区有 3 位来自华南师范大学的大一新生寒假爆肝 14 天,一起完成了一个太空科幻题材小游戏的创作,已经上线发布在微信小游戏,用户满意度更是全 5 分,目前游戏完全免费也没有任何广告,感兴趣的童鞋可以微信搜索【星旅StarTrek】体验一下噢。

游戏讲了一个关于述人类命运存亡的科幻故事。在游戏中你可以探索无限大的宇宙空间,在符合物理的太空中自由穿梭与几十种不同的行星、恒星、超新星、彗星、黑洞与白洞之间。

期间主程 HK-SHAO 也写了开发周记作为技术分享发到了 Cocos 的论坛,本篇文章摘自开发周记,希望分享的技术能够帮助大家。


大家好,我是 HK-SHAO ,随着游戏的不断迭代,游戏效果、内容也逐渐丰富,游戏项目和其代码有越来越多的细节实现需要注意。

所以我特写下周记,记录一些我在开发过程中,游戏效果实现的方法、原理,以及一些需要注意的方面。同时也很感谢 Cocos 为我们提供了免费的开发工具进行游戏的创作

囿于时间匆忙,内容可能会略显晦涩和粗糙,见谅。

1

TS 和 Creator 的简单介绍

首先,这个 Cocos Creator 小游戏的程序部分是用 TypeScript 编写的,原因在于 TypeScript 是一个比较严谨的语言,它是由微软开发的,拥有强类型并且比 JavaScript 的功能更多,被称作 JavaScript 的超集。

TypeScript 可以被编译成任何版本的 JavaScript,所以它完全可以代替 JavaScript

正是由于 TypeScript 的强类型,TypeScript 代码的编写不容易出现隐藏的错误,因为 IDE 会进行非常好的错误提示,这样能够大大提升代码的生产力。

另外,用 TypeScript 编写游戏脚本,IDE 会进行代码提示,一个对象是什么类型、拥有哪些成员变量和方法、这些方法的作用是什么,这些 IDE 都会在代码编写过程中给予提示,省去了频繁查找 Cocos Creator 官方文档的麻烦。

然而上述在软件开发过程中 IDE 提供的比较基本的功能,由于 JavaScript 的弱类型而都无法提供。

在 Cocos Creator 里面,每个实体都是节点(cc.Node),而这些节点的结构都是树状的,我个人觉得这个设计特别好,不仅对于这个游戏引擎来说能够提高某些算法的效率,而且对于游戏开发者来说能够省去不少功夫。

这里要提的是,在前端开发中,网页的 DOM(文档对象模型)也是树状的,正是因为这个数据结构的优越性,网页才能被快速的渲染和更新。

正是由于 Cocos Creaor 使用了这样的数据结构,再加上它的游戏脚本是前端里的 JavaScript 或者 TypeScript,所以 Cocos Creaor 的游戏能够被打包到几乎所有平台(包括 Windows、Android、Linux、Mac OS、Web 以及许多第三方平台例如微信小游戏、百度小游戏等)。

简单点来说,只要能够打开浏览器上网的平台,CoCos Creator 都能够一键打包并发布到这个平台。

接下来,我会把游戏开发里面的一些技术细节一一列举出来

1

动效和物理效果

非线性动效

非线性动效相比线性的、匀速的动效在视觉观感上会好很多,这在现在的手机系统动画以及一些优秀的 PPT 内应用非常广泛。这个游戏在很多方面多次使用了一种非线性函数实现动效,以达到流畅、柔和的视觉效果。

这个非线性函数其实就是这个微分方程  y ′=y ( 1 − y )  的解 ,这是一个非常有用的非线性函数,在各种领域作用广泛。

例如开源的 Python 数学可视化引擎 Mainm 里就有它的身影,最近开源的动画引擎 movy.js 也有它的身影,除此之外这个魔幻的函数还在高中生物的种群密度、人口学、统计学等多个领域大显用途。我们先解一下这个微分方程。

如果常数 C 为 0,最后可以化成  , 这其实就是大名鼎鼎的 sigmoid 函数,其还在人工智能领域应用广泛。

这个函数曲线是 S 形的,所以高中生物也称作 S 形曲线。它也被称作 Logistic 函数,在最近的疫情分析,传染病模型里面也有它的身影,它的形状是这样的。我们可以看到,它的定义域是实数集,值域是 [ 0 , 1 ] ,并且从 0 到 1 变化非常缓和。

好了,回归正题,我在 Cocos Creator 的游戏开发中频繁的使用了这个优美的函数曲线,达到了比较赏心悦目的平滑动画效果。

它在程序里的实现方式是这样的  y ← y ∗ ( 2 − y ) 。更通俗一点来说,如果我想让一个值 t 平滑的从 min 变化到 max 可以在 update 函数里这样写。

t += (max-t)*dt*speed;

反之,如果我想让一个值 t 平滑的从max变化到 min 可以在 update 函数里这样写。

t -= (t-min)*dt*speed;

例如,我使用这种方法实现了根据触摸改变的非常平滑的摄影机缩放效果。

除此之外,根据地球到太阳的距离自动显示距离箭头,并且根据触摸自动隐藏或者显示,也利用了这个特性。

游戏中为了实现平滑而不生硬的视觉效果,我均采用改变游戏中实体受力的方式而避免直接改变速度,因为直接改变速度往往是在撞击时发生的,在其它情况尽量少发生。

例如,游戏中操控地球的前进,是给予地球刚体一个根据触摸位置而发生改变的持续力。而改变地球的旋转角度,则避免直接改变地球的旋转角,而是给予地球边缘一个小的持续力,以改变地球的角动量,从而实现改变地球的旋转角。

此外,我避免摄影机和背景直接跟随摄影机,而是通过给予它们对应刚体的受力,来实现一种错位的立体感和平滑移动感。

归一化 

一个向量的归一化就是这个向量的单位向量,在 Cocos Creator 里面,有 cc.Vec2 和 cc.Vec3 两种类型的向量,它们都有 normalize 这个方法获得单位向量。但是有时候我想把一个实数归一化怎么办?

聪明的读者可能已经想到了前文所提及的 sigmoid 函数,但是除此之外,我们其实还可以用 arctan 函数来对一个实数归一化,让它的值介于 0 到 1 之间。实际上这个函数作为激活函数在人工智能领域也和 sigmoid 一样应用广泛。

将一个实数归一化之后,我们能够较为容易的对这个数进行操作,这种方法在图形学,例如 Shader 程序设计里面应用广泛。我在游戏脚本里也用了这种方法,使得后面的计算和操作更为简便。

物理效果

在游戏主函数里,有大量向量之间的运算,用来计算受力的大小和方向。例如,在旋转地球时,通过给予地球边缘一个持续力来改变地球的角动量,从而改变旋转角,是一种非常优美的方法。

以黑洞为例,每个天体和地球之间都会形成大小相同,方向相反的力,符合牛顿第三定律

在物理引擎中,设置太空为失重环境,并且置地球的线性速度衰减为 0,符合牛顿第一定律。

而天体与地球的引力通过牛顿的万有引力公式计算,符合万有引力定律。

除此之外,为了考虑狭义相对论的长度收缩效应,地球在高速移动的时候,会在与速度垂直的方向收缩,这样地球会一定程度上变成椭球形。

另外游戏中的所有天体都会给地球一个力,因此地球所处的引力场其实非常复杂,这在一定程度上来说带给了玩家挑战。

游戏中的黑洞会有远高于其它天体的强引力,而游戏中的白洞会有强斥力,玩家可以充分发挥自己的能力,利用这样特性来实现一些高难度技巧性操作。

游戏在设计时的细节非常多,并且还在不停地打磨和完善,例如黑洞吸进了天体会碰撞,两个黑洞碰撞会形成更大的黑洞,而黑洞和白洞相撞会湮灭。

实际上玩家想要看到这些效果的概率较低,但是通过这些特性,相信玩家能够进行许多有趣的操作。

游戏中可以发射核弹,并且这些核弹会自动寻找距离最近的可打击天体然后毁灭之。

而游戏中的彗星在撞击时冲量很大时会自动销毁,被恒星或者黑洞捕获也会自动销毁。

地球的每次撞击都会调用震动相关 API,以实现更加真实的效果

游戏的相关奖罚机制在不断调整参数,以达到更好的效果。

游戏中充分利用了粒子,以实现更好的视觉效果,这一点在生成星空、彗星的尾巴和火焰时显得尤为重要。

视觉效果

视觉效果这一方面,着色器的作用非常大,然而移动端 GPU 太垃圾,好多着色器运行都会很卡,这是非常可惜的,这里我还是介绍一下 Cocos Creator 的材质 Materials 和效果 Effects。

在 Cocos Creator 里,每个材质可以绑定一个 Texture 纹理和 Effects,Effects 是 Cocos Creator 特有的一种程序,里面是包含了配置信息、顶点着色器和片元着色器,其中片元着色器非常强大。

例如你可以用 shader 程序生成一片动态的立体星空:

利用shader生成一颗旋转的恒星:

甚至一颗立体的、动态的黑洞:

或者生成一个银河系等:

1

游戏性能优化

随着游戏的不断迭代,我实现了越来越多的效果,同时游戏主逻辑也越来越复杂,再加上要渲染的实体越来越多,游戏在移动端的帧率有下降趋势(实际上,游戏在电脑网页上能够 200 满帧运行,然而移动端的性能比较差,可能会不足 60 帧或者有略微掉帧情况)。

我们先看看游戏在调试模式下的帧率信息:

其中 FPS 就是 Frame per Second(每秒的帧数),一般来说帧率在 60 左右就足够了,实际上 Cocos Creator 将游戏锁定在了 60 帧左右,通过修改程序或者调试模式下更改游戏画面上方的配置,能提升游戏帧率上限。

现在我们看到,游戏其实是相当流畅的。然而电脑上的流畅不代表移动端的流畅,经过我的一些调试,我发现其实帧率能够在 170 以上,移动端就可以比较流畅了。实际上,上方图片还隐藏了很多信息,下面我一一举出。

  • Frame Time 游戏运行一帧所需时间

  • FPS 每秒帧数

  • Draw Call CPU 打包发送给 GPU 去渲染的打包数量

  • Game Logic 运行在 CPU上 的游戏处理逻辑每帧所需时间

  • Renderer GPU 渲染一帧画面所需时间

  • WebGL 是否启用 WebGL

实际上,Frame Time = Game Logic + Renderer,从上面的数据你也可以看出来。而 FPS 与 Frame Time 成反比,所以我们想要提高游戏的帧率,必须从 Game Logic 和 Renderer 下手。

优化 Game Logic

使用缓存、算法

首先,在 Game Logic 方面,其实是游戏的脚本运行在 CPU上 的耗时,通过缓存游戏对象,自动销毁无用的节点以及挂载,并运行在其上脚本来提升游戏逻辑方面的性能。

在游戏加载时,把必要的序列化对象全部加载,并且缓存到一个列表里面。

每次获取刚体对象都要调用 node.getComponent 方法,不如提前缓存了。

调用过的方法尽量都缓存下次使用,这样就不需要重复调用方法,大大提高效率。

另外,其它的一些算法也可以来优化游戏性能,例如检测并作用一个范围内的碰撞体,可以使用四叉树算法(如果是三维则用八叉树算法)。

使用Prefab 

除此之外,游戏中经常出现的或者需要频繁重复生成的节点,利用 Cocos Creator 的序列化功能,提前把这个节点序列化,生成一个 Prefab 文件,在需要使用时可以通过 cc.instantiate 方法进行反序列化,这样就可以更加高效的获得一个节点对象。

需要注意的是,如果这个 prefab 需要反复多次频繁反序列化,需将这个 prefab 设置为这样:

优化 Renderer

自动图集

使用自动图集能够让 Cocos Creator 自动把一系列碎图打包为整图,使用自动图集的优势非常大!

一张整图相比碎图来说网络请求次数更少,或者不需要重复进行硬盘读写,从这一方面来说,使用自动图集能够减轻 CPU、硬盘、网络等方面的压力

更为重要的是,使用整图可以让 GPU 一次渲染完成,避免 CPU 重复调用 GPU 进行渲染,这样可以降低 Draw Call,而 Draw Call 其实非常大的影响了游戏图像的渲染效率,所以使用自动图集能够提升渲染效率。

减少节点数

减少节点数同样是通过降低 Draw Call 来提升游戏性能,所以当一个节点在地图外不可见,或者以及无用,则考虑将这个节点自动销毁。

优化纹理(Materials和Effects) 

每个 Materials 可以挂载一个 Effects,而 Effects 说白了就算着色器(Shader),着色器分为顶点着色器和片元着色器,它们是直接运行在 GPU 上的程序,能够在 GPU 层面直接对图像进行操作,效率非常高。

在合适的时候使用着色器来实现效果,能够极大地提升游戏性能

然而,着色器虽然跑得很卡,也要适可而止。移动端的 GPU 性能远低于电脑,在电脑上高清无码满帧,可能在手机上就卡成 PPT,所以复杂的需要大量运算的着色器可能会拖慢游戏图像的渲染速度,使游戏性能大大降低。

例如下面这个着色器,在电脑上满帧,手机上会卡成 PPT。

最后非常高兴能够和 cyb 和 lby 合作这个游戏项目,做游戏的初衷是能完成自己喜欢的作品,并给玩家带来快乐,希望我们能够一起加油把这个项目继续完善得更好。

游戏已在微信发布,欢迎感兴趣的童鞋扫码体验噢。

戳【阅读原文】前往社区查看更多详细信息,快乐交流~

颤抖吧!00后已经开始爆肝写游戏赚钱了!相关推荐

  1. 爆肝写的博客,浏览量还是两位数!

    干货笔记

  2. 00后步入社会,有哪些适合你的创业项目?

    目前,许多00后已经开始进入社会,有自己想法的人也在思考如何创业.对于没有行业经验的00后来说,创业需要注意哪些方面?可以做哪些创业项目?让我们看看! 1.00后创业项目:校园项目 00后创业可以从熟 ...

  3. 00后开始找工作了,可能挣得比你还多,扎心了

    文|洪生鹏 01 记得90后刚步入社会参加工作时,曾被人贴上"非主流"."啃老族"."浮躁"."抗压能力弱"各种各样的标 ...

  4. 我12岁的时候还在玩泥巴,硅谷00后都开始玩创业了!

    今天看了一篇非常不错的文章,和大家分享下,到了我们这个年龄段都不知道make things happen and solve the problem,别人00后都已经开始创业,哎,只能怪自己努力的不够 ...

  5. 穿上资本小棉袄的00后社交,到底是什么鬼?

    被资本市场雪藏了好几年的社交产品,最近突然回温了!据说,最近有大概20多家社交APP都拿到了不同量级的融资. 大致看了一下这波备受追捧的社交APP:强调精神交流的Soul.心情漂流瓶一罐.兴趣社区fl ...

  6. 3万6千字爆肝,前端进阶不得不了解的函数式编程开发,含大量实例,手写案例,所有案例均可运行

    3w6爆肝,前端进阶不得不了解的函数式编程开发,含大量实例,手写案例,所有案例均可运行 认识函数式编程 函数相关复习 函数是一等公民 高级函数 函数作为参数 案例 1,模拟 forEach 案例 2, ...

  7. 爆肝一周,用Python在物联网设备上写了个智能语音助手

    1. 背景介绍 智能语音助手作为物联网领域的一个重要生态成员,是一种全新的交互方式,它能够解放双手,随时提供服务,无须借助任何按键.想必很多开发者都有玩过天猫精灵.小爱同学或者小度吧,看到这些炫酷的人 ...

  8. 现在的00后,真是卷死了呀,辞职信已经写好准备提交了·····

    都说00后躺平了,但是有一说一,该卷的还是卷.这不,四月份春招我们公司来了个00后,工作没两年,跳槽到我们公司起薪22K,都快接近我了. 后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了. 最 ...

  9. 公司来了个00后,真是卷死了呀,辞职信已经写好了·····

    人们都说00后躺平了,但是有一说一,该卷的还是卷.这不,三月份春招我们公司来了个00后,工作没两年,跳槽到我们公司起薪20K,都快接近我了. 后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了. ...

最新文章

  1. 免费查找AI最优论文神器:一键出结果,分分钟提取论文表格、最新数据
  2. 创建型模式之Builder模式
  3. 美团高德并不是解决快车问题的灵药,烧完钱之后只会产生新的滴滴
  4. 产品需求被误解是一种什么样的体验?
  5. Active Directory边界
  6. 疯狂软件mysql视频_疯狂软件MySql视频
  7. [转]iPhone发邮件编程
  8. Python爬虫之(七)数据提取-正则表达式
  9. 超简单!使用jQuery实现登录页面的“记住密码”功能
  10. java数字转读音_java 数字转汉语读音的程序
  11. 图解AUTOSAR(四)——基础软件层(BSW)
  12. 获取域名服务器信息吗,获取域名的WHOIS信息
  13. 人民日报:密码,让百姓生活更安全
  14. JavaScript blog式日历控件
  15. hive中导入csv,把csv导入到hive表中步骤
  16. 10GBASE-T SFP+电口模块知识百科
  17. spark报错:CREATE TEMPORARY TABLE
  18. Direct-X学习笔记--天空盒
  19. 跨平台下移动应用的开发框架对比与分析
  20. Mysql数据库默认端口修改,Windows版

热门文章

  1. 利用opencv画圆
  2. POJ 3077 Rounders G++
  3. Dynamics CRM项目实例之七:站点地图修改,联系人-订单-积分管理
  4. 智能记忆功能nest_Nest,Ecobee3和Honeywell歌词:您应该购买哪个智能恒温器?
  5. 计算机机房监控系统上海,上海企业在机房建设后安装机房监控,是否有必要?...
  6. 比例导引+弹道成型导引源程序
  7. 恒腾合作腾讯,流媒体IP的游戏开发前景几何?
  8. 大型购物平台的系统设计与架构
  9. 使用Git命令行推送代码到远程仓库,阿里云效Codeup代码管理平台
  10. A*算法(二)启发式算法