前言

此次博客是深鸿会博主(Zzt_01-23)学习完HarmonyOS(鸿蒙)后,自行开发的第一个鸿蒙demo——黑白翻棋,详细讲述了黑白翻棋的编写思路,内含详细解释,适合刚入门的小白,使读者在观看完此次博客后能够自行开发第一个小游戏APP——黑白翻棋,文末附有本个demo源代码。本博主也欢迎与各位感兴趣的读者一起学习HarmonyOS(鸿蒙)开发。

概述

本个demo将从零开始完成鸿蒙小游戏APP在可穿戴设备上的编译,此处以运动手表为例,在项目中我们所使用到的软件为DevEco Studio,下载地址为:DevEco Studio下载,在项目中我们要实现的内容为黑白翻棋APP的开发。

  1. 在初始界面中显示7*7的棋盘,棋盘中黑白色块为随意打乱的,棋盘上面显示游戏翻转的次数,棋盘下方显示一个“重新开始”的按钮,为用户提供重新开始改游戏。
    图一
  2. 点击7*7棋盘中任一色块,其上下左右四个色块也会跟着一起变色(在边缘的色块则只会改变其中若干个色块的颜色),棋盘上方的当前步数则会相应依次增加。
    图二
  3. 经过若干次点击后,当所有的色块都为白色时,则会弹出游戏成功界面,此时再点击棋盘,不会有任何变化,点击“重新开始”的按钮时则会重新返回步骤1界面所示。
    图三

正文

创建项目文件

DevEco Studio下载成功后,点击左上角的File,点击New,再选择New Project,选择Lite Wearable选项,选择默认的模板,然后选择保存路径,将文件命名为MyGame(文件名不能出现中文或者特殊字符,否则将无法成功创建项目文件),如图所示。
图四
图六
主要编写的文件为index.css、index.hml和index.js,打开路径如图所示,index.hml用于描述页面中包含哪些组件,index.css用于描述页面中的组件都长什么样,index.js用于描述页面中的组件是如何进行交互的。
在这里插入图片描述

实现开始界面的布局

首先我们要先在运动手表上画出一个7*7的棋盘,色块颜色先设定为全是白色,棋盘上方显示“当前步数:0”,棋盘下方有一个“重新开始”的按钮,如图所示:
在这里插入图片描述

  1. 首先在index.hml文件中创建一个基础容器div类名为container
<div class="container" >
</div>

在此容器中间添加一个文字组件text类名为steps,并且写上显示的固定部分“当前步数:”,为动态变换部分赋予一个名为currentSteps的变量

<text class="steps">
        当前步数:{{currentSteps}}
    </text>

再添加一个画布组件canvas类名为canvas,增加一个引用属性ref,以便在此画布上画出7*7表格

<canvas class="canvas" ref="canvas" ></canvas>

最后添加一个普通按钮,类名为bit,并赋值“重新开始”

<input type="button" value="重新开始" class="bit" />

至此,index.hml文件已经全部编写完成了

<div class="container" >
    <text class="steps">
        当前步数:{{currentSteps}}
    </text>
    <canvas class="canvas" ref="canvas" ></canvas>
    <input type="button" value="重新开始" class="bit" />
</div>
  1. 在index.css编写刚才添加组件的样式,首先编写container的样式,flex-direction为容器主轴方向,选择column(垂直方向从上到下),justify-content为容器当前行的主轴对齐格式,选择center(项目位于容器的中心),align-items为容器当前行的交叉轴对齐格式,选择center(元素在交叉轴居中),width、height分别为容器以像素为单位的宽度和高度,都设定为450px
.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width:450px;
    height:450px;
}

编写steps的样式,font-size为设置文本的尺寸,设定为18px,text-align为设置文本的文本对齐方式,选择center(文本居中对齐),width、height分别设定为300px和20px,letter-spacing为设置文本的字符间距,设定为0px,margin-top为设置上外边距,设定为10px

.steps {
    font-size: 18px;
    text-align:center;
    width:300px;
    height:20px;
    letter-spacing:0px;
    margin-top:10px;
}

编写canvas的样式,width、height都设定为320px,background-color为设置背景颜色,设定为#BBADA0

.canvas{
    width:320px;
    height:320px;
    background-color: #BBADA0;
}

编写bit的样式,width、height分别设定为150px和30px,background-color设定为#AD9D8F,font-size设定为24px,margin-top设定为10px

.bit{
    width:150px;
    height:30px;
    background-color:#AD9D8F;
    font-size:24px;
    margin-top:10px;
}

