[文章]【木棉花】:手表游戏——黑白翻棋 之 学习笔记(前篇)

阅读量0
1
5
前言
去年我们木棉花组织发过一篇文章“HarmonyOS手表游戏——黑白翻棋”,本文是我对该文章的一个学习笔记,随着IDE的升级,一些代码也需要作修改。以下是我的学习笔记及部分代码的修改O(∩_∩)O
源代码请移步至→原文章地址
概述
正文内容只展示部分代码,完整代码可以下载附件(附件1是源代码的代码更新)。效果图如下:


35.png

正文
1.创建一个空白的工程DevEco Studio下载安装成功后,打开DevEco Studio,点击左上角的File,点击New,再选择New Project,选择Empty Ability(JS),然后点击Next,给项目命名WatchGame_BW,选择设备类型Wearable,最后点击Finish。

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. }
  8. .steps {
  9.     font-size: 10px;
  10.     text-align:center;
  11.     width:100px;
  12.     height:18px;
  13.     letter-spacing:0px;
  14.     margin-top:5px;
  15. }
  16. .canvas{
  17.     width:160px;
  18.     height:160px;
  19.     background-color: #BBADA0;
  20. }
  21. .bit {
  22.     width: 75px;
  23.     height: 15px;
  24.     background-color: #AD9D8F;
  25.     font-size: 10px;
  26.     margin-top: 5px;
  27. }

  28. .stack{
  29.     width: 160px;
  30.     height: 160px;
  31.     margin-top: 5px;
  32. }

  33. .subcontainer{
  34.     left: 25px;
  35.     top: 47.5px;
  36.     width: 110px;
  37.     height: 65px;
  38.     justify-content: center;
  39.     align-content: center;
  40.     background-color: #E9C2A6;
  41. }

  42. .gameover{
  43.     font-size: 19px;
  44.     color:black;
  45. }
