8

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku

 2 years ago
source link: https://blog.51cto.com/harmonyos/5471009
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku

推荐 原创

开源基础软件社区官方 2022-07-14 10:48:52 ©著作权

文章标签 木棉花 鸿蒙 文章分类 HarmonyOS 编程语言 阅读数324

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

前言

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

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

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku_木棉花

正文

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

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

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku_木棉花_02

     事实上,因为网格区域用于承载数独的题目,它同时也是玩家主要面向的部分,所以网格区域的逻辑就是这个项目最核心的功能。网格区域中有两种颜色的网格,其中,蓝色网格内的数字是应用为用户提供的提示数字,白色网格则需要用户根据数独的规则合理填入数字,两种格子的数量加起来共计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_木棉花_03

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

结尾

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

 ​想了解更多关于开源的内容,请访问:​

 ​51CTO 开源基础软件社区​

 ​https://ost.51cto.com/#bkwz​


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK