天天看點

【木棉花】#夏日挑戰賽# 鴻蒙小遊戲項目——數獨Sudoku

​​「本文正在參加星光計劃3.0--夏日挑戰賽」​​

前言

    在上期内容的分享中,筆者介紹了如何搭建基礎的頁面架構(為之後的開發做準備),以及應用圖像和标簽的修改、應用的全屏化。而在本期,筆者就在上期的基礎上繼續展開數獨小遊戲項目的搭建。

    上期的内容回顧——>>​​https://ost.51cto.com/posts/14383​​

【木棉花】#夏日挑戰賽# 鴻蒙小遊戲項目——數獨Sudoku

正文

  本期,筆者将介紹如何利用代碼布局建立網格區域的UI。

  首先,筆者所說的網格區域指的是下圖被圈出的部分:

【木棉花】#夏日挑戰賽# 鴻蒙小遊戲項目——數獨Sudoku

     事實上,因為網格區域用于承載數獨的題目,它同時也是玩家主要面向的部分,是以網格區域的邏輯就是這個項目最核心的功能。網格區域中有兩種顔色的網格,其中,藍色網格内的數字是應用為使用者提供的提示數字,白色網格則需要使用者根據數獨的規則合理填入數字,兩種格子的數量加起來共計64個。而現在我們面臨的問題是——我們如何将這個6x6的平面網格系統搭建起來呢?

    筆者的思路是,先設計網格區域的UI,再完善網格區域的互動邏輯。而本期将介紹的内容就是如何設計網格區域的UI。

    網格區域中共有36格子,那麼這些格子需要用什麼UI元件做呢?Button元件無疑可以嘗試一下。那麼我們接下來所要做的就是把Button元件設計成每一個格子,然後讓他們按一定的順序排起來,組成一個網格系統。由于格子的數量較多,是以我們不能用XML布局一個一個定義,這樣不僅效率慢,而且占用記憶體。而如果我們選擇使用Java代碼布局的話,我們就可以利用for循環來渲染button元件,以此做到高效簡潔。

    當然,我們還面臨另一個問題——設計好的格子應該通過什麼布局排起來呢?因為我們是通過for循環來生成格子的,在這樣的前提下,隻有坐标布局才能與for循環無縫融合。

   以下是通過代碼布局設計網格區域的UI的具體步驟。

完善GameAbilitySlice

 由于數獨小遊戲項目的遊戲界面是用GameAbilitySlice承載的,是以我們首先要完善之前新建立的GameAbilitySlice。打開GameAbilitySlice,将代碼修改為如下:

package com.example.project.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;

public class GameAbilitySlice extends AbilitySlice {

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);

    }


    @Override
    protected void onBackground() {
        super.onBackground();
    }
}      

這樣以後,GameAbilitySlice就繼承了AbilitySlice的類,并且它被寫入了onStart和onBackground兩個生命周期回調函數。

設計題目

在設計網格區域之前,我們需要先建立一個數獨題目(這樣之後每個格子的顔色和數字才能被确定),這個題目的資訊需要用資料承載。

在這裡,我們将利用數組的形式存儲數獨題目。定義一個6x6的數組——将代碼修改為如下:

package com.example.project.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;



public class GameAbilitySlice extends AbilitySlice {

    //定義一個數組
    int[][] grid_c0=new int[6][];



    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);

        //為數組指派
        grid_c0[0]=new int[]{0,0,0,0,1,0};
        grid_c0[1]=new int[]{1,0,2,4,0,0};
        grid_c0[2]=new int[]{6,2,3,0,0,5};
        grid_c0[3]=new int[]{5,0,0,2,3,6};
        grid_c0[4]=new int[]{0,6,4,3,5,0};
        grid_c0[5]=new int[]{3,1,0,5,0,4};
        
        
    }


    @Override
    protected void onBackground() {
        super.onBackground();
    }
}      

可以看出,我們首先在GameAbilitySlice的内部定義了一個列數為6的數組grid_c0(即數組每行有六個數字),然後我們又在onStart函數内部為這個數組的每一列(第0列到第五列)指派,這樣grid_co就可以寫成矩陣:

                                              0   1   6   5   0   3

                                              0   0   2   0   6   1

                                              0   2   3   0   4   0

                                              0   4   0   2   3   5

                                              1   0   0   3   5   0

                                              0   0   5   6   0   4

通過代碼布局的方式建立GameAbilitySlice的UI界面

首先,在onStart内(”為數組指派”的下方)加入下列代碼:

PositionLayout layout1=new PositionLayout(getContext());
        layout1.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
        layout1.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);      

