Vue实现五子棋小游戏

Eleanor ·
更新时间:2024-09-20
· 1836 次阅读

本文实例为大家分享了Vue实现五子棋小游戏的具体代码,供大家参考,具体内容如下

<!DOCTYPE html> <html> <head>     <meta charset="utf-8">     <title>五子棋</title>     <script src="./configJS/vue.js"></script>     <script src="./configJS/jQuery 1.10.2.js"></script>     <style>         .fiveInRow {             position: absolute;             width: 100%;         }         .fiveStar {             position: absolute;             display: flex;             width: 542px;             height: 720px;             margin: -24px 65px;             justify-content: space-around;             align-items: center;         }         .starGroup {             height: 100%;             display: flex;             flex-direction: column;             justify-content: space-around;         }         .star {             width: 10px;             height: 10px;             border-radius: 50%;             background: black;         }         .boxRow {             position: absolute;             display: flex;             margin: 20px;             border: 1px solid black;             box-sizing: border-box;         }         .box {             width: 45px;             height: 45px;             border: 1px solid black;             box-sizing: border-box;         }         .chessBlock {             position: absolute;             margin: 20px;         }         .chessBox {             position: absolute;             z-index: 9;             width: 42px;             height: 42px;             display: flex;             justify-content: center;             align-items: center;         }         .chess {             width: 40px;             height: 40px;             border-radius: 50%;             border: 1px solid black;             box-sizing: border-box;         }         .overCover {             position: absolute;             display: flex;             flex-direction: column;             justify-content: center;             align-items: center;             width: 632px;             height: 632px;             color: red;             z-index: 11;         }         .btnGroup {             position: absolute;             top: 700px;             left: 235px;             display: flex;         }         .btnGroup button {             margin: 0 10px;         }     </style> </head> <body>     <div class="fiveInRow">         <!-- 棋盘五星层 -->         <div class="fiveStar">             <div class="starGroup">                 <div class="star"></div>                 <div class="star"></div>             </div>             <div class="star"></div>             <div class="starGroup">                 <div class="star"></div>                 <div class="star"></div>             </div>         </div>         <!-- 落子层 -->         <div class="chessBlock"></div>         <!-- 棋盘网格层 -->         <div class="boxRow" @click="downChess($event)"></div>         <!-- 功能BTN -->         <div class="btnGroup">             <button @click="giveUp()">认输</button>             <button @click="regret()">悔棋</button>             <button @click="openNew()">重开</button>         </div>     </div> </body> <script>     new Vue({         el: ".fiveInRow",         data: {             boxSize: 15, //棋盘大小             chessType: "black", //棋子类型,默认为黑             blackList: [], //黑子列表             whiteList: [], //白子列表             totleNum: 0, //落子总数             isOver: 0 //游戏是否结束         },         created() {             this.createBox()         },         watch: {             totleNum(val) {                 // 监听棋盘落子数                 let boxRow = $(".boxRow")[0];                 let overCover = `<div class="overCover">                     <h1 style="color:red;">棋盘满了,下一把吧!!!</h1>                 </div>`;                 if (val === this.boxSize * this.boxSize) {                     boxRow.innerHTML += overCover;                     this.isOver = 1;                 }             }         },         methods: {             createBox() {                 // 创建棋盘网格                 let box = `<div class="box"></div>`;                 let boxRow = $(".boxRow")[0];                 for (let i = 1; i < this.boxSize; i++) {                     let boxCloum = `<div class="boxCloum">`;                     for (let j = 1; j < this.boxSize; j++) {                         boxCloum += box;                     }                     boxRow.innerHTML += boxCloum + `</div>`;                 }             },             downChess(ev) {                 // 判断落子                 if (!this.isOver) {                     this.down(ev);                 } else {                     let overCover = $(".overCover")[0];                     let newSpan = `<h2>游戏已经结束了,请重新开始!</h2>`;                     if (overCover.children.length <= 3) overCover.innerHTML += newSpan;                 }             },             down(ev) {                 // 落子                 let chessBlock = $(".chessBlock")[0];                 let layerX = this.getLayer(ev.layerX);                 let layerY = this.getLayer(ev.layerY);                 if (layerX >= 0 && layerY >= 0) {                     let chessTemp = `<div                          class="chessBox" style="left:${layerX-21}px;top:${layerY-21}px;"                     ><span class="chess" style="background:${this.chessType};"></span></div>`;                     chessBlock.innerHTML += chessTemp;                     this.totleNum++;                     if (this.chessType === "black") {                         this.blackList.push([layerX, layerY]);                         this.isFive(this.blackList);                         this.chessType = "white";                     } else {                         this.whiteList.push([layerX, layerY]);                         this.isFive(this.whiteList);                         this.chessType = "black";                     }                 } else {                     console.log("瞅哪呢?看准点下!");                 }             },             getLayer(val) {                 // 获取落点相对位置                 if (val % 45 <= 20) {                     return val - val % 45;                 } else if (val % 45 >= 25) {                     return val - val % 45 + 45;                 } else {                     return -1;                 }             },             isFive(list) {                 // 判断是否落成五子                 this.isFiveInStraight(list, 0, 1);                 this.isFiveInStraight(list, 1, 0);                 this.isFiveInSlope(list, -1);                 this.isFiveInSlope(list, 1);             },             isFiveInStraight(list, a, b) {                 // 判断五子是否在水平线或垂直线                 let listSGT = {};                 for (let i = 0; i < list.length; i++) {                     if (!listSGT[list[i][b]]) {                         listSGT[list[i][b]] = [list[i][a]];                     } else {                         listSGT[list[i][b]].push(list[i][a]);                         this.isFiveNearby(listSGT[list[i][b]]);                     }                 }             },             isFiveInSlope(list, slope) {                 // 判断五子是否在正斜线或反斜线                 let listSLP = {};                 for (let i = 0; i < list.length; i++) {                     let b = list[i][1] - slope * list[i][0];                     if (!listSLP[b]) {                         listSLP[b] = [list[i][0]];                     } else {                         listSLP[b].push(list[i][0]);                         this.isFiveNearby(listSLP[b]);                     }                 }             },             isFiveNearby(arr) {                 // 判断五子是否相邻,连成一线                 let idx = 0;                 let player = this.chessType === "black" ? "Black(黑)" : "White(白)";                 if (arr.length >= 5) {                     arr.sort((a, b) => a - b)                     for (let i = 1; i < arr.length; i++) {                         idx = arr[i] - arr[i - 1] === 45 ? idx + 1 : 0;                         if (idx === 4) this.gameOver(player);                     }                 }             },             gameOver(player) {                 // 游戏结束                 console.log(player + " Win!!!");                 let boxRow = $(".boxRow")[0];                 let overCover = `<div class="overCover"><h1>${player} Win!!!</h1></div>`;                 boxRow.innerHTML += overCover;                 this.isOver = 1;             },             giveUp() {                 // 认输投降                 let player = this.chessType === "black" ? "White(白)" : "Black(黑)";                 if (!this.isOver) this.gameOver(player);             },             regret() {                 // 悔棋                 if (this.totleNum > 0 && !this.isOver) {                     let chessBlock = $(".chessBlock")[0];                     chessBlock.removeChild(chessBlock.children[--this.totleNum]);                     if (this.chessType === "black") {                         this.whiteList.pop();                         this.chessType = "white";                     } else {                         this.blackList.pop();                         this.chessType = "black";                     }                 } else {                     console.log("一个子都没有,悔个鸡儿悔!");                 }             },             openNew() {                 // 重新开始                 let chessBlock = $(".chessBlock")[0];                 let boxRow = $(".boxRow")[0];                 for (let i = this.totleNum - 1; i >= 0; i--) {                     chessBlock.removeChild(chessBlock.children[i]);                 }                 if (boxRow.children[14]) boxRow.removeChild(boxRow.children[14]);                 this.chessType = "black";                 this.blackList = [];                 this.whiteList = [];                 this.totleNum = this.isOver = 0;             }         }     }) </script> </html> 主要思路 1.画棋盘

小雨采用了最直接, 最暴力的方式, 就是把一堆小方块堆起来, 加上边框, 棋盘有了…什么? 你问我那五个点怎么画上去的? 页面上试出来的.

2.落子

落子是比较讲究的. 首先获取鼠标点击事件中的layerX, layerY, 这是鼠标点击的相对位置, 在本例中是比较好用的. 然后通过 getLayer() 函数获取点击点最近的网格点, 如下图, 鼠标点击在红框内则落子. 最后在相比网格点半个棋子位的地方落子就OK了.

3.判断获胜条件 isFive(list) {                 // 判断是否落成五子                 this.isFiveInStraight(list, 0, 1);                 this.isFiveInStraight(list, 1, 0);                 this.isFiveInSlope(list, -1);                 this.isFiveInSlope(list, 1);             },             isFiveInStraight(list, a, b) {                 // 判断五子是否在水平线或垂直线                 let listSGT = {};                 for (let i = 0; i < list.length; i++) {                     if (!listSGT[list[i][b]]) {                         listSGT[list[i][b]] = [list[i][a]];                     } else {                         listSGT[list[i][b]].push(list[i][a]);                         this.isFiveNearby(listSGT[list[i][b]]);                     }                 }             },             isFiveInSlope(list, slope) {                 // 判断五子是否在正斜线或反斜线                 let listSLP = {};                 for (let i = 0; i < list.length; i++) {                     let b = list[i][1] - slope * list[i][0];                     if (!listSLP[b]) {                         listSLP[b] = [list[i][0]];                     } else {                         listSLP[b].push(list[i][0]);                         this.isFiveNearby(listSLP[b]);                     }                 }             },             isFiveNearby(arr) {                 // 判断五子是否相邻,连成一线                 let idx = 0;                 let player = this.chessType === "black" ? "Black(黑)" : "White(白)";                 if (arr.length >= 5) {                     arr.sort((a, b) => a - b)                     for (let i = 1; i < arr.length; i++) {                         idx = arr[i] - arr[i - 1] === 45 ? idx + 1 : 0;                         if (idx === 4) this.gameOver(player);                     }                 }             },

这里主要有4个函数: isFive(), isFiveInStraight(), isFiveInSlope() 和 isFiveNearby().

isFive(): 这个只是调用后续函数的函数, 它将获胜条件分成了4类: 横线获胜, 竖线获胜, 斜率为1的斜线获胜 和 斜率为-1的斜线获胜.

isFiveInStraight(): 判断 横线获胜 竖线获胜 的功能函数. 这里的主要难点就是listSGT 对象的创建, 能否想到要用对象来实现落子的分类, 是这个函数的关键. 在 横线获胜 中, 将落子的layerY 坐标作为对象的属性, 将有相同layerY 坐标的棋子的layerX 组成一个数组作为属性的值. 竖线获胜 同理.

isFiveInSlope(): 判断 斜率为1的斜线获胜 斜率为-1的斜线获胜 的功能函数. 与 isFiveInStraight() 不同的是, 在创建listSLP 对象时, 以直线函数 y = k x + b y = kx+by=kx+b 中截距(b) 作为对象的属性, 以落子的layerX 坐标组成的数组作为属性的值, 其实用落子的layerY坐标也是一样的.

isFiveNearby(): 判断五子是否相邻的功能函数. 此函数直接获取上两个函数中所创建对象的值, 也就是落子坐标组成的数组. 首先判断数组长度是否大于5, 毕竟能少走一步是一步嘛. 之后将数组从小到大排序, 计算相邻两位的差, 并记录. 连续记录4次获胜.



VUE 小游戏 五子棋

需要 登录 后方可回复, 如果你还没有账号请 注册新账号