复制代码
代码更新部分:组件大小的数据全部都在原文章源代码的基础上减半再作微调,即原文章的数据不适用,以上代码是我调整修改后的
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. }
  17. .bitgrid3{
  18.     left:47.5px;
  19.     top:2.5px;
  20.     width:20px;
  21.     height:20px;
  22.     border-color:transparent;
  23.     background-color:transparent
  24. }
  25. .bitgrid4{
  26.     left:70px;
  27.     top:2.5px;
  28.     width:20px;
  29.     height:20px;
  30.     border-color:transparent;
  31.     background-color:transparent

  32. }
  33. .bitgrid5{
  34.     left:92.5px;
  35.     top:2.5px;
  36.     width:20px;
  37.     height:20px;
  38.     border-color:transparent;
  39.     background-color:transparent
  40. }
  41. .bitgrid6{
  42.     left:115px;
  43.     top:2.5px;
  44.     width:20px;
  45.     height:20px;
  46.     border-color:transparent;
  47.     background-color:transparent
  48. }
  49. .bitgrid7{
  50.     left:137.5px;
  51.     top:2.5px;
  52.     width:20px;
  53.     height:20px;
  54.     border-color:transparent;
  55.     background-color:transparent
  56. }
  57. .bitgrid8{
  58.     left:2.5px;
  59.     top:25px;
  60.     width:20px;
  61.     height:20px;
  62.     border-color:transparent;
  63.     background-color:transparent;
  64. }
  65. .bitgrid9{
  66.     left:25px;
  67.     top:25px;
  68.     width:20px;
  69.     height:20px;
  70.     border-color:transparent;
  71.     background-color:transparent;
  72. }
  73. .bitgrid10{
  74.     left:47.5px;
  75.     top:25px;
  76.     width:20px;
  77.     height:20px;
  78.     border-color:transparent;
  79.     background-color:transparent;
  80. }
  81. .bitgrid11{
  82.     left:70px;
  83.     top:25px;
  84.     width:20px;
  85.     height:20px;
  86.     border-color:transparent;
  87.     background-color:transparent;

  88. }
  89. .bitgrid12{
  90.     left:92.5px;
  91.     top:25px;
  92.     width:20px;
  93.     height:20px;
  94.     border-color:transparent;
  95.     background-color:transparent;
  96. }
  97. .bitgrid13{
  98.     left:115px;
  99.     top:25px;
  100.     width:20px;
  101.     height:20px;
  102.     border-color:transparent;
  103.     background-color:transparent;
  104. }
  105. .bitgrid14{
  106.     left:137.5px;
  107.     top:25px;
  108.     width:20px;
  109.     height:20px;
  110.     border-color:transparent;
  111.     background-color:transparent;
  112. }
  113. .bitgrid15{
  114.     left:2.5px;
  115.     top:47.5px;
  116.     width:20px;
  117.     height:20px;
  118.     border-color:transparent;
  119.     background-color:transparent;
  120. }
  121. .bitgrid16{
  122.     left:25px;
  123.     top:47.5px;
  124.     width:20px;
  125.     height:20px;
  126.     border-color:transparent;
  127.     background-color:transparent;
  128. }
  129. .bitgrid17{
  130.     left:47.5px;
  131.     top:47.5px;
  132.     width:20px;
  133.     height:20px;
  134.     border-color:transparent;
  135.     background-color:transparent;
  136. }
  137. .bitgrid18{
  138.     left:70px;
  139.     top:47.5px;
  140.     width:20px;
  141.     height:20px;
  142.     border-color:transparent;
  143.     background-color:transparent;

  144. }
  145. .bitgrid19{
  146.     left:92.5px;
  147.     top:47.5px;
  148.     width:20px;
  149.     height:20px;
  150.     border-color:transparent;
  151.     background-color:transparent;
  152. }
  153. .bitgrid20{
  154.     left:115px;
  155.     top:47.5px;
  156.     width:20px;
  157.     height:20px;
  158.     border-color:transparent;
  159.     background-color:transparent;
  160. }
  161. .bitgrid21{
  162.     left:137.5px;
  163.     top:47.5px;
  164.     width:20px;
  165.     height:20px;
  166.     border-color:transparent;
  167.     background-color:transparent;
  168. }
  169. .bitgrid22{
  170.     left:2.5px;
  171.     top:70px;
  172.     width:20px;
  173.     height:20px;
  174.     border-color:transparent;
  175.     background-color:transparent;
  176. }
  177. .bitgrid23{
  178.     left:25px;
  179.     top:70px;
  180.     width:20px;
  181.     height:20px;
  182.     border-color:transparent;
  183.     background-color:transparent;
  184. }
  185. .bitgrid24{
  186.     left:47.5px;
  187.     top:70px;
  188.     width:20px;
  189.     height:20px;
  190.     border-color:transparent;
  191.     background-color:transparent;
  192. }
  193. .bitgrid25{
  194.     left:70px;
  195.     top:70px;
  196.     width:20px;
  197.     height:20px;
  198.     border-color:transparent;
  199.     background-color:transparent;

  200. }
  201. .bitgrid26{
  202.     left:92.5px;
  203.     top:70px;
  204.     width:20px;
  205.     height:20px;
  206.     border-color:transparent;
  207.     background-color:transparent;
  208. }
  209. .bitgrid27{
  210.     left:115px;
  211.     top:70px;
  212.     width:20px;
  213.     height:20px;
  214.     border-color:transparent;
  215.     background-color:transparent;
  216. }
  217. .bitgrid28{
  218.     left:137.5px;
  219.     top:70px;
  220.     width:20px;
  221.     height:20px;
  222.     border-color:transparent;
  223.     background-color:transparent;
  224. }
  225. .bitgrid29{
  226.     left:2.5px;
  227.     top: 92.5px;
  228.     width:20px;
  229.     height:20px;
  230.     border-color:transparent;
  231.     background-color:transparent;
  232. }
  233. .bitgrid30{
  234.     left:25px;
  235.     top:92.5px;
  236.     width:20px;
  237.     height:20px;
  238.     border-color:transparent;
  239.     background-color:transparent;
  240. }
  241. .bitgrid31{
  242.     left:47.5px;
  243.     top:92.5px;
  244.     width:20px;
  245.     height:20px;
  246.     border-color:transparent;
  247.     background-color:transparent;
  248. }
  249. .bitgrid32{
  250.     left:70px;
  251.     top:92.5px;
  252.     width:20px;
  253.     height:20px;
  254.     border-color:transparent;
  255.     background-color:transparent;

  256. }
  257. .bitgrid33{
  258.     left:92.5px;
  259.     top:92.5px;
  260.     width:20px;
  261.     height:20px;
  262.     border-color:transparent;
  263.     background-color:transparent;
  264. }
  265. .bitgrid34{
  266.     left:115px;
  267.     top:92.5px;
  268.     width:20px;
  269.     height:20px;
  270.     border-color:transparent;
  271.     background-color:transparent;
  272. }
  273. .bitgrid35{
  274.     left:137.5px;
  275.     top:92.5px;
  276.     width:20px;
  277.     height:20px;
  278.     border-color:transparent;
  279.     background-color:transparent;
  280. }
  281. .bitgrid36{
  282.     left:2.5px;
  283.     top:115px;
  284.     width:20px;
  285.     height:20px;
  286.     border-color:transparent;
  287.     background-color:transparent;
  288. }
  289. .bitgrid37{
  290.     left:25px;
  291.     top:115px;
  292.     width:20px;
  293.     height:20px;
  294.     border-color:transparent;
  295.     background-color:transparent;
  296. }
  297. .bitgrid38{
  298.     left:47.5px;
  299.     top:115px;
  300.     width:20px;
  301.     height:20px;
  302.     border-color:transparent;
  303.     background-color:transparent;
  304. }
  305. .bitgrid39{
  306.     left:70px;
  307.     top:115px;
  308.     width:20px;
  309.     height:20px;
  310.     border-color:transparent;
  311.     background-color:transparent;

  312. }
  313. .bitgrid40{
  314.     left:92.5px;
  315.     top:115px;
  316.     width:20px;
  317.     height:20px;
  318.     border-color:transparent;
  319.     background-color:transparent;
  320. }
  321. .bitgrid41{
  322.     left:115px;
  323.     top:115px;
  324.     width:20px;
  325.     height:20px;
  326.     border-color:transparent;
  327.     background-color:transparent;
  328. }
  329. .bitgrid42{
  330.     left:137.5px;
  331.     top:115px;
  332.     width:20px;
  333.     height:20px;
  334.     border-color:transparent;
  335.     background-color:transparent;
  336. }
  337. .bitgrid43{
  338.     left:2.5px;
  339.     top:137.5px;
  340.     width:20px;
  341.     height:20px;
  342.     border-color:transparent;
  343.     background-color:transparent;
  344. }
  345. .bitgrid44{
  346.     left:25px;
  347.     top:137.5px;
  348.     width:20px;
  349.     height:20px;
  350.     border-color:transparent;
  351.     background-color:transparent;
  352. }
  353. .bitgrid45{
  354.     left:47.5px;
  355.     top:137.5px;
  356.     width:20px;
  357.     height:20px;
  358.     border-color:transparent;
  359.     background-color:transparent;
  360. }
  361. .bitgrid46{
  362.     left:70px;
  363.     top:137.5px;
  364.     width:20px;
  365.     height:20px;
  366.     border-color:transparent;
  367.     background-color:transparent;

  368. }
  369. .bitgrid47{
  370.     left:92.5px;
  371.     top:137.5px;
  372.     width:20px;
  373.     height:20px;
  374.     border-color:transparent;
  375.     background-color:transparent;
  376. }
  377. .bitgrid48{
  378.     left:115px;
  379.     top:137.5px;
  380.     width:20px;
  381.     height:20px;
  382.     border-color:transparent;
  383.     background-color:transparent;
  384. }
  385. .bitgrid49{
  386.     left:137.5px;
  387.     top:137.5px;
  388.     width:20px;
  389.     height:20px;
  390.     border-color:transparent;
  391.     background-color:transparent;
  392. }

复制代码
然后在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. const SIDELEN=20;
  10. const MARGIN=2.5;
  11. const COLORS = {
  12.     "0": "#FFFFFF",
  13.     "1": "#000000"
  14. }
复制代码
设置色块的点击事件
要点:点击时对应获取该方块的位置(例如该方块时第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.         }
  26. }
复制代码
最后调用函数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.                 context.fillStyle = COLORS[gridStr];
  7.                 let leftTopX = column * (MARGIN + SIDELEN) + MARGIN;
  8.                 let leftTopY = row * (MARGIN + SIDELEN) + MARGIN;
  9.                 context.fillRect(leftTopX, leftTopY, SIDELEN, SIDELEN);
  10.             }
  11.         }
  12.     },
复制代码
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中调用

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

更多资料请关注我们的项目 : Awesome-Harmony_木棉花

回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友