基于javascript canvas实现五子棋游戏
本文实例为大家分享了基于canvas的五子棋的具体代码,供大家参考,具体内容如下
第一部分:核心类Gobang
属性:
this.box=box;//存放五子棋的容器 this.canvas=null;//画布 this.ctx=null; this.size=600;//棋盘大小 this.cellNum=20;//单行棋格数量 this.padding=this.size/this.cellNum;//padding值 this.cellSize=(this.size-this.padding*2)/this.cellNum;//棋格大小 this.pieceSize=this.cellSize*3/4;//棋子大小 this.color=["black","#aaa"];//棋子颜色 this.myPieceType=null;//玩家棋子类型 this.aiPieceType=null;//电脑棋子类型 this.myPieces=[];//玩家累计棋子 this.aiPieces=[];//电脑累计棋子 this.isMyTurn=true;//先手 this.curPos=[this.cellNum/2-1,this.cellNum/2-1];//当前点击位置 this.timeId=null;//定时器id
方法:
init//初始化方法,获取canvas设置宽高,获取ctx createChessboard//创建背景棋盘 drawPiece//画一个棋子 clearPiece//清除棋子 registClick//注册鼠标点击事件,主要的逻辑函数 isIn//判断否在所下的棋子里面 isInAll//判断是否在所有下的棋子里面 isFull//是否下满 aiPutPiece//电脑落子,只是简单的实现了,获取玩家落子位子周围一格的随机位置 putPiece//实现下棋的函数 isWin//胜利判断,个人人为比较男一点点的算法 run//运行,类的入口函数,里面调用了,·init·/createChessBoard/registClick方法
第二部分:源代码
Gobang.js
/**五子棋**/ functionGobang(box){ this.box=box;//存放五子棋的容器 this.canvas=null;//画布 this.ctx=null; this.size=600;//棋盘大小 this.cellNum=20;//单行棋格数量 this.padding=this.size/this.cellNum;//padding值 this.cellSize=(this.size-this.padding*2)/this.cellNum;//棋格大小 this.pieceSize=this.cellSize*3/4;//棋子大小 this.color=["black","#aaa"];//棋子颜色 this.myPieceType=null;//玩家棋子类型 this.aiPieceType=null;//电脑棋子类型 this.myPieces=[];//玩家累计棋子 this.aiPieces=[];//电脑累计棋子 this.isMyTurn=true;//先手 this.curPos=[this.cellNum/2-1,this.cellNum/2-1];//当前点击位置 this.timeId=null;//定时器id //初始化方法 this.init=function(){ //创建canvas this.canvas=document.createElement("canvas"); //设置宽高 this.canvas.width=this.canvas.height=this.size; //加入到容器中 this.box.appendChild(this.canvas); //获取ctx this.ctx=this.canvas.getContext("2d"); }; //创建背景棋盘 this.createChessboard=function(){ //-----------边框----------- this.ctx.lineWidth=10; this.ctx.lineJoin="round"; this.ctx.strokeRect(0,0,this.size,this.size); //-----------创建棋盘----------- this.ctx.lineWidth=1; for(vari=0;i<=this.cellNum;i++){ //画横线 this.ctx.beginPath(); this.ctx.moveTo(this.padding,this.padding+i*this.cellSize); this.ctx.lineTo(this.size-this.padding,this.padding+i*this.cellSize); this.ctx.stroke(); //画竖线 this.ctx.beginPath(); this.ctx.moveTo(this.padding+i*this.cellSize,this.padding); this.ctx.lineTo(this.padding+i*this.cellSize,this.size-this.padding); this.ctx.stroke(); } }; //画一个棋子 this.drawPiece=(x,y,type=0)=>{ //根据坐标计算出图中位置 varposX,posY; posX=this.padding+x*this.cellSize; posY=this.padding+y*this.cellSize; //创建渐变色 vargrd=this.ctx.createRadialGradient(posX,posY,this.pieceSize/18,posX,posY,this.pieceSize); //type:0,黑棋1,白棋 grd.addColorStop(0,this.color[1-type]); grd.addColorStop(0,this.color[type]); this.ctx.fillStyle=grd; //画圆 this.ctx.beginPath();this.ctx.arc(posX,posY,this.pieceSize/2,0,2*Math.PI);this.ctx.fill(); }; //清除棋子 this.clearPiece=(x,y)=>{ //清除棋子所在位置的像素 varposX,posY; posX=this.padding+x*this.cellSize-this.pieceSize/2; posY=this.padding+y*this.cellSize-this.pieceSize/2; this.ctx.clearRect(posX,posY,this.pieceSize,this.pieceSize); //补上十字架 this.ctx.lineWidth=1; //竖线 this.ctx.beginPath();this.ctx.moveTo(posX+this.pieceSize/2,posY);this.ctx.lineTo(posX+this.pieceSize/2,posY+this.pieceSize);this.ctx.stroke(); //横线 this.ctx.beginPath();this.ctx.moveTo(posX,posY+this.pieceSize/2);this.ctx.lineTo(posX+this.pieceSize,posY+this.pieceSize/2);this.ctx.stroke(); }; //注册鼠标点击事件 this.registClick=function(){ this.canvas.addEventListener("click",(ev)=>{ //将位置坐标,转换为点 varx=Math.round((ev.clientX-this.padding)/this.cellSize); x=x<=0?0:x;x=x>this.cellNum?this.cellNum:x; vary=Math.round((ev.clientY-this.padding)/this.cellSize); y=y<=0?0:y;y=y>this.cellNum?this.cellNum:y; //设置当前位置 this.curPos=[x,y]; //玩家落子 if(this.isMyTurn&&!this.isInAll(this.curPos)){//判断是否轮到玩家,并且下的位置是否重复 this.putPiece(this.myPieces,this.curPos); } elsereturn;//轮到玩家的时候才能落子 //判断输赢 if(this.isWin(this.myPieces)){setTimeout(function(){alert("youwin!");},100);return;} //电脑落子 this.aiPutPiece(); //判断输赢 if(this.isWin(this.aiPieces)){setTimeout(function(){alert("robotwin!");},100);return;} this.isMyTurn=true; }); }; //判断否在所下的棋子里面 this.isIn=(pos,arr)=>{ varlen=arr.length; for(vari=0;i{ returnthis.isIn(pos,this.myPieces.concat(this.aiPieces)); } //是否下满 this.isFull=()=>{ return(this.myPieces.length+this.aiPieces.length)==(this.cellNum+1)*(this.cellNum+1); }; //电脑落子 this.aiPutPiece=()=>{ varx,y; //目前,制作了一点功能,就是在玩家刚刚落子的周围一格落子 //1.获得随机的周围的坐标 while(1){ x=this.curPos[0]+Math.pow(-1,parseInt(Math.random()*2)); y=this.curPos[1]+Math.pow(-1,parseInt(Math.random()*2)); if(x>=0&&x<=20&&y>=0&&y<=20&&!this.isInAll([x,y]))break; } //2.落子 this.putPiece(this.aiPieces,[x,y],1); } //实现下棋的函数 this.putPiece=(pieces,pos,type=0)=>{ this.drawPiece(pos[0],pos[1],type); pieces.push(pos); } //胜利判断 this.isWin=(pieces)=>{ /* *这里不用遍历棋盘来判断四个方向,只需要判断当前落子位置的四个方向。 */ varx,y,count=0; //处在水平线上判断 x=this.curPos[0]-1;y=this.curPos[1]; while(1)if(this.isIn([x,y],pieces)){count++;x--;}elsebreak;//左边 x=this.curPos[0]+1;y=this.curPos[1]; while(1)if(this.isIn([x,y],pieces)){count++;x++;}elsebreak;//右边 if(count>=4)returntrue;else/**左右匹配失败**/count=0; //处在垂直线上判断比较四次 x=this.curPos[0];y=this.curPos[1]-1; while(1)if(this.isIn([x,y],pieces)){count++;y--;}elsebreak;//上边 x=this.curPos[0];y=this.curPos[1]+1; while(1)if(this.isIn([x,y],pieces)){count++;y++;}elsebreak;//下边 if(count>=4)returntrue;else/**上下匹配失败**/count=0; //处在左对角线上的判断 x=this.curPos[0]-1;y=this.curPos[1]-1; while(1)if(this.isIn([x,y],pieces)){count++;x--;y--;}elsebreak;//左上 x=this.curPos[0]+1;y=this.curPos[1]+1; while(1)if(this.isIn([x,y],pieces)){count++;x++;y++;}elsebreak;//右下 if(count>=4)returntrue;else/**左对角线匹配失败**/count=0; //处在右对角线上的判断 x=this.curPos[0]+1;y=this.curPos[1]-1; while(1)if(this.isIn([x,y],pieces)){count++;x++;y--;}elsebreak;//右上 x=this.curPos[0]-1;y=this.curPos[1]+1; while(1)if(this.isIn([x,y],pieces)){count++;x--;y++;}elsebreak;//左下 if(count>=4)returntrue;else/**右对角线匹配失败**/returnfalse; }; //运行 this.run=function(){ //初始化方法 this.init(); //创建棋盘 this.createChessboard(); //注册点击事件 this.registClick(); } }
五子棋.html
06-五子棋