vue实现五子棋游戏
程序员文章站
2022-04-09 16:15:21
本文实例为大家分享了vue实现五子棋游戏的具体代码,供大家参考,具体内容如下思路1.vue实现五子棋空棋盘开局。画网格:网格有 15 行 15 列,共有 225 个交叉点黑先、白后,交替下子,每次只能...
本文实例为大家分享了vue实现五子棋游戏的具体代码,供大家参考,具体内容如下
思路
1.vue实现五子棋
空棋盘开局。
画网格:网格有 15 行 15 列,共有 225 个交叉点
黑先、白后,交替下子,每次只能下一子
胜负判定
按照简单的规则,从当前下子点位的方向判断()。如果有一个方向满足连续5个黑子或白子,游戏结束。
2.支持dom和canvas切换
判断浏览器是否支持canvas:
false: 不支持 切换dom方式
true: 支持 使用canvas
3.实现悔棋功能
4.实现撤销悔棋
例子:
为了简便,我就把所有写在一起了,按理来说是要分文件写的;
github io:链接
<!doctype html> <html> <head> <meta charset="utf-8"> <title>简易五子棋</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script> <style> body { margin: 0; padding: 0; } #app{ padding-left: 30%; width: 500px; } .h2title{ text-align: center; } #app h3{ color: red; } .fbuttons{ margin-bottom: 1rem; } .main{ background-color: bisque; width: 30rem; } .restart,.regret,.undo{ background: bisque; padding: 6px 10px; border-radius: 6px; font-size: 12px; cursor: pointer; } #chess { position: relative; width: 440px; height: 450px; padding-left: 30px; padding-top: 30px; background-color: bisque; } #chess .squre { width: 28px; height: 28px; border: 1px solid #666; float: left; } #box01 .squre:hover { background-color: pink; } #box01 { position: absolute; margin: 0 auto; width: 450px; height: 450px; top: 15px; left: 15px; } #box01 .qz { /* width: 28px; height: 28px; */ width: 30px; height: 30px; border: 0px solid #c7c7c7; float: left; border-radius: 50%; /* margin: 1px; */ } #box01 .qz:hover { background-color: pink; } .toggle{ float: right; } </style> </head> <body> <div id="app"> <h2 class="h2title">五子棋</h2> <h3>{{victory}}</h3> <div class="fbuttons"> <input type="button" value="重新开始" class="restart" @click="restartinit()" /> <input type="button" value="悔棋" class="regret" @click="regret()" /> <input type="button" value="撤销悔棋" class="undo" @click="undo()" /> <input type="button" :value="toggle?'切换dom':'切换canvas'" class="toggle" @click="togglef()" /> </div> <div class="main"> <canvas v-show="toggle" id="mycanvas" ref="canvas" width="480" height="480">当前浏览器不支持canvas</canvas> <div v-show="!toggle" id="chess" ref="chessbox"> <!-- <div id="box01"></div> <div id="box02"></div> --> </div> </div> </div> <!-- --> <script> var app = new vue({ el: "#app", data: { piecemaparr: [], //记录棋盘落子情况 piececolor: ["black", "white"], //棋子颜色 step: 0, //记录当前步数 checkmode: [ //输赢检查方向模式 [1, 0], //水平 [0, 1], //竖直 [1, 1], //左斜线 [1, -1], //右斜线 ], flag: false, victory: '', history: [], //历史记录位置 historyval: [], //历史记录不被删除数组 stephistory: 0, dompiece:[], // toggle: true //true为canvas,false为dom }, mounted(){ const mycanvas = document.getelementbyid("mycanvas"); if (!mycanvas.getcontext) { alert("当前浏览器不支持canvas."); this.toggle = false; this.drawpieceboarddom(); } else { console.log("当前浏览器支持canvas", this.toggle) this.drawpieceboard(); const canvas = this.$refs.canvas; // 添加点击监听事件 canvas.addeventlistener("click", e => { if (this.flag) { alert("游戏结束,请重新开始~"); return; } //判断点击范围是否越出棋盘 if (e.offsetx < 25 || e.offsetx > 450 || e.offsety < 25 || e.offsety > 450) { return; } let dx = math.floor((e.offsetx + 15) / 30) * 30; let dy = math.floor((e.offsety + 15) / 30) * 30; console.log('this.piecemaparr 数组', this.piecemaparr) if (this.piecemaparr[dx / 30 - 1][dy / 30 - 1] == 0) { console.log('落下棋子', dx, dy, this.piececolor[this.step % 2]) this.drawpiece(dx, dy, this.piececolor[this.step % 2]); //落下棋子 this.piecemaparr[dx / 30 - 1][dy / 30 - 1] = this.piececolor[this.step % 2]; //历史记录位置 this.history.length = this.step; this.history.push({ dx, dy, color: this.piececolor[this.step % 2] }); this.historyval.push({ dx, dy, color: this.piececolor[this.step % 2] }); this.stephistory++ console.log('this.history', this.history); //检查当前玩家是否赢了游戏 for (var i = 0; i < 4; i++) { this.checkwin(dx / 30 - 1, dy / 30 - 1, this.piececolor[this.step % 2], this.checkmode[i]); } this.step++; } else { alert("不能落在有棋子的地方!"); } }); } }, methods: { togglef() { this.toggle = !this.toggle; if (!this.toggle) { // console.log("当前---------------1") // let elem = document.getelementbyid('box01'); // if (elem !== null) { // elem.parentnode.removechild(elem); // let elem02 = document.getelementbyid('box02'); // elem02.parentnode.removechild(elem02); // } // this.drawpieceboarddom(); this.restartinit() } else { this.restartinit() // this.drawpieceboard(); } }, //初始化棋盘数组 piecearr() { for (let i = 0; i < 15; i++) { this.piecemaparr[i] = []; for (let j = 0; j < 15; j++) { this.piecemaparr[i][j] = 0; } } }, //重新开始 restartinit() { if (!this.toggle) { // console.log("-----dom-------") var elem = document.queryselector('#box01'); // console.log("elem",elem) if (elem != null ) { elem.parentnode.removechild(elem); let elem02 = document.queryselector('#box02'); elem02.parentnode.removechild(elem02); } this.drawpieceboarddom(); this.flag = false; this.step = 0; this.stephistory = 0; this.historyval = []; this.history = []; } else { //重画 this.repaint(); // 绘制棋盘 this.drawpieceboard(); this.flag = false; this.step = 0; this.stephistory = 0; this.historyval = []; this.history = []; } }, //---------canvas---------- // 绘制棋盘 drawpieceboard() { //初始化棋盘数组 this.piecearr(); //canvas 绘制 let canvas = this.$refs.canvas // 调用canvas元素的getcontext 方法访问获取2d渲染的上下文 let context = canvas.getcontext("2d"); context.strokestyle = '#666' for (let i = 0; i < 15; i++) { //落在方格(canvas 的宽高是450) // context.moveto(15 + i * 30, 15) // context.lineto(15 + i * 30, 435) // context.stroke() // context.moveto(15, 15 + i * 30) // context.lineto(435, 15 + i * 30) // context.stroke() //落在交叉点(480) context.beginpath(); context.moveto((i + 1) * 30, 30); context.lineto((i + 1) * 30, canvas.height - 30); context.closepath(); context.stroke(); context.beginpath(); context.moveto(30, (i + 1) * 30); context.lineto(canvas.width - 30, (i + 1) * 30); context.closepath(); context.stroke(); } }, //绘制棋子 drawpiece(x, y, color) { let canvas = this.$refs.canvas let context = canvas.getcontext("2d"); context.beginpath(); //开始一条路径或重置当前的路径 context.arc(x, y, 15, 0, math.pi * 2, false); context.closepath(); context.fillstyle = color; context.fill(); }, //胜负判断函数 checkwin(x, y, color, mode) { let count = 1; //记录 for (let i = 1; i < 5; i++) { if (this.piecemaparr[x + i * mode[0]]) { if (this.piecemaparr[x + i * mode[0]][y + i * mode[1]] == color) { count++; } else { break; } } } for (let j = 1; j < 5; j++) { if (this.piecemaparr[x - j * mode[0]]) { if (this.piecemaparr[x - j * mode[0]][y - j * mode[1]] == color) { count++; } else { break; } } } // console.log('胜负判断函数', count) // console.log('color', color) if (count >= 5) { if (color == 'black') { this.victory = "黑子棋方胜利!"; } else { this.victory = "白子棋方胜利!"; } // 游戏结束 // console.log('游戏结束') this.flag = true; } }, //重画函数 repaint() { //重画 let canvas = this.$refs.canvas; let context = canvas.getcontext("2d"); context.fillstyle = "bisque"; context.fillrect(0, 0, canvas.width, canvas.height); context.beginpath(); context.closepath(); }, //悔棋: // canvas 创建一个二维数组,下棋或者悔棋都操作这个数组。操作完数据,把画布全清,重新用数据画一个棋盘。 // dom 二维数组删除数组最后一项, 先清空棋子的填充颜色,在渲染上颜色 regret() { if (!this.toggle) { // console.log("-----dom------this.dompiece",this.dompiece) if (this.history.length && !this.flag) { this.history.pop(); //删除数组最后一项 console.log("-----dom------this.history", this.history) //重画 this.piecearr(); // let elem = document.getelementbyid('box01'); // if (elem !== null) { // elem.parentnode.removechild(elem); // let elem02 = document.getelementbyid('box02'); // elem02.parentnode.removechild(elem02); // } //这个太耗性能了 // this.drawpieceboarddom(); // 清空棋子的填充颜色 this.dompiece.foreach(e => { e.foreach(qz => { qz.style.backgroundcolor = ''; }) }); // 渲染棋子颜色 this.history.foreach(e => { this.dompiece[e.m][e.n].style.backgroundcolor = e.color this.piecemaparr[e.m][e.n] = e.color; }); this.step-- } else { alert("已经不能悔棋了~") } } else { if (this.history.length && !this.flag) { this.history.pop(); //删除数组最后一项 //重画 this.repaint(); // 绘制棋盘 this.drawpieceboard(); //绘制棋子 this.history.foreach(e => { this.drawpiece(e.dx, e.dy, e.color) this.piecemaparr[e.dx / 30 - 1][e.dy / 30 - 1] = e.color; }); this.step-- } else { alert("已经不能悔棋了~") } } }, //撤销悔棋 undo() { if (!this.toggle) { // console.log("-----dom------this.dompiece",this.dompiece) if ((this.historyval.length > this.history.length) && !this.flag) { this.history.push(this.historyval[this.step]) console.log("-----dom------this.history", this.history) // 清空棋子的填充颜色 this.dompiece.foreach(e => { e.foreach(qz => { qz.style.backgroundcolor = ''; }) }); // 渲染棋子颜色 this.history.foreach(e => { this.dompiece[e.m][e.n].style.backgroundcolor = e.color this.piecemaparr[e.m][e.n] = e.color; }); this.step++ } else { alert("不能撤销悔棋了~") } } else { if ((this.historyval.length > this.history.length) && !this.flag) { this.history.push(this.historyval[this.step]) //重画 this.repaint(); // 绘制棋盘 this.drawpieceboard(); this.history.foreach(e => { this.drawpiece(e.dx, e.dy, e.color) this.piecemaparr[e.dx / 30 - 1][e.dy / 30 - 1] = e.color; }); this.step++ } else { alert("不能撤销悔棋了~") } } }, // -----------dom----------- drawpieceboarddom() { // console.log("this", this) let that = this; //调用初始化棋盘数组函数 that.piecearr(); //创建一个容器 const box = document.queryselector("#chess"); const box01 = document.createelement("div"); box01.setattribute("id", "box01"); box.appendchild(box01); //画棋盘 const chess01 = document.queryselector("#box01"); const box02 = document.createelement("div"); box02.setattribute("id", "box02"); box.appendchild(box02); let arr = new array(); for (let i = 0; i < 14; i++) { arr[i] = new array(); for (let j = 0; j < 14; j++) { arr[i][j] = document.createelement("div"); arr[i][j].setattribute("class", "squre"); box02.appendchild(arr[i][j]); } } //画棋子 let arr01 = this.dompiece; for (let i = 0; i < 15; i++) { arr01[i] = new array(); for (let j = 0; j < 15; j++) { arr01[i][j] = document.createelement("div"); arr01[i][j].setattribute("class", "qz"); chess01.appendchild(arr01[i][j]); } } // console.log("this.dompiece",this.dompiece) // 填充颜色和判断 for (let m = 0; m < 15; m++) { for (let n = 0; n < 15; n++) { arr01[m][n].onclick = function() { //判断游戏是否结束 if (!that.flag) { if (that.piecemaparr[m][n] == 0) { //黑白交换下棋 // console.log(this); // console.log('落下棋子', that.piececolor[that.step % 2]) //确保填充颜色正确进行了判断 if (this.classname == "qz" && that.step % 2 == 0 && this.style.backgroundcolor == "") { //下棋填充黑颜色 this.style.backgroundcolor = that.piececolor[that.step % 2]; //写入棋盘数组 that.piecemaparr[m][n] = that.piececolor[that.step % 2]; //历史记录位置 that.history.length = that.step; that.history.push({ m, n, color: that.piececolor[that.step % 2] }); that.historyval.push({ m, n, color: that.piececolor[that.step % 2] }); that.stephistory++ console.log('this.history', that.history); } else if (this.classname == "qz" && that.step % 2 != 0 && this.style.backgroundcolor == "") { //下棋填充白颜色 this.style.backgroundcolor = that.piececolor[that.step % 2]; //写入棋盘数组 that.piecemaparr[m][n] = that.piececolor[that.step % 2]; //历史记录位置 that.history.length = that.step; that.history.push({ m, n, color: that.piececolor[that.step % 2] }); that.historyval.push({ m, n, color: that.piececolor[that.step % 2] }); that.stephistory++ console.log('this.history', that.history); } //检查当前是否赢了 for (var i = 0; i < 4; i++) { that.checkwin(m, n, that.piececolor[that.step % 2], that.checkmode[i]); } that.step++; // console.log('that.step', that.step); } else { alert("不能落在有棋子的地方!"); return; } } else { // that.flag = true; alert("游戏结束,请重新开始~"); return; } } } } }, } }); </script> </body> </html>
更多文章可以点击《vue.js前端组件学习教程》学习阅读。
关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。
更多vue学习教程请阅读专题《vue实战教程》
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。