canvas实现简易五子棋

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #myCanvas {
            background-color: cadetblue;
        }
    </style>
</head>

<body>
    <canvas id="myCanvas"></canvas>
    <script>
        class Gomoku {
            constructor(canvas, context) {
                this.canvas = canvas;
                this.context = context;
                this.canvas.width = 750;
                this.canvas.height = 750;
                this.canvas.addEventListener('click', this.handleClick.bind(this));
                this.canvas.addEventListener('mousemove', this.handleMouseMove.bind(this));
                this.init();
            }
            //初始化
            init() {
                this.isBlack = true;
                this.chessGame = new Array(15).fill(null).map(() => new Array(15).fill(null));
                this.chessboard()
            }
            handleClick(event) {
                let x = Math.round((event.offsetX - 25) / 50)
                let y = Math.round((event.offsetY - 25) / 50)
                //如果该位置有棋子,则无法落子
                if (this.chessGame[x][y]) {
                    return;
                }
                this.chessGame[x][y] = { isBlack: this.isBlack }
                this.drawChess(x, y, this.isBlack)
                this.x = x;
                this.y = y;
                //四条线的两端分别判断是否五子连线
                for (let i = 0; i < 4; i++) {
                    if (this.line(i, 'left') + this.line(i, 'right') == 4) {
                        return setTimeout(() => {
                            alert(this.isBlack ? '黑棋获胜' : '白棋获胜')
                            this.init()
                        }, 1)
                    }
                }
                this.isBlack = !this.isBlack
            }
            handleMouseMove(event) {
                let x = Math.round((event.offsetX - 25) / 50)
                let y = Math.round((event.offsetY - 25) / 50)
                //如果该位置有棋子,则无法落子
                if (!this.chessGame[x][y] && (x != this.willX || y != this.willY)) {
                    this.canvas.style.cursor = 'pointer'
                    this.context.clearRect(0, 0, 750, 750)
                    this.chessboard()
                    this.drawChess(x, y, this.isBlack, 0.8)
                    this.willX = x;
                    this.willY = y;
                }
                else if (this.chessGame[x][y] && (x != this.willX || y != this.willY)) {
                    this.canvas.style.cursor = 'default'
                    this.context.clearRect(0, 0, 750, 750)
                    this.chessboard()
                    this.willX = x;
                    this.willY = y;
                }
                else if (!this.chessGame[x][y] && !(x != this.willX || y != this.willY)) {
                    this.canvas.style.cursor = 'pointer'
                }
                else {
                    this.canvas.style.cursor = 'default'

                }
            }
            //创建棋盘
            chessboard() {
                this.context.clearRect(0, 0, 750, 750)
                let chessboard = new Path2D();
                for (let i = 0; i < 15; i++) {
                    chessboard.moveTo(50 * i + 25, 25)
                    chessboard.lineTo(50 * i + 25, 725)
                    this.context.stroke(chessboard)
                }
                for (let i = 0; i < 15; i++) {
                    chessboard.moveTo(25, 50 * i + 25)
                    chessboard.lineTo(725, 50 * i + 25)
                    this.context.stroke(chessboard)
                }
                this.chessGame.map((item1, x) => {
                    item1.map((item2, y) => {
                        if (item2) {
                            this.drawChess(x, y, item2.isBlack)
                        }

                    })
                })
            }
            //画棋子
            drawChess(x, y, isBlack, a = 1) {
                let chess = new Path2D();
                chess.arc(x * 50 + 25, y * 50 + 25, 20, 0, 2 * Math.PI)
                let cx = isBlack ? x * 50 + 15 : x * 50 + 35
                let cy = isBlack ? y * 50 + 15 : y * 50 + 35
                let grd = this.context.createRadialGradient(cx, cy, 0, cx, cy, 20)
                grd.addColorStop(0, isBlack ? ("rgba(204,204,204," + a + ")") : ("rgba(102,102,102," + a + ")"));
                grd.addColorStop(1, isBlack ? ("rgba(0,0,0," + a + ")") : ("rgba(255,255,255," + a + ")"));
                this.context.fillStyle = grd;
                this.context.fill(chess)
                // 边框虚线
                // this.context.save()
                // context.setLineDash([20, 5]);  // [实线长度, 间隙长度]
                // context.lineDashOffset = -0;
                // this.context.strokeStyle = this.isBlack ? 'black' : 'white';
                // this.context.stroke(chess)
                // this.context.restore()
            }
            //判断五子连线
            line(times, direction) {
                let count = 0;
                let x;
                let y;
                for (let i = 1; i < 5; i++) {
                    switch (times) {
                        case 0:
                            x = direction == 'left' ? this.x + i : this.x - i;
                            y = this.y;
                            break;
                        case 1:
                            x = this.x;
                            y = direction == 'left' ? this.y + i : this.y - i;
                            break;
                        case 2:
                            x = direction == 'left' ? this.x + i : this.x - i;
                            y = direction == 'left' ? this.y + i : this.y - i;
                            break;
                        case 3:
                            x = direction == 'left' ? this.x + i : this.x - i;
                            y = direction == 'left' ? this.y - i : this.y + i;
                            break;
                    }
                    if (this.chessGame[x] && this.chessGame[x][y] && this.chessGame[x][y].isBlack == this.isBlack) {
                        count++
                    }
                    else {
                        break;
                    }
                }
                return count
            }
        }
        let canvas = document.getElementById('myCanvas')
        let context = canvas.getContext('2d')
        let gomuku = new Gomoku(canvas, context);
    </script>
</body>

</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值