武汉迷萌!3D《巅峰漂移》技术分享
游戏玩法非常直观,通过手指滑动屏幕控制赛车的移动方向,躲避源源不断的敌人的追击,存活时间越长可以获得越高的分数。
玩家可以在游戏中充分展示自己的漂移技术,收集场景中的小星星以及击败其他敌人可以获得额外的金币和经验加成。
《巅峰漂移》设置了丰富的养成系统,玩家可以消耗金币对道具进行升级,以提升增益效果。还可以对最高速度、加速性能和额外得分进行升级,等级提升之后,你能够获得更快的移动速度、更高的加速效率以及更多的额外得分。
为了满足玩家对于车辆的多样性改装需求,从车辆的喷漆样式、尾气颜色到局内表情,游戏均做了丰富的设计。
此外,游戏还创新加入了段位系统,根据玩家所得最高分数解锁不同的段位,从黑铁、青铜到车神。除了微信好友,玩家还可以与全球玩家比拼,大大提升了竞技乐趣。
武汉当地游戏 CP 现状如何?游戏创作工作流是怎样?有哪些宝贵的技术经验呢?《巅峰漂移》项目组接受了 Cocos 的专访,以下为访谈内容整理:
请问《巅峰漂移》项目共有多少成员?其中研发人员的占比是?
除了《巅峰漂移》之外,我们已经上线的游戏项目还包括《披萨小王子2》《刺客别杀我》《巅峰漂移》《天天飚车 3D》,也欢迎各位开发者朋友搜索体验,此外,还有一款 APP 游戏《三国大作战》即将上线。
立项。
策划完成功能文档,界面原型,文档定稿,同时程序开发核心功能。
美术程序同步进行,程序完成剩余功能,对于 UI 相关的功能,会先使用一些常用的组件拼装界面,等美术出完效果图和切图后,统一替换。
最后整理,分包,压缩打包上传。
测试,提交。
游戏内的无限地图是如何实现的?
实现原理:分成 9 个 3x3 的格子(我们称为 Grid ), 每当玩家控制的赛车快移动到当前 Grid 边缘时,会将另外一边的 Grid 补到另一边。
游戏道具和资源都会刷在每个 Grid 子节点下面, 这样只需要移动 Grid 既可完成下面所有的资源的移动。
这样做的好处是:(1)很难看出地图上的资源有重复;(2)创建在其它 Grid 里的道具/星星可以重复使用,玩家离开后无需要再次创建,直到被玩家吃掉。
尾气和刹车痕的参数配置是?
在游戏过程中创建和销毁都是比较耗时的,通常我们可以将创建过程提前,销毁推迟操作, 但在某些情况下(比如无尽关卡)在游戏过程中生成不可避免,就不可能一次性创建所有节点。
1.分帧创建
关卡生成器负责将需要生成的 prefab,位置信息提交到节点管理器的“创建队列 ”。
节点管理器进入游戏后开启定时器,每过 N 帧,从“创建队列”拿一条创建信息。
(小技巧:nextInterval 可随时控制,这里自行做的定时器是为了可扩展性,比如检测到 fps 不稳时,可以考虑将创建间隔拉长)
从缓存里取节点,当节点不存在时自动实例化 Prefab (可在场景加载时,创建若干,以免在游戏中创建)
当资源被玩家吃到后,会通知节点管理器回收这些资源。
(这里的 poolManager 实际上就是对 cc.NodePool 的封装,每个 prefab 对应一个 NodePool. 方便快速查找)
这套机制在实际使用中复用性好,实用性非常高。
2.碰撞优化
(1)车的碰撞检测使用 ,Cocos 自带的 BoxCollider 实现。
每个车上有一个大的碰撞盒用于检测与敌方车辆的碰撞,且绑定了四个“方向碰撞盒”,用于检测是碰撞方位(因为碰撞无法确定碰撞点,只能用不同的碰撞盒表示不同的碰撞位置)以确定是被撞还是主动撞击(侧面和尾部可以撞毁敌车)。
为了效率,这四个方向的碰撞起初不检测碰撞的。
//设置方向碰撞盒的掩码 , 当masks =0 的时候表示不发生任何碰撞
enableDirCol(maks) {
for (var i = 0; i < this.dirColliders.length; i++) {
var c = this.dirColliders[i];
c.setMask(maks)
}
}
当最外面的碰撞盒发生碰撞时(onTriggerEnter),才开启"方向碰撞盒"的检测,并在最外层碰撞盒结束(onTriggerExit)的时候关闭"方向碰撞盒"的检测。
具体设置2个碰撞器的是否检测相互碰撞可以参考:
https://docs.cocos.com/creator3d/manual/zh/physics/physics-group-mask.html
(2)道具的碰撞检测,因为道具资源刷新非常多,峰值在 100 个左右的碰撞体,使用 BoxCollide 性能会严重受损,加上这些物体的碰撞不需要太精确。
还记得前面说的 Grid 吗?我们在 Grid 上又做了子网格:
每个道具都会刷新在网格里,相当于3维数组的一个元素, 通过数组索引即可知这个格子里的内容。
有的小伙伴可能觉得费内存,其实通常情况下只需要 x * z * 1 的空间(在不考虑 y 轴的情况下如:跳跃)
这里每个网格对象里记录着节点的位置信息:
我们通过赛车的本地坐标可以直接转换为其所在的格子坐标。
可直接使用格子坐标索引到附近的节点,时间复杂度 O(1):
(3)其它
● 向量计算:如果当一个向量已经计算过一次长度了,要实现归一化时,没有必要再 Vec3.normalize() 计算一次,可以直接使用使用除法,可以少开一次方。
● 能不必要每帧检测的地方就开定时器,隔帧检测。
● 尽量避免/减少在游戏过程动态加载。
● 所有有距离比较的地方,都使用 Vec3.squaredDistance 进行平方比较。
● 1-360度计算三角函数采用查表法。
「Creator星球游戏开发社区」助力小游戏开发者副业挣钱
软件著作权办理 已备案域名购买 小游戏源码出售 小游戏外包接单 开发者作品推荐
评论