本文实例为大家分享了Vue实现五子棋小游戏的具体代码,供大家参考,具体内容如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>五子棋</title>
<script src="./configJS/vue.js"></script>
<script src="./configJS/jQuery 1.10.2.js"></script>
<style>
.fiveInRow {
position: absolute;
width: 100%;
}
.fiveStar {
position: absolute;
display: flex;
width: 542px;
height: 720px;
margin: -24px 65px;
justify-content: space-around;
align-items: center;
}
.starGroup {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.star {
width: 10px;
height: 10px;
border-radius: 50%;
background: black;
}
.boxRow {
position: absolute;
display: flex;
margin: 20px;
border: 1px solid black;
box-sizing: border-box;
}
.box {
width: 45px;
height: 45px;
border: 1px solid black;
box-sizing: border-box;
}
.chessBlock {
position: absolute;
margin: 20px;
}
.chessBox {
position: absolute;
z-index: 9;
width: 42px;
height: 42px;
display: flex;
justify-content: center;
align-items: center;
}
.chess {
width: 40px;
height: 40px;
border-radius: 50%;
border: 1px solid black;
box-sizing: border-box;
}
.overCover {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 632px;
height: 632px;
color: red;
z-index: 11;
}
.btnGroup {
position: absolute;
top: 700px;
left: 235px;
display: flex;
}
.btnGroup button {
margin: 0 10px;
}
</style>
</head>
<body>
<div class="fiveInRow">
<!-- 棋盘五星层 -->
<div class="fiveStar">
<div class="starGroup">
<div class="star"></div>
<div class="star"></div>
</div>
<div class="star"></div>
<div class="starGroup">
<div class="star"></div>
<div class="star"></div>
</div>
</div>
<!-- 落子层 -->
<div class="chessBlock"></div>
<!-- 棋盘网格层 -->
<div class="boxRow" @click="downChess($event)"></div>
<!-- 功能BTN -->
<div class="btnGroup">
<button @click="giveUp()">认输</button>
<button @click="regret()">悔棋</button>
<button @click="openNew()">重开</button>
</div>
</div>
</body>
<script>
new Vue({
el: ".fiveInRow",
data: {
boxSize: 15, //棋盘大小
chessType: "black", //棋子类型,默认为黑
blackList: [], //黑子列表
whiteList: [], //白子列表
totleNum: 0, //落子总数
isOver: 0 //游戏是否结束
},
created() {
this.createBox()
},
watch: {
totleNum(val) {
// 监听棋盘落子数
let boxRow = $(".boxRow")[0];
let overCover = `<div class="overCover">
<h1 style="color:red;">棋盘满了,下一把吧!!!</h1>
</div>`;
if (val === this.boxSize * this.boxSize) {
boxRow.innerHTML += overCover;
this.isOver = 1;
}
}
},
methods: {
createBox() {
// 创建棋盘网格
let box = `<div class="box"></div>`;
let boxRow = $(".boxRow")[0];
for (let i = 1; i < this.boxSize; i++) {
let boxCloum = `<div class="boxCloum">`;
for (let j = 1; j < this.boxSize; j++) {
boxCloum += box;
}
boxRow.innerHTML += boxCloum + `</div>`;
}
},
downChess(ev) {
// 判断落子
if (!this.isOver) {
this.down(ev);
} else {
let overCover = $(".overCover")[0];
let newSpan = `<h2>游戏已经结束了,请重新开始!</h2>`;
if (overCover.children.length <= 3) overCover.innerHTML += newSpan;
}
},
down(ev) {
// 落子
let chessBlock = $(".chessBlock")[0];
let layerX = this.getLayer(ev.layerX);
let layerY = this.getLayer(ev.layerY);
if (layerX >= 0 && layerY >= 0) {
let chessTemp = `<div
class="chessBox" style="left:${layerX-21}px;top:${layerY-21}px;"
><span class="chess" style="background:${this.chessType};"></span></div>`;
chessBlock.innerHTML += chessTemp;
this.totleNum++;
if (this.chessType === "black") {
this.blackList.push([layerX, layerY]);
this.isFive(this.blackList);
this.chessType = "white";
} else {
this.whiteList.push([layerX, layerY]);
this.isFive(this.whiteList);
this.chessType = "black";
}
} else {
console.log("瞅哪呢?看准点下!");
}
},
getLayer(val) {
// 获取落点相对位置
if (val % 45 <= 20) {
return val - val % 45;
} else if (val % 45 >= 25) {
return val - val % 45 + 45;
} else {
return -1;
}
},
isFive(list) {
// 判断是否落成五子
this.isFiveInStraight(list, 0, 1);
this.isFiveInStraight(list, 1, 0);
this.isFiveInSlope(list, -1);
this.isFiveInSlope(list, 1);
},
isFiveInStraight(list, a, b) {
// 判断五子是否在水平线或垂直线
let listSGT = {};
for (let i = 0; i < list.length; i++) {
if (!listSGT[list[i][b]]) {
listSGT[list[i][b]] = [list[i][a]];
} else {
listSGT[list[i][b]].push(list[i][a]);
this.isFiveNearby(listSGT[list[i][b]]);
}
}
},
isFiveInSlope(list, slope) {
// 判断五子是否在正斜线或反斜线
let listSLP = {};
for (let i = 0; i < list.length; i++) {
let b = list[i][1] - slope * list[i][0];
if (!listSLP[b]) {
listSLP[b] = [list[i][0]];
} else {
listSLP[b].push(list[i][0]);
this.isFiveNearby(listSLP[b]);
}
}
},
isFiveNearby(arr) {
// 判断五子是否相邻,连成一线
let idx = 0;
let player = this.chessType === "black" ? "Black(黑)" : "White(白)";
if (arr.length >= 5) {
arr.sort((a, b) => a - b)
for (let i = 1; i < arr.length; i++) {
idx = arr[i] - arr[i - 1] === 45 ? idx + 1 : 0;
if (idx === 4) this.gameOver(player);
}
}
},
gameOver(player) {
// 游戏结束
console.log(player + " Win!!!");
let boxRow = $(".boxRow")[0];
let overCover = `<div class="overCover"><h1>${player} Win!!!</h1></div>`;
boxRow.innerHTML += overCover;
this.isOver = 1;
},
giveUp() {
// 认输投降
let player = this.chessType === "black" ? "White(白)" : "Black(黑)";
if (!this.isOver) this.gameOver(player);
},
regret() {
// 悔棋
if (this.totleNum > 0 && !this.isOver) {
let chessBlock = $(".chessBlock")[0];
chessBlock.removeChild(chessBlock.children[--this.totleNum]);
if (this.chessType === "black") {
this.whiteList.pop();
this.chessType = "white";
} else {
this.blackList.pop();
this.chessType = "black";
}
} else {
console.log("一个子都没有,悔个鸡儿悔!");
}
},
openNew() {
// 重新开始
let chessBlock = $(".chessBlock")[0];
let boxRow = $(".boxRow")[0];
for (let i = this.totleNum - 1; i >= 0; i--) {
chessBlock.removeChild(chessBlock.children[i]);
}
if (boxRow.children[14]) boxRow.removeChild(boxRow.children[14]);
this.chessType = "black";
this.blackList = [];
this.whiteList = [];
this.totleNum = this.isOver = 0;
}
}
})
</script>
</html>
主要思路
1.画棋盘
小雨采用了最直接, 最暴力的方式, 就是把一堆小方块堆起来, 加上边框, 棋盘有了…什么? 你问我那五个点怎么画上去的? 页面上试出来的.
2.落子
落子是比较讲究的. 首先获取鼠标点击事件中的layerX, layerY, 这是鼠标点击的相对位置, 在本例中是比较好用的. 然后通过 getLayer() 函数获取点击点最近的网格点, 如下图, 鼠标点击在红框内则落子. 最后在相比网格点半个棋子位的地方落子就OK了.
3.判断获胜条件
isFive(list) {
// 判断是否落成五子
this.isFiveInStraight(list, 0, 1);
this.isFiveInStraight(list, 1, 0);
this.isFiveInSlope(list, -1);
this.isFiveInSlope(list, 1);
},
isFiveInStraight(list, a, b) {
// 判断五子是否在水平线或垂直线
let listSGT = {};
for (let i = 0; i < list.length; i++) {
if (!listSGT[list[i][b]]) {
listSGT[list[i][b]] = [list[i][a]];
} else {
listSGT[list[i][b]].push(list[i][a]);
this.isFiveNearby(listSGT[list[i][b]]);
}
}
},
isFiveInSlope(list, slope) {
// 判断五子是否在正斜线或反斜线
let listSLP = {};
for (let i = 0; i < list.length; i++) {
let b = list[i][1] - slope * list[i][0];
if (!listSLP[b]) {
listSLP[b] = [list[i][0]];
} else {
listSLP[b].push(list[i][0]);
this.isFiveNearby(listSLP[b]);
}
}
},
isFiveNearby(arr) {
// 判断五子是否相邻,连成一线
let idx = 0;
let player = this.chessType === "black" ? "Black(黑)" : "White(白)";
if (arr.length >= 5) {
arr.sort((a, b) => a - b)
for (let i = 1; i < arr.length; i++) {
idx = arr[i] - arr[i - 1] === 45 ? idx + 1 : 0;
if (idx === 4) this.gameOver(player);
}
}
},
这里主要有4个函数: isFive(), isFiveInStraight(), isFiveInSlope() 和 isFiveNearby().
isFive(): 这个只是调用后续函数的函数, 它将获胜条件分成了4类: 横线获胜, 竖线获胜, 斜率为1的斜线获胜 和 斜率为-1的斜线获胜.
isFiveInStraight(): 判断 横线获胜 和 竖线获胜 的功能函数. 这里的主要难点就是listSGT 对象的创建, 能否想到要用对象来实现落子的分类, 是这个函数的关键. 在 横线获胜 中, 将落子的layerY 坐标作为对象的属性, 将有相同layerY 坐标的棋子的layerX 组成一个数组作为属性的值. 竖线获胜 同理.
isFiveInSlope(): 判断 斜率为1的斜线获胜 和 斜率为-1的斜线获胜 的功能函数. 与 isFiveInStraight() 不同的是, 在创建listSLP 对象时, 以直线函数 y = k x + b y = kx+by=kx+b 中截距(b) 作为对象的属性, 以落子的layerX 坐标组成的数组作为属性的值, 其实用落子的layerY坐标也是一样的.
isFiveNearby(): 判断五子是否相邻的功能函数. 此函数直接获取上两个函数中所创建对象的值, 也就是落子坐标组成的数组. 首先判断数组长度是否大于5, 毕竟能少走一步是一步嘛. 之后将数组从小到大排序, 计算相邻两位的差, 并记录. 连续记录4次获胜.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。