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

木棉花_小蓝
发布于 2022-7-27 21:40
浏览
2收藏

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

前言

  在上期的分享中,笔者详细介绍了如何利用代码布局创建网格区域的UI。而在这期的分享中,笔者将围绕网格区域增加相应的游戏功能。

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

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

 

正文

本期,笔者将详细介绍游戏的一个重要功能——数字填入的制作方法。

这个功能的制作分为两部分。第一个部分是让白色的Button组件(即网格区域中的白色方格)在被用户点击的情况下能获得焦点,效果图如下:

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku(3)-鸿蒙开发者社区图中橙色的格子代表这个Button组件处于焦点状态(此方格是最后一个被用户点击的Button组件),可供用户输入数字。显然,这样做的好处在于定位用户想要交互的网格,以方便用户执行数字填入的操作。

第二个部分则是提供数字填入的按钮以及增加填入数字的逻辑代码,效果图如下:

【木棉花】#夏日挑战赛# 鸿蒙小游戏项目——数独Sudoku(3)-鸿蒙开发者社区图中,笔者先是点击了网格区域中第二行第一列的白色格子,然后再点击标有数字5的圆形按钮,于是第二行第一列的格子内便生成数字5。如果点击其他圆形按钮,那么方格内就会生成其他数字。

下面笔者将介绍具体的步骤。

 

让白色方格能通过点击获得焦点

首先,我们先定义一个新的ShapeElement对象,在网格区域中的某个白色的Button组件获得焦点后,这个Button组件就会使用此ShapeElement对象定义背景元素(即变成橙色):

 ShapeElement element1=new ShapeElement();
        element1.setRgbColor(new RgbColor(255,125,0));    //将RGB的颜色设置为橙色
        element1.setStroke(12,new RgbColor(0,0,0));

接着,我们先在GameAbilitySlice中找到上期写入的二重for循环的代码

        for (y=0;y<6;y++){
            for (x=0;x < 6; x++) {
                Button button = new Button(this);

                number=grid_c0[x][y];

                string0=String.valueOf(number);
                button.setText(string0);

                button.setTextColor(Color.WHITE);
                button.setTextSize(75);
                button.setComponentSize(160, 160);

                button.setContentPosition(65+160* x, 230+160*y);

                if (number==0) {
                    button.setText("");

                    button.setBackground(element0);
                    button.setTextColor(Color.BLACK);

                }else{
                    button.setBackground(element3);

                }
                layout1.addComponent(button);


            }



        }

这段代码是本项目中非常重要的代码,他相当于整个游戏的基本框架。在后期的功能制作中,笔者将基于这个二重for循环的框架增加许多逻辑代码。

这里,我们在这段代码的基础上增加一些代码:

 for (y=0;y<6;y++){
            for (x=0;x < 6; x++) {
                Button button = new Button(this);
              
              //将组件设置为可触摸获得焦点  
                button.setTouchFocusable(true);

     
                button.setTextColor(Color.WHITE);
                button.setTextSize(75);
                button.setComponentSize(160, 160);

                button.setContentPosition(65+160* x, 230+160*y);

                if (number==0) {
                    button.setText("");

                    button.setBackground(element0);
                    button.setTextColor(Color.BLACK);

            

//设置焦点感知监听器
                    button.setComponentStateChangedListener(new Component.ComponentStateChangedListener() {
                        @Override
                        public void onComponentStateChanged(Component component, int i) {
                            if (ComponentState.isStateMatched(ComponentState.COMPONENT_STATE_FOCUSED,i)){
                                button.setBackground(element1);
                            }else{
                                button.setBackground(element0);
                            }
                        }
                    });


                }else{
                    button.setBackground(element3);

                }
                layout1.addComponent(button);


            }



        }

在上述代码中,笔者首先将for循环中的Button对象设置为可通过触摸获得焦点,接着在if的一个判断分路(number==0)中加入组件状态感知监听器:当某个满足number=0的Button组件(即网格区域中的白色方格)获得焦点时,它将改用element1作为背景元素;当它失去焦点时,它重新将element0作为其背景元素。

 

打开模拟机,便可查看相应的效果:

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

 

提供数字填入的按钮以及增加填入数字的逻辑代码

首先,我们先创建两个Button对象:

        button_temp = new Button(this);//用于数字输入
        button_empty=new Button(this);  //用于取消焦点


        for (y=0;y<6;y++){
            for (x=0;x < 6; x++) {

               ...
          
         }
    }

 

