鸿蒙推箱子小游戏:UI界面美化

在上文笔者向大家分享了推箱子小游戏基础功能的实现,本文将继续向大家介绍如何做 ui 界面美化,以及如何利用轻量级偏好数据库做数据的存储和读取。
ui 界面美化
①mainabilityslice
我们可以看到,所有的界面都是采用无框全屏化设计,因此第一步是要修改 config.json 文件。
打开文件,将代码做出如下修改:
...... launchtype: standard      }    ],    metadata: {      customizedata: [        {          name: hwc-theme,          value: androidhwext:style/theme.emui.light.notitlebar,          extra:         }      ]    }  }}  然后设计按钮样式,首先新建一个 graphic 文件:
接着在里面添加美化代码:
现在分析界面需求,其中带有“pokemon”字样的是本地图片,因此我们需要的控件有四个按钮以及一张图片,布局采用 directionallayout 即可。 代码如下:                    至此第一个界面就美化完成了。
②selectslice
这个界面的布局跟第一个界面大同小异,只是少了一个按钮,还有就是按钮的样式有点不同,因此需要再写一个 graphic 文件,方法同上。  
这里直接给出代码:
界面的代码如下:                ③initslice
在加载界面中,只是用到了一个播放 gif 的第三方组件,以及一张图片(文字图片)一个进度条组件,布局也使用最常规的 directionallayout 即可实现。
④gameslice
游戏界面的 ui 就稍微复杂一点,需要用到嵌套,之前说过,地图类继承自布局,所以实际上地图也是一个组件,理解了这一点之后,再来看代码会容易理解很多。 整体布局用了 directionallayout 纵向布局,在里面有需要横向布局的,则添加 directionallayout 的横向布局,做一个简单的嵌套。                                                                四个界面美化完毕!接下来做一些细节的调整。在按下历史记录按钮时,会显示每个关卡最近的一次历史记录,效果如下:
这实际上是一个自定义样式的 commondialog,如何自定义?首先创建一个自定义的 recorddialog 类和美化用的 xml 文件,然后在类里面添加自己的 xml 文件。  
具体方法可以看代码:
public class recorddialog {    static commondialog commondialog;    static void showdialog(context context,string s1,string s2,string s3){        directionallayout dl = (directionallayout) layoutscatter.getinstance(context)                .parse(resourcetable.layout_recordlayout,null,false);        commondialog = new commondialog(context);        commondialog.setautoclosable(true);        button btn = (button) dl.findcomponentbyid(resourcetable.id_btn);        text first = (text) dl.findcomponentbyid(resourcetable.id_firsttext);        first.settext(s1);        text second = (text) dl.findcomponentbyid(resourcetable.id_secondtext);        second.settext(s2);        text third = (text) dl.findcomponentbyid(resourcetable.id_thirdtext);        third.settext(s3);        btn.setclickedlistener(new component.clickedlistener() {            @override            public void onclick(component component) {                commondialog.destroy();            }        });        commondialog.setcornerradius(15);        commondialog.setcontentcustomcomponent(dl).show();    }}  
xml 文件如下:
关于这样的设计,这个小游戏中还有一处,点击关于游戏弹出的界面同样也是这么实现的:
代码如下:
public class mydialog {    private static text version;    static void showdialog(context context){        directionallayout dl = (directionallayout) layoutscatter.getinstance(context)                .parse(resourcetable.layout_mydialoglayout,null,false);        commondialog commondialog = new commondialog(context);        commondialog.setautoclosable(true);        button knowbtn = (button) dl.findcomponentbyid(resourcetable.id_knowbtn);        knowbtn.setclickedlistener(new component.clickedlistener() {            @override            public void onclick(component component) {                commondialog.destroy();            }        });        commondialog.setcornerradius(15);        commondialog.setcontentcustomcomponent(dl).show();    }    static string getversion(){        return version.gettext();    }}                    游戏中最后一处 ui 设计,就是点击设置按钮时出现的一个滑动块组件,可以保存一些全局设置:
public class setdialog {    static void showdialog(context context){        directionallayout dl = (directionallayout) layoutscatter.getinstance(context)                .parse(resourcetable.layout_setlayout,null,false);        commondialog commondialog = new commondialog(context);        commondialog.setautoclosable(true);        button surebtn = (button) dl.findcomponentbyid(resourcetable.id_surebtn);        switch choose = (switch) dl.findcomponentbyid(resourcetable.id_choose);        string value = mydb.getstring(dl.getcontext(),save);        if(value != null){            if(value.compareto(开) == 0){                choose.setchecked(true);            }            else if(value.compareto(关) == 0){                choose.setchecked(false);            }        }        choose.setcheckedstatechangedlistener(new absbutton.checkedstatechangedlistener() {            @override            public void oncheckedchanged(absbutton absbutton, boolean b) {                string key = save;                if(b){                    mydb.putstring(dl.getcontext(),key,开);                }                else {                    mydb.putstring(dl.getcontext(), key,关);                }            }        });        surebtn.setclickedlistener(new component.clickedlistener() {            @override            public void onclick(component component) {                commondialog.destroy();            }        });        commondialog.setcornerradius(15);        commondialog.setcontentcustomcomponent(dl).show();    }}                                至此,ui 美化部分已经全部完成。    
数据存储
      这里用到轻量级偏好数据库,关于数据库怎么使用,可以看这篇文章,文章写得很详细!
