JavaScript Canvas實(shí)現(xiàn)井字棋游戲
本文實(shí)例為大家分享了JavaScript Canvas實(shí)現(xiàn)井字棋游戲的具體代碼,供大家參考,具體內(nèi)容如下
index.html
<!DOCTYPE html> <html> <head> <title>Tic Tac Toe</title> <style> * { padding: 0; margin: 0; } body, html, #game { height: 100%; background: #FCFCFC; } #game { display: flex; align-items: center; justify-content: center; } </style> </head> <body> <div id="game"> <canvas id="canvas" width="300" height="300"></canvas> </div> <script src="game.js"></script> </body> </html>
game.js
players = 2; cell_count = 3; winCount = 3; cell_size = 100; size = cell_size * cell_count; var canvas = document.getElementById('canvas'); canvas.width = size; canvas.height = size; canvas.addEventListener('click', click, false); var ctx = canvas.getContext('2d'); ctx.imageSmoothingEnabled = false; ctx.lineWidth = 3; function clear() { ctx.clearRect(0, 0, canvas.width, canvas.height); } function line(x, y, w, h, color = '#ccc') { ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + w, y + h); ctx.strokeStyle = color; ctx.stroke(); ctx.closePath(); } function fillRect(i, j, color = '#F5F5F5') { ctx.fillStyle = color; ctx.fillRect(i * cell_size, j * cell_size, cell_size, cell_size); } var draw = { grid: (color = '#ccc') => { for (let i = 1; i < cell_count; i++) { line(cell_size * i, 0, 0, size, color); line(0, cell_size * i, size, 0, color); } }, // draw nothing, stub 0: (i, j, _) => { }, // draw X figure 1: (i, j, color = '#3F51B5') => { let left = (i + 0.1) * cell_size, top = (j + 0.1) * cell_size, size = 0.8 * cell_size; line(left, top, size, size, color); line(left + size, top, -size, size, color); }, // draw O figure 2: (i, j, color = '#FF5722') => { ctx.beginPath(); ctx.arc((i + 0.5) * cell_size, (j + 0.5) * cell_size, 0.4 * cell_size, 0, Math.PI * 2, false); ctx.strokeStyle = color; ctx.stroke(); ctx.closePath(); }, // draw Δ figure 3: (i, j, color = '#FDE619'/*'#FFEB3B'*/) => { let center = (i + 0.5) * cell_size, size = Math.sqrt(3) * 0.525 * cell_size, top = (j + 0.125) * cell_size, height = 0.75 * cell_size, step = size / 2; line(center, top, -step, height, color); line(center, top, step, height, color); line(center - step, top + height, size, 0, color); } }; let grid = new Array(cell_count * cell_count).fill(0), get = (i, j) => grid[j * cell_count + i], set = (i, j, val = 0) => grid[j * cell_count + i] = val, isFree = (i, j) => get(i, j) == 0, checkVictory = (who) => { let iterate = getter => { for (let i = 0; i < winCount; i++) if (getter(i) != who) return false; return true; }; let row, col, path = { vertical: _ => iterate(i => get(row + i, col)), horizntl: _ => iterate(j => get(col, row + j)), diagonal: _ => iterate(i => get(row + i, col + i)), opposite: _ => iterate(i => get(row + i, col + winCount - 1 - i)), }; for (row = 0; row <= cell_count - winCount; row++) { for (col = 0; col < cell_count; col++) { if (path.vertical()) return ['vertical', row, col]; if (path.horizntl()) return ['horizntl', col, row]; } for (col = 0; col <= cell_count - winCount; col++) { if (path.diagonal()) return ['diagonal', row, col]; if (path.opposite()) return ['opposite', row, col]; } } return []; }, onWin = ([type, row, col]) => { if (!type) return; let iterate = action => { for (let i = 0; i < winCount; i++) action(i); }; let drawSequence = { vertical: _ => iterate(i => fillRect(row + i, col)), horizntl: _ => iterate(j => fillRect(row, col + j)), diagonal: _ => iterate(i => fillRect(row + i, col + i)), opposite: _ => iterate(i => fillRect(row + i, col + winCount - 1 - i)), }; clear(); drawSequence[type](); draw.grid(); for (let i = 0; i < cell_count; i++) { for (let j = 0; j < cell_count; j++) draw[get(i, j)](i, j); } return true; }; let playerTurn = 0; function click(e) { let i = e.offsetX / cell_size | 0, j = e.offsetY / cell_size | 0; if (isFree(i, j)) { let figure = playerTurn++ % players + 1; set(i, j, figure); draw[figure](i, j); onWin(checkVictory(figure)) && canvas.removeEventListener('click', click, false); ; } } draw.grid();
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JavaScript中自定義swiper組件詳解
- JavaScript中箭頭函數(shù)與普通函數(shù)的區(qū)別詳解
- 用JavaScript實(shí)現(xiàn)輪播圖效果
- javascript實(shí)現(xiàn)點(diǎn)擊按鈕切換圖片
- JavaScript判斷是否為數(shù)組的各種方法匯總
- JavaScript實(shí)現(xiàn)煙花特效(面向?qū)ο?
- 詳細(xì)談?wù)凧avaScript中循環(huán)之間的差異
- javascript代碼簡(jiǎn)寫(xiě)的幾種常用方式匯總
- 13個(gè)JavaScript 一行程序,讓你看起來(lái)就是個(gè)專(zhuān)家
相關(guān)文章
javaScript函數(shù)中執(zhí)行C#代碼中的函數(shù)方法總結(jié)
這篇文章介紹了javaScript函數(shù)中執(zhí)行C#代碼中的函數(shù)方法總結(jié),有需要的朋友可以參考一下2013-08-08js實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制文本功能
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)點(diǎn)擊按鈕復(fù)制文本的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04JS獲取當(dāng)前使用的瀏覽器名字以及版本號(hào)實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇JS獲取當(dāng)前使用的瀏覽器名字以及版本號(hào)實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08js前端技巧之圖片格式轉(zhuǎn)換(File、Blob、base64)
這篇文章主要給大家介紹了關(guān)于js前端技巧之圖片格式轉(zhuǎn)換(File、Blob、base64)的相關(guān)資料,主要記錄一下比較常見(jiàn)的圖片格式(File、Blob、base64)在不同的場(chǎng)景他們之間的相互轉(zhuǎn)換的方法,需要的朋友可以參考下2023-04-04layui監(jiān)聽(tīng)select變化,以及設(shè)置radio選中的方法
今天小編就為大家分享一篇layui監(jiān)聽(tīng)select變化,以及設(shè)置radio選中的方法,具有好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09