时间:2022-11-07 09:38:43 | 栏目:NodeJS | 点击:次
本文实例为大家分享了Node.js+Socket.io实现双人在线五子棋对战的具体代码,供大家参考,具体内容如下
笔者建议读者在尝试写程序之前要先确保电脑已经安装了Node.js和NPM,一般两者都是在一块安装,五子棋程序的服务器端使用Node.js写的,不多说了,直接上代码。
服务器端代码: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="连接服务器" id='conn'> <input type="button" value="断开服务器" id='disconn'> <label id='tipMsg'></label> <!-- <input type="text" name="ip" id="ip" placeholder="请输入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'); //指定当前是否黑色下,只在UI中使用 var me = true; if(document.getElementById('white').checked) me=false; //指定当前位置是否下了棋子,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() { //我们设置棋盘总共15根横线15根总线,左右上下都有15px的边距,其中每个棋子相距30px,因此绘制棋盘从15px开始 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>等待对方上线。。。</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]); //开始绘制 context.beginPath(); //绘制指定圆 context.arc(15 +xx *30, 15 +yy *30, 15, 0, 2 *Math.PI); //进行填充 context.fillStyle = "#636766"; curIndex[xx][yy] = 1; document.getElementById('tipMsg').innerText='该你下了'; isclick=false; dsState=true; context.fill(); //结束绘制 context.closePath(); }); socket.on('tou1',function(data){ //console.log('tou1'); var strArr = data.split('-'); var xx = parseInt(strArr[0]); var yy = parseInt(strArr[1]); //开始绘制 context.beginPath(); //绘制指定圆 context.arc(15 +xx *30, 15 +yy *30, 15, 0, 2 *Math.PI); //进行填充 context.fillStyle = "#b9b9b9"; curIndex[xx][yy] = 2; document.getElementById('tipMsg').innerText='该你下了'; isclick=false; dsState=true; context.fill(); //结束绘制 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>对方已上线,黑棋先下</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); //判断该点是否已被下了 if(curIndex[x][y] != 0) return; //开始绘制 context.beginPath(); //绘制指定圆 context.arc(15 +x *30, 15 +y *30, 15, 0, 2 *Math.PI); //进行填充 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(); //结束绘制 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>
客户端有些代码没有实现,比如说断开连接和手动开启服务器,这些留给读者自己去实现吧,另外判断是否输赢的代码没有写,笔者觉得吧,会玩五子棋的都能看得出来,就不用再写了。