使用canvas画象棋界面

// 地图宽高  8/  8 +河界
// 格子
import {c} from "vite/dist/node/types.d-aGj9QkWt";

const lattice = 100;
const map = {
    width: lattice * 8,
    height: lattice * 8 + 100,
}

// 每个格子大小
class Chess {
    private canvas: HTMLCanvasElement;
    private width: number;
    private height: number;
    private ctx: CanvasRenderingContext2D;
    private initKios = ["車", "馬", "象", "士", "将", "士", "象", "馬", "車", "炮", "兵", "卒", "帅"]
    // 红方
    private redKiko: Kiko[] = []
    // 黑方
    private blackKiko: Kiko[] = []
    // 棋子画布
    private kikoCanvas: HTMLCanvasElement;
    private kikoCanvasCtx: CanvasRenderingContext2D;

    // 先手 // 默认红方
    private isStatus: ColorType = ColorType.RED;
    // 当前选中棋子
    private currentKiko: Kiko;

    constructor(canvas: HTMLCanvasElement) {
        this.canvas = canvas;
        this.ctx = this.canvas.getContext("2d")!;
        this.init();
    }

    init() {
        const {clientWidth, clientHeight} = document.documentElement;
        this.width = clientWidth;
        this.height = clientHeight;
        this.canvas.width = this.width;
        this.canvas.height = this.height;
        this.ctx.translate(100, 50)
        this.createCanvas();
        this.drawMap();
        this.drawKiKos();
    }

    createCanvas() {
        if (this.kikoCanvas) return;
        const newCanvas = document.createElement("canvas");
        this.kikoCanvas = newCanvas;
        newCanvas.width = map.width + 100;
        newCanvas.height = map.height + 150;
        newCanvas.style.position = "absolute";
        newCanvas.style.left = "550px";
        newCanvas.style.top = "-10px";
        newCanvas.style.width = map.width + 100 + "px";
        newCanvas.style.height = map.height + 150 + "px";
        // newCanvas.style.background="red";
        // this.canvas.appendChild(newCanvas);
        this.canvas.parentNode!.appendChild(newCanvas)
        this.kikoCanvasCtx = this.kikoCanvas.getContext("2d")!;
        this.kikoCanvasCtx.translate(50, 50)
        this.kikoCanvas.addEventListener("mousedown", e => {
            // 拿到坐标
            const {clientX, clientY} = e;
            const {x,y} = {
                x:clientX - this.kikoCanvas.offsetLeft - 50,
                y:clientY - this.kikoCanvas.offsetTop - 60
            }
            if(!this.currentKiko){
                console.log(clientX - this.kikoCanvas.offsetLeft - 50, clientY - this.kikoCanvas.offsetTop - 60)
                //是红方还是黑方
                const item = this.getCheckKiko(x,y);
                if(item){
                    this.currentKiko = item!;
                }
                console.log(item)
            }else {
                this.currentKiko.move(x,y);
                Kiko.drawKiko(this.redKiko);
                Kiko.drawKiko(this.blackKiko);
                this.currentKiko = undefined;
            }

        })

    }

