趁着休息,花了1小时参考网上各类简单的写了个五子棋,主要实现功能,未进行任何优化
修改画布大小及棋子布局
<template>
<div class="board">
<canvas id="board" width="600" height="600"></canvas>
</div>
</template>
CSS相应如下
.board {
border: 1px solid red;
width: 630px;
height: 630px;
padding: 0 0;
margin: 0 0;
display: flex;
align-items: center;
justify-content: center;
}
1、绘制棋盘,以30为一格,考虑棋子落在交叉点,故在绘制时右移和下移了15,并将数组进行重置(600的棋盘,30一个,共20个)
drawBoard() {
const canvas = document.getElementById("board");
const ctx = canvas.getContext("2d");
// 设置线条颜色
ctx.strokeStyle = "black";
// 绘制横线
for (let i = 0; i <= 19; i++) {
ctx.beginPath();
ctx.moveTo(15, i * 30 + 15);
ctx.lineTo(570 + 15, i * 30 + 15);
ctx.stroke();
}
// 绘制竖线
for (let i = 0; i <= 19; i++) {
ctx.beginPath();
ctx.moveTo(i * 30 + 15, 0 + 15);
ctx.lineTo(i * 30 + 15, 570 + 15);
ctx.stroke();
}
// 重置为0
for (let i = 0; i <= 19; i++) {
this.board.push(new Array(20).fill(0))
}
// console.log(this.board)
},
2、绘制棋子,考虑正负15的距离,此处在绘制完成后,进行了正负判断,选手交换
drawCell() {
let container = document.getElementById("board");
container.addEventListener("click", this.handleClickAndDraw)
},
handleClickAndDraw(event) {
let x = event.offsetX;
let y = event.offsetY;
console.log(x + ' ' + y)
// 计算棋子落在哪个方格中
const cellX = Math.floor((event.offsetX) / 30);
const cellY = Math.floor((event.offsetY) / 30);
console.log(cellX, cellY)
// 判断该位置是否有棋子
if (this.board[cellX][cellY] !== 0) {
alert("该位置已有棋子")
return;
}
const canvas = document.getElementById("board");
const ctx = canvas.getContext("2d");
//画带渐变色的棋子,同心圆形式
let grd = ctx.createRadialGradient(
cellX * 30 + 15,
cellY * 30 + 15,
2,
cellX * 30 + 15,
cellY * 30 + 15,
10
)
grd.addColorStop(0, this.player === 1 ? '#FFFFFF' : '#4C4C4C')
grd.addColorStop(1, this.player === 1 ? '#DADADA' : '#000000')
ctx.beginPath()
ctx.fillStyle = grd
ctx.arc(
cellX * 30 + 15,
cellY * 30 + 15,
10,
0,
2 * Math.PI,
false
);
ctx.fill();
ctx.closePath();
this.board[cellX][cellY] = this.player; //将黑白棋信息存储
this.winner = this.checkWinner(this.board)
if (this.winner != null) {
alert(this.winner)
}
this.player = this.player === 1 ? 2 : 1
},
3、正负判断,这个主要采取网上CSDN,并未进行过多加工
checkWinner(board) {
// 检查横向是否有五子连线
for (let i = 0; i < 19; i++) {
let count = 0;
for (let j = 0; j < 19; j++) {
if (board[i][j] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
// 检查纵向是否有五子连线
for (let j = 0; j < 19; j++) {
let count = 0;
for (let i = 0; i < 19; i++) {
if (board[i][j] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
// 检查右斜线是否有五子连线
for (let i = 0; i < 14; i++) {
for (let j = 0; j < 14; j++) {
let count = 0;
for (let k = 0; k < 5; k++) {
if (board[i + k][j + k] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
}
// 检查左斜线是否有五子连线
for (let i = 0; i < 14; i++) {
for (let j = 4; j < 19; j++) {
let count = 0;
for (let k = 0; k < 5; k++) {
if (board[i + k][j - k] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
}
// 如果没有五子连线,则游戏继续
return null;
}
最后,完整代码如下App.vue
<script>
export default {
data() {
return {
board: [],
player: 1,//1--白棋;2--黑棋
winner: null
};
},
mounted() {
this.drawBoard();
this.drawCell();
},
methods: {
drawBoard() {
const canvas = document.getElementById("board");
const ctx = canvas.getContext("2d");
// 设置线条颜色
ctx.strokeStyle = "black";
// 绘制横线
for (let i = 0; i <= 19; i++) {
ctx.beginPath();
ctx.moveTo(15, i * 30 + 15);
ctx.lineTo(570 + 15, i * 30 + 15);
ctx.stroke();
}
// 绘制竖线
for (let i = 0; i <= 19; i++) {
ctx.beginPath();
ctx.moveTo(i * 30 + 15, 0 + 15);
ctx.lineTo(i * 30 + 15, 570 + 15);
ctx.stroke();
}
// 重置为0
for (let i = 0; i <= 19; i++) {
this.board.push(new Array(20).fill(0))
}
// console.log(this.board)
},
drawCell() {
let container = document.getElementById("board");
container.addEventListener("click", this.handleClickAndDraw)
},
handleClickAndDraw(event) {
let x = event.offsetX;
let y = event.offsetY;
console.log(x + ' ' + y)
// 计算棋子落在哪个方格中
const cellX = Math.floor((event.offsetX) / 30);
const cellY = Math.floor((event.offsetY) / 30);
console.log(cellX, cellY)
// 判断该位置是否有棋子
if (this.board[cellX][cellY] !== 0) {
alert("该位置已有棋子")
return;
}
const canvas = document.getElementById("board");
const ctx = canvas.getContext("2d");
//画带渐变色的棋子,同心圆形式
let grd = ctx.createRadialGradient(
cellX * 30 + 15,
cellY * 30 + 15,
2,
cellX * 30 + 15,
cellY * 30 + 15,
10
)
grd.addColorStop(0, this.player === 1 ? '#FFFFFF' : '#4C4C4C')
grd.addColorStop(1, this.player === 1 ? '#DADADA' : '#000000')
ctx.beginPath()
ctx.fillStyle = grd
ctx.arc(
cellX * 30 + 15,
cellY * 30 + 15,
10,
0,
2 * Math.PI,
false
);
ctx.fill();
ctx.closePath();
this.board[cellX][cellY] = this.player; //将黑白棋信息存储
this.winner = this.checkWinner(this.board)
if (this.winner != null) {
alert(this.winner)
}
this.player = this.player === 1 ? 2 : 1
},
checkWinner(board) {
// 检查横向是否有五子连线
for (let i = 0; i < 19; i++) {
let count = 0;
for (let j = 0; j < 19; j++) {
if (board[i][j] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
// 检查纵向是否有五子连线
for (let j = 0; j < 19; j++) {
let count = 0;
for (let i = 0; i < 19; i++) {
if (board[i][j] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
// 检查右斜线是否有五子连线
for (let i = 0; i < 14; i++) {
for (let j = 0; j < 14; j++) {
let count = 0;
for (let k = 0; k < 5; k++) {
if (board[i + k][j + k] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
}
// 检查左斜线是否有五子连线
for (let i = 0; i < 14; i++) {
for (let j = 4; j < 19; j++) {
let count = 0;
for (let k = 0; k < 5; k++) {
if (board[i + k][j - k] === this.player) {
count++;
} else {
count = 0;
}
if (count >= 5) {
return this.player;
}
}
}
}
// 如果没有五子连线,则游戏继续
return null;
}
}
};
</script>
<template>
<div class="board">
<canvas id="board" width="600" height="600"></canvas>
</div>
</template>
<style scoped>
.board {
border: 1px solid red;
width: 630px;
height: 630px;
padding: 0 0;
margin: 0 0;
display: flex;
align-items: center;
justify-content: center;
}
</style>
效果图
1 条评论
《今天不是最后一天》国产剧高清在线免费观看:https://www.jgz518.com/xingkong/39895.html