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

最近因为项目需要,所以研究了一下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的朋友们,可以看看这本书。

(0)

相关推荐

  • 纯JavaScript 实现flappy bird小游戏实例代码

    前言: <flappy bird>是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏于2013年5月24日上线,并在2014年2月突然暴红.2014年2月,<Flappy Bird>被开发者本人从苹果及谷歌应用商店撤下.2014年8月份正式回归APP STORE,正式加入Flappy迷们期待已久的多人对战模式.游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍. 正文: 接下来就是一步一步来实现它 步骤1:页面布局,这儿就不多说了,页面内容如下:

  • C++版本简易Flappy bird

    大一,上学期学完了C,写了几个控制台游戏 这学期自学C++,由于学校课程第七周才有C++ 边学边写了这个小游戏,SDL 图形库完成的图形绘画 时间匆忙,BUG也有,代码效率比较低 和原作品还是很大的差别, 源代码在附件游戏文件夹中 演示图 #include <stdlib.h> #include<windows.h> #include <time.h> #include<conio.h> #include <iostream> #include

  • 纯javascript模仿微信打飞机小游戏

    七夕情人节也不要忘了打游戏喔喔-,下面小编为大家准备的情人节礼物之纯javascript模仿微信打飞机小游戏分享给天下的情人们. 首先给大家展示效果图: 查看演示      源码下载 纯JavaScript模仿微信打飞机游戏,做网页小游戏的借鉴下,界面设计是竖长形仿手机屏幕风格,游戏效果流畅.具有分数统计,里面的JS封装类中包括有创建飞机类.飞机移动行为控制,创建子弹类,产生min到max之间的随机数,判断本方飞机是否移出边界,如果移出边界,则取消mousemove事件,反之加上mousemov

  • javascript实现别踩白块儿小游戏程序

    最近有朋友找我用JS帮忙仿做一个别踩白块的小游戏程序,但他给的源代码较麻烦,而且没有注释,理解起来很无力,我就以自己的想法自己做了这个小游戏,主要是应用JS对DOM和数组的操作. 程序思路:如图:将游戏区域的CSS设置为相对定位.溢出隐藏;两块"游戏板"上分别排布着24块方格,黑色每行随机产生一个,"游戏板"向下滚动并交替显示,将每个操作板的黑块位置存入数组,每次点击时将数组pop出来进行比对(我觉得亮点在这--). 这里是游戏的GitHub地址,大家可以到里点击中

  • Javascript编写2048小游戏

    去年2048很火, 本来我也没玩过, 同事说如果用JS写2048 只要100多行代码: 今天试了一下, 逻辑也不复杂, 主要是数据构造函数上的数据的各种操作, 然后通过重新渲染DOM实现界面的更新, 整体不复杂, JS,css,和HTML合起来就300多行: 界面的生成使用了underscore.js的template方法, 使用了jQuery,主要是DOM的选择和操作以及动画效果,事件的绑定只做了PC端的兼容,只绑定了keydown事件: 把代码放到github-page上, 通过点击这里查看

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

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

  • js实现鼠标跟随小游戏

    本文实例为大家分享了js实现鼠标跟随小游戏的具体代码,供大家参考,具体内容如下 在创建项目的时候,记得要引入jquery.min.js 的库,也可以引入别的版本的jquery库 在Script里的代码: <script type="text/javascript"> $(document).ready(function() { var canvas = document.getElementById("c"); var ctx = canvas.getC

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

    本文实例讲述了JS网页在线获取鼠标坐标值的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>显示鼠标坐标</title> </head> <body onMousemove="m

  • Python使用django框架实现多人在线匿名聊天的小程序

    最近看到好多设计类网站,都提供了多人在线匿名聊天的小功能,感觉很有意思,于是基于python的django框架自己写了一个,支持手动实时更名,最下方提供了完整的源码. 在线聊天地址(无需登录,开一个窗口,代表一个用户): http://zhaozhaoli.vicp.io/chatroom/happy/ 移动端聊天效果图: 网页版聊天效果图: 实现思路: 发送的消息通过ajax先写入数据库,通过ajax的循环请求,将写入数据库的消息显示到前端界面. 前端核心代码: <script> $(fun

  • python 基于opencv 实现一个鼠标绘图小程序

    需求 在画布上用鼠标画图,可以画圆或矩形,按m键在两种模式下切换.左键按下时开始画图,移动到哪儿画到哪儿,左键释放时结束画图. 实现思想 用鼠标画图:需要定义鼠标的回调函数mouse_event 画圆或矩形:需要定义一个画图的模式mode 左键单击.移动.释放:需要捕获三个不同的事件 开始画图,结束画图:需要定义一个画图的标记位drawing 实现代码 import cv2 as cv import numpy as np drawing = False # 是否开始画图 mode = True

  • poshytip 基于jquery的 插件 主要用于显示微博人的图像和鼠标提示等

    这种效果常常有两个需求 1 鼠标移动到人图像上时,显示这个人的信息,鼠标离开人图像时隐藏这个人的相关信息 2当鼠标移动到到人的信息块时,信息依然显示,当鼠标离开人的信息块时,信息隐藏 3 必须是自动关闭而不是手动关闭 通常第一个比较容易满足,但是第一个在遇到事件冒泡时,搞起来也比较麻烦, 这个时候在遇到第二个需求,就很难搞定了, 做微博APP时,常常要显示人的个人信息,想吧新浪或腾讯的那个js弄过来吧,搞了半天没找见是那一段js, 博客园里面推荐的一堆tooltip 均不能满足3个要求, 找了老

  • nodejs实现大文件(在线视频)的读取

    nodejs进行视频读取时不能像读取图片之类的一次性读取,而是必须读取一部分返回一部分,这样客户端的播放才会边缓冲边播放,而不必等待全部缓冲完再播放. 老规矩,直接贴代码讲解: var fs = require('fs'); function readBigFileEntry(filename, response) { path.exists(filename, function(exists) { if (!filename || !exists) { response.writeHead(4

  • 人尽可用的Windows技巧小贴士之下篇

    寻找Windwos Media Player 如果你有大量的多媒体文件,想要寻找到某一特定文件可能并非易事.Windows Media Player 11可以让用户通过搜索唱片音轨.艺术家或其它标准轻松找到目标文件.例如,要查询Bob Dylan的"Like a Rolling Stone",在搜索框中输入"Title:Rolling Stone"便会得到与该名称相似的搜索结果列表. 捕捉屏幕 Vista的捕获工具能够让抓捕全部或部分屏幕图片及添加注释变的易如反掌,

  • 鼠标悬停小图标显示大图标

    页面元素为div->table->tr->td,对于td中的图片,鼠标悬停上则显示大图片,鼠标离开则大图片消失: 首先需要知道jq创建dom元素语法:$(html标签),例如这里创建了一个img标签var img = $("<img class='changePhoto'></img>"); 其次鼠标的悬停与离开这里使用的是hover方法,语法为$(selector).hover(inFunction,outFunction), 规定当鼠标指针

  • 适合初学者开发的C#在线英汉词典小程序

    今天写了一个英汉词典小程序,我加了好多注释,适合初学者一起参考,哪里写的不好请帮忙指出,一起学习进步. 这里用到了,泛型,泛型字典,一些控件的操作,split的应用,数组的应用,时间间隔,linkLabel的使用. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using

随机推荐