• 技术文章 >web前端 >Vue.js

    手把手带你使用Vue开发一个五子棋小游戏!

    青灯夜游青灯夜游2022-06-22 22:01:08转载168
    本篇文章带大家利用Vue基础语法来写一个五子棋小游戏,希望对大家有所帮助!

    在之前的文章中,用JS的基础语法写了一个五子棋小游戏,今天用Vue的基础语法来写一个,感受一下两者的区别。。至于怎么判断胜负,我还是把上篇文章的方法复制粘贴过来了,如果想了解这个逻辑,可以看我之前的那篇文章。(学习视频分享:vuejs视频教程

    1.绘制游戏区域和游戏元素

    开始写代码之前,一定要记得先导包Vue文件。棋盘还是用二维数组来渲染,可以使用Array(15).fill(0).map(()=>Array(15).fill(0))方法来快速生成数组。

        //创建Vue实例
        let vm = new Vue({
          //挂载到对应的盒子上
          el: '#app',
          data: {
            //快速生成用来渲染棋盘的数组,15*15,默认值是0
            list: Array(15).fill(0).map(()=>Array(15).fill(0))
          },
        })

    数组生成之后,就可以用v-for方法对Html进行渲染了。第一层循环生成tr标签,第二层循环生成td标签。然后将index和index02这两个参数传入点击事件函数中,并且使用vue样式绑定,将黑棋和白棋这两种样式绑定在td中。

     <div id="app">
        <table>
          <!-- 渲染tr -->
          <tr v-for="(item,index) in list">
            <!-- 渲染td,绑定点击事件,并把参数传递到事件中 -->
            <td v-for="(item02,index02) in item" @click="doClick(index,index02)"
              :class="{'bgc1':item02==1,'bgc2':item02==2}"></td>
          </tr>
        </table>
        <!-- 悔棋按钮 -->
        <button @click="withdraw">悔棋</button>
      </div>

    附上CSS样式

      <style>
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
          list-style: none;
        }
    
        table {
          position: relative;
          width: 730px;
          height: 730px;
          margin: 0 auto;
          border: 5px solid black;
          background: url(./src=http___pic45.nipic.com_20140804_2372131_155038114014_2.jpg&refer=http___pic45.nipic.webp) no-repeat;
          background-size: 100%;
          background-position: center;
          padding: 24px 12px;
        }
    
        td {
          width: 35px;
          height: 35px;
          border-radius: 50%;
          margin-right: 13px;
          margin-bottom: 11px;
          cursor: pointer;
        }
    
        .bgc1 {
          background-color: black;
        }
    
        .bgc2 {
          background-color: white;
        }
    
        button {
          position: absolute;
          width: 200px;
          height: 100px;
          bottom: 100px;
          right: 200px;
          text-align: center;
          line-height: 100px;
          font-size: 25px;
        }
      </style>

    1.png

    2.点击事件

    首先用flag变量来判断黑白棋顺序。数组里的默认值都是0,点击下棋的原理就是改变这个值,上面td的样式绑定中,如果值变为1,就渲染出bgc1样式,也就是黑色。值为2就渲染出白色。在这个事件中,数组的值改变后,页面不会重新渲染,所以需要用this.$set()方法,让v-for强制更新。因为我们用的是Vue语法,这个事件函数要写入methods中。

        //所有黑棋数组
        let blackArr = []
        //所有白棋数组
        let whiteArr = []
        //下棋顺序变量
        let flag = true
        
        //创建Vue实例
       let vm = new Vue({
          //挂载到对应的盒子上
          el: '#app',
          data: {
            //用来渲染棋盘的数组,15*15
            list: Array(15).fill(0).map(()=>Array(15).fill(0))
          },
          methods: {
            //点击事件,参数a,b对应td里的index,index02
            doClick(a, b) {
              //判断是黑棋还是白棋
              if (flag) {
                //判断格子内是否已经有棋子
                if (this.list[a][b] == 0) {
                  //改变点击的td对应的数组元素的值,并且强制更新数组渲染页面
                  this.$set(this.list[a], b, 1)
                  flag = !flag
                  //将对应的棋子坐标添加至总数组中,后面判断胜负需要用
                  blackArr.push([a, b])
                }
              } else {
                this.$set(this.list[a], b, 2)
                flag = !flag
                whiteArr.push([a, b])
              }
            },
          },
        })

    3.悔棋功能

    悔棋的原理就是将最后一颗棋子的值变为0。如何知道哪颗棋子是最后一颗呢,上面不是声明了两个全局数组吗,数组里的最后一个元素不就是最后一颗棋子了。值改变为0后,要把这个元素从全局数组中删除,因为这个数组不仅是悔棋的时候用到,后面判断胜负也会用到,不删除的话会干扰到判断胜负。悔棋事件的函数同样要写在methods里面。

            //悔棋事件
            withdraw() {
              //判断前面一步下的是黑棋还是白棋
              if (!flag) {
                //获取最后一颗棋子的位置
                const a = blackArr[blackArr.length - 1][0]
                const b = blackArr[blackArr.length - 1][1]
                //将最后一刻棋子对应的数组元素的值改为0,并且强制更新数组渲染页面
                this.$set(this.list[a], b, 0)
                //把这个棋子从总数组里面删除,否则会影响到输赢判断
                blackArr.splice(blackArr.length - 1, 1)
                flag = !flag
              } else {
                const a = whiteArr[whiteArr.length - 1][0]
                const b = whiteArr[whiteArr.length - 1][1]
                this.$set(this.list[a], b, 0)
                whiteArr.splice(whiteArr.length - 1, 1)
                flag = !flag
              }
            }

    4.判断胜负

    判断胜负的逻辑我前面的文章中已经写过一遍了,这里我就不做赘述了。感兴趣的可以去看前面一篇文章,如何用原生JS写五子棋。这里直接把方法拿过来,在点击事件里面调用就可以了,记得参数要传进去

    2.png

      //横轴获胜逻辑
        function XWin(a, b) {
          //当前X轴的所有棋子集合数组
          let xAllArr = []
          //判断横轴胜负逻辑的X轴棋子数组
          let xWinArr = []
          //判断下的是黑棋还是白棋
          if (!flag) {
            blackArr.map(item => {
              if (item[0] == a) {
                //将当前排的所有棋子加入对应数组
                xAllArr.push(item[1])
              }
            })
          } else {
            whiteArr.map(item => {
              if (item[0] == a) {
                xAllArr.push(item[1])
              }
            })
          }
          //把横排总数组排序,方便比较
          xAllArr.sort((a, b) => a - b)
          for (let i = 1; i < xAllArr.length; i++) {
            if (xAllArr[i] == (+xAllArr[i - 1] + 1)) {
              //如果相邻的两个棋子数量相差1,就将其添加至胜负逻辑数组
              xWinArr.push(xAllArr[i])
            } else {
              //否则得清空
              xWinArr = []
            }
          }
          //获胜条件
          if (xWinArr.length == 4) {
            //这里要用定时器将弹框变成异步任务,否则第五颗棋子渲染不出来就提示获胜了
            if (!flag) {
              setTimeout(function () {
                alert('黑棋获胜!')
                location.reload()
              }, 100)
            } else {
              setTimeout(function () {
                alert('白棋获胜!')
                location.reload()
              }, 100)
            }
          }
        }
        //竖轴获胜逻辑
        function YWin(a, b) {
          let yAllArr = []
          let yWinArr = []
          if (!flag) {
            blackArr.map(item => {
              if (item[1] == b) {
                yAllArr.push(item[0])
              }
            })
          } else {
            whiteArr.map(item => {
              if (item[1] == b) {
                yAllArr.push(item[0])
              }
            })
          }
          yAllArr.sort((a, b) => a - b)
          for (let i = 1; i < yAllArr.length; i++) {
            if (yAllArr[i] == (+yAllArr[i - 1] + 1)) {
              yWinArr.push(yAllArr[i])
            } else {
              yWinArr = []
            }
          }
          if (yWinArr.length == 4) {
            if (!flag) {
              setTimeout(function () {
                alert('黑棋获胜!')
                location.reload()
              }, 100)
            } else {
              setTimeout(function () {
                alert('白棋获胜!')
                location.reload()
              }, 100)
            }
          }
        }
        //正斜轴获胜逻辑
        function X_YWin(a, b) {
          let x_yAllArr = []
          let x_yWinArr = []
          if (!flag) {
            blackArr.map(item => {
              if ((item[0] - a) == (item[1] - b)) {
                x_yAllArr.push(item[1])
              }
            })
          } else {
            whiteArr.map(item => {
              if ((item[0] - a) == (item[1] - b)) {
                x_yAllArr.push(item[1])
              }
            })
          }
          x_yAllArr.sort((a, b) => a - b)
          for (let i = 1; i < x_yAllArr.length; i++) {
            if (x_yAllArr[i] == (+x_yAllArr[i - 1] + 1)) {
              x_yWinArr.push(x_yAllArr[i])
            } else {
              x_yWinArr = []
            }
          }
          if (x_yWinArr.length == 4) {
            if (!flag) {
              setTimeout(function () {
                alert('黑棋获胜!')
                location.reload()
              }, 100)
            } else {
              setTimeout(function () {
                alert('白棋获胜!')
                location.reload()
              }, 100)
            }
          }
        }
       //反斜轴获胜逻辑
        function Y_XWin(a, b) {
          let y_xAllArr = []
          let y_xWinArr = []
          if (!flag) {
            blackArr.map(item => {
              if (0 - (item[0] - a) == (item[1] - b)) {
                y_xAllArr.push(item[1])
              }
            })
          } else {
            whiteArr.map(item => {
              if (0 - (item[0] - a) == (item[1] - b)) {
                y_xAllArr.push(item[1])
              }
            })
          }
          y_xAllArr.sort((a, b) => a - b)
          for (let i = 1; i < y_xAllArr.length; i++) {
            if (y_xAllArr[i] == (+y_xAllArr[i - 1] + 1)) {
              y_xWinArr.push(y_xAllArr[i])
            } else {
              y_xWinArr = []
            }
          }
          if (y_xWinArr.length == 4) {
            if (!flag) {
              setTimeout(function () {
                alert('黑棋获胜!')
                location.reload()
              }, 100)
            } else {
              setTimeout(function () {
                alert('白棋获胜!')
                location.reload()
              }, 100)
            }
          }
        }

    3.png

    写在最后

    到这里五子棋的功能就写完了,Vue的基础语法比原生的DOM语法要便捷了不少。判断胜负的逻辑,我还是照搬了上篇文章,感兴趣的可以去看我前面的文章:

    《如何使用原生JS,快速写出一个五子棋小游戏 》

    https://juejin.cn/post/7107172938062757925?share_token=83f7dc0c-3038-4310-b9b5-ba8a7c914af4

    4.png

    【相关视频教程推荐:web前端

    以上就是手把手带你使用Vue开发一个五子棋小游戏!的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:Vue vue.js vue3
    上一篇:Vue指令入门之聊聊六大常用内置指令 下一篇:Vue3和Vue2的差异是什么?全方位对比一下!
    20期PHP线上班

    相关文章推荐

    • 【活动】充值PHP中文网VIP即送云服务器• vue项目首次加载缓慢怎么办?两种解决方案• 9个提高开发效率和性能的Vue小技巧• Vue指令入门之聊聊六大常用内置指令• jquery和vue中的ajax有什么区别• Github 上 8 个不可错过的 Vue 项目,快来收藏!!
    1/1

    PHP中文网