了解一下canvas,看到别人的h5象棋,自己比较感兴趣就写了一波

原创
2017/08/18 15:42
阅读数 86

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>H5 Canvas 中国象棋</title>
</head>
<body>
<div id="canvasBox" style="margin: 0 auto;">
    <canvas id="canvas">
        你的浏览器不支持canvas!
    </canvas>
    <button onclick="suofang(1)">放大</button>
    <button onclick="suofang(0)">缩小</button>
</div>
</body>
<script type="text/javascript">
    var comcell = 0.5;//系数控制大小的

    var canvasBox = document.getElementById('canvasBox');
    var canvas = document.getElementById('canvas');
    var ctx = '';
    
    var qzArray = [];
    var nowStep = 'red';

    function suofang(m){
        for(i in qzArray){
            qzArray[i].x = (qzArray[i].x)/comcell;
            qzArray[i].y = (qzArray[i].y)/comcell;
        }
        
        if(m>0){
            comcell = parseFloat(comcell)+0.1;
        }else{
            comcell = parseFloat(comcell)-0.1;
        }
        if(comcell>1){
            comcell = 1;
        }
        if(comcell<0.2){
            comcell = 0.2;
        }

        comcell = comcell.toFixed(1);
        for(i in qzArray){
            qzArray[i].x = (qzArray[i].x)*comcell;
            qzArray[i].y = (qzArray[i].y)*comcell;
        }
        init();
    }

    function drowLine(x,y,mx,my,color){
        color = color || 'darkred';
        ctx.strokeStyle=color;
        ctx.beginPath();
        ctx.moveTo(x,y);
        ctx.lineTo(mx,my);
        ctx.stroke();
        ctx.closePath();
    }

    function drowMark(x,y,l){
        l = l || 0;
        if(l>=0){
            drowLine(x+10 * comcell,y-10 * comcell,x+20 * comcell,y-10 * comcell);
            drowLine(x+10 * comcell,y-10 * comcell,x+10 * comcell,y-20 * comcell);

            drowLine(x+10 * comcell,y+10 * comcell,x+20 * comcell,y+10 * comcell);
            drowLine(x+10 * comcell,y+10 * comcell,x+10 * comcell,y+20 * comcell);
        }
        if(l<=0){
            drowLine(x-10 * comcell,y-10 * comcell,x-20 * comcell,y-10 * comcell);
            drowLine(x-10 * comcell,y-10 * comcell,x-10 * comcell,y-20 * comcell);

            drowLine(x-10 * comcell,y+10 * comcell,x-20 * comcell,y+10 * comcell);
            drowLine(x-10 * comcell,y+10 * comcell,x-10 * comcell,y+20 * comcell);
        }
    }

    function createQipan(){
        ctx.clearRect(-100 * comcell,-100 * comcell,1000 * comcell,1100 * comcell);
        //棋盘begin
        ctx.strokeStyle='darkred';
        ctx.strokeRect(0,0,800 * comcell,900 * comcell);
        ctx.save();
        //画棋盘线
        for(var i=1;i<=8;i++){
            if(i<=7){
                drowLine(i*100 * comcell,0,i*100 * comcell,400 * comcell,'darkred');
                drowLine(i*100 * comcell,500 * comcell,i*100 * comcell,900 * comcell,'darkred');
            }
            drowLine(0,i*100 * comcell,800 * comcell,i*100 * comcell,'darkred');
        }

        //画米子格
        drowLine(300 * comcell,0,500 * comcell,200 * comcell);
        drowLine(500 * comcell,0,300 * comcell,200 * comcell);

        drowLine(300 * comcell,900 * comcell,500 * comcell,700 * comcell);
        drowLine(500 * comcell,900 * comcell,300 * comcell,700 * comcell);

        //画炮兵位标记
        drowMark(100 * comcell,200 * comcell);
        drowMark(700 * comcell,200 * comcell)

        drowMark(100 * comcell,700 * comcell);
        drowMark(700 * comcell,700 * comcell);

        drowMark(0,300 * comcell,1);
        drowMark(200 * comcell,300 * comcell);
        drowMark(400 * comcell,300 * comcell);
        drowMark(600 * comcell,300 * comcell);
        drowMark(800 * comcell,300 * comcell,-1);
        drowMark(0,600 * comcell,1);
        drowMark(200 * comcell,600 * comcell);
        drowMark(400 * comcell,600 * comcell);
        drowMark(600 * comcell,600 * comcell);
        drowMark(800 * comcell,600 * comcell,-1);
        ctx.restore();

        //绘制文字
        ctx.save();
        ctx.font = 60 * comcell+"px microsoft yahei";
        ctx.translate(800 * comcell / 2, 900 * comcell / 2);
        var radian = Math.PI / -2; 
        ctx.rotate(radian); 
        ctx.fillText("楚", -30 * comcell, -270 * comcell);
        ctx.fillText("河", -30 * comcell, -150 * comcell);
        ctx.restore();

        ctx.save();
        ctx.font = 60 * comcell+"px microsoft yahei";
        ctx.translate(800 * comcell / 2, 900 * comcell / 2);
        var radian = Math.PI / 2; 
        ctx.rotate(radian); 
        ctx.fillText("漢", -30 * comcell, -270 * comcell);
        ctx.fillText("界", -30 * comcell, -150 * comcell);
        ctx.restore();

        /*ctx.save();
        ctx.font = 12 * comcell+"px microsoft yahei";
        ctx.translate(800 * comcell / 2, 900 * comcell / 2);
        ctx.fillText("mmp的这个canvas画图真的强!", -100 * comcell, 0);
        ctx.restore();*/
    }

    function createQizi(qzName,name,role,x,y,isChoose,isDead){
        isChoose = isChoose || 0;
        isDead = isDead || 0;
        var qz = new Object();
        qz.qzName = qzName;
        qz.name = name;
        qz.role = role;
        qz.x = x;
        qz.y = y;
        qz.isChoose = isChoose;
        qz.isDead = isDead;
        if(isDead==0){
            ctx.beginPath();
            ctx.arc(x,y,50 * comcell,0,Math.PI*2,true);
            ctx.fillStyle="#D38E40";
            ctx.fill();
            ctx.closePath();
            ctx.beginPath();
            ctx.strokeStyle="white";
            ctx.arc(x,y,45 * comcell,0,Math.PI*2,true);
            ctx.font = 60 * comcell+"px microsoft yahei";
            ctx.fillStyle=(role=="red")?"red":"black";
            ctx.fillText(qzName,x-50*0.6 * comcell,y+50*0.4 * comcell);
            ctx.stroke();
            ctx.closePath();
        }
        if(isDead==0 && isChoose==1){
            ctx.beginPath();
            ctx.strokeStyle="#ffff00";
            ctx.lineWith=2;
            ctx.arc(x,y,48 * comcell,0,Math.PI*2,true);
            ctx.stroke();
            ctx.closePath();
        }
        if(canPush){
            qzArray.push(qz);
        }
    }

    function init(){
        canvasBox.style.width = 1000 * comcell+'px';
        canvas.width = 1000 * comcell;
        canvas.height = 1100 * comcell;
        ctx = canvas.getContext('2d')
        ctx.translate(100 * comcell,100 * comcell);
        createQipan();
        if(qzArray.length<1){
            createQizi('車','c','black',0  ,0);
            createQizi('馬','m','black',100 * comcell,0);
            createQizi('象','x','black',200 * comcell,0);
            createQizi('士','s','black',300 * comcell,0);
            createQizi('将','j','black',400 * comcell,0);
            createQizi('士','s','black',500 * comcell,0);
            createQizi('象','x','black',600 * comcell,0);
            createQizi('馬','m','black',700 * comcell,0);
            createQizi('車','c','black',800 * comcell,0);
            createQizi('炮','p','black',100 * comcell,200 * comcell);
            createQizi('炮','p','black',700 * comcell,200 * comcell);
            createQizi('卒','z','black',0,300 * comcell);
            createQizi('卒','z','black',200 * comcell,300 * comcell);
            createQizi('卒','z','black',400 * comcell,300 * comcell);
            createQizi('卒','z','black',600 * comcell,300 * comcell);
            createQizi('卒','z','black',800 * comcell,300 * comcell);

            createQizi('车','c','red',0  ,900 * comcell);
            createQizi('马','m','red',100 * comcell,900 * comcell);
            createQizi('相','x','red',200 * comcell,900 * comcell);
            createQizi('士','s','red',300 * comcell,900 * comcell);
            createQizi('帥','j','red',400 * comcell,900 * comcell);
            createQizi('士','s','red',500 * comcell,900 * comcell);
            createQizi('相','x','red',600 * comcell,900 * comcell);
            createQizi('马','m','red',700 * comcell,900 * comcell);
            createQizi('车','c','red',800 * comcell,900 * comcell);
            createQizi('炮','p','red',100 * comcell,700 * comcell);
            createQizi('炮','p','red',700 * comcell,700 * comcell);
            createQizi('兵','z','red',0,600 * comcell); 
            createQizi('兵','z','red',200 * comcell,600 * comcell);
            createQizi('兵','z','red',400 * comcell,600 * comcell);
            createQizi('兵','z','red',600 * comcell,600 * comcell);
            createQizi('兵','z','red',800 * comcell,600 * comcell);
        }else{
            for(i in qzArray){
                createQizi(qzArray[i].qzName,qzArray[i].name,qzArray[i].role,qzArray[i].x  ,qzArray[i].y,qzArray[i].isChoose,qzArray[i].isDead);
            }
        }
    }
    var canPush = 1;
    window.onload=function(){
        init();
        canPush = 0;
    }
    canvas.onclick=function(event){
        var e = event || window.event;
        var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollY = document.documentElement.scrollTop || document.body.scrollTop;

        var x = e.pageX || e.clientX + scrollX;
        var y = e.pageY || e.clientY + scrollY;

        x=x-canvas.offsetLeft-100 * comcell;
        if(x<-50 * comcell || x>850 * comcell){
            return false;
        }

        y=y-canvas.offsetTop-100 * comcell;
        if(y<-50 * comcell || y>950 * comcell){
            return false;
        }
        
        if(isUsedPoint(x,y)){
            x = Math.floor(Math.abs( (x+50 * comcell) /(100 * comcell) ))*100 * comcell;
            y = Math.floor(Math.abs( (y+50 * comcell) /(100 * comcell) ))*100 * comcell;

            var res = checkXY_isEmpty(x,y);

            if(res===true){
                var historyQz = isChoosedQizi();

                //走棋
                if(historyQz){
                    if( !checkRoleStep(historyQz) ){
                        return false;
                    }
                    var canGo = theWayCanGo(x,y,historyQz);
                    if(canGo===true){
                        is_jiangjun(x,y,historyQz);
                        rePutQizi(x,y,historyQz);
                        if(historyQz.role=='red'){
                            nowStep = 'black';
                        }else{
                            nowStep = 'red';
                        }
                        init();
                    }else{
                        alert(canGo);
                    }
                }
            }else{
                var historyQz = isChoosedQizi();

                if(historyQz){
                    var nowChooseQz = chooseQizi(res);
                    if(res === historyQz){
                        return false;//这里表示没动
                    }
                    if(nowChooseQz.role === historyQz.role){
                        //切换选中的棋
                        rePutQizi(historyQz.x,historyQz.y,historyQz);
                        chooseQizi(nowChooseQz);
                    }else{
                        //吃棋
                        var canGo = theWayCanGo(res.x,res.y,historyQz);
                        if(canGo===true){
                            is_jiangjun(res.x,res.y,historyQz);
                            dieQizi(nowChooseQz);
                            rePutQizi(nowChooseQz.x,nowChooseQz.y,historyQz);
                            if(historyQz.role=='red'){
                                nowStep = 'black';
                            }else{
                                nowStep = 'red';
                            }
                        }else{
                            //不能走棋子不能选中
                            notChooseQizi(nowChooseQz);
                            alert(canGo);
                        }
                    }
                }else{
                    if( !checkRoleStep(res) ){
                        return false;
                    }else{
                        chooseQizi(res);
                    }
                }
            }
        }
    }


    //判断是否为将军
    function is_jiangjun(x,y,qz){
        var res = false;
        var nqz = qz;
        nqz.x = x;
        nqz.y = y;
        var r = qz.role;
        var jiang = '';
        for(i in qzArray){
            if(qzArray[i].name=='j' && qzArray[i].role!=r){
                jiang = qzArray[i];
                break;
            }
        }
        var canGo = theWayCanGo(jiang.x,jiang.y,nqz);
        if(canGo===true){
            res = true;
            console.log('将军!');
            alert('将军!');
        }
        return res;
    }

    function checkRoleStep(qz){
        if(qz.role!==nowStep){
            console.log('现在该'+nowStep+'走棋!');
            var r = nowStep=='red' ? '红方' : '黑方';
            alert('现在该'+r+'走棋!');
            return false;
        }else{
            return true;
        }
    }

    function theWayCanGo(x,y,qz){
        var r = qz.role;
        var n = qz.name;
        var qzn = qz.qzName;
        var hx = qz.x;
        var hy = qz.y;
        var cell = 100 * comcell;
        var res = true;
        switch(n){
            case 'c' :
                if(x!=hx && y!=hy){
                    res = qzn+'不能这么走!';
                }

                //往上走
                if(x==hx && y<hy){
                    for(var i=hy-cell;i>y;i=i-cell){
                        if(checkXY_isEmpty(x,i)!==true){
                            res = qzn+'不能这么走,不能跳过中间的棋子!';
                            break;
                        }
                    }
                }
                //往下走
                if(x==hx && y>hy){
                    for(var i=hy+cell;i<y;i=i+cell){
                        if(checkXY_isEmpty(x,i)!==true){
                            res = qzn+'不能这么走,不能跳过中间的棋子!';
                            break;
                        }
                    }
                }
                //往左走
                if(y==hy && x<hx){
                    for(var i=hx-cell;i>x;i=i-cell){
                        if(checkXY_isEmpty(i,y)!==true){
                            res = qzn+'不能这么走,不能跳过中间的棋子!';
                            break;
                        }
                    }
                }
                //往右走
                if(y==hy && x>hx){
                    for(var i=hx+cell;i<x;i=i+cell){
                        if(checkXY_isEmpty(i,y)!==true){
                            res = qzn+'不能这么走,不能跳过中间的棋子!';
                            break;
                        }
                    }
                }
                
            break;
            case 'm' :
                if( !( (Math.abs(x-hx)==100 * comcell && Math.abs(y-hy)==200 * comcell) || (Math.abs(x-hx)==200 * comcell && Math.abs(y-hy)==100 * comcell) ) ){
                    res = qzn+'不能这么走!';
                }else if(Math.abs(x-hx)==200 * comcell){
                    //横跳
                    if(x<hx){
                        if(checkXY_isEmpty(hx-cell,hy)!==true){
                            res = qzn+'不能这么走,蹩'+qzn+'腿了!';
                        }
                    }
                    if(x>hx){
                        if(checkXY_isEmpty(hx+cell,hy)!==true){
                            res = qzn+'不能这么走,蹩'+qzn+'腿了!';
                        }
                    }
                }else{
                    //竖跳
                    if(y<hy){
                        if(checkXY_isEmpty(hx,hy-cell)!==true){
                            res = qzn+'不能这么走,蹩'+qzn+'腿了!';
                        }
                    }
                    if(y>hy){
                        if(checkXY_isEmpty(hx,hy+cell)!==true){
                            res = qzn+'不能这么走,蹩'+qzn+'腿了!';
                        }
                    }
                    
                }
            break;
            case 'x' :
                if(r==='red'){
                    if(y<500 * comcell){
                        res = qzn+'不能这么走,'+qzn+'不能过河!';
                        break;
                    }
                }else{
                    if(y>400 * comcell){
                        res = qzn+'不能这么走,'+qzn+'不能过河!';
                        break;
                    }
                }
                
                if( Math.abs(x-hx)!=200 * comcell || Math.abs(y-hy)!=200 * comcell){
                    res = qzn+'不能这么走!';
                }else{
                    //右上
                    if(x>hx && y<hy){
                        if(checkXY_isEmpty(hx+cell,hy-cell)!==true){
                            res = qzn+'不能这么走,'+qzn+'眼被填了!';
                        }
                    }
                    //右下
                    if(x>hx && y>hy){
                        if(checkXY_isEmpty(hx+cell,hy+cell)!==true){
                            res = qzn+'不能这么走,'+qzn+'眼被填了!';
                        }
                    }
                    //左上
                    if(x<hx && y<hy){
                        if(checkXY_isEmpty(hx-cell,hy-cell)!==true){
                            res = qzn+'不能这么走,'+qzn+'眼被填了!';
                        }
                    }
                    //左下
                    if(x<hx && y>hy){
                        if(checkXY_isEmpty(hx-cell,hy+cell)!==true){
                            res = qzn+'不能这么走,'+qzn+'眼被填了!';
                        }
                    }
                }
            break;
            case 's' :
                var minx = 300 * comcell;
                var maxx = 500 * comcell;
                if(x>maxx || x<minx){
                    res = qzn+'不能这么走!';
                    break;
                }
                if(r==='red'){
                    var miny = 700 * comcell;
                    if(y<miny){
                        res = qzn+'不能这么走!';
                        break;
                    }
                }else{
                    var maxy = 200 * comcell;
                    if(y>maxy){
                        res = qzn+'不能这么走!';
                        break;
                    }
                }
                if( Math.abs(x-hx)!=100 * comcell || Math.abs(y-hy)!=100 * comcell ){
                    res = qzn+'不能这么走!';
                }
            break;
            case 'j' :
                var minx = 300 * comcell;
                var maxx = 600 * comcell;
                if(r==='red'){
                    var miny = 700 * comcell;
                    if(x<minx || x>maxx || y<miny || Math.abs(hx-x)>cell || Math.abs(hy-y)>cell || (hx!=x && hy!=y) ){
                        res = qzn+'不能这么走!';
                    }
                }else{
                    var maxy = 200 * comcell;
                    if(x<minx || x>maxx || y>maxy || Math.abs(hx-x)>cell || Math.abs(hy-y)>cell || (hx!=x && hy!=y) ){
                        res = qzn+'不能这么走!';
                    }
                }
            break;
            case 'p' :
                if(x!=hx && y!=hy){
                    res = qzn+'不能这么走!';
                }
                var count = 0;
                
                //往前走
                if(x==hx && y>hy){
                    for(var i=hy+cell;i<y;i=i+cell){
                        if(checkXY_isEmpty(x,i)!==true){
                            count++;
                        }
                    }
                }
                //往后走
                if(x==hx && y<hy){
                    for(var i=hy-cell;i>y;i=i-cell){
                        if(checkXY_isEmpty(x,i)!==true){
                            count++;
                        }
                    }
                }
                //往左走
                if(y==hy && x<hx){
                    for(var i=hx-cell;i>x;i=i-cell){
                        if(checkXY_isEmpty(i,y)!==true){
                            count++;
                        }
                    }
                }
                //往右走
                if(y==hy && x>hx){
                    for(var i=hx+cell;i<x;i=i+cell){
                        if(checkXY_isEmpty(i,y)!==true){
                            count++;
                            break;
                        }
                    }
                }
                if(count>1){
                    res = qzn+'不能这么走,不能跳过多个棋子!';
                }else if(count==1){
                    if(checkXY_isEmpty(x,y)===true){
                        res = qzn+'不能这么走!';
                    }
                }else{
                    if(checkXY_isEmpty(x,y)!==true){
                        res = qzn+'不能这么走,必须要隔一个棋子才能吃!';
                    }
                }
            break;
            case 'z' :
                if(r==='red'){
                    if(y-hy>0 ){
                        res = qzn+'不能倒退!';
                        break;
                    }
                    if( Math.abs(x-hx)>100 * comcell || Math.abs(y-hy)>100 * comcell ){
                        res = qzn+'走远了,不能这么走!';
                        break;
                    }
                    if(hy>400 * comcell && x-hx!=0){
                        res = qzn+'没有过河,不能这么走!';
                        break;
                    }
                }else{
                    if(hy-y>0 ){
                        res = qzn+'不能倒退!';
                        break;
                    }
                    if( Math.abs(x-hx)>100 * comcell || Math.abs(y-hy)>100 * comcell ){
                        res = qzn+'走远了,不能这么走!';
                        break;
                    }
                    if(hy<500 * comcell && x-hx!=0){
                        res = qzn+'没有过河,不能这么走!';
                        break;
                    }
                }
            break;
        }
        return res;
    }

    function checkXY_isEmpty(x,y){
        var re=true;
        for(i in qzArray){
            if(qzArray[i].x==x && qzArray[i].y==y && qzArray[i].isDead==0){
                re = qzArray[i];
                break;
            }
        }
        return re;
    }

    function rePutQizi(nx,ny,hq){
        for(i in qzArray){
            if(qzArray[i].x==hq.x && qzArray[i].y==hq.y && qzArray[i].isDead==0 && qzArray[i].isChoose==1){
                qzArray[i].x = nx;
                qzArray[i].y = ny;
                qzArray[i].isChoose = 0;
                init();
                break;
            }
        }
    }

    //选中棋子
    function chooseQizi(q){
        var res = false;
        
        for(i in qzArray){
            if(qzArray[i].x==q.x && qzArray[i].y==q.y && qzArray[i].isDead==0 && qzArray[i].isChoose==0){
                qzArray[i].isChoose=1;
                res = qzArray[i];
                init();
                break;
            }
        }
        return res;
    }

    function notChooseQizi(q){
        for(i in qzArray){
            if(qzArray[i]===q){
                qzArray[i].isChoose=0;
                init();
                break;
            }
        }
    }

    //棋子死亡
    function dieQizi(q){
        for(i in qzArray){
            if(qzArray[i].x==q.x && qzArray[i].y==q.y && qzArray[i].isDead==0 && qzArray[i].isChoose==1){
                qzArray[i].isChoose=0;
                qzArray[i].isDead=1;
                init();
                break;
            }
        }
    }

    //是否存在选中的棋子
    function isChoosedQizi(){
        for(i in qzArray){
            if(qzArray[i].isDead==0 && qzArray[i].isChoose==1){
                return qzArray[i];
                break;
            }
        }
        return false;
    }

    function isUsedPoint(x,y){
        for(var i=0;i<=800 * comcell;i=i+100 * comcell){
            for(var j=0;j<=900 * comcell;j=j+100 * comcell){
                ctx.beginPath();
                ctx.arc(i,j,50 * comcell,0,Math.PI*2,true);
                if( ctx.isPointInPath(x+100 * comcell,y+100 * comcell)){
                    return true;
                }
                ctx.closePath();
            }
        }
        return false;
    }

</script>
</html> 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部