    //画地图
    drawMap() {
        // this.ctx.strokeStyle="red"
        this.ctx.lineWidth = 2
        this.ctx.beginPath();
        this.ctx.moveTo(500, 20);
        this.ctx.lineTo(500 + map.width, 20);
        this.ctx.lineTo(500 + map.width, 20 + map.height);
        this.ctx.lineTo(500, 20 + map.height)
        this.ctx.lineTo(500, 20);

        for (let i = 0; i < 8; i++) {
            for (let j = 0; j < 9; j++) {
                if (j == 4) {//画楚河汉界
                    this.ctx.font = " bold 50px 楷书";
                    if (i == 1) {
                        this.ctx.fillText("楚 河", 500 + i * lattice, 30 + j * lattice + lattice / 2)
                    } else if (i == 6) {
                        this.ctx.fillText("汉 界", 500 + i * lattice, 30 + j * lattice + lattice / 2)
                    }
                } else {
                    this.ctx.rect(500 + i * lattice, 20 + j * lattice, lattice, lattice);
                }
                // 画x
                if ([3].includes(i) && [0, 7].includes(j)) {
                    this.ctx.moveTo(500 + i * lattice, 20 + j * lattice)
                    this.ctx.lineTo(500 + i * lattice + 200, 20 + j * lattice + 200)
                    this.ctx.moveTo(700 + i * lattice, 20 + j * lattice)
                    this.ctx.lineTo(500 + i * lattice, 20 + j * lattice + 200)
                }

                if ([2, 4, 6].includes(i) && [2, 5].includes(j)) {
                    this.drawTriangle(i, j)
                }
                if ([1, 7].includes(i) && [1, 6].includes(j)) {
                    this.drawTriangle(i, j)
                }
                if (i == 0 && [2, 5].includes(j)) {
                    let offset = 490;
                    this.ctx.moveTo(offset + 20 + i * lattice, 100 + j * lattice)
                    this.ctx.lineTo(offset + 20 + i * lattice, 110 + j * lattice)
                    this.ctx.lineTo(offset + 30 + i * lattice, 110 + j * lattice)
                    this.ctx.moveTo(offset + 30 + i * lattice, 130 + j * lattice)
                    this.ctx.lineTo(offset + 20 + i * lattice, 130 + j * lattice)
                    this.ctx.lineTo(offset + 20 + i * lattice, 140 + j * lattice)
                }

                if (i == 7 && [2, 5].includes(j)) {
                    let offset = 590;
                    this.ctx.moveTo(offset + i * lattice, 100 + j * lattice)
                    this.ctx.lineTo(offset + i * lattice, 110 + j * lattice)
                    this.ctx.lineTo(offset - 10 + i * lattice, 110 + j * lattice)
                    this.ctx.moveTo(offset - 10 + i * lattice, 130 + j * lattice)
                    this.ctx.lineTo(offset + i * lattice, 130 + j * lattice)
                    this.ctx.lineTo(offset + i * lattice, 140 + j * lattice)
                }

            }
        }
        this.ctx.closePath();
        this.ctx.stroke();

    }

    // 画小三角
    drawTriangle(i: number, j: number, offset: number = 490) {

        if (i == 0 && [2, 5].includes(j)) {
            let offset = 490;
            this.ctx.moveTo(offset + 20 + i * lattice, 100 + j * lattice)
            this.ctx.lineTo(offset + 20 + i * lattice, 110 + j * lattice)
            this.ctx.lineTo(offset + 30 + i * lattice, 110 + j * lattice)
            this.ctx.moveTo(offset + 30 + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + 20 + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + 20 + i * lattice, 140 + j * lattice)
        } else if (i == 7 && [2, 5].includes(j)) {
            let offset = 590;
            this.ctx.moveTo(offset + i * lattice, 100 + j * lattice)
            this.ctx.lineTo(offset + i * lattice, 110 + j * lattice)
            this.ctx.lineTo(offset - 10 + i * lattice, 110 + j * lattice)
            this.ctx.moveTo(offset - 10 + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + i * lattice, 140 + j * lattice)
        } else {
            this.ctx.moveTo(offset + i * lattice, 100 + j * lattice)
            this.ctx.lineTo(offset + i * lattice, 110 + j * lattice)
            this.ctx.lineTo(offset - 10 + i * lattice, 110 + j * lattice)

            this.ctx.moveTo(offset + 20 + i * lattice, 100 + j * lattice)
            this.ctx.lineTo(offset + 20 + i * lattice, 110 + j * lattice)
            this.ctx.lineTo(offset + 30 + i * lattice, 110 + j * lattice)

            this.ctx.moveTo(offset + 30 + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + 20 + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + 20 + i * lattice, 140 + j * lattice)

            this.ctx.moveTo(offset - 10 + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + i * lattice, 130 + j * lattice)
            this.ctx.lineTo(offset + i * lattice, 140 + j * lattice)
        }


    }

