最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js+Socket.io實(shí)現(xiàn)雙人在線五子棋對戰(zhàn)

 更新時(shí)間:2022年05月06日 12:22:06   作者:飛翔的小猿  
這篇文章主要為大家詳細(xì)介紹了Node.js+Socket.io實(shí)現(xiàn)雙人在線五子棋對戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Node.js+Socket.io實(shí)現(xiàn)雙人在線五子棋對戰(zhàn)的具體代碼,供大家參考,具體內(nèi)容如下

筆者建議讀者在嘗試寫程序之前要先確保電腦已經(jīng)安裝了Node.js和NPM,一般兩者都是在一塊安裝,五子棋程序的服務(wù)器端使用Node.js寫的,不多說了,直接上代碼。

服務(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="斷開服務(wù)器" 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');
? ? ? ? //指定當(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() {
? ? ? ? ? ? //我們設(shè)置棋盤總共15根橫線15根總線,左右上下都有15px的邊距,其中每個(gè)棋子相距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);
? ? ? ? ? ? //進(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]);
? ? ? ? ? ? //開始繪制
? ? ? ? ? ? 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>對方已上線,黑棋先下</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;
? ? ? ? ? ? //開始繪制
? ? ? ? ? ? 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>

客戶端有些代碼沒有實(shí)現(xiàn),比如說斷開連接和手動(dòng)開啟服務(wù)器,這些留給讀者自己去實(shí)現(xiàn)吧,另外判斷是否輸贏的代碼沒有寫,筆者覺得吧,會(huì)玩五子棋的都能看得出來,就不用再寫了。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語音插件開發(fā))

    nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語音插件開發(fā))

    FFmpeg是一套開源的音視頻處理工具,通俗地講,可以對音視頻文件進(jìn)行剪切、拼接、水印、轉(zhuǎn)碼等處理,這篇文章主要介紹了nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語音插件開發(fā)),需要的朋友可以參考下
    2023-05-05
  • Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解

    Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解

    Node.js是一個(gè)基于Chrome?V8引擎的JavaScript運(yùn)行時(shí)。類似于Java中的JRE,.Net中的CLR。本文將詳細(xì)為大家介紹Node.js中的回調(diào)函數(shù)及異步與同步,感興趣的可以了解一下
    2022-03-03
  • 詳解通過源碼解析Node.js中cluster模塊的主要功能實(shí)現(xiàn)

    詳解通過源碼解析Node.js中cluster模塊的主要功能實(shí)現(xiàn)

    這篇文章主要介紹了詳解通過源碼解析Node.js中cluster模塊的主要功能實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • NodeJS學(xué)習(xí)筆記之MongoDB模塊

    NodeJS學(xué)習(xí)筆記之MongoDB模塊

    nodejs是個(gè)強(qiáng)大的平臺(tái),有基本功能,而且可以掛很多模塊。我們現(xiàn)在需要和mongodb連接的驅(qū)動(dòng),就類似比如mysql的java驅(qū)動(dòng)一樣。nodejs有好幾個(gè)mongodb的第三方驅(qū)動(dòng)。和jdbc不一樣,沒有標(biāo)準(zhǔn)。所以需要到驅(qū)動(dòng)的網(wǎng)站上去了解學(xué)習(xí)怎么使用它訪問mongodb。
    2015-01-01
  • node后端服務(wù)保活的實(shí)現(xiàn)

    node后端服務(wù)保活的實(shí)現(xiàn)

    這篇文章主要介紹了node后端服務(wù)?;畹膶?shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Node.js模塊Modules的使用實(shí)戰(zhàn)教程

    Node.js模塊Modules的使用實(shí)戰(zhàn)教程

    這篇文章主要介紹了Node.js模塊Modules的使用,模塊就是一個(gè)聲明了裝飾器@Module()的類。裝飾器@Module()提供了元數(shù)據(jù),以便讓Nest組織應(yīng)用程序結(jié)構(gòu)
    2023-04-04
  • 前端常見面試題之a(chǎn)sync/await和promise的區(qū)別

    前端常見面試題之a(chǎn)sync/await和promise的區(qū)別

    async/await是異步代碼的新方式,以前的方法有回調(diào)函數(shù)和Promise,下面這篇文章主要給大家介紹了關(guān)于前端常見面試題之a(chǎn)sync/await和promise區(qū)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • node?gyp安裝canvas原生模塊編譯node?pregyp詳解

    node?gyp安裝canvas原生模塊編譯node?pregyp詳解

    這篇文章主要為大家介紹了Nodejs關(guān)于原生模塊編譯node-gyp + node-pre-gyp (以安裝canvas為例)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • node連接mysql查詢事務(wù)處理的實(shí)現(xiàn)

    node連接mysql查詢事務(wù)處理的實(shí)現(xiàn)

    本文主要介紹了node連接mysql查詢事務(wù)處理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • nodejs中express入門和基礎(chǔ)知識(shí)點(diǎn)學(xué)習(xí)

    nodejs中express入門和基礎(chǔ)知識(shí)點(diǎn)學(xué)習(xí)

    這篇文章給大家分享了關(guān)于學(xué)習(xí)nodejs中express入門和基礎(chǔ)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們參考下。
    2018-09-09

最新評(píng)論

武平县| 浏阳市| 四会市| 长宁区| 霍林郭勒市| 土默特右旗| 多伦县| 大名县| 万山特区| 大同县| 雷波县| 宜君县| 灵台县| 佛教| 和平区| 新民市| 海原县| 科尔| 和田市| 维西| 彭山县| 临湘市| 磐安县| 新河县| 邓州市| 济阳县| 江山市| 长海县| 萍乡市| 嫩江县| 武威市| 鄂托克前旗| 天柱县| 天镇县| 郸城县| 新宾| 聊城市| 平利县| 镇江市| 江北区| 门头沟区|