在上文筆者向大家分享了推箱子小游戲基礎(chǔ)功能的實現(xiàn),本文將繼續(xù)向大家介紹如何做 UI 界面美化,以及如何利用輕量級偏好數(shù)據(jù)庫做數(shù)據(jù)的存儲和讀取。
UI 界面美化
①M(fèi)ainAbilitySlice

我們可以看到,所有的界面都是采用無框全屏化設(shè)計,因此第一步是要修改 config.json 文件。
打開文件,將代碼做出如下修改:
...... "launchType":"standard" } ], "metaData":{ "customizeData":[ { "name":"hwc-theme", "value":"androidhwext:style/Theme.Emui.Light.NoTitleBar", "extra":"" } ] } } }然后設(shè)計按鈕樣式,首先新建一個 graphic 文件:

接著在里面添加美化代碼:
現(xiàn)在分析界面需求,其中帶有“Pokemon”字樣的是本地圖片,因此我們需要的控件有四個按鈕以及一張圖片,布局采用 DirectionalLayout 即可。 代碼如下:
至此第一個界面就美化完成了。
②SelectSlice

這個界面的布局跟第一個界面大同小異,只是少了一個按鈕,還有就是按鈕的樣式有點不同,因此需要再寫一個 graphic 文件,方法同上。
這里直接給出代碼:
界面的代碼如下:
③InitSlice

在加載界面中,只是用到了一個播放 gif 的第三方組件,以及一張圖片(文字圖片)一個進(jìn)度條組件,布局也使用最常規(guī)的 DirectionalLayout 即可實現(xiàn)。
④GameSlice

游戲界面的 UI 就稍微復(fù)雜一點,需要用到嵌套,之前說過,地圖類繼承自布局,所以實際上地圖也是一個組件,理解了這一點之后,再來看代碼會容易理解很多。 整體布局用了 DirectionalLayout 縱向布局,在里面有需要橫向布局的,則添加 DirectionalLayout 的橫向布局,做一個簡單的嵌套。
四個界面美化完畢!接下來做一些細(xì)節(jié)的調(diào)整。在按下歷史記錄按鈕時,會顯示每個關(guān)卡最近的一次歷史記錄,效果如下:

這實際上是一個自定義樣式的 CommonDialog,如何自定義?首先創(chuàng)建一個自定義的 RecordDialog 類和美化用的 xml 文件,然后在類里面添加自己的 xml 文件。
具體方法可以看代碼:
publicclassRecordDialog{
staticCommonDialogcommonDialog;
staticvoidshowDialog(Contextcontext,Strings1,Strings2,Strings3){
DirectionalLayoutdl=(DirectionalLayout)LayoutScatter.getInstance(context)
.parse(ResourceTable.Layout_recordlayout,null,false);
commonDialog=newCommonDialog(context);
commonDialog.setAutoClosable(true);
ButtonBtn=(Button)dl.findComponentById(ResourceTable.Id_Btn);
Textfirst=(Text)dl.findComponentById(ResourceTable.Id_firstText);
first.setText(s1);
Textsecond=(Text)dl.findComponentById(ResourceTable.Id_secondText);
second.setText(s2);
Textthird=(Text)dl.findComponentById(ResourceTable.Id_thirdText);
third.setText(s3);
Btn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
commonDialog.destroy();
}
});
commonDialog.setCornerRadius(15);
commonDialog.setContentCustomComponent(dl).show();
}
}
xml 文件如下:
關(guān)于這樣的設(shè)計,這個小游戲中還有一處,點擊關(guān)于游戲彈出的界面同樣也是這么實現(xiàn)的:

代碼如下:
publicclassMyDialog{
privatestaticTextversion;
staticvoidshowDialog(Contextcontext){
DirectionalLayoutdl=(DirectionalLayout)LayoutScatter.getInstance(context)
.parse(ResourceTable.Layout_mydialoglayout,null,false);
CommonDialogcommonDialog=newCommonDialog(context);
commonDialog.setAutoClosable(true);
ButtonknowBtn=(Button)dl.findComponentById(ResourceTable.Id_knowBtn);
knowBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
commonDialog.destroy();
}
});
commonDialog.setCornerRadius(15);
commonDialog.setContentCustomComponent(dl).show();
}
staticStringgetVersion(){
returnversion.getText();
}
}
游戲中最后一處 UI 設(shè)計,就是點擊設(shè)置按鈕時出現(xiàn)的一個滑動塊組件,可以保存一些全局設(shè)置:

