自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

HarmonyOS小游戲項目—數獨Sudoku(五)

系統(tǒng) OpenHarmony
在本期的分享中,筆者將繼續(xù)完善項目的相關功能,并制作判定游戲是否通關的功能。

??想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區(qū)??

??https://ost.51cto.com??

前言

Hello,各位好久不見!

非常抱歉,這段時間作者在忙于其他事情,所以一直沒有在社區(qū)更文。

時間過得很快,HarmonyOS與OpenHarmony也發(fā)展地很快,目前DevEco Studio的鴻蒙SDK也已經更新到API8的版本了。對于鴻蒙操作系統(tǒng)的蒸蒸日上,我感到非常喜悅。

最近的一段時間,我重新閱讀了放在IDE中的數獨游戲項目的代碼,發(fā)現(xiàn)自己曾經寫的代碼其實挺爛的。事實上,我是在接觸了鴻蒙的前端后,才開始嘗試去學習Java語言并利用Java創(chuàng)建UI的。所以在寫這個項目時,我的Java仍處于比較菜的水平,權限修飾符用的很亂,并且有些代碼雖然能運行,但也寫的不簡潔或者不合理,所以近期我對這個項目的代碼進行了許多優(yōu)化。實際上,作為一個學習者,任何人在編程的初期都不可避免地會寫一些爛代碼,以及踩一些坑。我們進步的過程,不僅是學習一些未接觸過的新知識,更重要的是在之前所寫過的代碼中不斷優(yōu)化,并在這個過程中不斷提煉新的計算機思維。

另外,因為DevEco studo的SDK8版本已經將Java移除了,這意味著在IDE中用Java代碼編譯的程序只能運行在SDK7以前的華為機型,所以筆者在更新完關于數獨項目的文章后,就暫時不繼續(xù)分享有關Java的代碼了,而是先嘗試去學習與分享關于JavaScrip與ets的內容。   

上期的內容回顧——>>https://ost.51cto.com/posts/15252。

正文

 在本期的分享中,筆者將繼續(xù)完善項目的相關功能,并制作判定游戲是否通關的功能。

定義兩個重要的數組

打開GameAbilitySlice,并在合適的位置定義兩個二維數組——grids_win和grids_input。注意,這兩個數組是作為全局變量定義的,他們不能定義在生命周期函數或其他函數內。

//定義兩個二維數組
int[][] grids_win=new int[6][];
int[][] grids_input=new int[6][];
......
@Override
protected void onStart(Intent intent) {
super.onStart(intent);
.......

在這兩個新定義的數組變量,grids_win代表儲存了數獨答案的二維數組,而grids_input代表用戶在游戲交互過程中將要改變的數組。這兩個數組在項目中主要用于判定游戲的勝利與否,而判斷邏輯是這樣的:如果grid_input中每行每列的元素都等于grids_win中每行每列的元素,這就意味著用戶在數獨網格填入的數字與答案一致,此時游戲勝利;否則,游戲未成功。

在定義grids_win與grids_input前,我們在之前的文章中已經定義了grid_c0,而grid_c0用于生成網格區(qū)域中的數獨題目的。接下來,我們再定義grid_c0數組所對應的答案數組——grid_v0(注意,grid_c0與grid_v0均是定義在onstart函數內的局部變量):

...
@Override
protected void onStart(Intent intent) {
super.onStart(intent);
grid_c0[0]=new int[]{0,0,0,0,1,0};
...
//定義grid_v0
int[][] grid_v0=new int[6][];
grid_v0[0]=new int[]{4,3,5,6,1,2};
grid_v0[1]=new int[]{1,5,2,4,6,3};
grid_v0[2]=new int[]{6,2,3,1,4,5};
grid_v0[3]=new int[]{5,4,1,2,3,6};
grid_v0[4]=new int[]{2,6,4,3,5,1};
grid_v0[5]=new int[]{3,1,6,5,2,4};

然后,我們再進行如下賦值操作(筆者也驚訝地發(fā)現(xiàn),Java的數組賦值竟然可以如此輕松快捷qwq):

grids_input=grid_c0;
grids_win=grid_v0;

這樣,grids_input和grids_win就被輸入對應的數據了。

或許讀者會問,為什么不直接把grid_c0和grid_v0分別作為用戶交互的數組和答案數組來使用呢?原因是,grid_c0與grid_v0只是分別作為這個游戲的某一個一個關卡的題目與答案,在后文,筆者會導入更多的題目與答案,所以我們需要另外定義grid_input與grid_win作為兩個全局變量,當關卡不同時,這兩個變量也就分別負責儲存不同的題目與答案,以及參與判斷游戲是否勝利的邏輯判斷過程。

創(chuàng)建三個功能按鈕

我們先找到之前創(chuàng)建的6個圓形button對象(即用于在網格區(qū)域輸入數字的Button組件),并在這6個圓形button對象的監(jiān)聽器內各加入一行指令(即下面代碼中“//”前的部分):

//按鍵區(qū)域
Button button_input1=new Button(this);
button_input1.setText("1");
button_input1.setTextColor(Color.BLACK);
button_input1.setTextSize(75);
button_input1.setBackground(element2);
button_input1.setComponentSize(150, 150);
button_input1.setPosition(70,1600);
button_input1.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setTextColor(Color.BLACK);
button_temp.setText("1");
grids_input[j1][k1]=1; //為網格區(qū)域對應的題目矩陣的相應位置賦值1
}
});
layout1.addComponent(button_input1);
Button button_input2=new Button(this);
button_input2.setText("2");
button_input2.setTextColor(Color.BLACK);
button_input2.setTextSize(75);
button_input2.setBackground(element2);
button_input2.setComponentSize(150, 150);
button_input2.setPosition(70+160*1,1600);
button_input2.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setTextColor(Color.BLACK);
button_temp.setText("2");
grids_input[j1][k1]=2;//為網格區(qū)域對應的題目矩陣的相應位置賦值2
}
});
layout1.addComponent(button_input2);

