1.首先五子棋会有棋盘,先创建一个HTML页面,在元素中添加一个canvas标签,同时设置了canvas画布的宽、高都为800px,给canvas画布添加了样式,代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>五子棋游戏</title>
</head>
<style>
canvas {
background-color: rgb(221, 210, 182);
display: block;
margin: 0 auto;
}
.tip{
width: 100%;
text-align: center;
font-size: 30px;
color: red;
}
</style>
<body>
<!--展示获胜提示-->
<div class="tip"></div>
<canvas width="800" height="800" id="box"></canvas>
</body>
</html>
2.这里我们开始绘制棋盘,五子棋的棋盘是 15行15列的直线组成,我们定义每格的宽高都为50,那么棋盘高度和宽度都为700
<script>
//获取canvas节点
let myCanvas = document.getElementById('box');
//获取我们的canvas画笔
let context = myCanvas.getContext('2d');
//绘制棋盘15行15列
for(let i = 1; i < = 15; i++){
//先画横线,让棋盘预留50px的边界,我们从x轴为50,y轴为50的位置作为起点
//起点x轴坐标为50,保持不变,y轴每一行从上到下为50的倍数增加
context.moveTo(50, 50*i);
//终点x轴坐标为750,保持不变,y轴每一行从上到下为50的倍数增加
context.lineTo(750, 50*i);
cotext.stroke();
//竖线同理
//起点y轴坐标为50,保持不变,x轴每一行从左到右为50的倍数增加
context.moveTo(50*i, 50);
//终点y轴坐标为750,保持不变,x轴每一行从左到右为50的倍数增加
context.lineTo(50*i, 750);
cotext.stroke();
}
</script>
绘制完成后的效果
3.添加在棋盘上点击就落子的逻辑,五子棋有黑白两种棋子颜色,我们默认先落子的为黑子,为了让棋子能准确的落在交叉点上,我们需要对鼠标点击的位置进行判断,我们把棋盘的每个交叉点对应二维数组里的占位(如图中的红圈占位就是array[4][4]),红圈的半径为网格的宽度的50%也就是25,当鼠标点击在红圈区域时,我们就把棋子视为要落在红圈中的交叉点上
let isWhite = false; //添加是否到白棋下子的标识,初始为false
let circles = []; //设置保存棋子位置的二维数组
let isEnd= false; //判断是否结束的标识
//为棋盘注册点击事件
myCanvas.addEventListener('click',(e)=>{
//获取鼠标点击位置的坐标
let {offsetX,offsetY} = e;
//判断游戏是否结束
if(isEnd){ return; }
//判断棋子落在棋盘外的位置,不允许落子
if(offsetX < 25 || offsetY < 25 || offsetX > 775 || offsetY >775) {
return false;
}
//
let i = Math.floor(offsetX+25/50); //获取点击位置在第几根竖线的区域中,即二维数组的行
let j = Math.floor(offsetY+25/50); //获取点击位置在第几根横线的区域中,即二维数组的列
let x = i*50; //获取x轴坐标位置
let y = j*50; //获取y轴坐标位置
//识别不能重复落子
if( circles[i][j] ){
alert('当前位置已有棋子,不能重复落子!');
return ;
}
//判断当前棋子的颜色,并存入二维数组中
let circles[i][j] = isWhite ? 'white':'black';
let color = isWhite ? '#fff':'#000';
//绘制棋子
context.beginPath();
//在当前坐标位置为圆心,绘制一个半径为20的圆
context.arc(x,y,20,0,2*Math.PI);
//为棋子设置环形渐变的颜色,让棋子看起来有光泽
let gradient = context.createRadialGradient(x-10,y-10,x,y,20);
gradient.addColor(0,'#ccc'); //棋子上光泽色
gradient.addColor(0,color); //棋子颜色
//为棋子加上阴影
context.shadowColor = '#333';
context.shawdowBlur = 20;
context.shawdowOffsetX = 5;
context.shadowOffsetY = 5;
//填充颜色
context.fillStyle = gradient;
context.fill();
context.closePath();
//在这里添加当前颜色的棋子是否胜出的逻辑,获胜函数如下方4、5、6
if(verticalWin(i,j) || horizontalWin(i,j) || obliqueWin(i,j)) {
isEnd = true; //有获胜者游戏结束
tip[0].innerHTML = `${isWhite? '白':'黑'}子获胜`;
return;
}
//最后把棋子颜色的标识切换
isWhite = !isWhite
})
4.接下来我们来先纵向获胜的逻辑函数,接收当前棋子所在的位置代的行列数,从当前位置出发纵向寻找是否同色棋子连续出现了4次,则获胜,代码如下
function verticalWin(x,y){
let up = 0; //记录当前位置往上棋子出现的次数
let down = 0; //记录当前位置往下棋子出现的次数
let target = isWhite ? 'white':'black'; //获取当前棋子的颜色
//循环4次,若有相同颜色的棋子出现次数+1
for(let i = 1; i < 5; i++){
//纵向x轴保持不变
//向下找出现相同颜色的棋子,次数+1
if(circles[x][y-i] && circles[x][y-i] === target) down++;
//向上找出现相同颜色的棋子,次数+1
if(circles[x][y+i] && circles[x][y+i] === target) up++;
}
//4次都出现了相同颜色则返回true,及获胜
return up+down >= 4;
}
5.横向逻辑同理,代码如下
function horizontalWin(x,y){
let left = 0; //记录当前位置往左棋子出现的次数
let right = 0; //记录当前位置往右棋子出现的次数
let target = isWhite ? 'white':'black'; //获取当前棋子的颜色
//循环4次,若有相同颜色的棋子出现次数+1
for(let i = 1; i < 5; i++){
//横向y轴保持不变
//向左找出现相同颜色的棋子,次数+1
if(circles[x-i][y] && circles[x-i][y] === target) left++;
//向右找出现相同颜色的棋子,次数+1
if(circles[x+i][y] && circles[x+i][y] === target) right++;
}
//当4次都出现了相同颜色则返回true,及获胜
return left+right >= 4;
}
6.判断斜向获胜,我们也分为左方和右方出现的次数想加来判断,
如果当前棋子位置前4列的位置时,是没办法实现左斜上方或左斜下方连出4子的情况,右边也同理,当前棋子位置后4列的位置时,不可能出现连续4子的情况,因此要先排除这类情况
function obliqueWin(x,y) {
let left = 0; //记录当前位置斜上方棋子出现的次数
let right= 0; //记录当前位置斜下方棋子出现的次数
let target = isWhite ? 'white':'black';
for (let i = 1; i < 5; i++) {
//判断左边斜上方和左边斜下方是否出现同色棋子
if (x > 4 && ((circles[x - i][y + i] && circles[x - i][y + i]) || (circles[x - i][y - i] && circles[x - i][y - i]))=== target) left++;
//判断右边斜上方和右边斜下方是否出现同色棋子
if (x < 10 && ((circles[x + i][y-i] && circles[x+i][y-i]) || (circles[x + i][y+i] && circles[x + i][y+i])) === target) right++;
}
return left + right >= 4;
}
以上就是我实现五子棋游戏交互的一个思路了,谢谢大家的观看!