[文章]【木棉花】:手机游戏——黑白翻棋

阅读量0
0
0
前言
之前发过两篇黑白翻棋游戏的手表版本,这次给大家带来的小分享是黑白翻棋的手机版本,也是JS写的,功能代码基本一致(采用第二篇的算法),只是布局会作相应修改。
概述
该游戏会随机生成一个题目,最终当棋盘上的方格都为白色的时候游戏成功,效果如下
02.png
01.png

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

2.界面布局
1.代码删除的部分
先在entry>src>main>js>default>pages.index>index.hml 文件里把以下代码删掉
  1. <text class="title">
  2.         {{ $t('strings.hello') }} {{ title }}
  3.     </text>
复制代码
entry>src>main>js>default>pages.index>index.js 文件里把以下代码删掉
  1. title:" "
  2.    onInit() {
  3.         this.title = this.$t('strings.world');
  4.     }
复制代码
entry>src>main>js>default>pages.index>index.css 文件里把container部分以下的代码删掉
2.棋盘设置
这里以画布组件canvas来描绘棋盘
index.hml
  1. <canvas class="canvas" ref="canvas"> </canvas>
复制代码
index.css
  1. .canvas{
  2.     width:320px;
  3.     height:320px;
  4.     background-color: #BBADA0;
  5. }
复制代码
打开模拟器,界面如下
05.png

3.棋子设置
棋子是通过canvas组件的方法来绘制填充多个正方形,这里我设置的棋盘是7x7的,每个方格的边长SIDELEN为40,方格间的间距MARGIN为5,以一个数组来表示每个方格,并初始化赋值为0,用0表示白色,1代表黑色,这样我们就能定义一个用0和1表示键,颜色表示值的字典COLORS
index.js,在export default上方添加以下代码
  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. var context;
  10. const SIDELEN=40;
  11. const MARGIN=5;

  12. const COLORS = {
  13.     "0": "#FFFFFF",
  14.     "1": "#000000"
  15. }
复制代码
export default下方添加以下代码,遍历数组grids的每一个元素,将其转换成String型,对应的是COLORS中的颜色,然后调用画布组件中的方法fillRect填充方格的颜色,参数为方格的左上角的坐标及方格的长宽

  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.     },
复制代码

最后在drawGrids函数上方添加以下代码调用drawGrids
  1. onShow(){
  2.        this.drawGrids();
  3.    },
复制代码
打开模拟器,就能有如下效果
06.png

3.游戏规则的设置
1.获取点击位置的坐标并对应方格
给画布组件添加点击事件onclick和触摸事件touchstart
index.hml
  1.         <canvas class="canvas" ref="canvas" onclick="click" @touchstart='touchstartfunc'> </canvas>
复制代码
事件touchstart,在手指刚触摸屏幕时就触发该事件,其参数为TouchEvent,其对象属性touches包含屏幕触摸点的信息数组,而我们需要的坐标信息就包含在这个数组里;这里我们需要获取到的坐标是相对于组件左上角的,即localX和localY,这样也方便我们设置点击范围来触发色块的翻转(获取坐标这块详细可看我上一篇文章)其次,参数a和b分别代表传递的方格的行列值。

index.js
  1. var localx;
  2. var localy;
  3. var a;
  4. var b;
复制代码
  1. touchstartfunc(msg) {
  2.         localx=msg.touches[0].localX;
  3.         localy=msg.touches[0].localY;
  4.     },
  5. getgrid() {
  6.     if (MARGIN < localx && localx < (MARGIN + SIDELEN)) {
  7.         b = 0;
  8.     }
  9.     if (1 * (MARGIN + SIDELEN) + MARGIN < localx && localx < 2 * (MARGIN + SIDELEN)) {
  10.         b = 1;
  11.     }
  12.     if (2 * (MARGIN + SIDELEN) + MARGIN < localx && localx < 3 * (MARGIN + SIDELEN)) {
  13.         b = 2;
  14.     }
  15.     if (3 * (MARGIN + SIDELEN) + MARGIN < localx && localx < 4 * (MARGIN + SIDELEN)) {
  16.         b = 3;
  17.     }
  18.     if (4 * (MARGIN + SIDELEN) + MARGIN < localx && localx < 5 * (MARGIN + SIDELEN)) {
  19.         b = 4;
  20.     }
  21.     if (5 * (MARGIN + SIDELEN) + MARGIN < localx && localx < 6 * (MARGIN + SIDELEN)) {
  22.         b = 5;
  23.     }
  24.     if (6 * (MARGIN + SIDELEN) + MARGIN < localx && localx < 7 * (MARGIN + SIDELEN)) {
  25.         b = 6;
  26.     }
  27.     if (MARGIN < localy && localy < (MARGIN + SIDELEN)) {
  28.         a = 0;
  29.     }
  30.     if (1 * (MARGIN + SIDELEN) + MARGIN < localy && localy < 2 * (MARGIN + SIDELEN)) {
  31.         a = 1;
  32.     }
  33.     if (2 * (MARGIN + SIDELEN) + MARGIN < localy && localy < 3 * (MARGIN + SIDELEN)) {
  34.         a = 2;
  35.     }
  36.     if (3 * (MARGIN + SIDELEN) + MARGIN < localy && localy < 4 * (MARGIN + SIDELEN)) {
  37.         a = 3;
  38.     }
  39.     if (4 * (MARGIN + SIDELEN) + MARGIN < localy && localy < 5 * (MARGIN + SIDELEN)) {
  40.         a = 4;
  41.     }
  42.     if (5 * (MARGIN + SIDELEN) + MARGIN < localy && localy < 6 * (MARGIN + SIDELEN)) {
  43.         a = 5;
  44.     }
  45.     if (6 * (MARGIN + SIDELEN) + MARGIN < localy && localy < 7 * (MARGIN + SIDELEN)) {
  46.         a = 6;
  47.     }
  48. }