這樣做的目的是——在onStart的方法内建立一個PositionLayout的對象。并且,這個對象的高度和寬度繼承了父元件(其父元件可以認為是手機螢幕)的尺寸。PositionLayout的中文名是坐标布局,它屬于一種容器元件[容器元件是用來放置其它常用子元件(如按鈕元件,文本元件)的]。我們這裡之是以用坐标布局,而不是用其它布局,是因為坐标布局可以用坐标(x,y)來确定其子元件的位置。相較于方向布局和依賴布局,坐标布局更加直覺和精确,這也是我們選用坐标布局的主要原因。

建立網格區域

首先,我們事先定義一些資料,以便在後面使用:

int x;
   int y;
   int number;
   String string0;      

接着,我們為Button元件建立兩種背景元素:

ShapeElement element0=new ShapeElement();
        element0.setRgbColor(new RgbColor(255,255,255));    //設定RGB顔色(白色)
        element0.setStroke(5,new RgbColor(0,0,0));                  //設定邊框的厚度和顔色(黑色)

        ShapeElement element3=new ShapeElement();
        element3.setRgbColor(new RgbColor(0,125,225));        //設定RGB顔色(藍色)
        element3.setStroke(5,new RgbColor(0,0,0));                 //設定邊框的厚度和顔色(黑色)      

于是,我們得到了element0和element3兩種背景元素,他們分别可以把Button元件裝飾成藍色網格狀和白色網格狀。

之後,我們通過雙重for循環來渲染Button元件,并在坐标布局的協助下,利用這些Button元件構成一個網格:

for (y=0;y<6;y++){
            for (x=0;x < 6; x++) {
                Button button = new Button(this);  //建立Button對象

                number=grid_c0[x][y];    //按照兩個for循環的序列對數組grid_c0取值(x代表grid_c0對應的行數,y代表grid_c0對應的列數)

                string0=String.valueOf(number);   
                button.setText(string0);           //将number由整形變量轉化為字元串,然後把它設定為button顯示的文字


                button.setTextColor(Color.WHITE);
                button.setTextSize(75);
                button.setComponentSize(160, 160);
//定義按鈕的尺寸,按鈕内文字的大小和顔色


                button.setContentPosition(65+160* x, 230+160*y);
//定義按鈕的位置,設位置為T,那麼T是關于x和y的函數

           

                if (number==0) {            //判斷number是否為0

                    button.setText("");
                    button.setBackground(element0);
                    button.setTextColor(Color.BLACK);
     //如果是0,button将不顯示任何文字,并且使用element0作為button的背景元素



                }else{
                    button.setBackground(element3);
    //如果不是0,button顯示文字,并且使用element3作為button的背景元素

                }

                layout1.addComponent(button);  //将button元件加入到坐标布局中


            }



        }      

這段代碼看起來稍微有點複雜,但隻要了解好代碼各層的邏輯關系,了解起來還是不費勁的。首先,我們設定了兩個for循環,可以看出,以y為變量的for循環嵌套着以x為變量的for循環,這意味着,變量x每完成一次0到5循環,變量y的值才加1,于是這兩個for循環會共同生成36個Button元件。

每生成一個Button元件時,系統都會根據這個元件在兩個for循環中對應的x和y值,對grid_c0進行取值,以及确定這個Button元件的坐标。這樣以後,網格區域每行每列的數字就能與grid_c0每行每列的數字對應起來(也就是跟數獨題目對應起來)。

接着,我們還加入了一個判斷條件,如果這個Button元件對grid_c0取到的數字為0,那麼它将作為待使用者填入數字的白色空白網格;如果這個Button元件對grid_c0取到的數字不是0(設其為t),那麼它将作為用于提示的藍色網格(這個網格将顯示數字t)。

最後,我們再加上如下代碼:

setUIContent(layout1);      

這樣以後,我們之前所建立的坐标布局對象layout1就被成功設定為GameAbilitySlice的UI架構了。

如果想檢視設計的UI效果,我們可以打開MainAbility,把setMainRoute方法内的InitialAbilitySlice修改為GameAbilitySlice(這樣就可以修改應用預設顯示的頁面)。當我們打開模拟機時,我們看到的第一個頁面就是GameAbilitySlice了。

效果圖如下:

【木棉花】#夏日挑戰賽# 鴻蒙小遊戲項目——數獨Sudoku

顯然,圖中網格區域中數字的分布與數組grid_c0的矩陣的數字排布一緻,隻不過,網格區域中的白色格子在矩陣中用數字0表示。

                                              0   1   6   5   0   3

                                              0   0   2   0   6   1

                                              0   2   3   0   4   0

                                              0   4   0   2   3   5

                                              1   0   0   3   5   0

                                              0   0   5   6   0   4

結尾

   本期的内容就先分享到這裡,更多關于數獨小遊戲項目精彩的内容我将在下期繼續為大家揭曉。

​​想了解更多關于開源的内容,請通路:​​

繼續閱讀