因为我个人喜欢游戏,一直想做一小游戏,但是一直拖着,没时间做,现在终于在周末空闲时间做了一个微信小游戏。
第一次写技术文章,篇幅可能较长,但是自我感觉干货满满,如果有不好的地方希望小伙伴们多多提出意见,内含游戏核心数值设计的全过程。
如果你正准备做游戏开发,或者不知道怎么下手,希望本文能为你带来一定的收获
废话不多说,先上图看看效果,如果想先体验,可直接拖到底部
注意:本文不涉及太多具体代码以及全部代码,会列出一个新手在 Cocos 开发一款完整游戏的思想,避免大家采坑,但是会有一些核心的数值或者关键代码提供参考学习,纯干货。
当时最初的设计是一款轻量级的射击爽游,自动发射子弹,通过手指触摸移动来改变角色的移动,吃不同的 Buff 可以叠加对应的能力,通过打击砖块获得更高分数。
以下是目前支持的一些功能
如果条件允许数值设计其实也是专门的数值策划的工作,但是… 我也做了,为了想要得到玩家在不同时间段攻击应该是多少,我做了一个 Excel 来推算玩家攻击的数值,后作为实际开发怪物生命的设置。先上一张我的数值设计的样子(实际上 Excel 推算了 100 行的数值左右,图太长,所以我只截取了前面一部分)。
数值设计我觉得算是整个游戏的一个核心,是游戏平衡,可玩性的核心,这一部分我花了一部分时间来思考,整个游戏设计是只有攻击和生命,没有护甲,所以对于计算来说用了比较简单的 减法公式
公式1:攻击 = 消耗
公式2:生命 - 消耗 = 结果
数值组成字段 Tab 说明
对于 Excel 的操作我就不做介绍了,各位大佬自行百度。应该各种教程特别多
1:我的想法就是 最初玩家一秒能打死一个砖块(因为初始的攻击速度在 0.5 秒一发子弹,子弹移动到怪物身上大约0.5 秒左右),于是就有了第二列第一行 打击时间为 1s
得出第一个初始值:打击时间 1s
2:然后就是每波怪,玩家的打击时间应该增加多少呢?因为这是一个怪物无限往下掉,打击时间肯定不能太久,否则打不死就 GG 了,所以我设定了一个成长率为 0.01,通过数值验证比较合适,到第30波的时候也就 1.3s,
得到第二个初始值以及计算公式:打击时间成长率 0.01,打击时间的计算公式为: =B2+B2*C2 【注意:这个值需要多次尝试,根据自己的需求来得到最终的结果】
3:然后就是怪物的血量应该是多少,一开始肯定不能设计得太多,如果设计得太多,并且要在 1 秒内打死 那么攻击肯定也特别高,而我的想法就是攻击需要根据吃 Buff 来进行叠加。
得出第三个初始值:怪物初始血量为 2
4:同样的血量肯定有成长因素,所以这里就出现了一个血量成长率,这里我最开始从 1 的倍率一直到 0.2 倍率都试了,发现 0.55 比较合适成长不低不高,算是比较满意的状态
得到第四个初始值以及实际血量计算公式:血量成长率 0.55, 血量成长的计算公式为: =A3A3E2+D2*E2,血量增加除了和成长有关,还得和砖块的波数成比例,波数越高怪物血量随之约高。
怪物波数的平方*血量成长 + 上一波砖块血量 * 血量成长,【最开始我只想了 血量 * 成长,发现比较低,在50波以上的时候数值还是太低了,所以我增加了一个怪物波数的条件】
5:最后一个 玩家攻击就相对比较简单了,砖块血量 / 打击时间 = 玩家攻击
得出玩家攻击数值:初始值设定的 2 (因为怪物设定的初始血量为 2,因为一发打死一个小朋友)
玩家实际攻击 = 砖块血量 / 打击时间
至此整个游戏核心的数值就设计完毕,但是漏了一点,因为这是一个类似射击类的游戏,子弹不止一发,所以后面需要 将子弹速度、炮筒数量加进去一起计算。
以下是砖块血量计算的完整代码
第一行 hp 变量最终值乘以了 0.65,因为 Buff 的随机性导致攻击可能不能和数值表设计的完全一致,所以这里做了一个优化。
当炮筒达到满状态并且攻速达到满状态的时候(满攻速是 2 帧(≈0.03s)一发,算上满炮筒 大概是 0.03s 3 or 4发子弹),当时发现攻击过于高了,所以在玩家达到不同状态的时候给 HP 增加了一定的数值修正。
攻速 Buff 每次减少 3 帧(也就是攻速会提升 0.045s 左右),上限为 2 帧。
攻击 Buff 每次增加 3 点攻击力,无上限,出现的概率比攻速要大
游戏核心数值搞定了,开发其实就是比较轻松的了,无非查查API,想想游戏怎么做。
这里我列一下我做整个游戏的一个步骤
1:想好整个游戏的具体玩法,如何操作,如果胜利和死亡,核心玩法是什么。一步一步的完成整个游戏。
2:第一步,完成玩家的操作,拖拽移动
3:第二步,完成玩家的发射等功能、子弹管理(速度、子弹状态、炮筒数量等等)。
4:第三步:开始制作砖块,设定好砖块的位置,按照固定的速度往下掉。
5:第四步:处理子弹和砖块的碰撞【这里自喷一下,最开始我居然用的 Cocos 提供的物理引擎来进行碰撞检测等操作,后发现当子弹特别多的时候,就有点卡了,于是我查了一下,找到了普通的 2d 碰撞检测】。
6:第五步:制作各种界面,如开始界面,结束界面等。
哦对了,游戏涉及到的数据存储,我是用的 Node 来写的后端,因为作为前端开发,只会 Node 哈哈哈
坑2 :精灵图,对于 Cocos 建议不用自己去合并精灵图,麻烦,而且不易扩展,每次新增一个图都要重新生成。可以使用官方提供的 自动合并精灵图,会根据我们的引用自动生成精灵图,特别好用
坑3 :我在引入友盟统计的时候,发现导入进来各种问题,微信授权也没有,然后我发现不知是我操作问题,还是 SDK 代码的问题,于是我自己吧友盟的 min.js 文件格式化之后 一通改动。
额其他的暂时没想到了,如果想到了,我在在补上。
1:微信部署其实很简单,微信小游戏现在不需要软著了,但是貌似隔壁抖音必须要软著
2:目前提审的时候 基本上都是一次过,只要不涉及什么违法违纪什么的,基本上都没问题。
3:值得一提的是,微信小程序做版本兼容一直是个很头疼的问题,这个得想好
Cocos 提供了全局参数 CC_DEBUG 为true表示开发环境
小程序提供了 __wxConfig.envVersion 属性用来区分小程序的状态 develop = 开发版 ,trial = 体验版, release = 正式版
1: 这个也很简单,但是前提是 需要满足 1000 独立 UV ,这个比较麻烦,但是没有什么是难道我们的。
2:然后有个小问题就是,微信 Banner 广告如何正确的定位在底部,因为微信是按照他自己的位置和像素进行计算,而且只支持top属性,所以很坑爹,也就是说和 Cocos 的尺寸并不兼容,这里我说一下我的解决方案。
// 定位 Left 的计算方式
Left = (屏幕宽 - 设定的 Banner 宽) / 2;
// 定位 Top 的计算方式,这里的 20 是自己设定的距离底部的距离,Banner的高度需要通过 onResize事件来动态获取
Top = 屏幕高 - Banner 高 - 20;
以下是详细的相关代码
const getWxSystemInfo = () => {
return new Promise(resolve => {
wxFn().getSystemInfo({
success: res => {
resolve(res);
}
})
})
}
/**
* 下面的内容在一个函数体内,我单独复制出来的
**/
const wxInfo: any = await getWxSystemInfo();
// 首页banner
this.homeBannerAd = wxFn().createBannerAd({
adUnitId: 'adUnitId',
adIntervals: 30,
style: {
left: 20,
// 初始化的时候 随便设
top: 0,
width: wxInfo.screenWidth - 40
}
});
this.homeBannerAd?.onResize((res) => {
this.homeBannerAd.style.top = wxInfo.screenHeight - res.height - 20;
});
终于,写完了,,
现在这个游戏第一期排名送现金红包活动,大家可以去体验玩玩,顺便赚钱钱
以下是体验地址,欢迎大家体验
如果大家有什么问题,或者不清楚的欢迎留言讨论!!!
最后感谢 UI 大佬提供的资源素材
他的虎课网:https://huke88.com/person/opus/126352.html
他的站酷:https://zhujiu.zcool.com.cn/