项目地址,已上传github ——>
client端使用简单的h5+js实现了棋局的总体布局。 server端使用node的socket.io模块与客户端进行数据交互,棋子的落点和输赢校验均是在server端完成。
五子棋ui界面请见..
client端的界面这里就不做过多解释了,只要稍微懂点h5就可以自行去这里 下载源代码观看,因为今天的主题主要是socket.io这一块,所以本章只概述client和server是如何通过tcp连接进行交互的。
首先先带大家看一下目录结构
| server.js (socket服务器) | gobang-ui.html (是玩家下棋页面) | index.html (是用户登陆界面) | home.html (是用户大厅界面, 用来匹配等待的 如果在线人数少于2人, 则匹配失败, 并会返回错误信息) | game.html (client端程序的入口,内嵌iframe来显示各个页面,通过改变iframe的src属性,来达成伪页面跳转) | img (图片资源文件夹) | tou.jpg (棋盘界面用户的头像,因为登录界面只要输入用户名就可以开始游戏了,所以所有用户的头像都是一样的)
game.html主界面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; width: 100%; height: 100%; } </style> <!-- 引入cdn上的socket.io库 --> <script src="/UploadFiles/2021-04-02/socket.io.js">为什么我们要用嵌入iframe改变src属性的方式来制造页面跳转的现象?因为页面的每一次跳转或刷新都会使socket连接断开。就好像http中的request请求一样,页面每次所以我们应尽量避免页面跳转这个操作。
// 这行代码表示client端对server端进行第一次连接 var socket = io('ws://localhost:3000')在index.html也就是用户的登录界面
<!-- 这是用户登录的按钮 --> <div onclick="login()">开始游戏</div>当点击了这个按钮之后,它会触发js中的login方法,但这个方法并不会直接去连接server,因为socket连接在game.html中,所以目前来看,这个页面只是game.html的子页面,这个方法在判断input中的value是否为空后,立即通过全局对象parent调用的父页面(game.html)中的login方法
// index.html中的login方法 function login() { if (username.value === undefined || username.value === '') { return } // 调用父窗口的login方法 parent.login(username.value) }game.html中的login方法,这个方法通过socket向server触发了login事件
function login(username) { socket.emit('login', username) }server.js
// 监听连接 io.on('connection', function (socket) { // 玩家登陆, socket.emit('login', username)就是触发了这个事件 // 监听了login事件 socket.on('login', function (name) { // players是一个全局数组,里面存放了所有的玩家对象,如果players中 var flag = players.some(function (value) { return value.name === name }) if (flag) { socket.emit('home', {'flag': true}) } else { console.log(name + '已登陆') // 创建玩家 new Player(socket, name) // 将玩家放进数组中 // players.push(player) // 如果用户名没有重名,那么触发client端的home事件 socket.emit('home', {'playerCount': playerCount, 'name': name}) } }) })玩家client对home事件的监听
// 玩家登陆成功 socket.on('home', function (data) { if (data.flag) { game.contentWindow.flag.hidden = false } else { game.contentWindow.flag.hidden = true // 保存用户名和玩家在线人数到localStorage中 localStorage.setItem('name', data.name) localStorage.setItem('playerCount', data.playerCount) // location.href = './home.html' game.src = 'home.html' } })home.html玩家等待大厅, home.html和index.html长得基本一致,所以它也有一个按钮,匹配按钮,通过它来触发play事件
// 玩家开始匹配 this.socket.on('play', function () { // 如果空闲玩家总数大于或等于2,那么开始游戏 if (playerCount >= 2) { self.pipei = true // 如果已经有人在开始匹配了,那么这个玩家就不需要走下面函数了,因为继续执行的话相当于再开一个棋局 if (isExistFZ(self) > 0) { // 保持不动就好,房主会自动找到你的 return } // 如果没有房主,那么这个玩家将成为房主 self.fz = true // 可用的玩家数 var player2 = null self.timer = setInterval(function () { console.log('正在匹配...') if (player2 = findPlayer(self)) { console.log('匹配成功') self.gamePlay = new Game(self, player2) player2.gamePlay = self.gamePlay clearInterval(self.timer) } }, 1000) } else { socket.emit('player less') } })server.js中有两个类,一个是Player玩家类,另一个是Game棋局类,一个棋局对应两个玩家。
Player类的属性
this.socket = socket // socket对象,玩家通过它来监听数据 this.name = name // 玩家的名称 this.color = null // 玩家棋子的颜色 this.state = 0 // 0代表空闲, 1在游戏中 this.pipei = false // 是否在匹配 this.gamePlay = null // 棋局对象 this.flag = true // 是否轮到这个玩家出棋 this.fz = false // 是否是房主Player类对象监听的事件
// 监听玩家是否退出游戏 this.socket.on('disconnect', function () { // 删除数组中的玩家 // players.splice(players.indexOf(self), 1) // 删不掉 // delete players[players.indexOf(self)] // 新的删除方式 players = players.filter(function (value) { return value.name !== self.name }) playerCount-- // 如果退出游戏的玩家正在进行游戏,那么这局游戏也该退出 if (self.state === 0) { gameCount-- } console.log(self.name + '已退出游戏') }) // 玩家开始匹配 this.socket.on('play', function () { // 如果空闲玩家总数大于或等于2,那么开始游戏 if (playerCount >= 2) { self.pipei = true // 如果已经有人在开始匹配了,那么这个玩家就不需要走下面函数了,因为继续执行的话相当于再开一个棋局 if (isExistFZ(self) > 0) { // 保持不动就好,房主会自动找到你的 return } // 如果没有房主,那么这个玩家将成为房主 self.fz = true // 可用的玩家数 var player2 = null self.timer = setInterval(function () { console.log('正在匹配...') if (player2 = findPlayer(self)) { console.log('匹配成功') self.gamePlay = new Game(self, player2) player2.gamePlay = self.gamePlay clearInterval(self.timer) } }, 1000) } else { socket.emit('player less') } }) // 玩家取消匹配按钮 this.socket.on('clearPlay', function () { clearInterval(self.timer) }) // 监听数据,玩家下棋的时候触发 this.socket.on('data', function (data) { if (self.flag) { add_pieces(self.gamePlay, data, self.color) } }) // 最后将当前玩家实例放到players全局玩家数组中去 players.push(this)Game(棋局类)
// 棋盘的格子数 this.column = 21 this.arr = init_arr() // 存储棋盘坐标的二位数组 // 一局棋局上的两个玩家 this.play1 = play1 this.play2 = play2 // 修改游戏状态 this.play1.state = 1 this.play2.state = 1 // 在游戏中,是否匹配为false this.play1.pipei = false this.play2.pipei = false this.play1.fz = false this.play1.fz = false // 随机给两个玩家分配棋子颜色 this.play1.color = ~~(Math.random() * 2) === 0 "htmlcode">// 添加棋子 function add_pieces(self, position, color) { if (self.arr[position.x][position.y] === undefined) { self.arr[position.x][position.y] = color if (color === self.play1.color) { self.play1.flag = false self.play2.flag = true } else if (color === self.play2.color) { self.play1.flag = true self.play2.flag = false } check_result(self, self.arr, position, color) } } // 初始化数组 function init_arr() { var arr = [] for (var i = 0; i < 21; i++) { arr.push(new Array(21)) } return arr }如果大家喜欢的话,请在github上下载我的源码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]