Button button_input3=new Button(this);
button_input3.setText("3");
button_input3.setTextColor(Color.BLACK);
button_input3.setTextSize(75);
button_input3.setBackground(element2);
button_input3.setComponentSize(150, 150);
button_input3.setPosition(70+160*2,1600);
button_input3.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setTextColor(Color.BLACK);
button_temp.setText("3");
grids_input[j1][k1]=3;//為網格區(qū)域對應的題目矩陣的相應位置賦值3
}
});
layout1.addComponent(button_input3);
Button button_input4=new Button(this);
button_input4.setText("4");
button_input4.setTextColor(Color.BLACK);
button_input4.setTextSize(75);
button_input4.setBackground(element2);
button_input4.setComponentSize(150, 150);
button_input4.setPosition(70+160*3,1600);
button_input4.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setText("4");
grids_input[j1][k1]=4;//為網格區(qū)域對應的題目矩陣的相應位置賦值4
}
});
layout1.addComponent(button_input4);
Button button_input5=new Button(this);
button_input5.setText("5");
button_input5.setTextColor(Color.BLACK);
button_input5.setTextSize(75);
button_input5.setBackground(element2);
button_input5.setComponentSize(150, 150);
button_input5.setPosition(70+160*4,1600);
button_input5.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setText("5");
grids_input[j1][k1]=5;//為網格區(qū)域對應的題目矩陣的相應位置賦值5
}
});
layout1.addComponent(button_input5);
Button button_input6=new Button(this);
button_input6.setText("6");
button_input6.setTextColor(Color.BLACK);
button_input6.setTextSize(75);
button_input6.setBackground(element2);
button_input6.setComponentSize(150, 150);
button_input6.setPosition(70+160*5,1600);
button_input6.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setText("6");
grids_input[j1][k1]=6;//為網格區(qū)域對應的題目矩陣的相應位置賦值6
}
});
layout1.addComponent(button_input6);
setUIContent(layout1);

}

指令中的變量j1和變量k1,就是筆者在上期內容中利用Text組件轉換所得的的每個網格的位置信息(詳細原理詳見上期內容)。這樣以后,用戶每次在某個區(qū)域上輸入數字(1到6的整數)時,數組grids_input的對應存儲位置也會被輸入相應的數字元素。

完成上述操作后,我們開始另外創(chuàng)建三個新的按鈕,每個按鈕都負責不同的功能(如圖箭頭所指部分):

【木棉花】#打卡不停更#HarmonyOS小游戲項目——數獨Sudoku(5)-開源基礎軟件社區(qū)

首先,我們?yōu)閷⒁獎?chuàng)建的Button對象定義基本的背景元素:

//背景元素
...
ShapeElement element4=new ShapeElement();
element4.setRgbColor(new RgbColor(0,125,225)); //設置Rgb顏色
element4.setCornerRadius(50); //設置圓角

然后通過代碼布局創(chuàng)建這三個按鈕(需要寫入的Button對象的方法都差不多,只是一些參數不同):