https://ost.51cto.com/posts/7911利用数据库存储每个关卡的信息,首先要新建一个数据库类 mydb:public class mydb {    private static final string preference_file_name = db;    private static preferences preferences;    private static databasehelper databasehelper;    private static preferences.preferencesobserver mpreferencesobserver;    private static void initpreference(context context){        if(databasehelper==null){            databasehelper = new databasehelper(context);        }        if(preferences==null){            preferences = databasehelper.getpreferences(preference_file_name);        }    }    public static void putstring(context context, string key, string value) {        initpreference(context);        preferences.putstring(key, value);        preferences.flush();    }    public static string getstring(context context, string key) {        initpreference(context);        return preferences.getstring(key, null);    }    public static boolean deletepreferences(context context) {        initpreference(context);        boolean isdelete= databasehelper.deletepreferences(preference_file_name);        return isdelete;    }    public static void registerobserver(context context, preferences.preferencesobserver preferencesobserver){        initpreference(context);        mpreferencesobserver=preferencesobserver;        preferences.registerobserver(mpreferencesobserver);    }    public static void unregisterobserver(){        if(mpreferencesobserver!=null){            // 向preferences实例注销观察者            preferences.unregisterobserver(mpreferencesobserver);        }    }}   
在结束游戏时,如果打开了自动保存按钮,则进行存储:
if(gamemap.iswin()){                            ticktimer.stop();                            commondialog commondialog = new commondialog(getcontext());                            commondialog.setsize(800,400);                            commondialog.settitletext(  注意);                            commondialog.setcontenttext(             恭喜您完成游戏!!!);                            commondialog.setbutton(0, 确定, new idialog.clickedlistener() {                                @override                                public void onclick(idialog idialog, int i) {                                    commondialog.destroy();                                    string value = mydb.getstring(getcontext(),save);                                    if(value != null){                                        if(value.compareto(开) == 0){                                            mydb.putstring(getcontext(),key,ticktimer.gettext());                                        }                                    }                                    present(new selectslice(),new intent());                                    terminate();                                }                            });                            commondialog.show();                        }  在点击历史记录时,会进行数据读取:        //历史记录按钮        recordbtn.setclickedlistener(new component.clickedlistener() {            @override            public void onclick(component component) {                string[] s = {第一关:无,第二关:无,第三关:无};                string first = mydb.getstring(getcontext(),first);                string second = mydb.getstring(getcontext(),second);                string third = mydb.getstring(getcontext(),third);                if(first == null){                    first = s[0];                }                else {                    first = 第一关: + first;                }                if(second == null){                    second = s[1];                }                else {                    second = 第二关: + second;                }                if(third == null){                    third = s[2];                }                else {                    third = 第三关: + third;                }                recorddialog.showdialog(getcontext(),first,second,third);            }        });开启自动保存,才会在游戏结束时存进数据库,实际上也是利用数据库中某个 key 中的 value 控制。 具体实现如下:        choose.setcheckedstatechangedlistener(new absbutton.checkedstatechangedlistener() {            @override            public void oncheckedchanged(absbutton absbutton, boolean b) {                string key = save;                if(b){                    mydb.putstring(dl.getcontext(),key,开);                }                else {                    mydb.putstring(dl.getcontext(), key,关);                }            }        });  至此,项目已经全部分享完成,由于作品中涉及大量的图片资源均是网络资源(避免侵权),故仅作学习交流使用,实际上,绝大部分代码已经在文章中了,剩下的就是读者理解之后动手衔接起来!一定要动手!  
后续作者也会开发更多的小游戏供大家学习交流~(下期可能就是 arkui 的小游戏啦!)期待与大家一起进步!!!


海辰储能荣登“2023全球新能源企业500强”
如果比特币和加密货币是作为一种投资资产那么价格波动就不是问题
安装油烟在线监测设备还有哪些好处?
Zoom适配于M1 Mac的本机版本正在更新中
苹果WWDC 2021将于6月7-11日举行
鸿蒙推箱子小游戏:UI界面美化
元器件的封装形式有哪些?
人工智能和加密货币发展迅速,将使GPU一直处于供应短缺的状态
模数转换器时钟优化:测试工程观点
教你如何用万用表判断电解电容的正负极
离线语音茶吧机设计应用案例详解
伟世通预计2018年推出首款汽车座舱主机控制系统SmartCore
PT展——“5G融合,共建万物互联的智能世界”
欧胜最新创新型myZone技术为耳机和耳麦提供全球首款数字环
芯片半导体最新消息
软件测试的五个目的,你知道几个?
了解I2C Primer、PMBus和SMBus通信协议
蓝牙耳机什么牌子好?盘点便宜又好用的蓝牙耳机品牌
读《价值共生:数字时代的碳中和》,TA们这样说…
DTU数据转换模块助力企业微电网数字化建设