至此,index.css文件已经全部编写完成了

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width:450px;
    height:450px;
}
.steps {
    font-size: 18px;
    text-align:center;
    width:300px;
    height:20px;
    letter-spacing:0px;
    margin-top:10px;
}
.canvas{
    width:320px;
    height:320px;
    background-color: #BBADA0;
}
.bit{
    width:150px;
    height:30px;
    background-color:#AD9D8F;
    font-size:24px;
    margin-top:10px;
}
  1. 在index.js编写描述页面中的组件是如何进行交互的,首先在data函数中为当前步数赋值为0
data: {
        currentSteps: 0,
    }

在文件开头定义一个全局变量量context,创建一个onReady()函数,用于定义2d绘画工具

var context;

onReady(){
        context=this.$refs.canvas.getContext('2d');
    }

用0表示白色,1代表黑色,这样我们就能定义一个用0和1表示键,颜色表示值的字典COLORS,并且定义全局常量边长SIDELEN为40,间距MARGIN为5,定义一个全局变量的二维数组grids,其中的值全为0

var grids=[[0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0]];

const SIDELEN=40;
const MARGIN=5;

const COLORS = {
    "0": "#FFFFFF",
    "1": "#000000"
}

创建drawGrids()函数,先将grids的值利用toString()函数全部转化为字符串,fillStyle表社画图的背景颜色,引用字典即可,fillRect表示画矩形的大小,其中有四个参数,第一个参数指定矩形左上角的x坐标,第二参数指定矩形左上角的y坐标,第三个参数指定矩形的高度,第四个参数指定矩形的宽度,最后创建onShow()调用drawGrids()函数即可

onShow(){
        this.drawGrids();
    },
    drawGrids(){
        for (let row = 0 ;row < 7 ;row++){
            for (let column = 0; column < 7;column++){
                let gridStr = grids[row][column].toString();

                context.fillStyle = COLORS[gridStr];
                let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;
                let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;
                context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);
            }
        }
    }

至此,index.js文件已经全部编写完成了,运行即可得出开始界面布局了

var grids=[[0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0]];

var context;

const SIDELEN=40;
const MARGIN=5;

const COLORS = {
    "0": "#FFFFFF",
    "1": "#000000"
}

export default {
    data: {
        currentSteps: 0,
    },
    onReady(){
        context=this.$refs.canvas.getContext('2d');
    },
    onShow(){
        this.drawGrids();
    },
    drawGrids(){
        for (let row = 0 ;row < 7 ;row++){
            for (let column = 0; column < 7;column++){
                let gridStr = grids[row][column].toString();

                context.fillStyle = COLORS[gridStr];
                let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;
                let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;
                context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);
            }
        }
    }
}

实现题目的随机生成和色块的翻转

其次我们要先在运动手表上随机生成一个色块被打乱的7*7的棋盘,并且点击棋盘中任一色块,其上下左右四个色块也会跟着一起变色(在边缘的色块则只会改变其中若干个色块的颜色),棋盘上方的当前步数则会相应依次增加,如图所示:
在这里插入图片描述
在这里插入图片描述
1.为了使点击任意一个色块时能得到其对应的二维数组的下标,我们需要给每个色块添加一个按钮button,并增加一个点击事件click,分别给这些按钮设定一个类名和点击按钮所调用的函数然后为了使按钮显示在棋盘格子的上方,需要添加一个栈stack类名设定位stack,使画布先进栈,按钮后进栈,这样就能达到预期效果了,index.hml代码如下:

