這篇文章主要講解了vue實(shí)現(xiàn)五子棋游戲的詳細(xì)代碼,內(nèi)容清晰明了,對此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會有幫助。
成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比湯旺網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式湯旺網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋湯旺地區(qū)。費(fèi)用合理售后完善,10年實(shí)體公司更值得信賴。
思路
1.vue實(shí)現(xiàn)五子棋
空棋盤開局。
畫網(wǎng)格:網(wǎng)格有 15 行 15 列,共有 225 個(gè)交叉點(diǎn)
黑先、白后,交替下子,每次只能下一子
勝負(fù)判定
按照簡單的規(guī)則,從當(dāng)前下子點(diǎn)位的方向判斷()。如果有一個(gè)方向滿足連續(xù)5個(gè)黑子或白子,游戲結(jié)束。
2.支持dom和canvas切換
判斷瀏覽器是否支持canvas:
false: 不支持 切換dom方式
true: 支持 使用canvas
3.實(shí)現(xiàn)悔棋功能
4.實(shí)現(xiàn)撤銷悔棋
例子:
為了簡便,我就把所有寫在一起了,按理來說是要分文件寫的;
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; } .h3Title{ text-align: center; } #app h4{ 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"> <h3 class="h3Title">五子棋</h3> <h4>{{victory}}</h4> <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">當(dāng)前瀏覽器不支持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, //記錄當(dāng)前步數(shù) checkMode: [ //輸贏檢查方向模式 [1, 0], //水平 [0, 1], //豎直 [1, 1], //左斜線 [1, -1], //右斜線 ], flag: false, victory: '', history: [], //歷史記錄位置 historyVal: [], //歷史記錄不被刪除數(shù)組 stepHistory: 0, domPiece:[], // toggle: true //true為canvas,false為dom }, mounted(){ const myCanvas = document.getElementById("myCanvas"); if (!myCanvas.getContext) { alert("當(dāng)前瀏覽器不支持Canvas."); this.toggle = false; this.drawpieceBoardDom(); } else { console.log("當(dāng)前瀏覽器支持Canvas", this.toggle) this.drawpieceBoard(); const canvas = this.$refs.canvas; // 添加點(diǎn)擊監(jiān)聽事件 canvas.addEventListener("click", e => { if (this.flag) { alert("游戲結(jié)束,請重新開始~"); return; } //判斷點(diǎn)擊范圍是否越出棋盤 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 數(shù)組', 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); //檢查當(dāng)前玩家是否贏了游戲 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("當(dāng)前---------------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(); } }, //初始化棋盤數(shù)組 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() { //初始化棋盤數(shù)組 this.pieceArr(); //canvas 繪制 let canvas = this.$refs.canvas // 調(diào)用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() //落在交叉點(diǎn)(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(); //開始一條路徑或重置當(dāng)前的路徑 context.arc(x, y, 15, 0, Math.PI * 2, false); context.closePath(); context.fillStyle = color; context.fill(); }, //勝負(fù)判斷函數(shù) 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('勝負(fù)判斷函數(shù)', count) // console.log('color', color) if (count >= 5) { if (color == 'black') { this.victory = "黑子棋方勝利!"; } else { this.victory = "白子棋方勝利!"; } // 游戲結(jié)束 // console.log('游戲結(jié)束') this.flag = true; } }, //重畫函數(shù) 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 創(chuàng)建一個(gè)二維數(shù)組,下棋或者悔棋都操作這個(gè)數(shù)組。操作完數(shù)據(jù),把畫布全清,重新用數(shù)據(jù)畫一個(gè)棋盤。 // dom 二維數(shù)組刪除數(shù)組最后一項(xiàng), 先清空棋子的填充顏色,在渲染上顏色 regret() { if (!this.toggle) { // console.log("-----dom------this.domPiece",this.domPiece) if (this.history.length && !this.flag) { this.history.pop(); //刪除數(shù)組最后一項(xiàng) 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); // } //這個(gè)太耗性能了 // 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("已經(jīng)不能悔棋了~") } } else { if (this.history.length && !this.flag) { this.history.pop(); //刪除數(shù)組最后一項(xiàng) //重畫 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("已經(jīng)不能悔棋了~") } } }, //撤銷悔棋 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; //調(diào)用初始化棋盤數(shù)組函數(shù) that.pieceArr(); //創(chuàng)建一個(gè)容器 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() { //判斷游戲是否結(jié)束 if (!that.flag) { if (that.pieceMapArr[m][n] == 0) { //黑白交換下棋 // console.log(this); // console.log('落下棋子', that.pieceColor[that.step % 2]) //確保填充顏色正確進(jìn)行了判斷 if (this.className == "qz" && that.step % 2 == 0 && this.style.backgroundColor == "") { //下棋填充黑顏色 this.style.backgroundColor = that.pieceColor[that.step % 2]; //寫入棋盤數(shù)組 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]; //寫入棋盤數(shù)組 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); } //檢查當(dāng)前是否贏了 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("游戲結(jié)束,請重新開始~"); return; } } } } }, } }); </script> </body> </html>
看完上述內(nèi)容,是不是對vue實(shí)現(xiàn)五子棋游戲的詳細(xì)代碼有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)頁標(biāo)題:vue實(shí)現(xiàn)五子棋游戲的詳細(xì)代碼
當(dāng)前鏈接:http://vcdvsql.cn/article6/gjeeig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、外貿(mào)建站、微信公眾號、用戶體驗(yàn)、企業(yè)網(wǎng)站制作、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)