五子棋小游戏(JS+Node+Websocket)可分房间对战

您所在的位置:网站首页 怎么在qq玩五子棋 五子棋小游戏(JS+Node+Websocket)可分房间对战

五子棋小游戏(JS+Node+Websocket)可分房间对战

2023-09-23 08:32| 来源: 网络整理| 查看: 265

主要通过js、canvas、node、websocket来实现五子棋游戏。

tip:如果你想清楚的了解怎么实现,请一步步看思路流程,文章最后有项目的gitee地址、对应B站视频,可直接食用。

首先搭建一个express服务:

const express = require('express') const path = require('path') const app = express() //静态资源目录 app.use(express.static(path.join(__dirname, 'public'))); let port = 3003 app.get('/home', (req, res, next) => { res.writeHead(200, { 'Content-type': 'text/html;charset=utf-8' }) res.end('欢迎来到express') next() }) const server = app.listen(port, () => { console.log('成功启动express服务,端口号是' + port) })

这个时候我们可以访问静态文件里面的文件了,如: 在这里插入图片描述 public下面的index.html在访问3003/的时候在浏览器渲染。 在这里插入图片描述 这也说明了我们的node服务启动成功,接口在3003端口上。

前端页面,里面包括css\html但是不包括js,只是引入js文件:

五子棋 * { padding: 0; margin: 0; } html, body { width: 100%; height: 100%; overflow: hidden; } canvas { margin-top: 200px; margin-left: 300px; background-color: rgb(213, 176, 146); display: inline-block; border-radius: 8px; border: 1px solid black; } .resultBox { position: absolute; text-align: center; top: 200px; left: 760px; width: 200px; height: 450px; /* background-color: #ccc; */ background-color: rgb(213, 176, 146); color: 38px; line-height: 60px; font-weight: bold; } 白旗已下0 黑旗已下0 //低版本 不再使用 1:生成棋盘 2:生成棋子 3:棋子落点 4:五子成线 ?赢 :输 流程:

1.页面:渲染完成,输入房间号 2.选择白棋 、 黑棋 3.选择白棋后先下 黑棋有了白棋才能下 4.一方胜利,游戏结束。

页面加载后开始连接服务器。 控制台打印连接成功。输入房间号。

房间号里面只能容纳两个人,多余的人为观众,不可控制器盘的棋子

棋盘构造函数 //线条构造函数 //线条颜色 x y function Line(color, x, y) { this.color = color; this.x = x this.y = y } //画横线 Line.prototype.getXLine = function () { ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, this.y); ctx.lineTo(this.x, this.y); ctx.strokeStyle = this.color; ctx.closePath(); ctx.fill(); ctx.stroke(); } //画竖线 Line.prototype.getYLine = function () { ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(this.x, 0); ctx.strokeStyle = this.color; ctx.lineTo(this.x, this.y); ctx.closePath(); ctx.fill(); ctx.stroke(); } //线条相隔大小 后面 num += flag let num = 0 //线条随机颜色数组 // let colorsList = ["#33B5E5", "#0099CC", "#AA66CC", "#9933CC", "#99CC00", "#669900", "#FFBB33", "#FF8800", "#FF4444", "#CC0000"] //循环画线 for (let i = 0; i item.getXLine() }) //画竖线 getYLineArr.map(item => { item.getYLine() }) 棋子构造函数 function Chessman(x, y, color) { this.x = x this.y = y this.color = color } Chessman.prototype.update = function () { ctx.save(); ctx.beginPath() ctx.fillStyle = this.color// 背景颜色为白色 ctx.arc(this.x, this.y, 20, 0, Math.PI * 2, false) ctx.fill() ctx.closePath() } 棋子落在棋盘

选择白棋 黑棋,每点击一次棋盘会进行判断是否是该你下棋子

//当前点击的坐标 相对于canvas的坐标 let arr = [e.clientX - MarginLeftNum, e.clientY - MarginTopNum] //当前点击坐标到 棋盘 0,0 的距离 // let newArrLong = Math.sqrt((0 - arr[0]) * (0 - arr[0]) + (0 - arr[1]) * (0 - arr[1])) //25 let newArrLong = flag / 2 newARR = [] //循环判断当前点击坐标到哪个棋盘坐标的距离最短,棋子放置到该坐标点 lineXAndlineYArr.map((item, index) => { let newArrLongA = Math.sqrt((item[0] - arr[0]) * (item[0] - arr[0]) + (item[1] - arr[1]) * (item[1] - arr[1])) if (newArrLongA if (blackOrRedChessman % 2 !== 0) { return false } console.log("%c当前点击棋子坐标:", "color:red;font-size:20px;", newARR) } else { //黑 if (blackOrRedChessman % 2 == 0) { return false } console.log("%c当前点击棋子坐标:", "color:red;font-size:20px;", newARR) }

随后查看该点是否已经有了棋子

//判断该点是否已经有棋子 let hasYesOrNo = JSON.stringify(hasChessmanArrList).includes(JSONstringify(newARR)) if (!hasYesOrNo) { //没有的话加入棋子数组 hasChessmanArrList.push(newARR) } else { alert('已经有棋子') return } 棋子落子后触发服务器棋子位子更新

//lineXAndlineYArrRed 白棋 //lineXAndlineYArrBlack 黑棋 //lineXAndlineYArrBlack 黑棋 //blackOrRedChessman 棋子数量

