电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

VUE+Canvas實現簡單五子棋游戲的全過程

瀏覽:2日期:2022-09-30 09:36:47
前言

在布局上,五子棋相比那些目標是隨機運動的游戲,實現起來相對簡單許多,思路也很清晰,總共分為:

(1)畫棋盤;

(2)監聽點擊事件畫黑白棋子;

(3)每次落子之后判斷是否有5子相連,有則贏。

最復雜的恐怕就是如何判斷五子棋贏了,那么就先從簡單的開始,畫個棋盤吧~

1、畫棋盤

棋盤很簡單,我們畫個15*15的棋盤,橫線豎線相交錯:

drawCheckerboard() { // 畫棋盤 let _this = this; _this.ctx.beginPath(); _this.ctx.fillStyle = '#fff'; _this.ctx.rect(0, 0, 450, 450); _this.ctx.fill(); for (var i = 0; i < 15; i++) {_this.ctx.beginPath();_this.ctx.strokeStyle = '#D6D1D1';_this.ctx.moveTo(15 + i * 30, 15); //垂直方向畫15根線,相距30px;_this.ctx.lineTo(15 + i * 30, 435);_this.ctx.stroke();_this.ctx.moveTo(15, 15 + i * 30); //水平方向畫15根線,相距30px;_this.ctx.lineTo(435, 15 + i * 30);_this.ctx.stroke(); _this.resultArr.push(new Array(15).fill(0)); }}

先用一個450 * 450 的正方形打底,四周留15寬度的空白,然后畫上間隔為30的線。在for循環里,我們還初始化了一個15 * 15的二維數組,并全部填上0,沒錯,就是記錄落子的。

VUE+Canvas實現簡單五子棋游戲的全過程

2、監聽點擊事件畫黑白棋子

好了,我們在獲取dom的時候順便監聽一下click事件,來畫棋子:

let container = document.getElementById('gobang');

container.addEventListener('click', _this.handleClick);

handleClick(event) { let x = event.offsetX - 70; let y = event.offsetY - 70; if (x < 15 || x > 435 || y < 15 || y > 435) {// 點出界的return; } this.drawChess(x, y); if(this.winGame){this.drawResult();return; } this.whiteTurn = !this.whiteTurn; this.drawText();}

畫棋子的代碼:

drawChess(x, y) { let _this = this; let xLine = Math.round((x - 15) / 30); // 豎線第x條 let yLine = Math.round((y - 15) / 30); // 橫線第y條 if(_this.resultArr[xLine][yLine] !== 0){return; } let grd = _this.ctx.createRadialGradient(xLine * 30 + 15,yLine * 30 + 15,4,xLine * 30 + 15,yLine * 30 + 15,10 ); grd.addColorStop(0, _this.whiteTurn ? '#fff' : '#4c4c4c'); grd.addColorStop(1, _this.whiteTurn ? '#dadada' : '#000'); _this.ctx.beginPath(); _this.ctx.fillStyle = grd; _this.ctx.arc(xLine * 30 + 15,yLine * 30 + 15,10,0,2 * Math.PI,false ); _this.ctx.fill(); _this.ctx.closePath(); _this.setResultArr(xLine, yLine); _this.checkResult(xLine, yLine);}

很容易可以計算出點擊坐標最近的那個棋盤交叉點,當然,如果那里已經落了子,就得return。然后在交點處畫上白子或者黑子,這里用漸變填充使棋子看起來更像那么回事。接著,在對應的二維數組里記錄一下棋子狀況:

setResultArr(m, n) { let _this = this; _this.resultArr[m][n] = _this.whiteTurn ? 1 : 2; // 白棋為1;黑棋為2 }

VUE+Canvas實現簡單五子棋游戲的全過程

3、檢查五子棋輸贏結果

輸贏結果怎么判斷?肉眼看去,無非就是以當前落子為0,0原點建立坐標系,然后判斷0°,180°,45°和135°四條線上是否有連續5子。相比于直接遍歷計數,更好的方法就是取出四條線上的數據,然后判斷是否有相連的5個1或者2字符。

假設我們落子的數組坐標是[m, n]。

(1)橫線的結果數組字符串:this.resultArr[m].join(’’);

(2)豎線的結果數組字符串:

for(let i = 0; i<15; i++){lineHorizontal.push(_this.resultArr[i][n]);}

(3)135°(左上到右下):j從0-15,分別取this.resultArr[m - j][n -j]結果unshift進臨時數組頭部,取this.resultArr[m + j][n + j]放到臨時數組尾部,行成結果;

(4)45°(左下到右上):j從0-15,分別取this.resultArr[m + j][n -j]結果unshift進臨時數組頭部,取this.resultArr[m - j][n + j]放到臨時數組尾部,行成結果;

當然這里面都是要判斷一下數組越界。

得到結果字符串后,我們判斷是否有“22222”或者“11111”這樣的字符串存在,有則說明勝利。

checkResult(m ,n){ // 判斷是否有5子相連 let _this = this; let checkStr = _this.whiteTurn ? CheckStrWhite : CheckStrBlack; // 取出[m,n]橫豎斜四條線的一維數組 let lineVertical = _this.resultArr[m].join(’’); if(lineVertical.indexOf(checkStr) > -1){_this.winGame = true;return; } let lineHorizontal = []; for(let i = 0; i<15; i++){lineHorizontal.push(_this.resultArr[i][n]); } lineHorizontal = lineHorizontal.join(’’); if(lineHorizontal.indexOf(checkStr) > -1){_this.winGame = true;return; } let line135 = []; for(let j = 0; j < 15; j++){if(m - j >= 0 && n - j >= 0){ // 左上角 line135.unshift(_this.resultArr[m - j][n -j]);}if(j > 0 && m + j < 15 && n + j < 15){ // 右下角 line135.push(_this.resultArr[m + j][n + j]);} } line135 = line135.join(’’); if(line135.indexOf(checkStr) > -1){_this.winGame = true;return; } let line45 = []; for(let j = 0; j < 15; j++){if(m + j < 15 && n - j >= 0){ // 右上角 line45.unshift(_this.resultArr[m + j][n -j]);}if(j > 0 && m - j >=0 && n + j < 15){ // 左下角 line45.push(_this.resultArr[m - j][n + j]);} } line45 = line45.join(’’); if(line45.indexOf(checkStr) > -1){_this.winGame = true;return; }}

最后勝出,我們顯示一下是哪方獲勝。

VUE+Canvas實現簡單五子棋游戲的全過程

至此,一個簡單的黑白棋游戲就做好了~~~~~

老規矩,源碼貼上:

<template> <div class='gobang'> <canvas height='600'></canvas> </div></template> <script>const CheckStrWhite = '11111';const CheckStrBlack = '22222';export default { name: 'Gobang', data() { return { ctx: null, winGame: false, whiteTurn: false, // 白棋輪;true-黑棋輪 resultArr: [] // 記錄棋子位置的數組 }; }, mounted() { let _this = this; let container = document.getElementById('gobang'); container.addEventListener('click', _this.handleClick); _this.ctx = container.getContext('2d'); _this.ctx.translate(70,70); _this.drawCheckerboard(); }, computed:{ chessText(){ return this.whiteTurn ? ’白棋’ : ’黑棋’; } }, methods: { drawCheckerboard() { // 畫棋盤 let _this = this; _this.ctx.beginPath(); _this.ctx.fillStyle = '#fff'; _this.ctx.rect(0, 0, 450, 450); _this.ctx.fill(); for (var i = 0; i < 15; i++) {_this.ctx.beginPath();_this.ctx.strokeStyle = '#D6D1D1';_this.ctx.moveTo(15 + i * 30, 15); //垂直方向畫15根線,相距30px;_this.ctx.lineTo(15 + i * 30, 435);_this.ctx.stroke();_this.ctx.moveTo(15, 15 + i * 30); //水平方向畫15根線,相距30px;棋盤為14*14;_this.ctx.lineTo(435, 15 + i * 30);_this.ctx.stroke(); _this.resultArr.push(new Array(15).fill(0)); } _this.drawText(); }, drawChess(x, y) { let _this = this; let xLine = Math.round((x - 15) / 30); // 豎線第x條 let yLine = Math.round((y - 15) / 30); // 橫線第y條 if(_this.resultArr[xLine][yLine] !== 0){return; } let grd = _this.ctx.createRadialGradient(xLine * 30 + 15,yLine * 30 + 15,4,xLine * 30 + 15,yLine * 30 + 15,10 ); grd.addColorStop(0, _this.whiteTurn ? '#fff' : '#4c4c4c'); grd.addColorStop(1, _this.whiteTurn ? '#dadada' : '#000'); _this.ctx.beginPath(); _this.ctx.fillStyle = grd; _this.ctx.arc(xLine * 30 + 15,yLine * 30 + 15,10,0,2 * Math.PI,false ); _this.ctx.fill(); _this.ctx.closePath(); _this.setResultArr(xLine, yLine); _this.checkResult(xLine, yLine); }, setResultArr(m, n) { let _this = this; _this.resultArr[m][n] = _this.whiteTurn ? 1 : 2; // 白棋為1;黑棋為2 },checkResult(m ,n){ // 判斷是否有5子相連 let _this = this; let checkStr = _this.whiteTurn ? CheckStrWhite : CheckStrBlack; // 取出[m,n]橫豎斜四條線的一維數組 let lineVertical = _this.resultArr[m].join(’’); if(lineVertical.indexOf(checkStr) > -1){_this.winGame = true;return; } let lineHorizontal = []; for(let i = 0; i<15; i++){lineHorizontal.push(_this.resultArr[i][n]); } lineHorizontal = lineHorizontal.join(’’); if(lineHorizontal.indexOf(checkStr) > -1){_this.winGame = true;return; } let line135 = []; for(let j = 0; j < 15; j++){if(m - j >= 0 && n - j >= 0){ // 左上角 line135.unshift(_this.resultArr[m - j][n -j]);}if(j > 0 && m + j < 15 && n + j < 15){ // 右下角 line135.push(_this.resultArr[m + j][n + j]);} } line135 = line135.join(’’); if(line135.indexOf(checkStr) > -1){_this.winGame = true;return; } let line45 = []; for(let j = 0; j < 15; j++){if(m + j < 15 && n - j >= 0){ // 右上角 line45.unshift(_this.resultArr[m + j][n -j]);}if(j > 0 && m - j >=0 && n + j < 15){ // 左下角 line45.push(_this.resultArr[m - j][n + j]);} } line45 = line45.join(’’); if(line45.indexOf(checkStr) > -1){_this.winGame = true;return; } }, drawText(){ let _this = this; _this.ctx.clearRect(435 + 60, 0, 100, 70); _this.ctx.fillStyle = '#fff'; _this.ctx.font='20px Arial'; _this.ctx.fillText(’本輪:’ + _this.chessText, 435 + 70, 35); }, drawResult(){ let _this = this; _this.ctx.fillStyle = '#ff2424'; _this.ctx.font='20px Arial'; _this.ctx.fillText(_this.chessText+’勝!’, 435 + 70, 70); }, handleClick(event) { let x = event.offsetX - 70; let y = event.offsetY - 70; if (x < 15 || x > 435 || y < 15 || y > 435) {// 點出界的return; } this.drawChess(x, y); if(this.winGame){this.drawResult();return; } this.whiteTurn = !this.whiteTurn; this.drawText(); } }};</script> <!-- Add 'scoped' attribute to limit CSS to this component only --><style scoped lang='scss'>.gobang { #gobang { background: #2a4546; }}</style>總結

到此這篇關于VUE+Canvas實現簡單五子棋游戲的文章就介紹到這了,更多相關VUE+Canvas五子棋游戲內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
主站蜘蛛池模板: 河南卓美创业科技有限公司-河南卓美防雷公司-防雷接地-防雷工程-重庆避雷针-避雷器-防雷检测-避雷带-避雷针-避雷塔、机房防雷、古建筑防雷等-山西防雷公司 | 庭院灯_太阳能景观灯_草坪灯厂家_仿古壁灯-重庆恒投科技 | 自恢复保险丝_贴片保险丝_力特保险丝_Littelfuse_可恢复保险丝供应商-秦晋电子 | 展厅设计-展馆设计-专业企业展厅展馆设计公司-昆明华文创意 | 光栅尺厂家_数显表维修-苏州泽升精密机械| 运动木地板厂家_体育木地板安装_篮球木地板选购_实木运动地板价格 | 千淘酒店差旅平台-中国第一家针对TMC行业的酒店资源供应平台 | 安全,主动,被动,柔性,山体滑坡,sns,钢丝绳,边坡,防护网,护栏网,围栏,栏杆,栅栏,厂家 - 护栏网防护网生产厂家 | 手术示教系统-数字化手术室系统-林之硕医疗云智能视频平台 | 快速门厂家-快速卷帘门-工业快速门-硬质快速门-西朗门业 | 丁基胶边来料加工,医用活塞边角料加工,异戊二烯橡胶边来料加工-河北盛唐橡胶制品有限公司 | 爆破器材运输车|烟花爆竹运输车|1-9类危险品厢式运输车|湖北江南专用特种汽车有限公司 | 免费个人pos机申请办理-移动pos机刷卡-聚合收款码办理 | 耐热钢-耐磨钢-山东聚金合金钢铸造有限公司 | 北京西风东韵品牌与包装设计公司,创造视觉销售力! | 耐高温风管_耐高温软管_食品级软管_吸尘管_钢丝软管_卫生级软管_塑料波纹管-东莞市鑫翔宇软管有限公司 | 小型单室真空包装机,食品单室真空包装机-百科| 照相馆预约系统,微信公众号摄影门店系统,影楼管理软件-盟百网络 | 电动车头盔厂家_赠品头盔_安全帽批发_山东摩托车头盔—临沂承福头盔 | 氟氨基酮、氯硝柳胺、2-氟苯甲酸、异香兰素-新晨化工 | 法钢特种钢材(上海)有限公司 - 耐磨钢板、高强度钢板销售加工 阀门智能定位器_电液动执行器_气动执行机构-赫尔法流体技术(北京)有限公司 | 隧道窑炉,隧道窑炉厂家-山东艾瑶国际贸易 | 蓝米云-专注于高性价比香港/美国VPS云服务器及海外公益型免费虚拟主机 | 恒湿机_除湿加湿一体机_恒湿净化消毒一体机厂家-杭州英腾电器有限公司 | 深圳彩钢板_彩钢瓦_岩棉板_夹芯板_防火复合彩钢板_长鑫 | 金属软管_不锈钢金属软管_巩义市润达管道设备制造有限公司 | 香港新时代国际美容美发化妆美甲培训学校-26年培训经验,值得信赖! | 上海公司注册-代理记账-招投标审计-上海昆仑扇财税咨询有限公司 上海冠顶工业设备有限公司-隧道炉,烘箱,UV固化机,涂装设备,高温炉,工业机器人生产厂家 | 山东太阳能路灯厂家-庭院灯生产厂家-济南晟启灯饰有限公司 | 电动垃圾车,垃圾清运车-江苏速利达机车有限公司 | ?水马注水围挡_塑料注水围挡_防撞桶-常州瑞轩水马注水围挡有限公司 | 硅PU球场、篮球场地面施工「水性、环保、弹性」硅PU材料生产厂家-广东中星体育公司 | 时代北利离心机,实验室离心机,医用离心机,低速离心机DT5-2,美国SKC采样泵-上海京工实业有限公司 工业电炉,台车式电炉_厂家-淄博申华工业电炉有限公司 | 耐高温电缆厂家-远洋高温电缆 | 隧道风机_DWEX边墙风机_SDS射流风机-绍兴市上虞科瑞风机有限公司 | 啤酒设备-小型啤酒设备-啤酒厂设备-济南中酿机械设备有限公司 | 北京公司注册_代理记账_代办商标注册工商执照-企力宝 | 烟雾净化器-滤筒除尘器-防爆除尘器-除尘器厂家-东莞执信环保科技有限公司 | MVE振动电机_MVE震动电机_MVE卧式振打电机-河南新乡德诚生产厂家 | 流量检测仪-气密性检测装置-密封性试验仪-东莞市奥图自动化科技有限公司 | 便携式谷丙转氨酶检测仪|华图生物科技百科 |