今天更新的第二篇博客,是最近没事的时候写的一个小游戏-----五子棋,用canvas和js写的一个,大家可能觉得,一个破五子棋,网上的逻辑一大堆,各种判断都有,这些我写完以后也去看了,才知道网上早就有人开发了一个比我这个方法好的逻辑,但是我的正方法我个人觉得比较喜欢,所以分享出来给大家看看。
之所以用canvas做这个游戏,考虑到现在玩游戏的时候基本都是比较新型的浏览器或者手机,一般对canvas的兼容性都比较好,第二点是因为用canvas写这个游戏比较简单。。。请轻喷。好了,不废话了,贴代码咯。
// JavaScript Document var can,txt,mousePos,posArray,posArray_x,posArray_y,flag=false,qizi_color,success_array=[],type,GameStatus="on"; function init(){ can = document.getElementById("mycanvas"); txt=can.getContext("2d"); drawpic(); can.addEventListener("click", function(evt){ if(GameStatus=="on"){addqizi(evt);} }, false); }; function drawpic(){ txt.clearRect(0,0,800,800); txt.strokeStyle="black"; txt.fillStyle="#e0e0e0"; txt.fillRect(0,0,800,800); txt.lineWidth="1px"; for(var i=0;i<26;i++){ txt.beginPath(); txt.moveTo(30*i+25,25); txt.lineTo(30*i+25,775); txt.stroke(); txt.beginPath(); } for(var j=0;j<26;j++){ txt.beginPath(); txt.moveTo(25,30*j+25); txt.lineTo(775,30*j+25); txt.stroke(); txt.beginPath(); } posArray=[ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ] }; function addqizi(evt){ mousePos=getMousePos(can, evt); posArray_x=parseInt((mousePos.x-25)/30); posArray_y=parseInt((mousePos.y-25)/30); if((mousePos.x-25)%30>15&&(mousePos.y-25)%30>15){ posArray_x+=1; posArray_y+=1; }else if((mousePos.x-25)%30>15&&(mousePos.y-25)%30<15){ posArray_x+=1; }else if((mousePos.x-25)%30<15&&(mousePos.y-25)%30>15){ posArray_y+=1; } if(posArray[posArray_x][posArray_y]==0){ if(flag==false){ qizi_color = txt.createRadialGradient(30*posArray_x+25,30*posArray_y+25,2,30*posArray_x+25,30*posArray_y+25,12); qizi_color.addColorStop(0,"#505050"); qizi_color.addColorStop(1,"#000000"); flag=true; posArray[posArray_x][posArray_y]=1; }else if(flag==true){ qizi_color = txt.createRadialGradient(30*posArray_x+25,30*posArray_y+25,3,30*posArray_x+25,30*posArray_y+25,12); qizi_color.addColorStop(0,"#dedede"); qizi_color.addColorStop(1,"#cccccc"); flag=false; posArray[posArray_x][posArray_y]=2; } txt.fillStyle=qizi_color; txt.beginPath(); txt.arc(30*posArray_x+25,30*posArray_y+25,12,0,Math.PI*2,true); txt.closePath(); txt.fill(); check_result(posArray_x,posArray_y); } } function check_result(i,n){ type=posArray[i][n]; //当棋子在左上角的时候 //------------------------------------------------------------------------- //---------------------------左上角----------------------------------------- if(i<5&&n<5){ //先判断横着的是否形成了五个棋子 for(var num=0;num<=i;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //再判断竖着的是否形成了五个棋子 for(var num=0;num<=n;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜着往下进行判断 if(i>n){ for(var x=(i-n),y=0;x<=i,y<=n;x++,y++){ for(var a= x,b=y;a<x+5,b<y+5;a++,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } }else if(i<=n){ for(var x=0,y=(n-i);y<=n,x<=i;x++,y++){ for(var a= x,b=y;a<x+5,b<y+5;a++,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //斜着往上进行判断 if(i+n==4){ for(i=0;i<5;i++){ if(posArray[i][4-i]==type){ success_array.push(1); }else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //---------------------------上边距------------------------------ else if(i>=5&&i<21&&n<5){ //横着排列 for(var num=i-4;num<=i;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //再判断竖着的是否形成了五个棋子 for(var num=0;num<=n;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜着往上 for(var x=i+n,y=0;x>=i,y<=n;x--,y++){ for(var a= x,b=y;a>x-5,b<y+5;a--,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜着往下 for(var x=i-n,y=0;x<=i,y<=n;x++,y++){ for(var a=x,b=y;a<x+5,b<y+5;a++,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //---------------------------左边距------------------------------ else if(i<5&&n>=5&&n<21){ //横着 for(var num=0;num<=i;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); break; } } chenckResult(); } //竖着 for(var num=n-4;num<=n;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜上 for(var x=0,y=n+i;x<=i,y>=n;x++,y--){ for(var a=x,b=y;a<x+5,b>y-5;a++,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜下 for(var x=0,y=n-i;x<=i,y<=n;x++,y++){ for(var a=x,b=y;a<x+5,b<y+5;a++,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //---------------------------左下角------------------------------ else if(i<5&&n>20){ //横着 for(var num=0;num<=i;num++) { for (var mum = num; mum < num + 5; mum++) { if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //竖着 for(var num=25;num>=n;num--) { for (var mum = num; mum > num - 5; mum--) { if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜上 if(i>25-n){ for(var x=i+n-25,y=25;x<=i,y>=n;x++,y--){ for(var a=x,b=y;a<x+5,b>y-5;a++,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } }else if(i<=25-n){ for(var x=0,y=n+i;x<=i,y>=n;x++,y--){ for(var a=x,b=y;a<x+5,b>y-5;a++,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //斜下 if(n-i==21){ for(var x=0;x<5;x++){ if(posArray[x][21+x]==type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //---------------------------下边距------------------------------ else if(i>=5&&i<21&&n>20){ //横着 for(var num=i-4;num<=i;num++){ for(var mum=num;mum<num+5;mum++){ if(posArray[mum][n]==type){ success_array.push(1); }else{ success_array.push(0); } } chenckResult(); } //竖着 for(var num=25;num>=n;num--) { for (var mum = num; mum > num - 5; mum--) { if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜上 for(var x=i+n-25,y=25;x<=i,y>=n;x++,y--){ for(var a=x,b=y;a<x+5,b>y-5;a++,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜下 for(var x=i-n+25,y=25;x>=i,y>=n;x--,y--){ for(var a=x,b=y;a>x-5,b>y-5;a--,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //----------------------------------右边距--------------------------------- else if(i>20&&n>=5&&n<21){ //横着 for(var num=25;num>=i;num--){ for(var mum=num;mum>num-5;mum--){ if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //竖着 for(var num=n-4;num<=n;num++){ for(var mum=num;mum<num+5;mum++){ if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜上 for(var x=25,y=n+i-25;x>=i,y<=n;x--,y++){ for(var a=x,b=y;a>x-5,b<y+5;a--,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜下 for(var x=25,y=n-i+25;x>=i,y>=n;x--,y--){ for(var a=x,b=y;a>x-5,b>y-5;a--,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //----------------------------------右上角--------------------------------- else if(i>20&&n<5){ //横着 for(var num=25;num>=i;num--){ for(var mum=num;mum>num-5;mum--){ if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //竖着 for(var num=0;num<=n;num++){ for(var mum=num;mum<num+5;mum++){ if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜上 if(25-i>n){ for(var x=i+n,y=0;x>=i,y<=n;x--,y++){ for(var a=x,b=y;a>x-5,b<y+5;a--,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } }else{ for(var x=25,y=n+i-25;x>=i,y<=n;x--,y++){ for(var a=x,b=y;a>x-5,b<y+5;a--,b++){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //斜下 if(i=n+21){ for(n=0;n<5;n++){ if(posArray[n+21][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } //------------------------------------------------------------------------- //----------------------------------右下角--------------------------------- else if(i>20&&n>20){ //横着 for(var num=25;num>=i;num--){ for(var mum=num;mum>num-5;mum--){ if(posArray[mum][n] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //竖着 for(var num=25;num>=n;num--){ for(var mum=num;mum>num-5;mum--){ if(posArray[i][mum] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜上 if(i+n==46){ for(i=21;i<=25;i++){ if(posArray[i][46-i] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } //斜下 if(i<n){ for(var x=i+25-n,y=25;x>=i,y>=n;x--,y--){ for(var a=x,b=y;a>x-5,b>y-5;a--,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } }else{ for(var x=25,y=n+25-i;x>=i,y>=n;x--,y--){ for(var a=x,b=y;a>x-5,b>y-5;a--,b--){ if(posArray[a][b] == type){ success_array.push(1); } else{ success_array.push(0); } } chenckResult(); } } } //------------------------------------------------------------------------- //---------------------------中间区域------------------------------ else if(i>=5&&i<21&&n>=5&&n<21){ //横着 for(var num=i-4;num<=i;num++){ for(var mum=num;mum<num+5;mum++){ if(posArray[mum][n]==type){ success_array.push(1); }else{ success_array.push(0); } } chenckResult(); } //竖着 for(var num=n-4;num<=n;num++){ for(var mum=num;mum<num+5;mum++){ if(posArray[i][mum]==type){ success_array.push(1); }else{ success_array.push(0); } } chenckResult(); } //斜上 for(var x=i-4,y=n+4;x<=i,y>=n;x++,y--){ for(var a=x,b=y;a<x+5,b>y-5;a++,b--){ if(posArray[a][b]==type){ success_array.push(1); }else{ success_array.push(0); } } chenckResult(); } //斜下 for(var x=i-4,y=n-4;x<=i,y<=n;x++,y++){ for(var a=x,b=y;a<x+5,b<y+5;a++,b++){ if(posArray[a][b]==type){ success_array.push(1); }else{ success_array.push(0); } } chenckResult(); } } } function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left * (canvas.width / rect.width), y: evt.clientY - rect.top * (canvas.height / rect.height) } } function chenckResult(){ if(success_array.toString()==[1,1,1,1,1].toString()){ if(type==1){ alert("黑子胜利!"); }else{ alert("白子胜利!"); } GameStatus="off"; success_array=[]; return; }else{ success_array=[]; } } init(); function Restrat(){ init(); GameStatus="on"; }
其实这些代码还有很多可以优化的位置,只是后来写完了一直有事儿,就没有进行细化,不过大家可以看看里面的一些逻辑,虽然逻辑比较复杂,但是能把这些全部想通的话其实也是一个不错的选择,之前js有一千多行,后来被我压缩成700多行了。。。但是还有很多可以压缩的空间,网上的方法我也看过,只需要两百多行就可以搞定,本来后来想写一个网上的方法的,一直忙到现在都没什么时间去写了,网上的方法逻辑比较简单,后来也就不想去动了 。
这个方法是用的纯数组实现的,虽然逻辑上,速率上比网上的慢很多,但是我想说的是这个逻辑还是比较适合游戏的,数组在游戏里或者是复杂的动画里真的是比较神器的东西(ps.纯属个人理解)。
谢谢您花时间看完这两篇博客,希望您不吝赐教,提出您宝贵的意见。