//按鍵區(qū)—操作
Button button_clean=new Button(this);//“清除”按鈕
//基本UI屬性方法
button_clean.setText("清除");
button_clean.setTextColor(Color.WHITE);
button_clean.setTextSize(75);
button_clean.setBackground(element4);
button_clean.setComponentSize(280, 150);
button_clean.setPosition(50,1900);
//設置點擊監(jiān)聽器
button_clean.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
button_temp.setText("");
grids_input[j1][k1]=0;
}
});
//設置狀態(tài)改變監(jiān)聽器,讓按鈕擁有動態(tài)效果
button_clean.setComponentStateChangedListener(new Component.ComponentStateChangedListener() {
@Override
public void onComponentStateChanged(Component component, int i) {
if (ComponentState.isStateMatched(ComponentState.COMPONENT_STATE_PRESSED,i)){
button_clean.setComponentSize(290, 160); //組件處于被點擊態(tài)時尺寸放大
}else {
button_clean.setComponentSize(280, 150); //組件不處于被點擊態(tài)時尺寸恢復初始值
}
}
});
//將組件放入自定義布局
layout1.addComponent(button_clean);
Button button_replay=new Button(this);//"重新開始"按鈕
//基本UI屬性方法
button_replay.setText("重新開始");
button_replay.setTextColor(Color.WHITE);
button_replay.setTextSize(75);
button_replay.setBackground(element4);
button_replay.setComponentSize(370, 150);
button_replay.setPosition(50+307,1900);
//設置點擊監(jiān)聽器
button_replay.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
Intent intent_replay=new Intent();
present(new GameAbilitySlice(),intent_replay);
}
});
//設置狀態(tài)改變監(jiān)聽器,讓按鈕擁有動態(tài)效果
button_replay.setComponentStateChangedListener(new Component.ComponentStateChangedListener() {
@Override
public void onComponentStateChanged(Component component, int i) {
if (ComponentState.isStateMatched(ComponentState.COMPONENT_STATE_PRESSED,i)){
button_replay.setComponentSize(380,160);
}else {
button_replay.setComponentSize(370, 150);
}
}
});
//將組件放入自定義布局
layout1.addComponent(button_replay);
Button button_pr=new Button(this);//“提交“按鈕
//基本UI屬性方法
button_pr.setText("提交");
button_pr.setTextColor(Color.WHITE);
button_pr.setTextSize(75);
button_pr.setBackground(element4);
button_pr.setComponentSize(280, 150);
button_pr.setPosition(50+700,1900);
//設置點擊監(jiān)聽器
button_pr.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
}
});
//設置狀態(tài)改變監(jiān)聽器,讓按鈕擁有動態(tài)效果
button_pr.setComponentStateChangedListener(new Component.ComponentStateChangedListener() {
@Override
public void onComponentStateChanged(Component component, int i) {
if (ComponentState.isStateMatched(ComponentState.COMPONENT_STATE_PRESSED,i)){
button_pr.setComponentSize(290, 160);
}else {
button_pr.setComponentSize(280, 150);
}
}
});
//將組件放入自定義布局
layout1.addComponent(button_pr);

這樣之后,我們就新創(chuàng)建了三個按鈕。其中,第一個”清除“按鈕用于在網格區(qū)域的獲焦網格上輸入空字符串,這意味著我們實現(xiàn)了清除白色網格內已輸入數字的功能。在清除白色網格內的數字的同時,此按鈕還將grid_input(即在游戲過程會被用戶修改參數的矩陣)對應位置的元素賦值為0,確保grid_input內的對應元素可以在清除功能被執(zhí)行時更新(否則游之后的游戲判斷功能會出bug)。

第二個”重新開始“按鈕用于讓應用從當前的GameAbilitySlice跳轉至另一個新生成的GameAbilitySlice,能夠實現(xiàn)頁面刷新的功能。由于在之前的文章中,我們在onBackground回調中加入了銷毀指令,所以系統(tǒng)由舊的GameAbilitySlice導航至新的GameAbilitySlice時,舊的GameAbilitySlice由于進入background態(tài)后會啟用onBackground回調,進而被銷毀。假如之前我們沒有添加銷毀指令,那么用戶每點擊一次”重新開始“的按鈕,AbilitySlice的實例棧就會堆放一個GameAbilitySlice,這是非常浪費系統(tǒng)內存資源的。

第三個按鈕是”提交“鍵,我們已經寫入了基本的方法,但他的監(jiān)聽器內是未添加任何代碼的。接下來我們就在這個button對象的監(jiān)聽器內加入一些指令,以實現(xiàn)判斷游戲是否成功的功能。

制作判定游戲成功的函數

首先,我們在合適的位置定義一個布爾型函數:

