欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

怎么在node.js中利用socket.io實(shí)現(xiàn)多人在線匹配聯(lián)機(jī)五子棋

怎么在node.js中利用socket.io實(shí)現(xiàn)多人在線匹配聯(lián)機(jī)五子棋?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

站在用戶的角度思考問題,與客戶深入溝通,找到辰溪網(wǎng)站設(shè)計與辰溪網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋辰溪地區(qū)。

首先先帶大家看一下目錄結(jié)構(gòu)

| server.js (socket服務(wù)器) 
| gobang-ui.html (是玩家下棋頁面) 
| index.html (是用戶登陸界面)
| home.html (是用戶大廳界面, 用來匹配等待的 如果在線人數(shù)少于2人, 則匹配失敗, 并會返回錯誤信息)
| game.html (client端程序的入口,內(nèi)嵌iframe來顯示各個頁面,通過改變iframe的src屬性,來達(dá)成偽頁面跳轉(zhuǎn))
| img (圖片資源文件夾)
| tou.jpg (棋盤界面用戶的頭像,因?yàn)榈卿浗缑嬷灰斎胗脩裘涂梢蚤_始游戲了,所以所有用戶的頭像都是一樣的)

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="https://cdn.bootcss.com/socket.io/2.1.0/socket.io.js"></script>
</head>
<body>
<!-- 這里是程序的入口,通過js改變src屬性,來切換頁面 -->
<iframe id="game" src="index.html" width="100%" height="100%" scrolling="no"></iframe>
</body>
</html>

為什么我們要用嵌入iframe改變src屬性的方式來制造頁面跳轉(zhuǎn)的現(xiàn)象?因?yàn)轫撁娴拿恳淮翁D(zhuǎn)或刷新都會使socket連接斷開。就好像http中的request請求一樣,頁面每次所以我們應(yīng)盡量避免頁面跳轉(zhuǎn)這個操作。

// 這行代碼表示client端對server端進(jìn)行第一次連接
var socket = io('ws://localhost:3000')

在index.html也就是用戶的登錄界面

<!-- 這是用戶登錄的按鈕 -->
<div onclick="login()">開始游戲</div>

當(dāng)點(diǎn)擊了這個按鈕之后,它會觸發(fā)js中的login方法,但這個方法并不會直接去連接server,因?yàn)閟ocket連接在game.html中,所以目前來看,這個頁面只是game.html的子頁面,這個方法在判斷input中的value是否為空后,立即通過全局對象parent調(diào)用的父頁面(game.html)中的login方法

// index.html中的login方法
function login() {
 if (username.value === undefined || username.value === '') {
  return
 }
 // 調(diào)用父窗口的login方法
 parent.login(username.value)
}

game.html中的login方法,這個方法通過socket向server觸發(fā)了login事件

function login(username) {
 socket.emit('login', username)
}

server.js

// 監(jiān)聽連接
io.on('connection', function (socket) {
 // 玩家登陸, socket.emit('login', username)就是觸發(fā)了這個事件
 // 監(jiān)聽了login事件
 socket.on('login', function (name) {
 // players是一個全局?jǐn)?shù)組,里面存放了所有的玩家對象,如果players中 
 var flag = players.some(function (value) {
  return value.name === name
 })
 if (flag) {
  socket.emit('home', {'flag': true})
 } else {
  console.log(name + '已登陸')
  // 創(chuàng)建玩家
  new Player(socket, name)
  // 將玩家放進(jìn)數(shù)組中
  // players.push(player)
  // 如果用戶名沒有重名,那么觸發(fā)client端的home事件
  socket.emit('home', {'playerCount': playerCount, 'name': name})
 }
 })
})

玩家client對home事件的監(jiān)聽

