基于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-五子棋