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

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

准备工作

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

游戏基本原理

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

开始实现服务端代码

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

复制代码 代码如下:

var http = require('http'),
    io = require('socket.io');

var app = http.createServer().listen(9091);

var ws = io.listen(app);

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

复制代码 代码如下:

var postions = {};

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

复制代码 代码如下:

ws.on('connection', function(client){
    // 广播函数
    var broadcast = function(msg, cl){
        for(var k in ws.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!');
        // 删除客户端,并通知其它客户端
        delete postions[client.id];
        // 把消息广播给其它所有的客户端
        broadcast({
            type: 'disconnect',
            id: client.id
        }, client);
    });
    // 断开连接
    client.on('disconnect', function(){
        console.log('disconnect!');
        // 删除客户端,并通知其它客户端
        delete postions[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,里面有合并与压缩两个版本,开发的时候可以用合并版.

完整代码如下:

复制代码 代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>socket.io 多人同时在线互动 例子</title>
    <meta charset="utf-8">
</head>
<body>

<script type="text/javascript" src="socket.io.js"></script>
<script type="text/javascript">
    var ws = io.connect('http://localhost:9091/');
    var isfirst;

    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(var i in data){
                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();
    })

    function move(id, pos){
        var ele = 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';
    }

    function remove(id){
        var ele = 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.运行服务器代码node io_multigame.js
4.打开多个io_multigame.html页面,即可看到效果

总结

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

时间: 2024-08-31 13:50:03

Nodejs实现多人同时在线移动鼠标的小游戏分享_node.js的相关文章

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

最近因为项目需要,所以研究了一下nodejs的websocket实现,socket.io,这是nodejs后台应用websocket广泛使用的框架 准备工作 安装socket.io,使用命令npm install socket.io windows系统的话,需要vc编译环境,因为安装socket.io的时候,会编译vc代码 游戏基本原理 服务器监听客户端的连接 客户端连接成功时候,绑定页面移动鼠标事件,事件里处理发送当前坐标给服务器 服务器保存一个全局的坐标对象,并以客户端唯一编号为键值 有新连

Nodejs express框架一个工程中同时使用ejs模版和jade模版_node.js

在某些项目中,比如你接手了一个别人的项目然后你不想用蛋疼的ejs,或者你不想用蛋疼的jade.你有不想重写之前的页面,那么你现在可能需要新引入ejs或者jade模块,你仅仅需要做下面两步也许就能完成使用两个模版的工作 1.consolidate.js cd 到项目目录: npm install consolidate --save 打开项目的app.js(也许你的叫其他名字) 把app.js的形如下面的代码片段 app.set('view engine', 'jade'); 改为 var eng

Nodejs中读取中文文件编码问题、发送邮件和定时任务实例_node.js

关于nodejs读取中文文件真是折腾了不少时间,网上各种方案,最后没有一个适用我,好在解决了. 下面的三个知识点都是从项目中抽出的,要单独运行脚本的话需要用全局模式来安装模块,比如安装中文转换模块(后续其它的也需要这么做): 复制代码 代码如下: npm install -g iconv-lite npm install -g nodemailer npm install -g node-schedule 1.nodejs读取中文文件编码问题 准备一个文本文件(当然也可以是csv文件等)test

nodejs分页类代码分享_node.js

分页类,我放在 plugin/Paginate.js 复制代码 代码如下: /** * 分页插件类(缺少每页的显示数,listrows明天写) * @param page {Number} 当前页 * @param pagesize {Number} 每页记录数 * @param total {Number} 总记录数 * @constructor */function Paginate(page, pagesize, total){    if(!page || page <1){      

NodeJS学习笔记之(Url,QueryString,Path)模块_node.js

一,开篇分析 这篇文章把这三个模块拿来一起说,原因是它们各自的篇幅都不是很长,其次是它们之间存在着依赖关系,所以依次介绍并且实例分析.废话不多说了,请看下面文档: (1),"Url模块" 来个小栗子: 复制代码 代码如下:  var url = require('url');  var queryUrl = "http://localhost:8888/bb?name=bigbear&memo=helloworld" ;  console.log(typeo

用nodejs的实现原理和搭建服务器(动态)_node.js

今天是我学习的Node.js的第二天,所谓的node.js其实它是javascript编写的服务器的语言,同时它又是属于后台的框架,是一个开放性的平台. 一.相关理论知识: 我们可以用requre来引入模块.用module.exprorts来导出模块. 安装nodejs和配置npm 1.安装nodejs,安装完后在cmd命令行中敲入node -v,查看版本. 2.在cmd中敲入npm config list查看是否安装npm. 3.设置镜像地址. 淘宝镜像:在命令行中敲入npm config s

吃豆人30周年纪念谷歌首页logo变身在线小游戏

5月22日是经典游戏<吃豆人>(PACMAN)诞生30周年的纪念日,为了庆祝吃豆人30岁生日,官方与玩家都发起了很多纪念活动. 北京时间5月21日23时(日本时间5月22日0时),著名搜索引擎谷歌(google)也更换了纪念性<吃豆人>的LOGO,不过与之前各种LOGO不同,这次的LOGO本身就是一个在线小游戏,大家打开google首页,静等几秒,就可以游戏了,游戏方式与原作一样,操作吃豆人躲避幽灵吃掉黄色"豆子"即可过关.游戏还原了原作的经典音效,并支持鼠标与

JS网页在线获取鼠标坐标值的方法

 这篇文章主要介绍了JS网页在线获取鼠标坐标值的方法,涉及javascript操作页面窗口位置元素的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了JS网页在线获取鼠标坐标值的方法.分享给大家供大家参考.具体实现方法如下:   代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

有没有一种能够多人实时在线编辑word或者excel的网页或者软件

问题描述 有没有一种能够多人实时在线编辑word或者excel的网页或者软件 在线编辑,通用型的办公控件,兼容性好的,比较稳定的.不能是a这边编辑完了,保存后,关闭文档,b那边打开才能看到.要求是a这边一更改,点击保存,另一边b就自动更新了,或者b更改完,都不用点击保存,a那边就能自动同步了,有没有这种软件或者网页,不要告诉我360云盘,百度云盘,微部落等等等这些上传文件就能多人同时编辑的,但是这样不能起到实时编辑的功能! 解决方案 推荐你看一下http://www.zhuozhengsoft.