// 玩家登陸成功
 socket.on('home', function (data) {
 if (data.flag) {
  game.contentWindow.flag.hidden = false
 } else {
  game.contentWindow.flag.hidden = true
  // 保存用戶名和玩家在線人數(shù)到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長得基本一致,所以它也有一個按鈕,匹配按鈕,通過它來觸發(fā)play事件

// 玩家開始匹配
 this.socket.on('play', function () {
 // 如果空閑玩家總數(shù)大于或等于2,那么開始游戲
 if (playerCount >= 2) {
  self.pipei = true
  // 如果已經(jīng)有人在開始匹配了,那么這個玩家就不需要走下面函數(shù)了,因?yàn)槔^續(xù)執(zhí)行的話相當(dāng)于再開一個棋局
  if (isExistFZ(self) > 0) {
  // 保持不動就好,房主會自動找到你的
  return
  }
  // 如果沒有房主,那么這個玩家將成為房主
  self.fz = true
  // 可用的玩家數(shù)
  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棋局類,一個棋局對應(yīng)兩個玩家。

Player類的屬性

this.socket = socket // socket對象,玩家通過它來監(jiān)聽數(shù)據(jù)
 this.name = name // 玩家的名稱
 this.color = null // 玩家棋子的顏色
 this.state = 0 // 0代表空閑, 1在游戲中
 this.pipei = false // 是否在匹配
 this.gamePlay = null // 棋局對象
 this.flag = true // 是否輪到這個玩家出棋
 this.fz = false // 是否是房主

Player類對象監(jiān)聽的事件

// 監(jiān)聽玩家是否退出游戲
 this.socket.on('disconnect', function () {
  // 刪除數(shù)組中的玩家
  // players.splice(players.indexOf(self), 1) // 刪不掉
  // delete players[players.indexOf(self)]
  // 新的刪除方式
  players = players.filter(function (value) {
   return value.name !== self.name
  })
  playerCount--
  // 如果退出游戲的玩家正在進(jìn)行游戲,那么這局游戲也該退出
  if (self.state === 0) {
   gameCount--
  }
  console.log(self.name + '已退出游戲')
 })
 // 玩家開始匹配
 this.socket.on('play', function () {
  // 如果空閑玩家總數(shù)大于或等于2,那么開始游戲
  if (playerCount >= 2) {
   self.pipei = true
   // 如果已經(jīng)有人在開始匹配了,那么這個玩家就不需要走下面函數(shù)了,因?yàn)槔^續(xù)執(zhí)行的話相當(dāng)于再開一個棋局
   if (isExistFZ(self) > 0) {
    // 保持不動就好,房主會自動找到你的
    return
   }
   // 如果沒有房主,那么這個玩家將成為房主
   self.fz = true
   // 可用的玩家數(shù)
   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)
 })
  // 監(jiān)聽數(shù)據(jù),玩家下棋的時候觸發(fā)
 this.socket.on('data', function (data) {
  if (self.flag) {
   add_pieces(self.gamePlay, data, self.color)
  }
 })
 // 最后將當(dāng)前玩家實(shí)例放到players全局玩家數(shù)組中去
 players.push(this)

Game(棋局類)

// 棋盤的格子數(shù)
  this.column = 21
  this.arr = init_arr() // 存儲棋盤坐標(biāo)的二位數(shù)組
  // 一局棋局上的兩個玩家
  this.play1 = play1
  this.play2 = play2
  // 修改游戲狀態(tài)
   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
   // 隨機(jī)給兩個玩家分配棋子顏色
   this.play1.color = ~~(Math.random() * 2) === 0 ? 'white' : 'black'
   this.play2.color = this.play1.color === 'white' ? 'black' : 'white'
   // 誰是白棋誰先走
   this.play1.flag = this.play1.color === 'white'? true: false
   this.play2.flag = this.play2.color === 'white'? true: false

添加棋子方法

// 添加棋子
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)
 }
}
// 初始化數(shù)組
function init_arr() {
 var arr = []
 for (var i = 0; i < 21; i++) {
  arr.push(new Array(21))
 }
 return arr
}

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。

網(wǎng)站題目:怎么在node.js中利用socket.io實(shí)現(xiàn)多人在線匹配聯(lián)機(jī)五子棋
網(wǎng)站網(wǎng)址:http://chinadenli.net/article2/ieggic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、移動網(wǎng)站建設(shè)網(wǎng)站排名、網(wǎng)站收錄做網(wǎng)站、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)
亚洲欧美视频欧美视频| 99久热只有精品视频免费看| 三级理论午夜福利在线看| 欧美成人久久久免费播放| 国产av一区二区三区久久不卡| 夫妻性生活一级黄色录像| 男女午夜福利院在线观看| 午夜国产精品国自产拍av| 国产精品超碰在线观看| 国产亚洲精品久久久优势| 亚洲免费黄色高清在线观看| 免费性欧美重口味黄色| 国产户外勾引精品露出一区| 91人妻人澡人人爽人人精品| 偷拍美女洗澡免费视频| 久久热这里只有精品视频| 人人爽夜夜爽夜夜爽精品视频| 国产成人av在线免播放观看av| 午夜视频在线观看日韩| 亚洲天堂国产精品久久精品| 九九热精彩视频在线免费| 国产性情片一区二区三区| 中文字字幕在线中文乱码二区| 欧美日韩有码一二三区| 一个人的久久精彩视频| 欧美在线观看视频免费不卡| 亚洲熟妇中文字幕五十路| 欧美黑人精品一区二区在线| 台湾综合熟女一区二区| 亚洲国产精品久久精品成人| 我想看亚洲一级黄色录像| 91久久精品中文内射| 亚洲国产日韩欧美三级| 五月综合激情婷婷丁香| 国产女性精品一区二区三区| 精品偷拍一区二区三区| 欧美人妻盗摄日韩偷拍| 久久99午夜福利视频| 国产精品欧美一区两区| 亚洲黄香蕉视频免费看| 欧美同性视频免费观看|