使用 cocos 实现一个合成大西瓜-公平版本

559 阅读4分钟

序言

上文写了使用 cocos 实现一个合成大西瓜,但是里面存着一些公平性问题,现在解决一下。

上个版本遗留了一些问题公平性问题,着重解决一下

大屏幕相对小屏幕有优势的问题

这个问题的存在会大大降低活动的公平性,可以说使用手机的用户无法和使用平板的用户竞争,因此严重打击了用户的积极性,属于必须解决的问题。

原因

我们可以看看cocos多分辨率适配方案 。总结来说,如果我们使用“适配高度”模式,假如设计图纸分辨率为 800 x 480,屏幕分辨率为 1024 x 768 。适配高度模式,将设计分辨率的高度自动撑满屏幕高度,也就是将球放大到 768/480 = 1.6 倍。这样就可以看到在不同高度的屏幕下,球缩放的大小是不一致的。屏幕大小也是不一致的,所以整个屏幕可以放下同一种球的个数也是不一样的。这就导致了不公平的根本原因。

解决思路

如果要保证活动的公平,那么不同尺寸屏幕可以放下的同一种球的个数是要相同的。要保证不同屏幕可放球个数相同可以通过缩放球的大小做到。那我的解决思路就是以 iphone 6 作为标准屏幕,iphone 6 可以放下多少个标准球,其他屏幕也根据 iphone 6 中可以放下的球的个数去缩放球的大小。比 iphone 6 屏幕大的,就放大球,比 iphone 6 屏幕小的就缩小球。下面就要寻找具体的缩放公式,达到所有屏幕放的标准球个数相同。

解决过程

我们以 iphone 6 作为基础,以它作为标准,就是iphone 6 可以放多少个标准球,其他屏幕也正好放多少个标准球。

  • iphone 6 h5页面嵌入小程序中,除去标题部分可用分辨率为: 375 * 603 (实际上这个值是多少关系不大,就是作为一个标准)

  • 假设设计稿的高度为: designHeight

  • 假设实际屏幕大小为:W * H

  • 假设球在iphone 6下原始放大放大系数为:X

    • 我这里取的是0.7 * (2 / 3), 0.7是基础难度系数, 2 / 3 是因为用的我用的是3倍图
    • 其实整个值才是难度,只需要关注整个值的大小去调节难度。至于为啥基础系数是 0.7 ,这个也是慢慢调整出来适合的难度。
  • 假设标准球的半径为:R

  • cocos 对于球半径的缩放为:屏幕高度 ÷ designHeight

    • 那么标准球在 iphone 6 中的半径为 R * (603 ÷ designHeight) * X

iphone 6 屏幕可放球的个数

(375 * 603) ÷ (π(R * (603 ÷ designHeight) * X)²)

实际屏幕可放球的个数

假设实际屏幕缩放大为:S, 则球的半径被缩放为 S 倍。

则实际屏幕中可放的球的个数为:(W * H) ÷ (π(R * (H ÷ designHeight) * S)²)

最终我们就是要求 S

计算

(W * H) ÷ (π(R * (H ÷ designHeight) * S)²) = (375 * 603) ÷ (π(R * (603 ÷ designHeight) * X)²)

化简得到:S² = (W * X² * 603) ÷ (375 * H);

最后 S 就是:S = 根号 (W * (0. 7 * (2 ÷ 3))² * 603) ÷ (375 * H)

代码

const clientWidth = document.body.clientWidth;
const clientHeight = document.body.clientHeight;
const actualScale = Math.sqrt((clientWidth *  Math.pow(0.7 * (2 / 3), 2) * 603)/(375 * clientHeight));

展示结果

在iphone 6 和平板中

1.png 在 iphone 12中

2.png 可以看到,在不同型号屏幕中,可以放的球个数基本是相同了,实际验证多种屏幕,可放的标准球都是78-80个

可变屏幕球无限下落问题

如果遇到折叠屏等可变屏幕,当用户进入游戏的时候是折叠屏幕,然后展开屏幕,就会发现,点击边缘地区球无限下落消失。这样当遇到不想要的球就直接点击边缘地区,只留下想要的球。

原因

开始的时候会去初始化碰撞区域,可变屏幕在初始化之后去变动屏幕,新的区域不在碰撞区域之内,球就掉下去了。

解决思路

  • 考虑当用户改变屏幕的时候重新计算碰撞区域,但是这样做有明显的缺陷,就是已经存在的球需要重新调整大小和位置,这样就会导致碰撞,这样就产生了新的问题,所以不太可行。
  • 不允许球落在非初始化区域。用户展开屏幕以后也不改变球的大小和位置,这样做比较简单也不会产生新的问题。

解决过程

用户点击的区域超过了边缘,则在边缘生产球即可。