简介
手机屏幕宽高比千差万别,如果不做好适配,就会在屏幕上留有黑边,或者有些内容超出去了,体验不会很好,因此我们需要做好适配,完善好一个游戏
像素
最开始html采用的是像素来进行适配,因为屏幕的度量不是米,厘米,而是一个个像素,多少个像素就显示多少个“格子”
devicePixelRatio
随着设备的发展,像素的“格子”越来越小,有时候完全一样大小的手机,新的手机的格子尺寸是原本格子的一半,这样用像素来描述已经不精确了,因此引进了这一个概念
如375*667的iphone6,实际像素为750*1334,我们给的图需要真实的像素,才能展现得更精细,因此就衍生两个概念,屏幕宽高和游戏宽高,屏幕宽高*pixelratio=游戏宽高
很多游戏开发都用750*1334这个比例作为参考,宽高比(aspect ratio)为0.56,(我偷偷定义为0.56屏)
在dom的canvas API上,canvas.width/canvas.height是上下文宽高,即游戏宽高,而style.width或者通过transform来描述的,是css的宽高,即屏幕宽高
两个视口的适配
如果比例一致,如游戏是640*1334(即0.56屏),我们可以简单等比缩放即可
如果比例不一致,有两种做法
- 一种是调整屏幕中canvas的尺寸,让其和游戏尺寸比例相等,但是这样就会有黑边,或者内容超出(此时游戏内容尺寸一直不变)
- 一种是调整游戏的尺寸,让其和屏幕尺寸比例相等,首先我们需要选择宽或者高,作为基准轴,然后先缩放对齐,最后改变另外一个轴的长度,如375*812(iphoneX)的屏幕,我们使用750*1334的基准进行开发,宽对齐750(fixedWidth),那么游戏内的高度就变成了1624
如果是调整游戏的尺寸,那么游戏内的UI也需要坐对应的调整,因为只是视口变大了,但是UI的定位还没有改变,仍需要进一步进行调整
游戏内容适配
通常来说我们会选择固定宽(fixedWidth),因为从iphone6过渡到iphoneX的第一感觉是高度变大了,而不是宽变窄了
适配需要考虑两个轴向,水平和垂直,由于采用了fixedWidth,我们不需要考虑水平了,仅仅考虑垂直轴即可
UI比例布局
1.如果屏幕高度变长了,我们就会觉得下面有更多的空间可以利用了,参考html里面div的盒模型,我们可以可以假想有3个盒子,上,中,下,第一个盒子在30%的位置,中间的在50%的位置,这样,我们高度变长的后,依然还能保证一个合理的比例布局
2.伪代码newY = preY * (newH / preH);背景布局
1.背景不像UI那样,UI不能被视口边界给裁掉,背景是可以的
2.通常来说,我们定义一种极限的情况,如1334*1334,标准下,我们只能看到中间750的部分,长边占满,短边通过变宽变窄来控制我们看到的多少
3.伪代码bg.pos = mid; bg.scale = maxSize/1334UI重叠
1.如果我们的高度不断变小,这个时候按照比例布局的盒子还是叠在一起,这个时候只能通过缩小scale来放置重叠了
2.这个时候我们可以定义一个高比例,如果高为原本的高度的0.7,则盒模型的缩放为原本的0.7(超过1要保持1,因为过大会导致水平方向越界),这样垂直方向就不会重叠了动态适配
1.动态适配在我们需要我们监听resize,orientationchanged事件,进行动态适配
2.缺点是代码量较大,如果没问题,我们一次性赋值也是可以的可变形的适配
这种一般需要具体情况具体分析了,如顶部的标题栏,宽始终占满,但是高是可变化的
这种适配通常只用缩放一个轴向,或者直接设置宽高打组适配
1.有时候我们希望某个面板和一个标题一起,这个时候可以打成一个组,公用一个锚点,使用组来进行适配
2.实在有一些特殊需求的时候,我们可能需要用一些数学公示来适配了,如两个盒子在高更高的时候离开的更远,伪代码img.y = Math.pow(scaleH, 1.02),通过这样实现一些特殊的需求
动画冲突
有时候我们通过适配改变了一个显示对象的缩放,位置,这时候使用动画的时候,可能初始值已经不正确了,或者终点值
这个时候我们可以使用双层容器,外层容器是适配,内层是动画用,如外层适配导致了缩放为0.8,但是内层依然是1到1.2的放大,两者最终会被叠加