const sendItemsArr = JSON.stringify({ lineXAndlineYArrRed, lineXAndlineYArrBlack, hasChessmanArrList, blackOrRedChessman }) mySocket.emit('sendItemsArr', sendItemsArr) 服务器派发另一个人更新棋子位置 websocketObj.on('sendItemsArr', (sendItemsArr) => { itemsArr = sendItemsArr //触发所以的 sendFunEventCallBack 事件 让前端监听 io.sockets.emit("getItemsArr", itemsArr); }) 前端接受最新的棋子位置: //websocket mySocket.on('getItemsArr', (getItemsArr) => { const ItemsArr = JSON.parse(getItemsArr) lineXAndlineYArrRed = ItemsArr.lineXAndlineYArrRed lineXAndlineYArrBlack = ItemsArr.lineXAndlineYArrBlack hasChessmanArrList = ItemsArr.hasChessmanArrList blackOrRedChessman = ++ItemsArr.blackOrRedChessman // 判断这次点击棋子颜色 //生成棋子 放置棋盘中 lineXAndlineYArrRed.map(i => { new Chessman(i[0], i[1], color1).update() }) lineXAndlineYArrBlack.map(i => { new Chessman(i[0], i[1], color2).update() }) //改变页面上的信息 redP.innerHTML = '白旗已下' + lineXAndlineYArrRed.length blackP.innerHTML = '黑旗已下' + lineXAndlineYArrBlack.length })

再而判断下的这枚棋子,白棋或者黑棋棋子是否已经有了五个:

//判断棋子数量是否已经大于5 没到5 决对赢不了的 ~ if (newlineXAndlineYArr.length >= 5) { //向右向左倾斜判断、横向纵向判断 leftRightFangXiang() // //向右倾斜 function leftRightFangXiang() { // 深拷贝一份数据 let newlineXAndlineYArrR = JSON.parse(JSON.stringify(newlineXAndlineYArr)) let newRightArrList = [] for (let i = 0; i newRightArrList = [] for (let j = 0; j newRightArrList.push([newARR[0] + flag * (k - i + 1), newARR[1]]) } if (rightOrRight(newRightArrList, newlineXAndlineYArrR, newARR) == 'win') { console.log("%c横向赢了哦~", "color:red;font-size:30px;"); break } } //y if (1) { newRightArrList = [] for (let j = 0; j newRightArrList.push([newARR[0], newARR[1] + flag * (k - i + 1)]) } if (rightOrRight(newRightArrList, newlineXAndlineYArrR, newARR) == 'win') { console.log("%c纵向赢了哦~", "color:red;font-size:30px;"); break } } // //左下 // 前 + - 张俊卿 - + if (1) { newRightArrList = [] for (let j = 0; j newRightArrList.push([newARR[0] - flag * (k - i + 1), newARR[1] + flag * (k - i + 1)]) } if (rightOrRight(newRightArrList, newlineXAndlineYArrR, newARR) == 'win') { console.log("%c左下赢了哦~", "color:red;font-size:30px;"); break } } //右下 // 前 - - 张俊卿 + + 后 if (1) { newRightArrList = [] for (let j = 0; j newRightArrList.push([newARR[0] + flag * (k - i + 1), newARR[1] + flag * (k - i + 1)]) } if (rightOrRight(newRightArrList, newlineXAndlineYArrR, newARR) == 'win') { console.log("%c右下赢了哦~", "color:red;font-size:30px;"); break } } } } } 胜利

**有5个连成了一条线,服务器更新棋子位置 **

//初始化函数 mySocket.emit('clearItemsArr')

node

websocketObj.on('clearItemsArr', () => { let clearItemsArr = JSON.parse(itemsArr) clearItemsArr.lineXAndlineYArrRed = [] clearItemsArr.lineXAndlineYArrBlack = [] clearItemsArr.hasChessmanArrList = [] clearItemsArr.blackOrRedChessman = 0 // websocketObj.emit('getItemsArr',itemsArr ) //触发所以的 sendFunEventCallBack 事件 让前端监听 io.sockets.emit("clearItemsArrAll", JSON.stringify(clearItemsArr)); })

前端接受重置位置,页面重置:

//websocket mySocket.on('clearItemsArrAll', (getItemsArr) => { const ItemsArr = JSON.parse(getItemsArr) lineXAndlineYArrRed = ItemsArr.lineXAndlineYArrRed lineXAndlineYArrBlack = ItemsArr.lineXAndlineYArrBlack hasChessmanArrList = ItemsArr.hasChessmanArrList blackOrRedChessman = ++ItemsArr.blackOrRedChessman //赢了 resultP.innerHTML = blackOrRedChessman % 2 == 0 ? '黑棋子方胜利' : '白棋子方胜利' var r = window.confirm(resultP.innerHTML + ",是否重新开始!"); if (r == true) { redP.innerHTML = '白旗已下0' blackP.innerHTML = '黑旗已下0' againInit() } })

重置画布:

//重新开始 function againInit() { // window.history.go(0) //横线对象数组 getXLineArr = [] //竖线对象数组 getYLineArr = [] //偶数白色 基数 黑色 blackOrRedChessman = 0 //所有棋子数组 hasChessmanArrList = [] //坐标点数组 //白旗坐标数组 lineXAndlineYArrRed = [] //黑棋坐标数组 lineXAndlineYArrBlack = [] ctx.clearRect(0, 0, canvas.width, canvas.height) init() }

主要是使用html、js、node、websocket完成了一个可以分多个房间的双人五子棋游戏,其他人可以观战。

git地址:

五子棋分房间双人战斗

git clone https://gitee.com/zhang745929987/gobang-room-two-fight.gitcd 进去 npm inode或者nodemon test.js

完整代码在git上,有兴趣可以玩一玩,提出一些改进意见。

B站视频

javascript五子棋讲解 javascript五子棋演示

演示:

在这里插入图片描述 如果拉下来运行不起来的话: 在这里插入图片描述 这是暴跨域问题的解决方案; 如果报错socket的问题的时候,你需要更新socket的版本; https://cdn.socket.io/ 在这找最新的连接地址引入天幻index.html的src即可。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3