文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-12-02 21:39

关注

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

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

https://harmonyos.51cto.com

前言

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

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

概述

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


正文

1.创建一个空白的工程

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


2.界面布局

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

这里记几个小要点:

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

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

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

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

    相应的组件大小颜色等属性设置在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.  } 

    修改的说明

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

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

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

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

    结语

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

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

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

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

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

    https://harmonyos.51cto.com

     

    来源:鸿蒙社区内容投诉

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    软考中级精品资料免费领

    • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

      难度     813人已做
      查看
    • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

      难度     354人已做
      查看
    • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

      难度     318人已做
      查看
    • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

      难度     435人已做
      查看
    • 2024年上半年系统架构设计师考试综合知识真题

      难度     224人已做
      查看

    相关文章

    发现更多好内容

    猜你喜欢

    AI推送时光机
    位置:首页-资讯-后端开发
    咦!没有更多了?去看看其它编程学习网 内容吧
    首页课程
    资料下载
    问答资讯