【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku(2) 原创 精华

木棉花_小蓝
发布于 2022-7-11 15:10
浏览
5收藏

「本文正在参加星光计划3.0--夏日挑战赛」

前言

    在上期内容的分享中,笔者介绍了如何搭建基础的页面框架(为之后的开发做准备),以及应用图像和标签的修改、应用的全屏化。而在本期,笔者就在上期的基础上继续展开数独小游戏项目的搭建。

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

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku(2)-鸿蒙开发者社区

正文

  本期,笔者将介绍如何利用代码布局创建网格区域的UI。

  首先,笔者所说的网格区域指的是下图被圈出的部分:

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku(2)-鸿蒙开发者社区     事实上,因为网格区域用于承载数独的题目,它同时也是玩家主要面向的部分,所以网格区域的逻辑就是这个项目最核心的功能。网格区域中有两种颜色的网格,其中,蓝色网格内的数字是应用为用户提供的提示数字,白色网格则需要用户根据数独的规则合理填入数字,两种格子的数量加起来共计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(2)-鸿蒙开发者社区

显然,图中网格区域中数字的分布与数组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

结尾

   本期的内容就先分享到这里,更多关于数独小游戏项目精彩的内容我将在下期继续为大家揭晓。

 【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku(2)-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-7-11 15:10:50修改
10
收藏 5
回复
举报
8条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

楼主是学了数独才这么优秀的吗?

回复
2022-7-11 18:46:41
wx6245597465b5f
wx6245597465b5f

优秀!

回复
2022-7-15 15:41:36
mb61e428166ecd8
mb61e428166ecd8

所以程序写得好,数学一定要很强吧

回复
2022-7-15 16:19:33
小威爱学习
小威爱学习

最打动我的是这个页面,看着真的太舒服了

回复
2022-7-15 16:45:07
木棉花_小蓝
木棉花_小蓝 回复了 mb61e428166ecd8
所以程序写得好,数学一定要很强吧

emm,这个不好说,但写程序是要用到数学思维的

回复
2022-7-28 13:11:31
SummerRic
SummerRic

数独小游戏可可可,期待下期。

回复
2022-7-28 14:10:14
wx65854328c160e
wx65854328c160e

怎么我效果出不来


回复
2024-6-15 19:30:25
木棉花_小蓝
木棉花_小蓝 回复了 wx65854328c160e
怎么我效果出不来

这个已经是远古代码了,Java已经被弃用了

回复
2024-6-23 10:07:14
回复
    相关推荐