使用鸿蒙原生做游戏适配问题

637 阅读3分钟

由于自己以前查资料,作者都不说版本号,这个是我SDK3时候制作,SDK5的时候做的适配。

前言:

作者没怎么制作过安卓,只有游戏引擎的使用知识,当时制作鸿蒙时,是2020-12,工作了半年。 其实对于软件,有时没必要去适配,因为系统会将你的需要的模块,对应的分隔开来,但对于游戏来讲不行,我们必须要按照自己的坐标。 当时我们,匆匆忙忙的制作完,测试时虽然有考虑到了适配问题,但没有丰富的机子,没有进行对应的测试,结果在鸿蒙智慧屏更新的时候,华为有了更多机型后,瞬间暴露了出来。 由于我们当时使用的坐标方式是px(像素),华为的人的使用的是dp(根据不同分辨率生成不同的px,,,后续他们改成称vp,他们好像想渐渐的让人改掉一些安卓中的称呼,如logcat最早是存在的,后来变成hilog),最早我制定适配方案的时候,有考虑是将px都变成dp,但大部分的内容都是我们的人完成,所以几乎代码中充斥着px,而且根据我的计算dp和px不是等比关系,dp适合软件的适配,但不适合游戏的适配。

正文:

制作游戏时候,布局使用DependentLayout,不会相互影响。

    首先我们适配,要获取设备的长和宽(DisplayManager.getInstance()获取的是,设备长和宽,,这个会包括刘海屏的那部分,,,有其他的可以去掉刘海屏之后的长和宽,自己找吧)
    DisplayManager dm = DisplayManager.getInstance();
    Point p = new Point();
    dm.getDefaultDisplay(context).get().getRealSize(p);

    // 出现过设备长宽取反的问题(系统弹出更新的),,简单判断一下
    if(p.position[1] > p.position[0]){
        deviceHeight = p.position[0];
        deviceWidth = p.position[1];
    }else{
        deviceHeight = p.position[1];
        deviceWidth = p.position[0];
    }

接下来看下,这张图,这个就是适配原理。

image.png

我们已知的是deviceWidth和deviceWidth 好的,首先我们要一个做的时候的基础分辨率(平时我们做游戏时是540*960),但当时给我们的智慧屏是1920-1080,,我们使用它当基础分辨率。 首先计算appWidth和appHeight(这个是游戏界面的内容,appMLR和appMTB是不同分辨率多余的部分)

看deviceWidth/deviceWidth的比是不是16/9(因为1920/1080是16/9)

  1. 是的话,证明是正常屏幕,,只要算对应的扩大缩小比例,

appWidth = (int) deviceWidth;

appHeight = (int) deviceHeight;

  1. 设备的宽高比正常屏幕大,证明是个长屏,高是设备高,,长有偏移量

appHeight = (int) deviceHeight;

appWidth = (int) (deviceHeight * appRatio);

appMLR = (int) ((deviceWidth - appWidth) / 2);

  1. 设备的宽高比正常屏幕低,证明是个宽屏,长是设备长,,高有偏移量

appWidth = (int) deviceWidth;

appHeight = (int) (deviceWidth / appRatio);

appMTB = (int) ((deviceHeight - appHeight) / 2);

最后算个游戏屏和基础屏的比例关系

appUnit = appWidth * 1f / 1920;

计算完这些值之后接下来就简单了

适配组件的大小(传值是w:基础屏下的长,h基础屏下的高)

    DependentLayout.LayoutConfig config = (DependentLayout.LayoutConfig) c.getLayoutConfig();
    float unit = DeviceManager.get().appUnit;
    config.width = (int) (w * unit);
    config.height = (int) (h * unit);
    c.setLayoutConfig(config);

适配组件的坐标(x,y)

MarginLeft:appMLR +x * DeviceManager.get().appUnit;

MarginBottom:appMLR +x * DeviceManager.get().appUnit;