手表游戏—黑白翻棋 之 学习笔记(前篇)

开发 前端
去年我们木棉花组织发过一篇文章“HarmonyOS手表游戏——黑白翻棋”,本文是我对该文章的一个学习笔记,随着IDE的升级,一些代码也需要作修改。以下是我的学习笔记及部分代码的修改O(∩_∩)O

[[424571]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

去年我们木棉花组织发过一篇文章“HarmonyOS手表游戏——黑白翻棋”,本文是我对该文章的一个学习笔记,随着IDE的升级,一些代码也需要作修改。以下是我的学习笔记及部分代码的修改O(∩_∩)O

源代码请移步至→原文章地址

概述

正文内容只展示部分代码,完整代码可以下载附件(附件1是源代码的代码更新)。效果图如下:

【木棉花】:手表游戏——黑白翻棋 之 学习笔记(前篇)-鸿蒙HarmonyOS技术社区
【木棉花】:手表游戏——黑白翻棋 之 学习笔记(前篇)-鸿蒙HarmonyOS技术社区

正文

1.创建一个空白的工程

DevEco Studio下载安装成功后,打开DevEco Studio,点击左上角的File,点击New,再选择New Project,选择Empty Ability(JS),然后点击Next,给项目命名WatchGame_BW,选择设备类型Wearable,最后点击Finish。

【木棉花】:手表游戏——黑白翻棋 之 学习笔记(前篇)-鸿蒙HarmonyOS技术社区

2.界面布局

通过效果图可见,初始布局分三个部分,由上至下分别是文本框、棋盘(画布组件)、按钮;游戏成功的布局有四个部分:文本框、棋盘(画布组件)、游戏成功界面、按钮。(完整代码及解释可以去看原文章)

这里记几个小要点:

1.当前步数显示的是一个动态的值,不是一个固定的值,这里以动态变量currentSteps来显示数据

2.游戏成功的文本框是显示在画布组件之上的(覆盖),而不是在画布组件的下方。该实现可通过添加一个堆叠容器stack,将游戏成功的文本组件放在画布组件之后

3.“游戏成功”的显示在初始时不会显示,所以要设置属性show,对应设一个布尔型变量isShow,并令isShow的初始值为假,游戏成功时其值为真,当为真时就可以显示了

  1. <div class="container"
  2.     <text class="steps"
  3.         当前步数:{{currentSteps}} 
  4.     </text> 
  5.     <stack class="stack"
  6.         <canvas class="canvas" ref="canvas"></canvas> 
  7.             <div class="subcontainer" show="{{isShow}}"
  8.                 <text class="gameover"
  9.                     游戏成功 
  10.                 </text> 
  11.             </div> 
  12.     </stack> 
  13.     <input type="button" value="重新开始" class="bit" onclick="restartGame"/> 
  14. </div> 

相应的组件大小颜色等属性设置在entry>src>main>js>default>pages.index>index.css文件里通过class设定的名称来去设置,代码如下:

  1. .container { 
  2.     flex-direction: column
  3.     justify-content: center; 
  4.     align-items: center; 
  5.     width:240px; 
  6.     height:240px; 
  7. .steps { 
  8.     font-size: 10px; 
  9.     text-align:center; 
  10.     width:100px; 
  11.     height:18px; 
  12.     letter-spacing:0px; 
  13.     margin-top:5px; 
  14. .canvas{ 
  15.     width:160px; 
  16.     height:160px; 
  17.     background-color: #BBADA0; 
  18. .bit { 
  19.     width: 75px; 
  20.     height: 15px; 
  21.     background-color: #AD9D8F; 
  22.     font-size: 10px; 
  23.     margin-top: 5px; 
  24.  
  25. .stack{ 
  26.     width: 160px; 
  27.     height: 160px; 
  28.     margin-top: 5px; 
  29.  
  30. .subcontainer{ 
  31.     left: 25px; 
  32.     top: 47.5px; 
  33.     width: 110px; 
  34.     height: 65px; 
  35.     justify-content: center; 
  36.     align-content: center; 
  37.     background-color: #E9C2A6; 
  38.  
  39. .gameover{ 
  40.     font-size: 19px; 
  41.     color:black; 

代码更新部分:组件大小的数据全部都在原文章源代码的基础上减半再作微调,即原文章的数据不适用,以上代码是我调整修改后的

3.实现色块的翻转

要先在运动手表上生成一个7*7的棋盘,并且点击棋盘中任一色块,其上下左右四个色块也会跟着一起变色(在边缘的色块则只会改变其中若干个色块的颜色)

原文章的实现方法是给这49个色块分别添加一个按钮,并分别添加点击事件。

布局方面如上所述,色块(按钮)是显示在棋盘(画布)之上,而游戏成功界面是显示在色块(按钮)及画布之上,因此stack里的顺序应该是canvas、button、gameover;且按钮的相关大小间距的数据也要如上“代码更新部分”一样作修改,代码(修改的部分)如下:

  1. .bitgrid1{ 
  2.     left:2.5px; 
  3.     top:2.5px; 
  4.     width:20px; 
  5.     height:20px; 
  6.     border-color:transparent; 
  7.     background-color:transparent 
  8.  
  9. .bitgrid2{ 
  10.     left:25px; 
  11.     top:2.5px; 
  12.     width:20px; 
  13.     height:20px; 
  14.     border-color:transparent; 
  15.     background-color:transparent 
  16. .bitgrid3{ 
  17.     left:47.5px; 
  18.     top:2.5px; 
  19.     width:20px; 
  20.     height:20px; 
  21.     border-color:transparent; 
  22.     background-color:transparent 
  23. .bitgrid4{ 
  24.     left:70px; 
  25.     top:2.5px; 
  26.     width:20px; 
  27.     height:20px; 
  28.     border-color:transparent; 
  29.     background-color:transparent 
  30.  
  31. .bitgrid5{ 
  32.     left:92.5px; 
  33.     top:2.5px; 
  34.     width:20px; 
  35.     height:20px; 
  36.     border-color:transparent; 
  37.     background-color:transparent 
  38. .bitgrid6{ 
  39.     left:115px; 
  40.     top:2.5px; 
  41.     width:20px; 
  42.     height:20px; 
  43.     border-color:transparent; 
  44.     background-color:transparent 
  45. .bitgrid7{ 
  46.     left:137.5px; 
  47.     top:2.5px; 
  48.     width:20px; 
  49.     height:20px; 
  50.     border-color:transparent; 
  51.     background-color:transparent 
  52. .bitgrid8{ 
  53.     left:2.5px; 
  54.     top:25px; 
  55.     width:20px; 
  56.     height:20px; 
  57.     border-color:transparent; 
  58.     background-color:transparent; 
  59. .bitgrid9{ 
  60.     left:25px; 
  61.     top:25px; 
  62.     width:20px; 
  63.     height:20px; 
  64.     border-color:transparent; 
  65.     background-color:transparent; 
  66. .bitgrid10{ 
  67.     left:47.5px; 
  68.     top:25px; 
  69.     width:20px; 
  70.     height:20px; 
  71.     border-color:transparent; 
  72.     background-color:transparent; 
  73. .bitgrid11{ 
  74.     left:70px; 
  75.     top:25px; 
  76.     width:20px; 
  77.     height:20px; 
  78.     border-color:transparent; 
  79.     background-color:transparent; 
  80.  
  81. .bitgrid12{ 
  82.     left:92.5px; 
  83.     top:25px; 
  84.     width:20px; 
  85.     height:20px; 
  86.     border-color:transparent; 
  87.     background-color:transparent; 
  88. .bitgrid13{ 
  89.     left:115px; 
  90.     top:25px; 
  91.     width:20px; 
  92.     height:20px; 
  93.     border-color:transparent; 
  94.     background-color:transparent; 
  95. .bitgrid14{ 
  96.     left:137.5px; 
  97.     top:25px; 
  98.     width:20px; 
  99.     height:20px; 
  100.     border-color:transparent; 
  101.     background-color:transparent; 
  102. .bitgrid15{ 
  103.     left:2.5px; 
  104.     top:47.5px; 
  105.     width:20px; 
  106.     height:20px; 
  107.     border-color:transparent; 
  108.     background-color:transparent; 
  109. .bitgrid16{ 
  110.     left:25px; 
  111.     top:47.5px; 
  112.     width:20px; 
  113.     height:20px; 
  114.     border-color:transparent; 
  115.     background-color:transparent; 
  116. .bitgrid17{ 
  117.     left:47.5px; 
  118.     top:47.5px; 
  119.     width:20px; 
  120.     height:20px; 
  121.     border-color:transparent; 
  122.     background-color:transparent; 
  123. .bitgrid18{ 
  124.     left:70px; 
  125.     top:47.5px; 
  126.     width:20px; 
  127.     height:20px; 
  128.     border-color:transparent; 
  129.     background-color:transparent; 
  130.  
  131. .bitgrid19{ 
  132.     left:92.5px; 
  133.     top:47.5px; 
  134.     width:20px; 
  135.     height:20px; 
  136.     border-color:transparent; 
  137.     background-color:transparent; 
  138. .bitgrid20{ 
  139.     left:115px; 
  140.     top:47.5px; 
  141.     width:20px; 
  142.     height:20px; 
  143.     border-color:transparent; 
  144.     background-color:transparent; 
  145. .bitgrid21{ 
  146.     left:137.5px; 
  147.     top:47.5px; 
  148.     width:20px; 
  149.     height:20px; 
  150.     border-color:transparent; 
  151.     background-color:transparent; 
  152. .bitgrid22{ 
  153.     left:2.5px; 
  154.     top:70px; 
  155.     width:20px; 
  156.     height:20px; 
  157.     border-color:transparent; 
  158.     background-color:transparent; 
  159. .bitgrid23{ 
  160.     left:25px; 
  161.     top:70px; 
  162.     width:20px; 
  163.     height:20px; 
  164.     border-color:transparent; 
  165.     background-color:transparent; 
  166. .bitgrid24{ 
  167.     left:47.5px; 
  168.     top:70px; 
  169.     width:20px; 
  170.     height:20px; 
  171.     border-color:transparent; 
  172.     background-color:transparent; 
  173. .bitgrid25{ 
  174.     left:70px; 
  175.     top:70px; 
  176.     width:20px; 
  177.     height:20px; 
  178.     border-color:transparent; 
  179.     background-color:transparent; 
  180.  
  181. .bitgrid26{ 
  182.     left:92.5px; 
  183.     top:70px; 
  184.     width:20px; 
  185.     height:20px; 
  186.     border-color:transparent; 
  187.     background-color:transparent; 
  188. .bitgrid27{ 
  189.     left:115px; 
  190.     top:70px; 
  191.     width:20px; 
  192.     height:20px; 
  193.     border-color:transparent; 
  194.     background-color:transparent; 
  195. .bitgrid28{ 
  196.     left:137.5px; 
  197.     top:70px; 
  198.     width:20px; 
  199.     height:20px; 
  200.     border-color:transparent; 
  201.     background-color:transparent; 
  202. .bitgrid29{ 
  203.     left:2.5px; 
  204.     top: 92.5px; 
  205.     width:20px; 
  206.     height:20px; 
  207.     border-color:transparent; 
  208.     background-color:transparent; 
  209. .bitgrid30{ 
  210.     left:25px; 
  211.     top:92.5px; 
  212.     width:20px; 
  213.     height:20px; 
  214.     border-color:transparent; 
  215.     background-color:transparent; 
  216. .bitgrid31{ 
  217.     left:47.5px; 
  218.     top:92.5px; 
  219.     width:20px; 
  220.     height:20px; 
  221.     border-color:transparent; 
  222.     background-color:transparent; 
  223. .bitgrid32{ 
  224.     left:70px; 
  225.     top:92.5px; 
  226.     width:20px; 
  227.     height:20px; 
  228.     border-color:transparent; 
  229.     background-color:transparent; 
  230.  
  231. .bitgrid33{ 
  232.     left:92.5px; 
  233.     top:92.5px; 
  234.     width:20px; 
  235.     height:20px; 
  236.     border-color:transparent; 
  237.     background-color:transparent; 
  238. .bitgrid34{ 
  239.     left:115px; 
  240.     top:92.5px; 
  241.     width:20px; 
  242.     height:20px; 
  243.     border-color:transparent; 
  244.     background-color:transparent; 
  245. .bitgrid35{ 
  246.     left:137.5px; 
  247.     top:92.5px; 
  248.     width:20px; 
  249.     height:20px; 
  250.     border-color:transparent; 
  251.     background-color:transparent; 
  252. .bitgrid36{ 
  253.     left:2.5px; 
  254.     top:115px; 
  255.     width:20px; 
  256.     height:20px; 
  257.     border-color:transparent; 
  258.     background-color:transparent; 
  259. .bitgrid37{ 
  260.     left:25px; 
  261.     top:115px; 
  262.     width:20px; 
  263.     height:20px; 
  264.     border-color:transparent; 
  265.     background-color:transparent; 
  266. .bitgrid38{ 
  267.     left:47.5px; 
  268.     top:115px; 
  269.     width:20px; 
  270.     height:20px; 
  271.     border-color:transparent; 
  272.     background-color:transparent; 
  273. .bitgrid39{ 
  274.     left:70px; 
  275.     top:115px; 
  276.     width:20px; 
  277.     height:20px; 
  278.     border-color:transparent; 
  279.     background-color:transparent; 
  280.  
  281. .bitgrid40{ 
  282.     left:92.5px; 
  283.     top:115px; 
  284.     width:20px; 
  285.     height:20px; 
  286.     border-color:transparent; 
  287.     background-color:transparent; 
  288. .bitgrid41{ 
  289.     left:115px; 
  290.     top:115px; 
  291.     width:20px; 
  292.     height:20px; 
  293.     border-color:transparent; 
  294.     background-color:transparent; 
  295. .bitgrid42{ 
  296.     left:137.5px; 
  297.     top:115px; 
  298.     width:20px; 
  299.     height:20px; 
  300.     border-color:transparent; 
  301.     background-color:transparent; 
  302. .bitgrid43{ 
  303.     left:2.5px; 
  304.     top:137.5px; 
  305.     width:20px; 
  306.     height:20px; 
  307.     border-color:transparent; 
  308.     background-color:transparent; 
  309. .bitgrid44{ 
  310.     left:25px; 
  311.     top:137.5px; 
  312.     width:20px; 
  313.     height:20px; 
  314.     border-color:transparent; 
  315.     background-color:transparent; 
  316. .bitgrid45{ 
  317.     left:47.5px; 
  318.     top:137.5px; 
  319.     width:20px; 
  320.     height:20px; 
  321.     border-color:transparent; 
  322.     background-color:transparent; 
  323. .bitgrid46{ 
  324.     left:70px; 
  325.     top:137.5px; 
  326.     width:20px; 
  327.     height:20px; 
  328.     border-color:transparent; 
  329.     background-color:transparent; 
  330.  
  331. .bitgrid47{ 
  332.     left:92.5px; 
  333.     top:137.5px; 
  334.     width:20px; 
  335.     height:20px; 
  336.     border-color:transparent; 
  337.     background-color:transparent; 
  338. .bitgrid48{ 
  339.     left:115px; 
  340.     top:137.5px; 
  341.     width:20px; 
  342.     height:20px; 
  343.     border-color:transparent; 
  344.     background-color:transparent; 
  345. .bitgrid49{ 
  346.     left:137.5px; 
  347.     top:137.5px; 
  348.     width:20px; 
  349.     height:20px; 
  350.     border-color:transparent; 
  351.     background-color:transparent; 

然后在index.js文件里用一个7*7的数组表示色块,其中0表示白色,1代表黑色,这样我们就能定义一个用0和1表示键,颜色表示值的字典COLORS,并且定义全局常量边长SIDELEN为20,间距MARGIN为2.5,定义一个全局变量的二维数组grids,其中的值全为0

  1. var grids=[[0, 0, 0, 0, 0, 0, 0], 
  2.            [0, 0, 0, 0, 0, 0, 0], 
  3.            [0, 0, 0, 0, 0, 0, 0], 
  4.            [0, 0, 0, 0, 0, 0, 0], 
  5.            [0, 0, 0, 0, 0, 0, 0], 
  6.            [0, 0, 0, 0, 0, 0, 0], 
  7.            [0, 0, 0, 0, 0, 0, 0], 
  8.            [0, 0, 0, 0, 0, 0, 0]]; 
  9.  
  10. const SIDELEN=20; 
  11. const MARGIN=2.5; 
  12. const COLORS = { 
  13.     "0""#FFFFFF"
  14.     "1""#000000" 

设置色块的点击事件

要点:点击时对应获取该方块的位置(例如该方块时第3行第4个,则坐标为(2,3)),并将该坐标传给函数changeOneGrids,去判断该方块上下左右是否有方块,并调用函数change变换其数组的值——若0则变为1,若1则变为0

  1. change(x,y){ 
  2.         if(this.isShow==false){ 
  3.             if(grids[x][y] == 0){ 
  4.                 grids[x][y] = 1; 
  5.             }else
  6.                 grids[x][y] = 0; 
  7.             } 
  8.         } 
  9.     }, 
  10. changeOneGrids(x,y){ 
  11.         if(x>-1 && y>-1 && x<7 && y<7){ 
  12.             this.change(x,y); 
  13.         } 
  14.         if(x+1>-1 && y>-1 && x+1<7 && y<7){ 
  15.             this.change(x+1,y); 
  16.         } 
  17.         if(x-1>-1 && y>-1 && x-1<7 && y<7){ 
  18.             this.change(x-1,y); 
  19.         } 
  20.         if(x>-1 && y+1>-1 && x<7 && y+1<7){ 
  21.             this.change(x,y+1); 
  22.         } 
  23.         if(x>-1 && y-1>-1 && x<7 && y-1<7){ 
  24.             this.change(x,y-1); 
  25.         } 

最后调用函数drawgrids去“上色”

  1. drawGrids(){ 
  2.         context=this.$refs.canvas.getContext('2d'); 
  3.         for (let row = 0 ;row < 7 ;row++){ 
  4.             for (let column = 0; column < 7;column++){ 
  5.                 let gridStr = grids[row][column].toString(); 
  6.  
  7.                 context.fillStyle = COLORS[gridStr]; 
  8.                 let leftTopX = column * (MARGIN + SIDELEN) + MARGIN; 
  9.                 let leftTopY = row * (MARGIN + SIDELEN) + MARGIN; 
  10.                 context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN); 
  11.             } 
  12.         } 
  13.     }, 

4.实现题目的随机生成

随机生成一个色块被打乱的7x7的棋盘,这里是在原来全白的棋盘上随机生成20个黑色块。

要点:把二维数组的下标放进一个列表中,Math.random()函数是随机[0,1)内的小数,Math.floor(x)为得出小于或等于x的最大整数,每次随机生成一个数后,读取刚才的列表对应的下标,即获得一个在7x7内的随机的坐标,调用函数changeOneGrids(x,y)

  1. initGrids(){ 
  2.         let array = []; 
  3.         for (let row = 0; row < 7; row++) { 
  4.             for (let column = 0; column < 7; column++) { 
  5.                 if (grids[row][column] == 0) { 
  6.                     array.push([row, column]) 
  7.                 } 
  8.             } 
  9.         } 
  10.         for (let i = 0; i < 20; i++){ 
  11.             let randomIndex = Math.floor(Math.random() * array.length); 
  12.             let row = array[randomIndex][0]; 
  13.             let column = array[randomIndex][1]; 
  14.             this.changeOneGrids(row,column); 
  15.         } 
  16.     } 

5.游戏结束

当该7x7数组的值全为1时游戏成功,此时isShow的值为真,色块的点击事件就不起效(change函数里加个对isShow的真假判断)

  1. gameover(){ 
  2.         for (let row = 0 ;row < 7 ;row++){ 
  3.             for (let column = 0; column < 7;column++){ 
  4.                 if (grids[row][column]==1){ 
  5.                     return false
  6.                 } 
  7.             } 
  8.         } 
  9.         return true
  10.     } 

然后在changeOneGrids函数里调用gameover函数;同时,随着每一次点击,都会调用changeOneGrids函数,所以步数的增加可以直接在每次changeOneGrids函数被调用时累加

  1. if(this.isShow==false){ 
  2.            this.currentSteps+=1;; 
  3.        } 
  4.        if(this.gameover()){ 
  5.            this.isShow=true
  6.        } 

6.重新开始

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

  1. restartGame(){ 
  2.      this.initGrids(); 
  3.      this.drawGrids(); 
  4.      this.isShow = false
  5.      this.currentSteps = 0; 
  6.  } 

修改的说明

1.画布组件的getContext不支持在onInit和onReady中进行调用,因此我改在drawGrids中调用,然后再在onShow中调用drawGrids

2.随机生成打乱的色块时,会调用changeOneGrids函数,此时会增加步数20

  1. data: { 
  2.         currentSteps: -20, 
  3.     }​ 

3.同1,色块的随机生成函数initGrids也放在onShow中调用

结语

以上是我的初步学习笔记啦,我修改过的源代码会上传到附件,更多详细的注解步骤可去看原文章。该学习笔记还有后续哦,后续是对其中一些功能实现采用另一种算法来实现,代码会在该篇的基础上再作修改,并且还会对相关知识注解作一个小分享,敬请期待(●ˇ∀ˇ●)

文章相关附件可以点击下面的原文链接前往下载

https://harmonyos.51cto.com/resource/1222

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-10-08 14:45:22

鸿蒙HarmonyOS应用

2020-12-14 09:58:28

鸿蒙HarmonyOS手表游戏

2022-08-22 17:28:34

ArkUI鸿蒙

2022-12-19 16:56:48

游戏开发鸿蒙

2022-11-01 15:17:48

JS鸿蒙小游戏

2014-09-01 10:36:35

个推推送

2022-10-31 15:22:37

JS鸿蒙小游戏

2011-01-19 10:32:09

sendmail配置

2011-01-19 10:57:54

sendmail配置

2011-03-08 16:30:24

Proftpd

2011-03-08 16:30:40

Proftpd

2011-03-08 16:15:22

Proftpd安装

2011-09-14 15:30:00

MongoDB

2009-06-18 11:25:26

Hibernate L

2010-07-28 11:19:55

HelloWorldbada

2015-01-14 10:18:51

智能手表可穿戴

2014-09-25 11:25:19

游戏引擎架构设计

2020-12-18 11:05:25

鸿蒙HarmonyOS游戏

2024-01-15 07:47:09

井字棋游戏编程练习Python

2020-12-11 12:27:35

鸿蒙HarmonyOS
点赞
收藏

51CTO技术栈公众号