鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)

​在上文笔者向大家分享了推箱子小游戏基础功能的实现​​,本文将继续向大家介绍如何做 UI 界面美化,以及如何利用轻量级偏好数据库做数据的存储和读取。

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(1)

UI 界面美化

①MainAbilitySlice

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(2)

我们可以看到,所有的界面都是采用无框全屏化设计,因此第一步是要修改 config.json 文件。

打开文件,将代码做出如下修改:

...... "launchType": "standard" } ], "metaData": { "customizeData": [ { "name": "hwc-theme", "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar", "extra": "" } ] } } }

然后设计按钮样式,首先新建一个 graphic 文件:

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(3)

接着在里面添加美化代码:

<?xml versinotallow="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="120"/> <stroke ohos:width="3vp" ohos:color="#fbc02d"/> <solid ohos:color="#fff8e1"/> </shape>

现在分析界面需求,其中带有“Pokemon”字样的是本地图片,因此我们需要的控件有四个按钮以及一张图片,布局采用 DirectionalLayout 即可。

代码如下:

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <Image ohos:layout_alignment="horizontal_center" ohos:width="350vp" ohos:height="100vp" ohos:image_src="$media:pokemon" ohos:scale_mode="zoom_center" ohos:bottom_margin="20vp" /> <Button ohos:id="$ id:startBtn" ohos:width="250vp" ohos:height="50vp" ohos:background_element="$graphic:background_ability_main" ohos:text_color="#ffffff" ohos:text_weight="700" ohos:text_size="20vp" ohos:text="开始游戏" ohos:bottom_margin="20vp" /> <Button ohos:id="$ id:recordBtn" ohos:width="250vp" ohos:height="50vp" ohos:background_element="$graphic:button" ohos:text_color="#fbc02d" ohos:text_weight="700" ohos:text_size="20vp" ohos:text="历史记录" ohos:bottom_margin="20vp" /> <Button ohos:id="$ id:aboutBtn" ohos:width="250vp" ohos:height="50vp" ohos:background_element="$graphic:button" ohos:text_color="#fbc02d" ohos:text_weight="700" ohos:text_size="20vp" ohos:text="关于游戏" ohos:bottom_margin="20vp" /> <Button ohos:id="$ id:exitBtn" ohos:width="250vp" ohos:height="50vp" ohos:text_color="#fbc02d" ohos:background_element="$graphic:button" ohos:text_weight="700" ohos:text_size="20vp" ohos:text="退出游戏" ohos:bottom_margin="20vp" /> </DirectionalLayout>

至此第一个界面就美化完成了。

②SelectSlice

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(4)

这个界面的布局跟第一个界面大同小异,只是少了一个按钮,还有就是按钮的样式有点不同,因此需要再写一个 graphic 文件,方法同上。

这里直接给出代码:

<?xml versinotallow="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="120"/> <stroke ohos:width="3vp" ohos:color="#7cc473"/> <solid ohos:color="#e5f0e4"/> </shape>

界面的代码如下:

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:orientation="vertical" ohos:alignment="center"> <Image ohos:width="361vp" ohos:height="70vp" ohos:scale_mode="zoom_center" ohos:layout_alignment="center" ohos:bottom_margin="30vp" ohos:image_src="$media:select" /> <Button ohos:layout_alignment="center" ohos:id="$ id:firstBtn" ohos:width="300vp" ohos:height="60vp" ohos:background_element="$graphic:select" ohos:text_color="#7cc473" ohos:text_weight="700" ohos:text_size="30fp" ohos:text="第一关" ohos:bottom_margin="30vp" /> <Button ohos:layout_alignment="center" ohos:id="$ id:secondBtn" ohos:width="300vp" ohos:height="60vp" ohos:background_element="$graphic:select" ohos:text_color="#7cc473" ohos:text_weight="700" ohos:text_size="30fp" ohos:text="第二关" ohos:bottom_margin="30vp" /> <Button ohos:layout_alignment="center" ohos:id="$ id:thirdBtn" ohos:width="300vp" ohos:height="60vp" ohos:background_element="$graphic:select" ohos:text_color="#7cc473" ohos:text_weight="700" ohos:text_size="30fp" ohos:text="第三关" ohos:bottom_margin="20vp" /> </DirectionalLayout>

