1. 程式人生 > >使用H5編寫網頁版象棋(原始碼)

使用H5編寫網頁版象棋(原始碼)

//車馬相士將士相馬車 8*11 var qzName=["車","馬","相","仕","將","仕","相","馬","車","炮","炮","兵","兵","兵","兵","兵"];// var qzRedArray=new Array(); var qzBlackArray=new Array(); var qzArray=new Array(); var body_w=document.body.clientWidth; var gameType=0; body_w=body_w%9==0?body_w:body_w-body_w%9
;//讓座標為整數 body_w=body_w<810?body_w:810; console.log(document.body.clientWidth+"|"+body_w); ///////////////////////////////////////////////////// // var b=document.getElementsByTagName('body')[0]; var b=document.getElementById('content'); b.style.textAlign='center'; var np=document.createElement('div'); var nbut=document.createElement('div'
); if(body_w==810){ np.style.width='1.1em'; np.style.float='right'; nbut.style.width='2.5em'; nbut.style.float='right'; nbut.style.padding='1em'; }else{ np.style.width='50%'; np.style.float='right'; nbut.style.width='40%'; nbut.style.float='right'
; } np.innerHTML='Good luck'; nbut.innerHTML='重新開始遊戲'; nbut.fontSize=body_w/16+'px'; nbut.style.border='solid 2px red'; nbut.style.borderRadius='20%'; nbut.style.cursor='pointer'; nbut.style.fontWeight='bold'; nbut.style.color='red'; nbut.onclick=function () { newGameStart(); }; np.id='mark'; np.style.fontFamily='微軟雅黑'; np.style.fontSize=body_w/16+'px'; b.appendChild(nbut); b.appendChild(np); /////////////////////////////// //var w=800,h=900; var w=body_w/9*8,h=w/8*9; var c=document.createElement('canvas'); var wh=w/2; var hh=h/2; var cell=w/8; var cellh=cell/2; c.width=w+cell; c.height=h+cell; c.id="can"; b.appendChild(c); var cxt=c.getContext("2d"); cxt.strokeStyle="#ff0000"; cxt.font=cell*0.8+"px 微軟雅黑"; //座標原點為中心,右下為正,左上為負 cxt.translate(wh+cellh,hh+cellh); //////////////////////////////////////////////////// var mouseClickCount=0; var qzRunTime=0; c.onclick=function(event) { mouseClickCount+=1; console.log("滑鼠點選了 "+mouseClickCount+" 次_____________________________________________________"); 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-c.offsetLeft-cellh-wh;y=y-c.offsetTop-cellh-hh; x=Math.abs(x%cell)>cellh?(x>0?x-x%cell+cell:x-x%cell-cell):x-x%cell; y=y>0?y-y%cell+cellh:y-y%cell-cellh; if(gameType==1){ clickHere(x,y); }else { np.innerHTML="勝負已分莫強求"; } console.log ('滑鼠點選的座標x:'+x+' y:'+y); }; function clickHere(x,y) { var qzHere=checkXYisEmpty(x,y);//空是true,有則返回棋子obj var qzChoose=null; for(i in qzArray){ if(qzArray[i].isChoose==true){ qzChoose=qzArray[i]; } } console.log(typeof qzHere); if(qzHere===true){//點選的地方是空的 if(qzChoose===null){//沒有選中的棋子 console.log("點選的地方是空的,沒有選中的棋子"); }else{//選中的棋子為qzChoose if(qzChoose.go(x,y)===true){///////////////////////// 完成- 走!//////////////////////////////// qzRunTime+=1; if(gameType==1){ np.innerHTML="棋局第"+qzRunTime+"步"; } isJiangJun(qzChoose); qzChoose.isChoose=false; } } }else {//點選的地方是object if(qzChoose===null){//沒有選中的棋子 if(qzRunTime%2==0 && qzHere.side=='紅方'){ console.log("紅:之前沒有選中棋子,所以選中點選的棋子,下choose"); qzHere.choose(); }else if(qzRunTime%2==1 && qzHere.side=='黑方'){ console.log("黑:之前沒有選中棋子,所以選中點選的棋子,下choose"); qzHere.choose(); }else{ if(qzRunTime%2==0){ console.log("warn:到紅方了"); np.innerHTML="紅方回合"; }else{ console.log("warn:到黑方了"); np.innerHTML="黑方回合"; } } }else{//選中的棋子為qzChoose,點選的是object if(qzChoose.side==qzHere.side){ console.log("點選的棋子和之前選中的棋子同一邊,所以,選中此棋子"); qzChoose.noChoose(); console.log("typeof qzHere:"+typeof qzHere+',下choose'); qzHere.choose(); }else { console.log("點選的棋子和之前選中的棋子敵對,所以,嘗試 吃子"); if(qzChoose.go(x,y)===true){///////////////////////// 完成- 走!//////////////////////////////// qzRunTime+=1; if(gameType==1){ np.innerHTML="棋局第"+qzRunTime+"步"; } isJiangJun(qzChoose); qzChoose.isChoose=false; } } } } rePut(); } newGameStart(); function isJiangJun(obj) { var html=''; for(i in qzBlackArray){ var o=qzBlackArray[i],a=o.x,b=o.y; if(o.go(qzRedArray[4].x,qzRedArray[4].y,true)===true){ html+='黑方'; o.x=a;o.y=b; rePut(); break; } } for(i in qzRedArray){ var o=qzRedArray[i],a=o.x,b=o.y; if(o.go(qzBlackArray[4].x,qzBlackArray[4].y,true)===true){ html+='紅方'; o.x=a;o.y=b; rePut(); break; } } if(html!==''){np.innerHTML=html+' :將軍 !'; } } function rePut() { console.log('repout()'); createQiPan(); for(index in qzArray){ var a=qzArray[index]; if(a.isDead){continue;} createQZ(a.x,a.y,a.name,a.side,a.isChoose); putQiZi(a); } } function gameOver(side) { gameType=0; np.innerHTML=side+'輸了 !'; } function createQZ(x,y,name,side,ischoose,isDead) { var qz=new Object(); qz.side=side; qz.x=x;qz.y=y; qz.name=name; qz.isChoose=ischoose?ischoose:false; qz.isDead=isDead?isDead:false; qz.goDead=function () { qz.isDead=true; if(qz.name=='將'){gameOver(qz.side);} console.log('createQZ:'+qz.name+' dead') }; qz.go=function (a,b,c) { var tryJiangJun=c?c:false; var theWayCanGo=way(qz,a,b,tryJiangJun); var is_empty=checkXYisEmpty(a,b); console.log("createQZ_theWayCanGo:"+theWayCanGo); if(theWayCanGo===true) { if (is_empty == true) { qz.x = a; qz.y = b; console.log("createQZ_function_把" + qz.side + "的【" + qz.name + "】移到座標(" + qz.x + "," + qz.y + "】)"); rePut(); return true; } else if (is_empty.side===qz.side){ console.log('createQZ_function_go_不能這麼走!'); if(!tryJiangJun)np.innerHTML="同陣營 !"; return false; }else{ if(qz.name=='炮'){ console.log('createQZ_function_go_不能這麼吃,要隔一個子!'); if(!tryJiangJun)np.innerHTML="隔空打炮 !"; return false; }else{ if(!tryJiangJun)is_empty.goDead(); qz.x = a; qz.y = b; console.log("createQZ_function_go_把" + qz.side + "的【" + qz.name + "】移到座標(" + qz.x + "," + qz.y + "】)"); rePut(); return true; } } }else if(theWayCanGo===1&&qz.name=='炮'){ if(is_empty!==true && is_empty.side!==qz.side){ if(!tryJiangJun)is_empty.goDead(); qz.x = a; qz.y = b; console.log("createQZ_function_PaoGo_" +is_empty.name+" Dead;把"+ qz.side + "的【" + qz.name + "】移到座標(" + qz.x + "," + qz.y + "】)"); rePut(); return true; }else { if(!tryJiangJun)np.innerHTML="禁止打空炮 !"; } }else { console.log('warn:go else ????????'); if(!tryJiangJun)np.innerHTML="你走遠了 !"; return false; } }; qz.choose=function () { cxt.beginPath(); cxt.lineWidth=cell/20; cxt.strokeStyle="#ffff00"; cxt.arc(qz.x,qz.y,cell/2.2,0,Math.PI*2,true); cxt.stroke(); cxt.closePath(); cxt.lineWidth=1; qz.isChoose=true; console.log('createQZ_fun_choose_'+qz.side+" 的 【"+qz.name+"】被選中,座標是:("+qz.x+","+qz.y+")"); }; qz.noChoose=function () { qz.isChoose=false; console.log('createQZ_fun_noChoose_'+qz.side+" 的 【"+qz.name+"】被取消選中,原座標是:("+qz.x+","+qz.y+")"); }; // console.log(qz.side+" 已建立:"+qz.name+",座標是:("+qz.x+","+qz.y+")"); return qz; } function way(obj,a,b,c){ var tryJiangJun=c?c:false; var x=obj.x, y=obj.y, k=obj.name, wayResult, countQiziOnRoad=0; if(x==a&&y==b){return false}//在原來的位置,沒有移動 console.log("【"+k+"】("+x+","+y+") 在走"); switch (k){ case "車": if(x==a){//y-b有沒有其它棋子 console.log("沿y軸:現在y="+y+"; 目標y=b("+b); if(Math.abs(y-b)==cell){return true} if(b<y){ console.log("b<y往上走,x不變,y減小"); for(var f=y-cell;f>b;f-=cell){ console.log("沿y軸:現在y="+f+"; 目標y=b("+b); if(checkXYisEmpty(a,f)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); if(!tryJiangJun)np.innerHTML="車步錯誤"; break; }else { wayResult=true; //能走 console.log("能走"); } } }else{ console.log("b>y往下走,x不變,y增大"); for(var f=y+cell;f<b;f+=cell){ console.log("沿y軸:現在y="+f+"; 目標y=b("+b); if(checkXYisEmpty(a,f)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); if(!tryJiangJun)np.innerHTML="車步錯誤"; break; }else { wayResult=true; //能走 console.log("能走"); } } } } else if(y==b){//x-a有沒有其它棋子 console.log("沿x軸:現在x="+x+"; 目標x=a("+a); if(Math.abs(x-a)==cell){return true} if(a<x){ console.log("a<x往左走,y不變,x減小"); for(var f=x-cell;f>a;f-=cell){ console.log("沿x軸:現在x="+f+"; 目標x=a("+a); if(checkXYisEmpty(f,b)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); if(!tryJiangJun)np.innerHTML="車步錯誤"; break; }else { wayResult=true; //能走 console.log("能走"); } } }else{ console.log("a>x往右走,y不變,x增大"); for(var f=x+cell;f<a;f+=cell){ console.log("沿y軸:現在x="+f+"; 目標x=a("+a); if(checkXYisEmpty(f,b)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); if(!tryJiangJun)np.innerHTML="車步錯誤"; break; }else { wayResult=true; //能走 console.log("能走"); } } } } else{ wayResult=false; //不能走 // console.log("??不能走"); if(!tryJiangJun)np.innerHTML="車步錯誤 !"; } break; case "馬"://xy---ab if(Math.abs(x-a)==2*cell && Math.abs(y-b)==cell){ if(x<a&&checkXYisEmpty(x+cell,y)===true){ wayResult=true; //能走 }else if(x>a&&checkXYisEmpty(x-cell,y)===true){ wayResult=true; //能走 }else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="馬步錯誤"; } }else if(Math.abs(x-a)==cell && Math.abs(y-b)==2*cell){ if(y<b&&checkXYisEmpty(x,y+cell)===true){ wayResult=true; //能走 }else if(y>b&&checkXYisEmpty(x,y-cell)===true){ wayResult=true; //能走 }else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="馬步錯誤"; } } break; case "相": if((obj.side=="紅方" && b<0)||(obj.side=="黑方"&&b>0)){ wayResult=false; //不能走 console.log('提示:相不能過河'); if(!tryJiangJun)np.innerHTML="相不能過河"; return wayResult; } console.log('相腳:'+(x+a)/2+","+(y+b)/2); if((Math.abs(x-a)==2*cell )&&( Math.abs(y-b)==2*cell)&&(checkXYisEmpty((x+a)/2,(y+b)/2)===true)){ wayResult=true; //能走 }else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="相步錯誤"; } break; case "仕": if(Math.abs(x-a)==cell && Math.abs(y-b)==cell&&Math.abs(a)<=cell&&Math.abs(b)>=2.5*cell){ wayResult=true; //能走 }else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="仕步錯誤"; } break; case "將": if(a==x){ if(Math.abs(y-b)==cell&&Math.abs(a)<=cell&&Math.abs(b)>=2.5*cell){ wayResult=true; //能走 }else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="將步錯誤"; } }else if(b==y){ if(Math.abs(a-x)==cell&&Math.abs(a)<=cell&&Math.abs(b)>=2.5*cell){ wayResult=true; //能走 }else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="將步錯誤"; } } break; case "炮": if(x==a){//y-b有沒有其它棋子 console.log("沿y軸:現在y="+y+"; 目標y=b("+b); if(Math.abs(y-b)==cell){return true} if(b<y){ console.log("b<y往上走,x不變,y減小"); for(var f=y-cell;f>b;f-=cell){ console.log("沿y軸:現在y="+f+"; 目標y=b("+b); if(checkXYisEmpty(a,f)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); countQiziOnRoad+=1; if(countQiziOnRoad==2){ if(!tryJiangJun)np.innerHTML="炮步錯誤"; break; } }else { wayResult=true; //能走 console.log("能走"); } } }else{ console.log("b>y往下走,x不變,y增大"); for(var f=y+cell;f<b;f+=cell){ console.log("沿y軸:現在y="+f+"; 目標y=b("+b); if(checkXYisEmpty(a,f)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); countQiziOnRoad+=1; if(countQiziOnRoad==2){ if(!tryJiangJun)np.innerHTML="炮步錯誤"; break; } }else { wayResult=true; //能走 console.log("能走"); } } } } else if(y==b){//x-a有沒有其它棋子 console.log("沿x軸:現在x="+x+"; 目標x=a("+a); if(Math.abs(x-a)==cell){return true} if(a<x){ console.log("a<x往左走,y不變,x減小"); for(var f=x-cell;f>a;f-=cell){ console.log("沿x軸:現在x="+f+"; 目標x=a("+a); if(checkXYisEmpty(f,b)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); countQiziOnRoad+=1; if(countQiziOnRoad==2){ if(!tryJiangJun)np.innerHTML="炮步錯誤"; break; } }else { wayResult=true; //能走 console.log("能走"); } } }else{ console.log("a>x往右走,y不變,x增大"); for(var f=x+cell;f<a;f+=cell){ console.log("沿y軸:現在x="+f+"; 目標x=a("+a); if(checkXYisEmpty(f,b)!==true){//路徑座標上有其它棋子 wayResult=false; //不能走 console.log("不能走"); countQiziOnRoad+=1; if(countQiziOnRoad==2){ if(!tryJiangJun)np.innerHTML="炮步錯誤"; break; } }else { wayResult=true; //能走 console.log("能走"); } } } } else{ wayResult=false; //不能走 if(!tryJiangJun)np.innerHTML="炮步錯誤 !"; // console.log("??不能走"); } break; case "兵": if(obj.side=="紅方"){ if(y>0){//未過河 if(x==a&&y-b==cell){ wayResult=true; //能走 }else { wayResult=false; //不能走 console.log('紅方兵未過河,只能向前走一步!'); if(!tryJiangJun)np.innerHTML="兵步錯誤"; } }else{//過河 if((Math.abs(x-a)==cell&&y==b)||(a==x&&y-b==cell)){ wayResult=true; //能走 }else { wayResult=false; //不能走 console.log('紅方兵未過河,只能向 前、左、右 方向走一步!'); if(!tryJiangJun)np.innerHTML="兵步錯誤"; } } }else{ if(y<0){//未過河 if(x==a&&y-b==-cell){ wayResult=true; //能走 console.log('黑方兵未過河,能走!'); }else { wayResult=false; //不能走 console.log('黑方兵未過河,只能向前走一步!'); if(!tryJiangJun)np.innerHTML="兵步錯誤"; } }else{//過河 if((Math.abs(x-a)==cell&&y==b)||(a==x&&y-b==-cell)){ wayResult=true; //能走 }else { wayResult=false; //不能走 console.log('黑方兵未過河,只能向 前、左、右 方向走一步!'); if(!tryJiangJun)np.innerHTML="兵步錯誤"; } } } break; default: } if(countQiziOnRoad===1){ return countQiziOnRoad; }else{ console.log("wayResult:"+wayResult); return wayResult; } } function checkXYisEmpty(x,y) { //指定座標上 是否為空,空則true,有棋子則返回棋子的; // console.log("指定座標上 是否為空,空則true,有棋子則返回棋子的side"); var re; for(i in qzArray){ if(qzArray[i].isDead===true){re=true;continue} // console.log("檢測座標:"+x+","+y+" 上有沒有"+qzArray[i].name); if(qzArray[i].x==x && qzArray[i].y==y){ re= qzArray[i].side+"_"+qzArray[i].name+"_"+qzArray[i].x+","+qzArray[i].y; console.log(re); re=qzArray[i]; break; }else { re=true; } } console.log("re:"+re); return re; } function putQiZi(object) { cxt.beginPath(); cxt.arc(object.x,object.y,cell/2,0,Math.PI*2,true); cxt.fillStyle="#DEB887"; cxt.fill(); cxt.fillStyle=(object.side=="紅方")?"red":"black"; cxt.fillText(object.name,object.x-cell*0.4,object.y+cell*0.3); cxt.closePath(); if(object.isChoose===true){object.choose()} // console.log(object.side+""+object.name+",已到位"); } function newGameStart() { gameType=1; createQiPan(); for(index in qzName){ // if(qzName[index]=='兵'){continue} switch (qzName[index]){ case '炮': var a=(index==10)?-1:1; qzRedArray[index]=createQZ(-3*cell*a,2.5*cell,qzName[index],"紅方"); qzBlackArray[index]=createQZ(-3*cell*a,-2.5*cell,qzName[index],"黑方"); break; case '兵': qzRedArray[index]=createQZ(-wh+(index-11)*2*cell,1.5*cell,qzName[index],"紅方"); qzBlackArray[index]=createQZ(-wh+(index-11)*2*cell,-1.5*cell,qzName[index],"黑方"); break; default: qzRedArray[index]=createQZ(-wh+index*cell,hh,qzName[index],"紅方"); qzBlackArray[index]=createQZ(-wh+index*cell,-hh,qzName[index],"黑方"); } qzArray=qzRedArray.concat(qzBlackArray); putQiZi(qzRedArray[index]); putQiZi(qzBlackArray[index]); } console.log('------------紅方先走!(Red First)-------------'); np.innerHTML="紅方先走"; } function clearCanvas() { cxt.clearRect(-c.width/2,-c.height/2,c.width,c.height); } function createQiPan() { clearCanvas(); cxt.strokeStyle="#ff0000"; cxt.lineWidth=1; //橫線 for(var i=0;i<=9;i++){ cxt.moveTo(-wh,-hh+cell*i); cxt.lineTo(wh,-hh+cell*i); } //豎線 for(var i=0;i<=8;i++){ cxt.moveTo(-wh+cell*i,-hh); if(i!=0 && i!=8){//除兩端外,中間豎線 分為兩段 cxt.lineTo(-wh+cell*i,-cellh); cxt.moveTo(-wh+cell*i,cellh); } cxt.lineTo(-wh+cell*i,hh); } //下方‘米’格 cxt.moveTo(-cell,hh); cxt.lineTo(cell,hh-2*cell); cxt.moveTo(-cell,hh-2*cell); cxt.lineTo(cell,hh); //上方‘米’格 cxt.moveTo(-cell,-hh); cxt.lineTo(cell,-hh+2*cell); cxt.moveTo(-cell,-hh+2*cell); cxt.lineTo(cell,-hh); cxt.stroke(); //兵位 for(var i=0;i<5;i++){ cxt.beginPath(); cxt.arc(-wh+2*cell*i,1.5*cell,cell/4,0,Math.PI*2,true); cxt.stroke(); cxt.beginPath(); cxt.arc(wh-2*cell*i,-1.5*cell,cell/4,0,Math.PI*2,true); cxt.stroke(); } //炮位 cxt.beginPath(); cxt.arc(-3*cell,2.5*cell,cell/4,0,Math.PI*2,true); cxt.stroke(); cxt.beginPath(); cxt.arc(3*cell,2.5*cell,cell/4,0,Math.PI*2,true); cxt.stroke(); cxt.beginPath(); cxt.arc(-3*cell,-2.5*cell,cell/4,0,Math.PI*2,true); cxt.stroke(); cxt.beginPath(); cxt.arc(3*cell,-2.5*cell,cell/4,0,Math.PI*2,true); cxt.stroke(); cxt.closePath(); //楚河 漢界 cxt.fillStyle='#ff0000'; cxt.beginPath(); cxt.fillText('楚河',-2.5*cell,0.6*cellh); cxt.fillText('漢界',1*cell,0.6*cellh); cxt.closePath(); }