之后,我们还需要在二重for循环的内部写入相应代码:

 for (y=0;y<6;y++){
            for (x=0;x < 6; x++) {
                Button button = new Button(this);
              
                button.setTouchFocusable(true);
     
                button.setTextColor(Color.WHITE);
                button.setTextSize(75);
                button.setComponentSize(160, 160);

                button.setContentPosition(65+160* x, 230+160*y);

                if (number==0) {
                    button.setText("");

                    button.setBackground(element0);
                    button.setTextColor(Color.BLACK);

//设置button的点击监听器
                 button.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {

//当某个Button对象被点击时,这个Button对象将被赋给button_temp
                            button_temp = button;

                        }
                    });
            
                    button.setComponentStateChangedListener(new Component.ComponentStateChangedListener() {
                        @Override
                        public void onComponentStateChanged(Component component, int i) {
                            if (ComponentState.isStateMatched(ComponentState.COMPONENT_STATE_FOCUSED,i)){
                                button.setBackground(element1);
                            }else{
                                button.setBackground(element0);
                            }
                        }
                    });


                }else{
                    button.setBackground(element3);

//设置Button对象的点击监听器
               button.setClickedListener(new Component.ClickedListener() {
                        @Override
                        public void onClick(Component component) {
//当某个Button对象被点击时,这个Button对象将被赋给button_empty
                            button_temp=button_empty;
                        }

                    });
                }
                layout1.addComponent(button);


            }



        }

在这次的修改中,我们为网格区域的白色网格与蓝色网格分别增加了两个监听器,使得这两种类型的网格被点击时,button_temp或者button_empty被赋予所点击的Button对象。

 

接着,我们需要在GameAbilitySlice的UI界面加入6个圆形按钮:

先创建这6个按钮的背景元素:

        ShapeElement element2=new ShapeElement();
        element2.setRgbColor(new RgbColor(255,255,255));
        element2.setShape(ShapeElement.OVAL);        //将组件形状设置为圆形
        element2.setStroke(10,new RgbColor(0,125,225));

 

然后,我们利用代码布局创建6个button对象,代码如下:

        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");
            
            }
        });
        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");
             
            }
        });
        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");
              
            }
        });
        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");
             
            }
        });
        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");
                  }
        });
        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");
            }
        });
        layout1.addComponent(button_input6);

虽然这段代码看起来很长,但实际上每个Button对象的代码模板都是一样的。在这段代码中,每个Button对象都定义了6个属性和一个监听器,这6个属性包括——组件显示的文本(Text)组件的显示的文本的颜色(TextColor)组件的显示的文本的大小(TextSize)组件的背景元素(Background)组件的尺寸(ComponentSize)组件的坐标(Position),而监听器中设置的执行事件则是为button_temp定义文本内容(即在白色方格上生成数字)。可以看出,每个圆形按钮的点击监听器中的指令都是面向button_temp的,而button_temp又取决于用户所点击的网格区域的button组件。所以笔者在创建button_temp与button_empty时,并没有定义它们的属性,button_temp的作用是作为数字输入的桥梁,而button_empty的作用则是防止用户点击网格区域的蓝色网格时,上一个获得焦点的白色网格仍然可以输入这么一个BUG。

 

我们再重新捋一捋数字输入的逻辑:

首先,我们随机点击网格区域中的一个白色Button对象(即白色方格),这个白色Button对象获得焦点变成橙色,并且这个白色Button对象被赋给了button_temp(即button_temp=button);之后,我们点击标有数字5的圆形按钮,则button_temp的显示文本内容被设置成“5”,又因为:button_temp=button,所以前面的操作等价于将获得焦点的Button对象(即橙色方格)的显示文本内容设置成“5”,于是我们可以在模拟机上看到,橙色的格子生成数字5。当我们点击其他白色方格或者蓝色方格时,原先处于焦点状态的橙色方格因为失去焦点,颜色恢复为白色。

 

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

结尾

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

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

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

这章学习了获得焦点,填入数字两个操作,下章会是什么呢?(无奖竞猜)

回复
2022-7-28 10:37:24
木棉花_小蓝
木棉花_小蓝 回复了 红叶亦知秋
这章学习了获得焦点,填入数字两个操作,下章会是什么呢?(无奖竞猜)

我也还在想着qwq

回复
2022-7-28 13:09:48
Luxiaoyuyuyu
Luxiaoyuyuyu

mark

回复
2022-7-28 15:21:04
回复
    相关推荐