<div class="container" >
    <text class="steps">
        当前步数:{{currentSteps}}
    </text>
    <stack class="stack">
        <canvas class="canvas" ref="canvas" ></canvas>

        <input type="button" class="bitgrid1"  onclick="getgrid1"/>
        <input type="button" class="bitgrid2"  onclick="getgrid2"/>
        <input type="button" class="bitgrid3"  onclick="getgrid3"/>
        <input type="button" class="bitgrid4"  onclick="getgrid4"/>
        <input type="button" class="bitgrid5"  onclick="getgrid5"/>
        <input type="button" class="bitgrid6"  onclick="getgrid6"/>
        <input type="button" class="bitgrid7"  onclick="getgrid7"/>
        <input type="button" class="bitgrid8"  onclick="getgrid8"/>
        <input type="button" class="bitgrid9"  onclick="getgrid9"/>
        <input type="button" class="bitgrid10"  onclick="getgrid10"/>
        <input type="button" class="bitgrid11"  onclick="getgrid11"/>
        <input type="button" class="bitgrid12"  onclick="getgrid12"/>
        <input type="button" class="bitgrid13"  onclick="getgrid13"/>
        <input type="button" class="bitgrid14"  onclick="getgrid14"/>
        <input type="button" class="bitgrid15"  onclick="getgrid15"/>
        <input type="button" class="bitgrid16"  onclick="getgrid16"/>
        <input type="button" class="bitgrid17"  onclick="getgrid17"/>
        <input type="button" class="bitgrid18"  onclick="getgrid18"/>
        <input type="button" class="bitgrid19"  onclick="getgrid19"/>
        <input type="button" class="bitgrid20"  onclick="getgrid20"/>
        <input type="button" class="bitgrid21"  onclick="getgrid21"/>
        <input type="button" class="bitgrid22"  onclick="getgrid22"/>
        <input type="button" class="bitgrid23"  onclick="getgrid23"/>
        <input type="button" class="bitgrid24"  onclick="getgrid24"/>
        <input type="button" class="bitgrid25"  onclick="getgrid25"/>
        <input type="button" class="bitgrid26"  onclick="getgrid26"/>
        <input type="button" class="bitgrid27"  onclick="getgrid27"/>
        <input type="button" class="bitgrid28"  onclick="getgrid28"/>
        <input type="button" class="bitgrid29"  onclick="getgrid29"/>
        <input type="button" class="bitgrid30"  onclick="getgrid30"/>
        <input type="button" class="bitgrid31"  onclick="getgrid31"/>
        <input type="button" class="bitgrid32"  onclick="getgrid32"/>
        <input type="button" class="bitgrid33"  onclick="getgrid33"/>
        <input type="button" class="bitgrid34"  onclick="getgrid34"/>
        <input type="button" class="bitgrid35"  onclick="getgrid35"/>
        <input type="button" class="bitgrid36"  onclick="getgrid36"/>
        <input type="button" class="bitgrid37"  onclick="getgrid37"/>
        <input type="button" class="bitgrid38"  onclick="getgrid38"/>
        <input type="button" class="bitgrid39"  onclick="getgrid39"/>
        <input type="button" class="bitgrid40"  onclick="getgrid40"/>
        <input type="button" class="bitgrid41"  onclick="getgrid41"/>
        <input type="button" class="bitgrid42"  onclick="getgrid42"/>
        <input type="button" class="bitgrid43"  onclick="getgrid43"/>
        <input type="button" class="bitgrid44"  onclick="getgrid44"/>
        <input type="button" class="bitgrid45"  onclick="getgrid45"/>
        <input type="button" class="bitgrid46"  onclick="getgrid46"/>
        <input type="button" class="bitgrid47"  onclick="getgrid47"/>
        <input type="button" class="bitgrid48"  onclick="getgrid48"/>
        <input type="button" class="bitgrid49"  onclick="getgrid49"/>
    </stack>
    <input type="button" value="重新开始" class="bit" />
</div>
  1. 编写stack的样式,width、height都设定为320px,margin-top设定为10px
.stack{
    width: 320px;
    height: 320px;
    margin-top: 10px;
}

分别编写每个按钮的样式,left为指示距边界框左上角的以像素为单位的水平坐标,top为指示距边界框左上角的以像素为单位的垂直坐标,border-color为设置边框颜色,transparent指透明颜色