③InitSlice

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(5)

在加载界面中,只是用到了一个播放 gif 的第三方组件,以及一张图片(文字图片)一个进度条组件,布局也使用最常规的 DirectionalLayout 即可实现。

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:orientation="vertical"> <com.bumptech.glide.load.resource.gif.drawableability.DraweeView ohos:layout_alignment="center" ohos:top_margin="100vp" ohos:id="$ id:draweeView" ohos:width="360vp" ohos:height="360vp" /> <Image ohos:width="291vp" ohos:height="53vp" ohos:layout_alignment="center" ohos:bottom_margin="30vp" ohos:scale_mode="zoom_center" ohos:image_src="$media:Loading" /> <ProgressBar ohos:layout_alignment="center" ohos:height="30vp" ohos:width="330vp" ohos:id="$ id:pb" ohos:max="100" ohos:min="0" ohos:progress_width="330vp" ohos:background_element="#edf1bb" ohos:progress_element="#f2c867" ohos:progress="0" /> </DirectionalLayout>

④GameSlice

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(6)

游戏界面的 UI 就稍微复杂一点,需要用到嵌套,之前说过,地图类继承自布局,所以实际上地图也是一个组件,理解了这一点之后,再来看代码会容易理解很多。

整体布局用了 DirectionalLayout 纵向布局,在里面有需要横向布局的,则添加 DirectionalLayout 的横向布局,做一个简单的嵌套。

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:orientation="vertical" > <DirectionalLayout ohos:id="$ id:dl" ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal" ohos:bottom_margin="20vp" > <Button ohos:id="$ id:backBtn" ohos:top_margin="10vp" ohos:left_margin="10vp" ohos:right_margin="8vp" ohos:width="40vp" ohos:height="40vp" ohos:layout_alignment="left" ohos:background_element="$graphic:backbutton" /> <Button ohos:id="$ id:setBtn" ohos:top_margin="10vp" ohos:left_margin="8vp" ohos:right_margin="10vp" ohos:width="40vp" ohos:height="40vp" ohos:background_element="$graphic:setbutton" /> <Image ohos:layout_alignment="right" ohos:top_margin="10vp" ohos:left_margin="85vp" ohos:width="40vp" ohos:height="40vp" ohos:scale_mode="zoom_center" ohos:image_src="$media:clock" /> </DirectionalLayout> <Image ohos:layout_alignment="center" ohos:width="372vp" ohos:height="35vp" ohos:scale_mode="zoom_center" ohos:image_src="$media:goal" ohos:bottom_margin="20vp" /> <com.example.pokemon.slice.GameMap ohos:layout_alignment="center" ohos:id="$ id:gameMap1" ohos:width="match_content" ohos:height="match_content" ohos:bottom_margin="15vp" /> <DirectionalLayout ohos:height="210vp" ohos:width="match_parent" ohos:orientation="horizontal" ohos:top_margin="20vp"> <Image ohos:layout_alignment="center" ohos:width="158vp" ohos:height="170vp" ohos:scale_mode="zoom_center" ohos:image_src="$media:stack" ohos:bottom_margin="20vp" /> <Button ohos:id="$ id:stackBtn" ohos:left_margin="15vp" ohos:bottom_margin="10vp" ohos:width="150vp" ohos:height="150vp" ohos:background_element="$graphic:button" ohos:text="回退" ohos:text_size="50fp" ohos:text_color="#fbc02d" /> </DirectionalLayout> </DirectionalLayout>

四个界面美化完毕!接下来做一些细节的调整。在按下历史记录按钮时,会显示每个关卡最近的一次历史记录,效果如下:

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(7)

