微信小程序五子棋游戲的棋盤(pán),重置,對(duì)弈實(shí)現(xiàn)方法【附demo源碼下載】
本文實(shí)例講述了微信小程序五子棋游戲的棋盤(pán),重置,對(duì)弈實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:
DEMO下載
效果圖

分析
1. 采用微信小程序的canvas制作五子棋;
2. 確定棋盤(pán)大小及格數(shù);
3. 繪制棋盤(pán)—-通過(guò)棋盤(pán)寬高和格數(shù)計(jì)算間距,同時(shí)保存坐標(biāo)點(diǎn);
4. 黑方和白方下子—-定義一個(gè)布爾變量代表各自的身份;
5. 重置棋盤(pán)—-重新開(kāi)始;
6. 通過(guò)判斷當(dāng)前棋手,悔棋時(shí)進(jìn)行改變。
繪制棋盤(pán)
drawLine(arr){
arr.forEach(current => {
this.ctx.setFillStyle(this.lineColor);
this.ctx.beginPath();
this.ctx.lineWidth = 1;
this.ctx.moveTo(current[0].x, current[0].y);
for (var i = 1; i < current.length; i++) {
this.ctx.lineTo(current[i].x, current[i].y);
}
this.ctx.stroke();
this.ctx.closePath();
this.ctx.draw(true);
});
}
drawChessboard(){
// 每個(gè)格子的寬高
var everyLen = this.everyLen;
// 標(biāo)記坐標(biāo)的個(gè)數(shù)
var count = 0;
// 從縱向保存坐標(biāo)
var arrY = [];
// 雙循環(huán)計(jì)算每個(gè)坐標(biāo)的橫縱坐標(biāo)
for(var i = 0;i <= this.type; i++){
var arr = [],arr0 = [];
for(var j = 0;j <= this.type; j++){
count++;
arr.push({
y: this.margin + i * everyLen,
x: this.margin + j * everyLen,
pointX: j,
pointY: i,
index: count
});
arr0.push({
x: this.margin + i * everyLen,
y: this.margin + j * everyLen
})
}
// 清空canvas
this.ctx.clearRect(0, 0, this.width, this.height);
// 保存橫線(xiàn)坐標(biāo)和豎線(xiàn)坐標(biāo)
this.everyPoint.push(arr);
arrY.push(arr0);
}
// 繪制橫向線(xiàn)
this.drawLine(this.everyPoint);
// 繪制豎向線(xiàn)
this.drawLine(arrY);
}
繪制當(dāng)前點(diǎn)擊坐標(biāo)的棋子
// 獲取當(dāng)前點(diǎn)擊位置的坐標(biāo)
getPosition(e){
return {
x: e.touches[0].x,
y: e.touches[0].y
};
}
// 將當(dāng)前坐標(biāo)和棋盤(pán)坐標(biāo)數(shù)組對(duì)比,找到精確坐標(biāo)
checkPoint(arr,po){
for (var i = 0; i < this.everyPoint.length; i++){
for (var j = 0; j < this.everyPoint[i].length; j++){
if (Math.abs(this.everyPoint[i][j].x - po.x) < this.everyLen/2 && Math.abs(this.everyPoint[i][j].y - po.y) < this.everyLen/2){
// 將棋盤(pán)精確坐標(biāo)保存到當(dāng)前持棋方數(shù)組
arr.push(this.everyPoint[i][j]);
// 同時(shí)刪除棋盤(pán)坐標(biāo)數(shù)組的該值,表示當(dāng)前位置已經(jīng)存在棋子
this.everyPoint[i].splice(j,1);
break;
}
}
}
}
// 繪制當(dāng)前坐標(biāo)棋子
drawCle(opts,color){
this.ctx.setFillStyle(color);
this.ctx.beginPath();
this.ctx.arc(opts.x, opts.y, this.r, 0, Math.PI * 2, true);
this.ctx.closePath();
this.ctx.fill();
this.ctx.draw(true);
}
drawLastPoint(type){
// 判斷是黑方持棋還是白方持棋,進(jìn)行繪制棋子
if(type == 'AI'){
this.AIPoint.forEach((current, index) => {
this.drawCle(current, '#000000');
});
}else{
this.myPoint.forEach((current, index) => {
this.drawCle(current, '#ffffff');
});
}
}
this.page.changeTouchStart = function (e) {
// 判斷游戲是否開(kāi)始
if (self.START_GAME){
// 獲取當(dāng)前坐標(biāo)
var newPo = self.getPosition(e);
// 獲取棋盤(pán)精確坐標(biāo)
if (!self.boolAI && self.boolMy) {
self.checkPoint(self.myPoint, newPo);
} else if (self.boolAI && !self.boolMy) {
self.checkPoint(self.AIPoint, newPo);
}
}
}
this.page.changeTouchEnd = function (e) {
if (self.START_GAME) {
// 繪制棋子
if (!self.boolAI && self.boolMy) {
self.boolAI = !self.boolAI;
self.boolMy = !self.boolMy;
self.drawLastPoint('PO');
// 判斷白棋是否五子勝利
if (self.myPoint.length >= 5 && self.checkWinner(self.myPoint)){
wx.showToast({title: '白棋勝利!'});
self.START_GAME = false;
}
} else if (self.boolAI && !self.boolMy) {
self.boolAI = !self.boolAI;
self.boolMy = !self.boolMy;
self.drawLastPoint('AI');
// 判斷黑棋是否五子勝利
if(self.AIPoint.length >= 5 && self.checkWinner(self.AIPoint)){
wx.showToast({ title: '黑棋勝利!' });
self.START_GAME = false;
}
}
}
}
五子棋勝利方判斷
五子棋勝利就是橫向、縱向、45度斜線(xiàn)方向、135度斜線(xiàn)方向連成五個(gè)顏色相同的棋子,為了更加清楚的表示,我將四個(gè)方向的判斷做四個(gè)函數(shù)處理。
checkTransverse(arr,po){//橫向檢查
var len = arr.length - 1;
var count = 1;
// 東
for(var i = 1; i < this.CHESS_LEN ; i++){
for (var j = 0; j < len; j++){
if(arr[j].pointX == po.pointX - i && arr[j].pointY == po.pointY){
count++;
}
}
}
if (count == this.CHESS_LEN) { return true;}
// 西
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX + i && arr[j].pointY == po.pointY) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
}
checkPortrait(arr,po){//縱向檢查
var len = arr.length - 1;
var count = 1;
// 南
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX && arr[j].pointY == po.pointY - i) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
// 北
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX && arr[j].pointY == po.pointY + i) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
}
checkNortheast(arr,po){//45度
var len = arr.length - 1;
var count = 1;
// 西南
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX - i && arr[j].pointY == po.pointY - i) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
// 東北
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX + i && arr[j].pointY == po.pointY + i) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
}
checkNorthwest(arr,po){//135度
var len = arr.length - 1;
var count = 1;
// 西北
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX - i && arr[j].pointY == po.pointY + i) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
// 東南
for (var i = 1; i < this.CHESS_LEN; i++) {
for (var j = 0; j < len; j++) {
if (arr[j].pointX == po.pointX + i && arr[j].pointY == po.pointY - i) {
count++;
}
}
}
if (count == this.CHESS_LEN) { return true; }
}
checkWinner(arr){
var currentPo = arr[arr.length - 1];
var win1 = this.checkTransverse(arr, currentPo);
var win2 = this.checkPortrait(arr, currentPo);
var win3 = this.checkNortheast(arr, currentPo);
var win4 = this.checkNorthwest(arr, currentPo);
if (win1 || win2 || win3 || win4){
return true;
}else{
return false;
}
}
重置棋盤(pán)
resetChessBoard(){
this.page.setData({ isHide: false });
this.init();
}
this.page.changeReset = function(e){
self.resetChessBoard();
}
注意
1. 繪制棋盤(pán)前必須清空canvas,方便最后的重新開(kāi)始和重置棋盤(pán);
2. 對(duì)當(dāng)前棋子的坐標(biāo)四個(gè)方向的判斷,采用的原始坐標(biāo)而不是計(jì)算后的繪制坐標(biāo);
3. 在判斷持棋人時(shí),各自采用一個(gè)值,方便添加悔棋功能。
只是實(shí)現(xiàn)了簡(jiǎn)單的對(duì)下五子棋功能,后續(xù)添加悔棋、記分、記時(shí)等功能!
同時(shí)向判斷勝利的函數(shù)可以合并為一進(jìn)行優(yōu)化!
希望本文所述對(duì)大家微信小程序開(kāi)發(fā)有所幫助。
相關(guān)文章
JSON序列化與解析原生JS方法且IE6和chrome測(cè)試通過(guò)
JSON序列化與解析本文通過(guò)原生JS方法實(shí)現(xiàn),IE6和chrome下均測(cè)試通過(guò),喜歡的朋友可以嘗試操作下2013-09-09
input?獲取光標(biāo)位置設(shè)置光標(biāo)位置方案
這篇文章主要為大家介紹了input?獲取光標(biāo)位置設(shè)置光標(biāo)位置方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
利用weixin-java-miniapp生成小程序碼并直接返回圖片文件流的方法
這篇文章主要介紹了利用weixin-java-miniapp生成小程序碼并直接返回圖片文件流的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
JavaScript生成隨機(jī)驗(yàn)證碼代碼實(shí)例
這篇文章主要介紹了JavaScript生成隨機(jī)驗(yàn)證碼代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
JavaScript實(shí)現(xiàn)多態(tài)和繼承的封裝操作示例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)多態(tài)和繼承的封裝操作,結(jié)合實(shí)例形式分析了javascript中多態(tài)與繼承的實(shí)現(xiàn)及封裝相關(guān)操作技巧,需要的朋友可以參考下2018-08-08