.bitgrid1{
    left:5px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid2{
    left:50px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid3{
    left:95px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid4{
    left:140px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid5{
    left:185px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid6{
    left:230px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid7{
    left:275px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid8{
    left:5px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid9{
    left:50px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid10{
    left:95px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid11{
    left:140px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid12{
    left:185px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid13{
    left:230px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid14{
    left:275px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid15{
    left:5px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid16{
    left:50px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid17{
    left:95px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid18{
    left:140px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid19{
    left:185px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid20{
    left:230px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid21{
    left:275px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid22{
    left:5px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid23{
    left:50px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid24{
    left:95px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid25{
    left:140px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid26{
    left:185px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid27{
    left:230px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid28{
    left:275px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid29{
    left:5px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid30{
    left:50px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid31{
    left:95px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid32{
    left:140px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid33{
    left:185px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid34{
    left:230px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid35{
    left:275px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid36{
    left:5px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid37{
    left:50px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid38{
    left:95px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid39{
    left:140px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid40{
    left:185px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid41{
    left:230px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid42{
    left:275px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid43{
    left:5px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid44{
    left:50px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid45{
    left:95px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid46{
    left:140px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid47{
    left:185px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid48{
    left:230px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid49{
    left:275px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}

至此,增加的组件样式已经全部设定完毕了。
3. 先增加一个函数change(x,y),接受二维数组的下标,用来改变二维数字的值,当isShow为false才使二维数组的值发生变化,这样就能达到当游戏成功时再点击色块时颜色不再发生变化,如果值为0 则改为1,如果值为1则改为0,这样对应的色块颜色也能跟着发生变化

change(x,y){
        if(this.isShow==false){
            if(grids[x][y] == 0){
                grids[x][y] = 1;
            }else{
                grids[x][y] = 0;
            }
        }
    }

之后增加一个函数changeOneGrids(x,y),接受二维数组的下标,调用刚才编写的函数change(x,y),改变其上下左右四个色块对应的二维数组的值,并且调用函数drawGrids()重新画图实现颜色的变化,当isShow为false才使currentSteps加1,这样就能达到当游戏成功时再点击色块时currentSteps不再发生变化

changeOneGrids(x,y){
        if(x>-1 && y>-1 && x<7 && y<7){
            this.change(x,y);
        }
        if(x+1>-1 && y>-1 && x+1<7 && y<7){
            this.change(x+1,y);
        }
        if(x-1>-1 && y>-1 && x-1<7 && y<7){
            this.change(x-1,y);
        }
        if(x>-1 && y+1>-1 && x<7 && y+1<7){
            this.change(x,y+1);
        }
        if(x>-1 && y-1>-1 && x<7 && y-1<7){
            this.change(x,y-1);
        }
        this.drawGrids();

        if(this.isShow==false){
            this.currentSteps+=1;;
        }
    }

再编写49个按钮对应的49个函数,作用是读取当前二维数组位置的下标,并且调用函数changeOneGrids(x,y)

 getgrid1(){
        this.changeOneGrids(0,0);
    },
    getgrid2(){
        this.changeOneGrids(0,1);
    },
    getgrid3(){
        this.changeOneGrids(0,2);
    },
    getgrid4(){
        this.changeOneGrids(0,3);
    },
    getgrid5(){
        this.changeOneGrids(0,4);
    },
    getgrid6(){
        this.changeOneGrids(0,5);
    },
    getgrid7(){
        this.changeOneGrids(0,6);
    },
    getgrid8(){
        this.changeOneGrids(1,0);
    },
    getgrid9(){
        this.changeOneGrids(1,1);
    },
    getgrid10(){
        this.changeOneGrids(1,2);
    },
    getgrid11(){
        this.changeOneGrids(1,3);
    },
    getgrid12(){
        this.changeOneGrids(1,4);
    },
    getgrid13(){
        this.changeOneGrids(1,5);
    },
    getgrid14(){
        this.changeOneGrids(1,6);
    },
    getgrid15(){
        this.changeOneGrids(2,0);
    },
    getgrid16(){
        this.changeOneGrids(2,1);
    },
    getgrid17(){
        this.changeOneGrids(2,2);
    },
    getgrid18(){
        this.changeOneGrids(2,3);
    },
    getgrid19(){
        this.changeOneGrids(2,4);
    },
    getgrid20(){
        this.changeOneGrids(2,5);
    },
    getgrid21(){
        this.changeOneGrids(2,6);
    },
    getgrid22(){
        this.changeOneGrids(3,0);
    },
    getgrid23(){
        this.changeOneGrids(3,1);
    },
    getgrid24(){
        this.changeOneGrids(3,2);
    },
    getgrid25(){
        this.changeOneGrids(3,3);
    },
    getgrid26(){
        this.changeOneGrids(3,4);
    },
    getgrid27(){
        this.changeOneGrids(3,5);
    },
    getgrid28(){
        this.changeOneGrids(3,6);
    },
    getgrid29(){
        this.changeOneGrids(4,0);
    },
    getgrid30(){
        this.changeOneGrids(4,1);
    },
    getgrid31(){
        this.changeOneGrids(4,2);
    },
    getgrid32(){
        this.changeOneGrids(4,3);
    },
    getgrid33(){
        this.changeOneGrids(4,4);
    },
    getgrid34(){
        this.changeOneGrids(4,5);
    },
    getgrid35(){
        this.changeOneGrids(4,6);
    },
    getgrid36(){
        this.changeOneGrids(5,0);
    },
    getgrid37(){
        this.changeOneGrids(5,1);
    },
    getgrid38(){
        this.changeOneGrids(5,2);
    },
    getgrid39(){
        this.changeOneGrids(5,3);
    },
    getgrid40(){
        this.changeOneGrids(5,4);
    },
    getgrid41(){
        this.changeOneGrids(5,5);
    },
    getgrid42(){
        this.changeOneGrids(5,6);
    },
    getgrid43(){
        this.changeOneGrids(6,0);
    },
    getgrid44(){
        this.changeOneGrids(6,1);
    },
    getgrid45(){
        this.changeOneGrids(6,2);
    },
    getgrid46(){
        this.changeOneGrids(6,3);
    },
    getgrid47(){
        this.changeOneGrids(6,4);
    },
    getgrid48(){
        this.changeOneGrids(6,5);
    },
    getgrid49(){
        this.changeOneGrids(6,6);
    }

最后是随机生成一个色块被打乱的7 7的棋盘,首先我们得先把二维数组的下标放进一个列表中,Math.random()函数是随机[0,1)内的小数,Math.floor(x)为得出小于或等于x的最大整数,每次随机生成一个数后,读取刚才的列表对应的下标,调用函数changeOneGrids(x,y),重复此操作若干次,这样就能随机生成一个色块被打乱的7*7的棋盘

initGrids(){
        let array = [];
        for (let row = 0; row < 7; row++) {
            for (let column = 0; column < 7; column++) {
                if (grids[row][column] == 0) {
                    array.push([row, column])
                }
            }
        }
        for (let i = 0; i < 20; i++){
            let randomIndex = Math.floor(Math.random() * array.length);
            let row = array[randomIndex][0];
            let column = array[randomIndex][1];
            this.changeOneGrids(row,column);
        }
    }

至此,这一部分内容已经全部编写完毕。

实现游戏结束页面

最后我们要实现当色块的颜色全部为白色时弹出游戏成功界面,并使按钮“重新开始”能够重新随机生成随机生成一个色块被打乱的7*7的棋盘,当前步数置为0,如图所示:
在这里插入图片描述

  1. 首先我们得在栈stack组件中增加一个游戏成功的容器div类名为subcontainer,以isShow控制该容器是否进栈,增加文本组件text,类名gameover,并赋值“游戏成功”
<div class="subcontainer" show="{{isShow}}">
            <text class="gameover">
                游戏成功
            </text>
        </div>

再为重新开始按钮增加一个点击事件click,所调用的函数为restartGame

<input type="button" value="重新开始" class="bit" onclick="restartGame"/>

至此所有组件全部添加完毕。
2. 编写刚才增加组件的样式,编写subcontainer的样式

.subcontainer {
    left:50px;
    top:95px;
    width: 220px;
    height: 130px;
    justify-content: center;
    align-items: center;
    background-color: #E9C2A6;
}

编写gameover的样式

.gameover {
    font-size: 38px;
    color: black;
}

至此所有组件已定义好样式了。
3.首先给isShow赋值false,将开头的全局变量grids赋值删除,增加一个函数给grids赋值,并调用函数initGrids()

var grids;

data: {
        currentSteps: 0,
        isShow: false
    }
    
onInit() {
        grids=[[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]];

        this.initGrids();
    }

增加一个函数gameover(),当棋盘所有色块颜色为白色时返回true,否则返回false,即当二维数组的值全为0时返回true,否则返回false

 gameover(){
        for (let row = 0 ;row < 7 ;row++){
            for (let column = 0; column < 7;column++){
                if (grids[row][column]==1){
                    return false;
                }
            }
        }
        return true;
    }

在函数changeOneGrids(x,y)中添加当函数gameover()为true时,将isShow赋值为true,使游戏成功界面显示在最上方,并使所有二维数组grids值赋值为6,字典中增加一个6对应白色,这样就能达到当游戏成功时再点击色块并不会发生任何变化,当函数gameover()为false时,步数增加1

const COLORS = {
    "0": "#FFFFFF",
    "1": "#000000"
}

changeOneGrids(x,y){
        if(x>-1 && y>-1 && x<7 && y<7){
            this.change(x,y);
        }
        if(x+1>-1 && y>-1 && x+1<7 && y<7){
            this.change(x+1,y);
        }
        if(x-1>-1 && y>-1 && x-1<7 && y<7){
            this.change(x-1,y);
        }
        if(x>-1 && y+1>-1 && x<7 && y+1<7){
            this.change(x,y+1);
        }
        if(x>-1 && y-1>-1 && x<7 && y-1<7){
            this.change(x,y-1);
        }
        this.drawGrids();

        if(this.isShow==false){
            this.currentSteps+=1;;
        }
        if(this.gameover()){
            this.isShow=true;
        }
    }

最后编写重新按钮对应的函数restartGame(),作用是是二维数组、isShow和当前步数全部置为初始化界面

restartGame(){
        this.onInit();
        this.drawGrids();
        this.isShow = false;
        this.currentSteps = 0;
    }

至此,整个demo全部完成了。

颜色代码介绍

DevEco Studio颜色代码是以十六进制RGB值表示的,前两位数字代表红色值,中间两位代表绿色值,最后两位代表蓝色值,每个红色、绿色或蓝色值可以在00(没有那种颜色)到FF(完全是那种颜色)之间变化,另外,透明是transparent。常见部分颜色代码如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

心得体会

本个demo整体难度不高,涉及的组件或样式都是很常见的,需要掌握栈、按钮、画布等组件即可完成编写,组件交互采用二维数组与字典串连整个项目,十分适合刚入门的读者编写与学习,其中组件学习可以前往官方文档查看更详细的介绍:官方文档

结语

本次项目为博主仅用三天全部编写完成的,感兴趣的读者可以自行跟着本博客编写,相信你们也能够完成的。如果有遇到什么问题,或者查找出其中的错误之处,欢迎留言。

源代码

index.hml如下:

<div class="container" >
    <text class="steps">
        当前步数:{{currentSteps}}
    </text>
    <stack class="stack">
        <canvas class="canvas" ref="canvas" ></canvas>
        <div class="subcontainer" show="{{isShow}}">
            <text class="gameover">
                游戏成功
            </text>
        </div>

        <input type="button" class="bitgrid1"  onclick="getgrid1"/>
        <input type="button" class="bitgrid2"  onclick="getgrid2"/>
        <input type="button" class="bitgrid3"  onclick="getgrid3"/>
        <input type="button" class="bitgrid4"  onclick="getgrid4"/>
        <input type="button" class="bitgrid5"  onclick="getgrid5"/>
        <input type="button" class="bitgrid6"  onclick="getgrid6"/>
        <input type="button" class="bitgrid7"  onclick="getgrid7"/>
        <input type="button" class="bitgrid8"  onclick="getgrid8"/>
        <input type="button" class="bitgrid9"  onclick="getgrid9"/>
        <input type="button" class="bitgrid10"  onclick="getgrid10"/>
        <input type="button" class="bitgrid11"  onclick="getgrid11"/>
        <input type="button" class="bitgrid12"  onclick="getgrid12"/>
        <input type="button" class="bitgrid13"  onclick="getgrid13"/>
        <input type="button" class="bitgrid14"  onclick="getgrid14"/>
        <input type="button" class="bitgrid15"  onclick="getgrid15"/>
        <input type="button" class="bitgrid16"  onclick="getgrid16"/>
        <input type="button" class="bitgrid17"  onclick="getgrid17"/>
        <input type="button" class="bitgrid18"  onclick="getgrid18"/>
        <input type="button" class="bitgrid19"  onclick="getgrid19"/>
        <input type="button" class="bitgrid20"  onclick="getgrid20"/>
        <input type="button" class="bitgrid21"  onclick="getgrid21"/>
        <input type="button" class="bitgrid22"  onclick="getgrid22"/>
        <input type="button" class="bitgrid23"  onclick="getgrid23"/>
        <input type="button" class="bitgrid24"  onclick="getgrid24"/>
        <input type="button" class="bitgrid25"  onclick="getgrid25"/>
        <input type="button" class="bitgrid26"  onclick="getgrid26"/>
        <input type="button" class="bitgrid27"  onclick="getgrid27"/>
        <input type="button" class="bitgrid28"  onclick="getgrid28"/>
        <input type="button" class="bitgrid29"  onclick="getgrid29"/>
        <input type="button" class="bitgrid30"  onclick="getgrid30"/>
        <input type="button" class="bitgrid31"  onclick="getgrid31"/>
        <input type="button" class="bitgrid32"  onclick="getgrid32"/>
        <input type="button" class="bitgrid33"  onclick="getgrid33"/>
        <input type="button" class="bitgrid34"  onclick="getgrid34"/>
        <input type="button" class="bitgrid35"  onclick="getgrid35"/>
        <input type="button" class="bitgrid36"  onclick="getgrid36"/>
        <input type="button" class="bitgrid37"  onclick="getgrid37"/>
        <input type="button" class="bitgrid38"  onclick="getgrid38"/>
        <input type="button" class="bitgrid39"  onclick="getgrid39"/>
        <input type="button" class="bitgrid40"  onclick="getgrid40"/>
        <input type="button" class="bitgrid41"  onclick="getgrid41"/>
        <input type="button" class="bitgrid42"  onclick="getgrid42"/>
        <input type="button" class="bitgrid43"  onclick="getgrid43"/>
        <input type="button" class="bitgrid44"  onclick="getgrid44"/>
        <input type="button" class="bitgrid45"  onclick="getgrid45"/>
        <input type="button" class="bitgrid46"  onclick="getgrid46"/>
        <input type="button" class="bitgrid47"  onclick="getgrid47"/>
        <input type="button" class="bitgrid48"  onclick="getgrid48"/>
        <input type="button" class="bitgrid49"  onclick="getgrid49"/>
    </stack>
    <input type="button" value="重新开始" class="bit" onclick="restartGame"/>
</div>

index.css如下:

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width:450px;
    height:450px;
}
.steps {
    font-size: 18px;
    text-align:center;
    width:300px;
    height:20px;
    letter-spacing:0px;
    margin-top:10px;
}
.stack{
    width: 320px;
    height: 320px;
    margin-top: 10px;
}.canvas{
    width:320px;
    height:320px;
    background-color: #BBADA0;
}
.subcontainer {
    left:50px;
    top:95px;
    width: 220px;
    height: 130px;
    justify-content: center;
    align-items: center;
    background-color:#E9C2A6;
}
.gameover {
    font-size: 38px;
    color: black;
}
.bit{
    width:150px;
    height:30px;
    background-color:#AD9D8F;
    font-size:24px;
    margin-top:10px;
}
.bitgrid1{
    left:5px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid2{
    left:50px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid3{
    left:95px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid4{
    left:140px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid5{
    left:185px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid6{
    left:230px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid7{
    left:275px;
    top:5px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid8{
    left:5px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid9{
    left:50px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid10{
    left:95px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid11{
    left:140px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid12{
    left:185px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid13{
    left:230px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid14{
    left:275px;
    top:50px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid15{
    left:5px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid16{
    left:50px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid17{
    left:95px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid18{
    left:140px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid19{
    left:185px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid20{
    left:230px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid21{
    left:275px;
    top:95px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid22{
    left:5px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid23{
    left:50px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid24{
    left:95px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid25{
    left:140px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid26{
    left:185px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid27{
    left:230px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid28{
    left:275px;
    top:140px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid29{
    left:5px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid30{
    left:50px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid31{
    left:95px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid32{
    left:140px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid33{
    left:185px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid34{
    left:230px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid35{
    left:275px;
    top:185px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid36{
    left:5px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid37{
    left:50px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid38{
    left:95px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid39{
    left:140px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid40{
    left:185px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid41{
    left:230px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid42{
    left:275px;
    top:230px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid43{
    left:5px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid44{
    left:50px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid45{
    left:95px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid46{
    left:140px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;

}
.bitgrid47{
    left:185px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid48{
    left:230px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}
.bitgrid49{
    left:275px;
    top:275px;
    width:40px;
    height:40px;
    border-color:transparent;
    background-color:transparent;
}


index.js如下:

var grids;
var context;

const SIDELEN=40;
const MARGIN=5;

const COLORS = {
    "0": "#FFFFFF",
    "1": "#000000"
}

export default {
    data: {
        currentSteps: 0,
        isShow: false
    },
    onInit() {
        grids=[[0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0]];

        this.initGrids();
    },
    initGrids(){
        let array = [];
        for (let row = 0; row < 7; row++) {
            for (let column = 0; column < 7; column++) {
                if (grids[row][column] == 0) {
                    array.push([row, column])
                }
            }
        }
        for (let i = 0; i < 20; i++){
            let randomIndex = Math.floor(Math.random() * array.length);
            let row = array[randomIndex][0];
            let column = array[randomIndex][1];
            this.changeOneGrids(row,column);
        }
    },
    onReady(){
        context=this.$refs.canvas.getContext('2d');
    },
    onShow(){
        this.drawGrids();
    },
    drawGrids(){
        for (let row = 0 ;row < 7 ;row++){
            for (let column = 0; column < 7;column++){
                let gridStr = grids[row][column].toString();

                context.fillStyle = COLORS[gridStr];
                let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;
                let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;
                context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);
            }
        }
    },
   change(x,y){
        if(this.isShow==false){
            if(grids[x][y] == 0){
                grids[x][y] = 1;
            }else{
                grids[x][y] = 0;
            }
        }
    },
    changeOneGrids(x,y){
        if(x>-1 && y>-1 && x<7 && y<7){
            this.change(x,y);
        }
        if(x+1>-1 && y>-1 && x+1<7 && y<7){
            this.change(x+1,y);
        }
        if(x-1>-1 && y>-1 && x-1<7 && y<7){
            this.change(x-1,y);
        }
        if(x>-1 && y+1>-1 && x<7 && y+1<7){
            this.change(x,y+1);
        }
        if(x>-1 && y-1>-1 && x<7 && y-1<7){
            this.change(x,y-1);
        }
        this.drawGrids();
        
        if(this.isShow==false){
            this.currentSteps+=1;;
        }
        if(this.gameover()){
            this.isShow=true;
        }
    },
    gameover(){
        for (let row = 0 ;row < 7 ;row++){
            for (let column = 0; column < 7;column++){
                if (grids[row][column]==1){
                    return false;
                }
            }
        }
        return true;
    },
    restartGame(){
        this.onInit();
        this.drawGrids();
        this.isShow = false;
        this.currentSteps = 0;
    },
    getgrid1(){
        this.changeOneGrids(0,0);
    },
    getgrid2(){
        this.changeOneGrids(0,1);
    },
    getgrid3(){
        this.changeOneGrids(0,2);
    },
    getgrid4(){
        this.changeOneGrids(0,3);
    },
    getgrid5(){
        this.changeOneGrids(0,4);
    },
    getgrid6(){
        this.changeOneGrids(0,5);
    },
    getgrid7(){
        this.changeOneGrids(0,6);
    },
    getgrid8(){
        this.changeOneGrids(1,0);
    },
    getgrid9(){
        this.changeOneGrids(1,1);
    },
    getgrid10(){
        this.changeOneGrids(1,2);
    },
    getgrid11(){
        this.changeOneGrids(1,3);
    },
    getgrid12(){
        this.changeOneGrids(1,4);
    },
    getgrid13(){
        this.changeOneGrids(1,5);
    },
    getgrid14(){
        this.changeOneGrids(1,6);
    },
    getgrid15(){
        this.changeOneGrids(2,0);
    },
    getgrid16(){
        this.changeOneGrids(2,1);
    },
    getgrid17(){
        this.changeOneGrids(2,2);
    },
    getgrid18(){
        this.changeOneGrids(2,3);
    },
    getgrid19(){
        this.changeOneGrids(2,4);
    },
    getgrid20(){
        this.changeOneGrids(2,5);
    },
    getgrid21(){
        this.changeOneGrids(2,6);
    },
    getgrid22(){
        this.changeOneGrids(3,0);
    },
    getgrid23(){
        this.changeOneGrids(3,1);
    },
    getgrid24(){
        this.changeOneGrids(3,2);
    },
    getgrid25(){
        this.changeOneGrids(3,3);
    },
    getgrid26(){
        this.changeOneGrids(3,4);
    },
    getgrid27(){
        this.changeOneGrids(3,5);
    },
    getgrid28(){
        this.changeOneGrids(3,6);
    },
    getgrid29(){
        this.changeOneGrids(4,0);
    },
    getgrid30(){
        this.changeOneGrids(4,1);
    },
    getgrid31(){
        this.changeOneGrids(4,2);
    },
    getgrid32(){
        this.changeOneGrids(4,3);
    },
    getgrid33(){
        this.changeOneGrids(4,4);
    },
    getgrid34(){
        this.changeOneGrids(4,5);
    },
    getgrid35(){
        this.changeOneGrids(4,6);
    },
    getgrid36(){
        this.changeOneGrids(5,0);
    },
    getgrid37(){
        this.changeOneGrids(5,1);
    },
    getgrid38(){
        this.changeOneGrids(5,2);
    },
    getgrid39(){
        this.changeOneGrids(5,3);
    },
    getgrid40(){
        this.changeOneGrids(5,4);
    },
    getgrid41(){
        this.changeOneGrids(5,5);
    },
    getgrid42(){
        this.changeOneGrids(5,6);
    },
    getgrid43(){
        this.changeOneGrids(6,0);
    },
    getgrid44(){
        this.changeOneGrids(6,1);
    },
    getgrid45(){
        this.changeOneGrids(6,2);
    },
    getgrid46(){
        this.changeOneGrids(6,3);
    },
    getgrid47(){
        this.changeOneGrids(6,4);
    },
    getgrid48(){
        this.changeOneGrids(6,5);
    },
    getgrid49(){
        this.changeOneGrids(6,6);
    }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