这实际上是一个自定义样式的 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 文件如下:

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_content" ohos:width="match_content" ohos:orientation="vertical"> <Text ohos:left_margin="5vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:width="match_content" ohos:height="match_content" ohos:text="最新通关记录:" ohos:multiple_lines="true" ohos:top_margin="20vp" ohos:text_size="20fp" /> <Text ohos:id="$ id:firstText" ohos:left_margin="120vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:width="match_content" ohos:height="match_content" ohos:text="第一关:无" ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="20fp" /> <Text ohos:left_margin="120vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:id="$ id:secondText" ohos:width="match_content" ohos:height="match_content" ohos:text="第二关:无" ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="20fp" /> <Text ohos:left_margin="120vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:id="$ id:thirdText" ohos:width="match_content" ohos:height="match_content" ohos:text="第三关:无" ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="20fp" /> <Button ohos:id="$ id:okBtn" ohos:width="250vp" ohos:height="50vp" ohos:background_element="$graphic:background_ability_main" ohos:text_color="#ffffff" ohos:text_weight="700" ohos:text_size="20vp" ohos:top_margin="30vp" ohos:text="确定" ohos:bottom_margin="20vp" ohos:left_margin="40vp" /> </DirectionalLayout>

关于这样的设计,这个小游戏中还有一处,点击关于游戏弹出的界面同样也是这么实现的:

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(8)

代码如下:

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(); } }

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_content" ohos:width="match_content" ohos:orientation="vertical" ohos:alignment="center"> <Text ohos:left_margin="5vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:width="match_content" ohos:height="match_content" ohos:text="游戏目标:收服在场的所有宝可梦!" ohos:multiple_lines="true" ohos:top_margin="20vp" ohos:text_size="20fp" /> <Text ohos:left_margin="5vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:width="match_content" ohos:height="match_content" ohos:text="游戏玩法:通过滑动屏幕控制人物,推动精灵球收服宝可梦,当收服完所有宝可梦时获得游戏胜利!" ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="20fp" /> <Text ohos:left_margin="5vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:id="$ id:versionText" ohos:width="match_content" ohos:height="match_content" ohos:text="游戏版本号:V1.0.0" ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="20fp" /> <Text ohos:left_margin="5vp" ohos:right_margin="5vp" ohos:layout_alignment="left" ohos:id="$ id:showText" ohos:width="match_content" ohos:height="match_content" ohos:text="开发人员:木棉花蓝锐鑫" ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="20fp" /> <Button ohos:id="$ id:knowBtn" ohos:width="250vp" ohos:height="50vp" ohos:background_element="$graphic:background_ability_main" ohos:text_color="#ffffff" ohos:text_weight="700" ohos:text_size="20vp" ohos:top_margin="30vp" ohos:text="已了解" ohos:bottom_margin="20vp" /> </DirectionalLayout>

游戏中最后一处 UI 设计,就是点击设置按钮时出现的一个滑动块组件,可以保存一些全局设置:

鸿蒙更新以后好多小游戏玩不了了(鸿蒙推箱子小游戏)(9)

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(); } }

<?xml versinotallow="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_content" ohos:width="match_content" ohos:orientation="vertical"> <DirectionalLayout ohos:id="$ id:dl" ohos:height="match_content" ohos:width="match_content" ohos:orientation="horizontal" > <Text ohos:left_margin="70vp" ohos:right_margin="25vp" ohos:layout_alignment="left" ohos:id="$ id:thirdText" ohos:width="match_content" ohos:height="match_content" ohos:text="自动保存 " ohos:multiple_lines="true" ohos:top_margin="10vp" ohos:text_size="30fp" /> <Switch ohos:id="$ id:choose" ohos:height="40vp" ohos:width="100vp" ohos:top_margin="10vp" ohos:text_state_on="开" ohos:text_state_off="关" ohos:text_color="#ffffff" ohos:text_size="20fp" ohos:thumb_element="#eff1f8" ohos:track_element="#f9bf2d" /> </DirectionalLayout> <Button ohos:id="$ id:sureBtn" ohos:width="250vp" ohos:height="50vp" ohos:background_element="$graphic:background_ability_main" ohos:text_color="#ffffff" ohos:text_weight="700" ohos:text_size="20vp" ohos:top_margin="30vp" ohos:text="确定" ohos:bottom_margin="20vp" ohos:left_margin="40vp" /> </DirectionalLayout>

至此,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,"关"); } } });

至此,项目已经全部分享完成,由于作品中涉及大量的图片资源均是网络资源(避免侵权),故仅作学习交流使用,实际上,绝大部分代码已经在文章中了,剩下的就是读者理解之后动手衔接起来!一定要动手!

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页