publicclassSetDialog{
staticvoidshowDialog(Contextcontext){
DirectionalLayoutdl=(DirectionalLayout)LayoutScatter.getInstance(context)
.parse(ResourceTable.Layout_setlayout,null,false);
CommonDialogcommonDialog=newCommonDialog(context);
commonDialog.setAutoClosable(true);
ButtonsureBtn=(Button)dl.findComponentById(ResourceTable.Id_sureBtn);
Switchchoose=(Switch)dl.findComponentById(ResourceTable.Id_choose);
Stringvalue=MyDB.getString(dl.getContext(),"save");
if(value!=null){
if(value.compareTo("開")==0){
choose.setChecked(true);
}
elseif(value.compareTo("關(guān)")==0){
choose.setChecked(false);
}
}
choose.setCheckedStateChangedListener(newAbsButton.CheckedStateChangedListener(){
@Override
publicvoidonCheckedChanged(AbsButtonabsButton,booleanb){
Stringkey="save";
if(b){
MyDB.putString(dl.getContext(),key,"開");
}
else{
MyDB.putString(dl.getContext(),key,"關(guān)");
}
}
});
sureBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
commonDialog.destroy();
}
});
commonDialog.setCornerRadius(15);
commonDialog.setContentCustomComponent(dl).show();
}
}
至此,UI 美化部分已經(jīng)全部完成。
數(shù)據(jù)存儲
這里用到輕量級偏好數(shù)據(jù)庫,關(guān)于數(shù)據(jù)庫怎么使用,可以看這篇文章,文章寫得很詳細(xì)!
https://ost.51cto.com/posts/7911利用數(shù)據(jù)庫存儲每個關(guān)卡的信息,首先要新建一個數(shù)據(jù)庫類 MyDB:
publicclassMyDB{
privatestaticfinalStringPREFERENCE_FILE_NAME="DB";
privatestaticPreferencespreferences;
privatestaticDatabaseHelperdatabaseHelper;
privatestaticPreferences.PreferencesObservermPreferencesObserver;
privatestaticvoidinitPreference(Contextcontext){
if(databaseHelper==null){
databaseHelper=newDatabaseHelper(context);
}
if(preferences==null){
preferences=databaseHelper.getPreferences(PREFERENCE_FILE_NAME);
}
}
publicstaticvoidputString(Contextcontext,Stringkey,Stringvalue){
initPreference(context);
preferences.putString(key,value);
preferences.flush();
}
publicstaticStringgetString(Contextcontext,Stringkey){
initPreference(context);
returnpreferences.getString(key,null);
}
publicstaticbooleandeletePreferences(Contextcontext){
initPreference(context);
booleanisDelete=databaseHelper.deletePreferences(PREFERENCE_FILE_NAME);
returnisDelete;
}
publicstaticvoidregisterObserver(Contextcontext,Preferences.PreferencesObserverpreferencesObserver){
initPreference(context);
mPreferencesObserver=preferencesObserver;
preferences.registerObserver(mPreferencesObserver);
}
publicstaticvoidunregisterObserver(){
if(mPreferencesObserver!=null){
//向preferences實例注銷觀察者
preferences.unregisterObserver(mPreferencesObserver);
}
}
}
在結(jié)束游戲時,如果打開了自動保存按鈕,則進(jìn)行存儲:
if(gameMap.isWin()){
tickTimer.stop();
CommonDialogcommonDialog=newCommonDialog(getContext());
commonDialog.setSize(800,400);
commonDialog.setTitleText("注意");
commonDialog.setContentText("恭喜您完成游戲?。?!");
commonDialog.setButton(0,"確定",newIDialog.ClickedListener(){
@Override
publicvoidonClick(IDialogiDialog,inti){
commonDialog.destroy();
Stringvalue=MyDB.getString(getContext(),"save");
if(value!=null){
if(value.compareTo("開")==0){
MyDB.putString(getContext(),key,tickTimer.getText());
}
}
present(newSelectSlice(),newIntent());
terminate();
}
});
commonDialog.show();
}
在點擊歷史記錄時,會進(jìn)行數(shù)據(jù)讀?。?
//歷史記錄按鈕
recordBtn.setClickedListener(newComponent.ClickedListener(){
@Override
publicvoidonClick(Componentcomponent){
String[]s={"第一關(guān):無","第二關(guān):無","第三關(guān):無"};
Stringfirst=MyDB.getString(getContext(),"first");
Stringsecond=MyDB.getString(getContext(),"second");
Stringthird=MyDB.getString(getContext(),"third");
if(first==null){
first=s[0];
}
else{
first="第一關(guān):"+first;
}
if(second==null){
second=s[1];
}
else{
second="第二關(guān):"+second;
}
if(third==null){
third=s[2];
}
else{
third="第三關(guān):"+third;
}
RecordDialog.showDialog(getContext(),first,second,third);
}
});
開啟自動保存,才會在游戲結(jié)束時存進(jìn)數(shù)據(jù)庫,實際上也是利用數(shù)據(jù)庫中某個 key 中的 value 控制。 具體實現(xiàn)如下:
choose.setCheckedStateChangedListener(newAbsButton.CheckedStateChangedListener(){
@Override
publicvoidonCheckedChanged(AbsButtonabsButton,booleanb){
Stringkey="save";
if(b){
MyDB.putString(dl.getContext(),key,"開");
}
else{
MyDB.putString(dl.getContext(),key,"關(guān)");
}
}
});
至此,項目已經(jīng)全部分享完成,由于作品中涉及大量的圖片資源均是網(wǎng)絡(luò)資源(避免侵權(quán)),故僅作學(xué)習(xí)交流使用,實際上,絕大部分代碼已經(jīng)在文章中了,剩下的就是讀者理解之后動手銜接起來!一定要動手!
后續(xù)作者也會開發(fā)更多的小游戲供大家學(xué)習(xí)交流~(下期可能就是 ArkUI 的小游戲啦!)期待與大家一起進(jìn)步?。。?/p>
-
游戲
+關(guān)注
關(guān)注
2文章
787瀏覽量
27245 -
ui界面
+關(guān)注
關(guān)注
0文章
11瀏覽量
1920 -
鴻蒙
+關(guān)注
關(guān)注
60文章
2858瀏覽量
45354 -
OpenHarmony
+關(guān)注
關(guān)注
31文章
3926瀏覽量
20719
原文標(biāo)題:鴻蒙推箱子小游戲:UI界面美化
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
單片機(jī)推箱子游戲程序模擬仿真
LabView資料分享:推箱子游戲
基于labview開發(fā)的10個小游戲(貪吃蛇、俄羅斯方塊、五子棋、象棋、2048、推箱子等)
基于C語言設(shè)計編寫的ARM推箱子
基于單片機(jī)的推箱子游戲仿真結(jié)果
單片機(jī):推箱子游戲HEX文件
語音識別的推箱子游戲設(shè)計

鴻蒙推箱子小游戲:UI界面美化
評論