复制代码
2.点击的方格及其上下左右都变色
change控制变色,若值为0则变为1,若为1则变为0。方格的横纵坐标都是0~6,changeOneGrids第一个判断是被点击的方格的变色,第二个判断是右边的格子是否在棋盘上,假如被点击的格子是右边界,则判断为假,右格子不会变色。以此类推对左格,上格,下格作判断,最后调用drawGrids绘制方格。
index.js
  1. change(x,y){
  2.    
  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.      this.drawGrids();
  27. }
复制代码
最后在点击事件上调用getgrid和changeOneGrids
  1. click(){
  2.       this.getgrid();
  3.       this.changeOneGrids(a,b);
  4.   }
复制代码

到此,效果如下
07.gif

3.生成随机打乱的棋盘(游戏题目)
先将数组以坐标形式存储在array,共49组坐标,然后随机生成0~48的整数,取该组坐标中第一个元素作为横坐标,第二个元素作为纵坐标,这里设置的是随机生成点击10下后的题目(后期为在此基础上以不同次数来设置不同难度)
  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 < 10; 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.     }
复制代码
然后在onshow上调用initGrids,注意initGrids要放在drawGrids之前

  1.    onShow(){
  2.         this.initGrids();
  3.         this.drawGrids();
  4.     },
复制代码
4.设置步数显示及游戏的重新开始

1.步数显示
步数这个文本组件显示在棋盘上方,故在index.hml文件里,将以下代码放在canvas上方,其中由于步数是个变量,故以currentSteps的值的变动来动态更新步数
index.hml
  1. <text class="steps">
  2.         当前步数:{{currentSteps}}
  3.     </text>
复制代码
index.css
  1. .steps {
  2.     font-size: 21px;
  3.     text-align:center;
  4.     width:200px;
  5.     height:39px;
  6.     letter-spacing:0px;
  7.     margin-top:10px;
  8.     background-color: #BBAD20;
  9. }
复制代码
由于initGrids会随机点击10下,为了使步数清零,在data里给它赋初值-10
index.js
  1. data: {
  2.         currentSteps:-10,
  3.     },
复制代码
在changeOneGrids上添加以下代码,使每次点击步数加一
  1. this.currentSteps+=1;
复制代码
2.游戏的重新开始

重新开始的按钮在棋盘的下方,故index.hml文件中在canvas下方添加代码
  1. <input type="button" value="重新开始" class="bit" onclick="restartGame"/>
复制代码
index.css
  1. .bit {
  2.     top: 20px;
  3.     width: 220px;
  4.     height: 40px;
  5.     background-color: #AD9D8F;
  6.     font-size: 25px;
  7.     margin-top: 10px;
  8. }
复制代码
游戏重新开始时,会再次随机生成游戏题目,并且步数重置为0
index.js
  1.     restartGame(){
  2.         this.initGrids();
  3.         this.drawGrids();
  4.         this.currentSteps = 0;
  5.     }
复制代码
5.游戏成功的设置

游戏成功的弹窗是显示在棋盘(canvas)上方的,该实现可通过添加一个堆叠容器stack,将游戏成功的文本组件放在画布组件之后;其次,“游戏成功”的显示在初始时不会显示,所以要设置属性show,对应设一个布尔型变量isShow,并令isShow的初始值为假,游戏成功时其值为真,当为真时就可以显示了
index.hml
  1.     <stack class="stack">
  2.         <canvas class="canvas" ref="canvas" onclick="click" @touchstart='touchstartfunc'> </canvas>
  3.         <div class="subcontainer" show="{{isShow}}">
  4.             <text class="gameover">
  5.                 游戏成功
  6.             </text>
  7.         </div>
  8.     </stack>
复制代码
index.css

  1. .stack{
  2.     width: 320px;
  3.     height: 320px;
  4.     margin-top: 10px;
  5. }

  6. .subcontainer{
  7.     left: 50px;
  8.     top: 95px;
  9.     width: 220px;
  10.     height: 130px;
  11.     justify-content: center;
  12.     align-content: center;
  13.     background-color: #E9C2A6;
  14. }

  15. .gameover{
  16.     font-size: 38px;
  17.     color:black;
  18.     justify-content: center;
  19.     margin-top: 30px;
  20. }
复制代码
index.js
  1. data: {
  2.         currentSteps:-10,
  3.         isShow:false
  4.     },
复制代码
  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中给“步数增加”添加判断条件
  1. if(this.isShow==false){
  2.             this.currentSteps+=1;
  3.         }
  4.         if(this.gameover()){
  5.             this.isShow=true;
  6.         }
复制代码
在restartGame中添加代码
  1.    this.isShow = false;
复制代码
恭喜你!!完成以上步骤后你就可以开始玩啦!!O(∩_∩)O
结语
以上就是我这次的小分享啦❀❀!后续会有该游戏的进阶版,我会不断完善的(ง •_•)ง
更多资料请关注我们的项目 : Awesome-Harmony_木棉花

回帖

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