Node.js+Socket.io實(shí)現(xiàn)雙人在線五子棋對(duì)戰(zhàn)
本文實(shí)例為大家分享了Node.js+Socket.io實(shí)現(xiàn)雙人在線五子棋對(duì)戰(zhàn)的具體代碼,供大家參考,具體內(nèi)容如下
筆者建議讀者在嘗試寫程序之前要先確保電腦已經(jīng)安裝了Node.js和NPM,一般兩者都是在一塊安裝,五子棋程序的服務(wù)器端使用Node.js寫的,不多說(shuō)了,直接上代碼。
服務(wù)器端代碼:socket.js
var app = require('http').createServer(handler) var io = require('socket.io')(app); var fs = require('fs'); ? app.listen(80); ? function handler (req, res) { ? ? fs.readFile(__dirname + '/wzq.html', ? ? function (err, data) { ? ? ? if (err) { ? ? ? ? res.writeHead(500); ? ? ? ? return res.end('Error loading wzq.html'); ? ? ? } ?? ? ? ? res.writeHead(200); ? ? ? res.end(data); ? ? }); ? } //io.set('log level',1); var users = {}; io.on('connection',function(socket){ ? ? io.sockets.emit('connect',{con:'connected'}); ? ? socket.on('location',function(from, to, msg){ ? ? ? ? if(to in users){ ? ? ? ? ? ? //console.log('to'+to+' ? '+msg); ? ? ? ? ? ? users[to].emit('to'+to,msg); ? ? ? ? } ? ? }); ? ? socket.on('newUser',function(user){ ? ? ? ? if(user in users){ ? ? ? ? ? ? socket.emit('exist',{}) ? ? ? ? } ? ? ? ? else{ ? ? ? ? ? ? users[user] = socket; ? ? ? ? ? ? if(users['u2']){ ? ? ? ? ? ? ? ? io.sockets.emit('stateok',{}); ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? }); ? ? socket.on('disconn',function(){ ? ? ? ? socket.emit('disconnection'); ? ? }) });
客戶端代碼:wzq.html
<!DOCTYPE html> <html lang="en"> <head> ? ? <meta charset="UTF-8"> ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ? <meta http-equiv="X-UA-Compatible" content="ie=edge"> ? ? <title>五子棋</title> ? ? <script src='https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js'></script> </head> ? <style> #chess { ? ? display: block; ? ? margin: 50px auto; ? ? box-shadow: -2px -2px 2px #efefef , 5px 5px 5px #b9b9b9; } #chess:hover{ ? ? cursor: pointer; } </style> <body> ? ? <!-- 棋盤 --> ? ? ? ? <input type="radio" name="WZQ" id="black" checked disabled='disabled'> ? ? <label for="black">黑棋</label> ? ? <input type="radio" name="WZQ" id="white" disabled='disabled'> ? ? <label for="white">白棋</label> ? ? <br/> ? ? <input type="button" value="連接服務(wù)器" id='conn'> ? ? <input type="button" value="斷開(kāi)服務(wù)器" id='disconn'> ? ? <label id='tipMsg'></label> ? ? <!-- <input type="text" name="ip" id="ip" placeholder="請(qǐng)輸入IP地址,就像這樣(ws://192.168.0.1:3000)"> --> ? ? <canvas id="chess" width="450px" height="450px"></canvas> ? ? <script> ? ? ? ? //獲取棋盤canvas ? ? ? ? var chess = document.getElementById("chess"); ? ? ? ? //獲取2d畫布 ? ? ? ? var context = chess.getContext('2d'); ? ? ? ? //指定當(dāng)前是否黑色下,只在UI中使用 ? ? ? ? ? ? ? ? var me = true; ? ? ? ? if(document.getElementById('white').checked) me=false; ? ? ? ? //指定當(dāng)前位置是否下了棋子,1代表黑,2代表白,0代表空 ? ? ? ? var curIndex = []; ? ? ? ? var dsState = false, isclick = false; ? ? ? ? for(var i =0; i <15; i++) { ? ? ? ? ? curIndex[i] = []; ? ? ? ? ? for(var j =0; j <15; j++) ? ? ? ? ? ? curIndex[i][j] = 0; ? ? ? ? } ? ? ? ? ? function drawtable() { ? ? ? ? ? ? //我們?cè)O(shè)置棋盤總共15根橫線15根總線,左右上下都有15px的邊距,其中每個(gè)棋子相距30px,因此繪制棋盤從15px開(kāi)始 ? ? ? ?? ? ? ? ? ? ? for(var i =0; i <15; i++){ ? ? ? ? ? ? ? ? for(var j =0; j <15; j++){ ? ? ? ? ? ? ? ? ? ? //繪制橫線 ? ? ? ? ? ? ? ? ? ? context.moveTo(15, 15 +j *30); ? ? ? ? ? ? ? ? ? ? context.lineTo(435, 15 +j *30); ? ? ? ? ? ? ? ? ? ? //繪制豎線 ? ? ? ? ? ? ? ? ? ? context.moveTo(15 +j *30, 15); ? ? ? ? ? ? ? ? ? ? context.lineTo(15 +j *30, 435);? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? //使用灰色描邊 ? ? ? ? ? ? ? ? ? ? context.strokeStyle = "#bfbfbf"; ? ? ? ? ? ? ? ? ? ? context.stroke(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }; ? ? ? ? drawtable(); ? ? ? ? var socket = io('http://223.2.42.103'); ? ? ? ? socket.on('connect',function(data){ ? ? ? ? ? ? document.getElementById('tipMsg').innerHTML='<b>等待對(duì)方上線。。。</b>'; ? ? ? ? }); ? ? ? ? if(me) socket.emit('newUser','u1'); ? ? ? ? socket.on('tou2',function(data){ ? ? ? ? ? ? //console.log('tou2'); ? ? ? ? ? ? var strArr = data.split('-'); ? ? ? ? ? ? var xx = parseInt(strArr[0]); ? ? ? ? ? ? var yy = parseInt(strArr[1]); ? ? ? ? ? ? //開(kāi)始繪制 ? ? ? ? ? ? context.beginPath(); ? ? ? ? ? ? //繪制指定圓 ? ? ? ? ? ? context.arc(15 +xx *30, 15 +yy *30, 15, 0, 2 *Math.PI); ? ? ? ? ? ? //進(jìn)行填充 ? ? ? ? ? ? context.fillStyle = "#636766"; ? ? ? ? ? ? curIndex[xx][yy] = 1; ? ? ? ? ? ? document.getElementById('tipMsg').innerText='該你下了'; ? ? ? ? ? ? isclick=false; ? ? ? ? ? ? dsState=true; ? ? ? ? ? ? context.fill(); ? ? ? ? ? ? //結(jié)束繪制 ? ? ? ? ? ? context.closePath(); ? ? ? ? }); ? ? ? ? socket.on('tou1',function(data){ ? ? ? ? ? ? //console.log('tou1'); ? ? ? ? ? ? var strArr = data.split('-'); ? ? ? ? ? ? var xx = parseInt(strArr[0]); ? ? ? ? ? ? var yy = parseInt(strArr[1]); ? ? ? ? ? ? //開(kāi)始繪制 ? ? ? ? ? ? context.beginPath(); ? ? ? ? ? ? //繪制指定圓 ? ? ? ? ? ? context.arc(15 +xx *30, 15 +yy *30, 15, 0, 2 *Math.PI); ? ? ? ? ? ? //進(jìn)行填充 ? ? ? ? ? ? context.fillStyle = "#b9b9b9"; ? ? ? ? ? ? curIndex[xx][yy] = 2; ? ? ? ? ? ? document.getElementById('tipMsg').innerText='該你下了'; ? ? ? ? ? ? isclick=false; ? ? ? ? ? ? dsState=true; ? ? ? ? ? ? context.fill(); ? ? ? ? ? ? //結(jié)束繪制 ? ? ? ? ? ? context.closePath(); ? ? ? ? }); ? ? ? ? socket.on('exist',function(data){ ? ? ? ? ? ? me=!me; ? ? ? ? ? ? document.getElementById('white').checked=true; ? ? ? ? ? ? document.getElementById('black').checked=false; ? ? ? ? ? ? socket.emit('newUser','u2'); ? ? ? ? }); ? ? ? ? socket.on('stateok',function(data){ ? ? ? ? ? ? document.getElementById('tipMsg').innerHTML='<b>對(duì)方已上線,黑棋先下</b>'; ? ? ? ? ? ? if(me){ ? ? ? ? ? ? ? ? dsState=true; ? ? ? ? ? ? ? ? isclick=false; ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? chess.onclick = function(event) { ? ? ? ? ? ? if(!dsState||isclick) return; ? ? ? ? ? ? //獲取要下的棋子的位置 ? ? ? ? ? ? var x = Math.floor(event.offsetX /30); ? ? ? ? ? ? var y = Math.floor(event.offsetY /30); ? ? ? ? ? ? //判斷該點(diǎn)是否已被下了 ? ? ? ? ? ? if(curIndex[x][y] != 0) return; ? ? ? ? ? ? //開(kāi)始繪制 ? ? ? ? ? ? context.beginPath(); ? ? ? ? ? ? //繪制指定圓 ? ? ? ? ? ? context.arc(15 +x *30, 15 +y *30, 15, 0, 2 *Math.PI); ? ? ? ? ? ? //進(jìn)行填充 ? ? ? ? ? ? if(me) { ? ? ? ? ? ? ? ? context.fillStyle = "#636766"; ? ? ? ? ? ? ? ? curIndex[x][y] = 1; ? ? ? ? ? ? ? ? //me = false; ? ? ? ? ? ? ? ? socket.emit('location','u1','u2',x+'-'+y); ? ? ? ? ? ? } ? ? ? ? ? ? else { ? ? ? ? ? ? ? ? context.fillStyle = "#b9b9b9"; ? ? ? ? ? ? ? ? curIndex[x][y] = 2; ? ? ? ? ? ? ? ? //me = true; ? ? ? ? ? ? ? ? socket.emit('location','u2','u1',x+'-'+y); ? ? ? ? ? ? } ? ? ? ? ? ? context.fill(); ? ? ? ? ? ? //結(jié)束繪制 ? ? ? ? ? ? context.closePath(); ? ? ? ? ? ? dsState=false; ? ? ? ? ? ? isclick=true; ? ? ? ? ? ? if(me){ ? ? ? ? ? ? ? ? document.getElementById('tipMsg').innerText='白棋思考中。。。' ? ? ? ? ? ? }else if(!me){ ? ? ? ? ? ? ? ? document.getElementById('tipMsg').innerText='黑棋思考中。。。' ? ? ? ? ? ? } ? ? ? ? }; ? ? ? ? document.getElementById('conn') ? ? ? ? window.unbeforeunload = function(){ ? ? ? ? ? ? socket.emit('disconn'); ? ? ? ? } ? ? </script> </body> </html>
客戶端有些代碼沒(méi)有實(shí)現(xiàn),比如說(shuō)斷開(kāi)連接和手動(dòng)開(kāi)啟服務(wù)器,這些留給讀者自己去實(shí)現(xiàn)吧,另外判斷是否輸贏的代碼沒(méi)有寫,筆者覺(jué)得吧,會(huì)玩五子棋的都能看得出來(lái),就不用再寫了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
node.js?實(shí)現(xiàn)手機(jī)號(hào)驗(yàn)證碼登錄功能
這篇文章主要介紹了node.js?實(shí)現(xiàn)手機(jī)號(hào)驗(yàn)證碼登錄功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08node.js使用免費(fèi)的阿里云ip查詢獲取ip所在地【推薦】
這篇文章主要介紹了node.js使用免費(fèi)的阿里云ip查詢獲取ip所在地的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-09-09輕松創(chuàng)建nodejs服務(wù)器(4):路由
這篇文章主要介紹了輕松創(chuàng)建nodejs服務(wù)器(4):路由,服務(wù)器需要根據(jù)不同的URL或請(qǐng)求來(lái)執(zhí)行不一樣的操作,我們可以通過(guò)路由來(lái)實(shí)現(xiàn)這個(gè)步驟,需要的朋友可以參考下2014-12-12nodejs 提示‘xxx’ 不是內(nèi)部或外部命令解決方法
本文介紹了node.js包管理工具npm安裝模塊后,無(wú)法通過(guò)命令行執(zhí)行命令,提示‘xxx’ 不是內(nèi)部或外部命令的解決方法,給需要的小伙伴參考下。2014-11-11在Linux系統(tǒng)上更新Node.js到最新版本的3種方法小結(jié)
這篇文章主要介紹了在Linux系統(tǒng)上更新Node.js到最新版本的3種方法,使用NVM,使用NPM,用二進(jìn)制包更新Node.js,文中有詳解更新方法,需要的朋友可以參考下2023-09-09詳解nodejs微信公眾號(hào)開(kāi)發(fā)——4.自動(dòng)回復(fù)各種消息
這篇文章主要介紹了詳解nodejs微信公眾號(hào)開(kāi)發(fā)——4.自動(dòng)回復(fù)各種消息,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04