    // 绘制棋子
    drawKiKos() {

        for (let i = 0; i < this.initKios.length; i++) {
            if (this.initKios[i] == "帅") {
                this.redKiko.push(Kiko.getKiko(400, 920, ColorType.RED, this.kikoCanvasCtx, this.initKios[i], 38));
            } else if (this.initKios[i] == "将") {
                this.blackKiko.push(Kiko.getKiko(i * lattice, 20, ColorType.BLACK, this.kikoCanvasCtx, this.initKios[i], 38));
            } else if (this.initKios[i] == "炮") {
                this.blackKiko.push(Kiko.getKiko(100, 220, ColorType.BLACK, this.kikoCanvasCtx, this.initKios[i], 38));
                this.blackKiko.push(Kiko.getKiko(700, 220, ColorType.BLACK, this.kikoCanvasCtx, this.initKios[i], 38));
                this.redKiko.push(Kiko.getKiko(100, 720, ColorType.RED, this.kikoCanvasCtx, this.initKios[i], 38));
                this.redKiko.push(Kiko.getKiko(700, 720, ColorType.RED, this.kikoCanvasCtx, this.initKios[i], 38));
            } else if (this.initKios[i] == "卒") {
                for (let v = 0; v < 5; v++) {
                    this.blackKiko.push(Kiko.getKiko(v * lattice * 2, 320, ColorType.BLACK, this.kikoCanvasCtx, this.initKios[i], 38));
                }
            } else if (this.initKios[i] == "兵") {
                for (let v = 0; v < 5; v++) {
                    this.redKiko.push(Kiko.getKiko(v * lattice * 2, 620, ColorType.RED, this.kikoCanvasCtx, this.initKios[i], 38));
                }
            } else {
                this.blackKiko.push(Kiko.getKiko(i * lattice, 20, ColorType.BLACK, this.kikoCanvasCtx, this.initKios[i], 38));
                this.redKiko.push(Kiko.getKiko(i * lattice, 920, ColorType.RED, this.kikoCanvasCtx, this.initKios[i], 38));
            }
        }
    }

    // 获取选中棋子
    getCheckKiko(x: number, y: number,) {
        if (this.isStatus == ColorType.RED) {
            return this.redKiko.find(item => {
                if (item.x - item.size / 2 < x &&
                    item.x + item.size / 2 > x &&
                    item.y - item.size / 2 < y &&
                    item.y + item.size / 2 > y) {
                    return item;
                }
            })
        }

        return this.blackKiko.find(item => {
            console.log(x, y)
            if (item.x - item.size / 2 < x &&
                item.x + item.size / 2 > x &&
                item.y - item.size / 2 < y &&
                item.y + item.size / 2 > y) {
                return item;
            }
        })

    }

}

enum ColorType {
    BLACK = "black",
    RED = "red",
}

// 棋子
abstract class Kiko {
    color: ColorType;
    x: number;
    y: number;
    size: number;
    ctx: CanvasRenderingContext2D;
    text: string;

    static getKiko(x: number, y: number, color: ColorType, ctx: CanvasRenderingContext2D, text: string, size: number) {
        switch (text) {
            case "兵":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "卒":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "車":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "馬":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "象":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "士":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "将":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "帅":
                return new SoldierKiko(x, y, color, ctx, text, size);
            case "炮":
                return new SoldierKiko(x, y, color, ctx, text, size);
            default:
                return new SoldierKiko(x, y, color, ctx, text, size);

        }
    }
    static drawKiko(arr:Kiko[]){
        arr.forEach(item=>item.draw());
    }
    constructor(x: number, y: number, color: ColorType, ctx: CanvasRenderingContext2D, text: string, size: number) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.size = size;
        this.ctx = ctx;
        this.text = text;
        this.draw();
    }

    draw() {
        this.ctx.strokeStyle = this.color
        this.ctx.beginPath();
        this.ctx.lineWidth = 1
        this.ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        this.ctx.fillStyle = "white";
        this.ctx.fill();
        this.ctx.stroke();
        this.ctx.beginPath();
        this.ctx.lineWidth = 2
        this.ctx.fillStyle = this.color;
        this.ctx.arc(this.x, this.y, this.size - 5, 0, Math.PI * 2);
        this.ctx.font = `bold ${this.size + 8}px 楷书`;
        this.ctx.fillText(this.text, this.x - this.size / 2 - 3, this.y + this.size / 2 - 2)
        this.ctx.stroke();
        this.ctx.closePath();
    }

    abstract move(x:number,y:number): void;

}


// 兵
class SoldierKiko extends Kiko {

    constructor(x: number, y: number, color: ColorType, ctx: CanvasRenderingContext2D, text: string, size: number) {
        super(x, y, color, ctx, text, size);
    }

    move(x:number,y:number): void {
        console.log(y,this.y)
        if(this.y>y){
            this.y-=100;
        }else {
            if(this.y>320)return;
            this.y+=100;
        }
        // 移动
        this.ctx.clearRect(-50,-50,map.width+100,map.height+100)

    }

}


export default Chess


 

  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值