import ......
public class GameAbilitySlice extends AbilitySlice {
......
private boolean Gamesuccess(){
int a,b;
for(a=0;a<6;a++){
for (b=0;b<6;b++){

if (grids_win[a][b]!=grids_input[a][b]){
return false;
}
}
}
return true;
}
......
@Override
protected void onStart(Intent intent) {
......

這個函數是返回布爾值的函數,其封裝的代碼也非常簡單,就是讓grid_win矩陣與grid_input矩陣的每個位置的元素進行比較,如果經過循環(huán)判斷為全部相等,那么這兩個矩陣就完全相等,即滿足了游戲勝利的條件。值得一提的是,由于此函數封裝的代碼包含的兩個變量——grids_win與grids_input是全局變量,所以筆者并沒有將執(zhí)行不同功能的代碼完全模塊化,這意味著如果這兩個全局變量在某些指令中被修改,Gamesuccess()是有幾率受到影響的,這是項目中不足的地方。

接著,我們通過代碼布局初始化兩個彈窗(彈窗必須定義在 button_pr之前):

//對話框
CommonDialog Dialog_win=new CommonDialog(getContext());
Dialog_win.setSize(800,400);
Dialog_win.setTitleText(" 游戲解答成功!");
Dialog_win.setButton(IDialog.BUTTON1,"返回主菜單",(iDialog, i) -> Dialog_win.destroy());
CommonDialog Dialog_fail=new CommonDialog(getContext());
Dialog_fail.setSize(800,400);
Dialog_fail.setTitleText(" 啊哦~沒有通過哦");
Dialog_fail.setContentText(" 游戲未成功解答");
Dialog_fail.setButton(IDialog.BUTTON1,"繼續(xù)游戲",(iDialog, i) -> Dialog_fail.destroy());

最后,我們在“提交”按鈕的監(jiān)聽器內加入指令:

Button button_pr=new Button(this);
......
button_pr.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
//加入指令
if (Gamesuccess()){
Dialog_win.show();//成功
}else {
//加入指令
Dialog_fail.setContentText(" 游戲未完成或答案不正確" );
Dialog_fail.show();//失敗
}
}
});
......
layout1.addComponent(button_pr);

可以看到,如果Gamesuccess()函數返回的值是true,那么系統(tǒng)就會調用Dialog_win的show()方法,將Dialog_win展示在屏幕前以提示游戲成功;如果返回的值是false,系統(tǒng)則調用 Dialog_fail的show()方法,將Dialog_fail展示在屏幕前以提示游戲未成功。這樣一來,游戲成功與否的判斷邏輯便得以成功搭建。?

經過上述的所有操作后,我們可以打開API為6的模擬機試玩,效果圖如下:

【木棉花】#打卡不停更#HarmonyOS小游戲項目——數獨Sudoku(5)-開源基礎軟件社區(qū)

【木棉花】#打卡不停更#HarmonyOS小游戲項目——數獨Sudoku(5)-開源基礎軟件社區(qū)

因為SDK6版本的P40模擬機在近期被停用了,所以我只能用平板模擬機調試程序(/(ㄒoㄒ)/~~),圖片看起來可能有點怪怪的。

結語

本期的內容就先分享到這里,更多關于數獨小游戲項目精彩的內容我將在下期繼續(xù)為大家揭曉。

???想了解更多關于開源的內容,請訪問:??

??51CTO 開源基礎軟件社區(qū)??

??https://ost.51cto.com??。

責任編輯:jianghua 來源: 51CTO開源基礎軟件社區(qū)
相關推薦

2022-07-29 14:47:34

數獨Sudoku鴻蒙

2022-10-19 15:19:53

數獨Sudoku鴻蒙

2022-10-19 15:27:36

數獨Sudoku鴻蒙

2013-06-17 12:44:38

WP7開發(fā)Windows Pho數獨游戲

2023-08-07 15:18:29

游戲開發(fā)鴻蒙Arkts

2024-07-31 09:46:13

2011-09-16 10:35:13

Android應用數獨經典游戲

2022-08-25 21:41:43

ArkUI鴻蒙

2022-11-01 15:17:48

JS鴻蒙小游戲

2021-01-12 12:16:55

鴻蒙HarmonyOS游戲

2021-01-15 12:15:36

鴻蒙HarmonyOS游戲

2022-03-24 08:33:58

小游戲項目cmdvue3

2023-11-06 11:33:15

C++數獨

2021-09-06 08:26:08

JavaScript數獨 LeetCode

2015-09-29 09:38:50

Java程序猜大小

2022-07-08 14:53:46

掃雷小游戲鴻蒙

2012-01-10 12:48:52

Java

2022-02-11 14:39:11

游戲JS鴻蒙

2022-10-28 16:20:10

JS鴻蒙小游戲

2022-02-11 14:02:09

游戲JS鴻蒙
點贊
收藏

51CTO技術棧公眾號