<!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>