zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Nodejs实现多人同时在线移动鼠标的小游戏分享

Nodejs 实现 分享 移动 鼠标 小游戏 多人 同时在线
2023-06-13 09:15:32 时间

最近因为项目需要,所以研究了一下nodejs的websocket实现,socket.io,这是nodejs后台应用websocket广泛使用的框架。

准备工作

1.安装socket.io,使用命令npminstallsocket.io
2.windows系统的话,需要vc编译环境,因为安装socket.io的时候,会编译vc代码

游戏基本原理

1.服务器监听客户端的连接
2.客户端连接成功时候,绑定页面移动鼠标事件,事件里处理发送当前坐标给服务器
3.服务器保存一个全局的坐标对象,并以客户端唯一编号为键值
4.有新连接来的时候,把坐标广播给其它客户端
5.客户端断开连接的时候,服务端删除它的坐标信息,并广播给其它客户端

开始实现服务端代码

scoket.io建立服务器监听的时候,需要依赖一个http连接,用来处理升级协议用,所以也需要一个http模块,代码如下:

复制代码代码如下:

varhttp=require("http"),
   io=require("socket.io");


varapp=http.createServer().listen(9091);

varws=io.listen(app);

然后定义一个全局的坐标对象

复制代码代码如下:


varpostions={};

开始监听客户端的连接,并新增广播函数(其实可用socket.io自带的广播方法io.sockets.broadcast.emit),核心代码如下:

复制代码代码如下:
ws.on("connection",function(client){
   //广播函数
   varbroadcast=function(msg,cl){
       for(varkinws.sockets.sockets){
           if(ws.sockets.sockets.hasOwnProperty(k)){
               if(ws.sockets.sockets[k]&&ws.sockets.sockets[k].id!=cl.id){
                   ws.sockets.sockets[k].emit("position.change",msg);
               }
           }
       }
   };
   console.log("\033[92m有新的连接来:\033[39m",postions);
   //客户端连接成功之后,就发送其它客户端的坐标信息
   client.emit("position.change",postions);
   //接收客户端发送消息
   client.on("position.change",function(msg){
       //目前客户端的消息就只有坐标消息
       postions[client.id]=msg;
       //把消息广播给其它所有的客户端
       broadcast({
           type:"position",
           postion:msg,
           id:client.id
       },client);
   });
   //接收客户端关闭连接消息
   client.on("close",function(){
       console.log("close!");
       //删除客户端,并通知其它客户端
       deletepostions[client.id];
       //把消息广播给其它所有的客户端
       broadcast({
           type:"disconnect",
           id:client.id
       },client);
   });
   //断开连接
   client.on("disconnect",function(){
       console.log("disconnect!");
       //删除客户端,并通知其它客户端
       deletepostions[client.id];
       //把消息广播给其它所有的客户端
       broadcast({
           type:"disconnect",
           id:client.id
       },client);
   })
   //定义客户端异常处理
   client.on("error",function(err){
       console.log("error->",err);
   })
});

分析上面的代码,关键点在于

1.新的客户端连接成功,发送其它客户端的坐标信息
2.客户端更新坐标信息的时候,通知其它客户端
3.客户端断开连接,通知其它客户端
4.广播消息类型分为修改坐标与移除坐标

编写客户端html页面

由于socket.io是自定义的框架,所以客户端需要引用socket.io.js,这个js可以从socket.io模块里查找,路径一般为node_modules\socket.io\node_modules\socket.io-client\dist,里面有合并与压缩两个版本,开发的时候可以用合并版.

完整代码如下:

复制代码代码如下:
<!DOCTYPEhtml>
<html>
<head>
   <title>socket.io多人同时在线互动例子</title>
   <metacharset="utf-8">
</head>
<body>

<scripttype="text/javascript"src="socket.io.js"></script>
<scripttype="text/javascript">
   varws=io.connect("http://localhost:9091/");
   varisfirst;

   ws.on("connect",function(){
       console.log(ws);
       //开始绑定mousemove事件
       document.onmousemove=function(ev){
           if(ws.socket.transport.isOpen){
               ws.emit("position.change",{x:ev.clientX,y:ev.clientY});
           }
       }
   })

   ws.on("position.change",function(data){
       //开始同时在线的别的客户端
       if(!isfirst){
           isfirst=true;
           //第一条消息是收到别个所有客户端的坐标
           for(variindata){
               move(i,data[i]);
           }
       }else{
           //否则,要不就是别个断开连接的消息,或者别个更新坐标的消息
           if("position"==data.type){
               move(data.id,data.postion);
           }else{
               remove(data.id);
           }
       }
   })

   ws.on("error",function(){
       console.log("error:",ws);
       ws.disconnect();
   })


   functionmove(id,pos){
       varele=document.querySelector("#cursor_"+id);
       if(!ele){
           //不存在,则创建
           ele=document.createElement("img");
           ele.id="cursor_"+id;
           ele.src="img/cursor.png";
           ele.style.position="absolute";
           document.body.appendChild(ele);
       }

       ele.style.left=pos.x+"px";
       ele.style.top=pos.y+"px";
   }

   functionremove(id){
       varele=document.querySelector("#cursor_"+id);
       ele.parentNode.removeChild(ele);
   }

</script>
</body>
</html>

页面中的img/cursor.png,可以这里找到,cursor.png,这里也有很多其它的鼠标图标,前端的原理比较简单,简单的分析如下

1.连接成功时,绑定页面mousemove事件,里面处理发送新坐标消息
2.收到消息根据消息类型,处理是修改其它客户端消息,还是移除其它客户端消息
3.定义添加其它客户端cursor图标与移除cursor图标
4.处理客户端异常消息,并添加断开连接,以让服务端移除坐标信息

运行例子

1.保存服务器代码为io_multigame.js
2.保存客户端代码为io_multigame.html
3.运行服务器代码nodeio_multigame.js
4.打开多个io_multigame.html页面,即可看到效果

总结

写的比较随意,参考了了不起的nodejs,这是一本好书,想了解nodejs的朋友们,可以看看这本书。