HarmonyOS(鸿蒙)运动手表第一个小游戏APP——黑白翻棋

  • 前言
  • 概述
  • 正文
    • 创建项目文件
    • 实现开始界面的布局
    • 实现题目的随机生成和色块的翻转
    • 实现游戏结束页面
    • 颜色代码介绍
  • 心得体会
  • 结语
  • 源代码

前言

此次博客是深鸿会博主(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);}
}

从零开发HarmonyOS(鸿蒙)运动手表小游戏——黑白翻棋相关推荐

  1. 黑白块游戏java代码_用java做的一个小游戏—黑白反斗棋(适合菜鸟)

    用Java做的一个小游戏,黑白反斗棋,我玩过了5*5和10*10的.是学习之后做的,不是自己原始开发的. import java.awt.Color; import java.awt.FlowLayo ...

  2. HarmonyOS应用开发实战 | 开发运动手表小游戏

    在学习完HarmonyOS应用开发文档后,有不少人进行了项目实践.下面本文将带大家从零开始完成鸿蒙小游戏App在运动手表上的编译,整体难度不高,属于入门级学习. 鸿蒙社区也非常期待大家的作品~ Har ...

  3. 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇)

    系列文章 手牵手,使用uni-app从零开发一款视频小程序 (系列上 准备工作篇) 手牵手,使用uni-app从零开发一款视频小程序 (系列下 开发实战篇) 前言 好久不见,很久没更新博客了,前段时间 ...

  4. html小游戏代码_研发实践:Mozilla分享如何开发一款WebVR小游戏

    文章相关引用及参考:mozvr 本文来自Mozilla的Josh Marinacci (映维网 2019年02月06日)在倡导新技术时,我总是尝试采用现实世界开发者的方式,而对于WebVR,开发一款游 ...

  5. 云开发谁是卧底线下小游戏发牌助手微信小程序源码-亲测可用

    云开发谁是卧底线下小游戏源码,发牌助手微信小程序源码. "谁是卧底OL"是一个非常有趣,风靡全国的比拼语言表述能力.知识面与想象力的游戏. 谁是卧底OL是一款由开发商北游科技倾力打 ...

  6. 视频教程-Layabox3D游戏开发入门-微信3D小游戏案例 -微信开发

    Layabox3D游戏开发入门-微信3D小游戏案例 有多年Unity程序开发经验,有策划和美术设计的经验.愿意在csdn这个平台和大家一起分享! 金龙 ¥29.00 立即订阅 扫码下载「CSDN程序员 ...

  7. 如何通过 LeanCloud 快速开发实时对战小游戏?

    实时对战是 LeanCloud 专门针对多人在线对战游戏推出的后端服务.开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配.在线对战消息同步等功能.本期直播课程我们将通过此服务来实现 ...

  8. 视频|如何通过 LeanCloud 快速开发实时对战小游戏

    实时对战是 LeanCloud 专门针对多人在线对战游戏推出的后端服务.开发者不需要自己搭建后端系统,利用云服务就可以轻松实现游戏内玩家匹配.在线对战消息同步等功能.本期直播课程我们将通过此服务来实现 ...

  9. Python 零代码的22个小游戏集合 freegames

    freegames 一.简介 简介:零代码的22个小游戏集合 作者:Grant Jenks 版本:2.4.0 安装: D:\>pip install freegames -i https://p ...

最新文章

  1. TOPCODER SAM 686 div1 300
  2. AJAX的post请求与上传文件
  3. 转载:python3 安装pycrypto
  4. windows 技术篇 - cmd命令查看当前目录下的所有文件和文件夹以及所有子目录下的文件,dir命令的使用方法
  5. MySQL事务的特性及事务隔离级别演示
  6. [蓝桥杯2018初赛]方格计数-巧妙枚举,找规,数论
  7. php三年经验 多少工资_PHP2年以上经验,在深圳工资能拿多少?
  8. springboot-21-maven多环境打包
  9. oracle中jason串,在oracle中使用json
  10. 离线语音控制系统 唤醒词.命令字
  11. 希腊字母发音,打印体手写体对照
  12. CentOS安装Nacos后,输入默认用户名和密码nacos/nacos,提示“用户名或密码错误”
  13. 如何让PPT给你的presentation加分
  14. 一种简单的生成伪随机数的方法(翻译)
  15. @keyup.enter.native
  16. 小半年的实习经历分享,希望对大家有用
  17. cpa考试专用计算机,cpa机考计算器
  18. php 替换表情符号,表情符号替换 – PHP
  19. Matlab和stk通过connector连接,win7下亲测好用
  20. 计算机辅助药物筛选教程,药物筛选之计算机辅助药物设计

热门文章

  1. MOS管的工作原理和区分
  2. python计算移动平均线_(转)简单移动平均线(Simple Moving Average,SMA) 定义及使用...
  3. linux卡在黑白进度条界面,linux启动画面、进度条问题
  4. 解决 ImportError: No module named 'serial' 问题
  5. 计算机设备内存,外部设备访问计算机内存的方法与流程
  6. Glide加载图片完成的回调
  7. 计算机二级vp是什么意思,全国计算机二级VP模拟试题.doc
  8. windows下删除EISA配置分区
  9. Chrome浏览器主页被劫持的解决
  10. 法院不能既判决驳回诉讼请求又告知当事人另行起诉