`

Node JS实战之制作涂鸦游戏

阅读更多
本文原文发表在http://tech.it168.com/a2012/0904/1393/000001393533_all.shtml中,乃本人编译之作品,禁止转载

Node.js目前无论是在前端还是后端开发中,已经越来越受到广大开发者的关注,相关使用Node.js进行开发的案例也越来越多。

  Node是一个Javascript运行环境(runtime)。实际上它是对GoogleV8引擎(应用于Google Chrome浏览器)进行了封装。V8引 擎执行Javascript的速度非常快,性能非常好。Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好。例 如,在服务器环境中,处理二进制数据通常是必不可少的,但Javascript对此支持不足,因此,V8.Node增加了Buffer类,方便并且高效地 处理二进制数据。因此,Node不仅仅简单的使用了V8,还对其进行了优化,使其在各环境下更加给力。

  在本文中,将带领读者通过实战制作一个能供多人在线涂鸦画画的游戏,让读者体会Node.js的特殊魅力,这个游戏的特点是多人在浏览这个页面时,大家都可以在页面上自由涂鸦,而且大家是互相看到其涂鸦的效果的。Node.js由于可以让开发者编写服务端运行的Javascript,因此能同时处理大量的连接,特别适合比如聊天,网络游戏等需要对即时性要求高的。本文要求读者有一定的Javascript和其他编程语言的基本知识。
     安装node.js

  首先,我们从nodejs.org下载node.js,这十分简单,特别是在windows下,直接安装installer的安装包setup运行就可以了,如果在linux等其他操作系统上运行,可以在终端中运行一系列的命令,如下:


  echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
mkdir ~/local
mkdir ~/node-latest-install
cd ~/node-latest-install
curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install # ok, fine, this step probably takes more than 30 seconds...
curl http://npmjs.org/install.sh | sh

  在安装完毕node.js后,我们需要安装node.js中的模块包,因为在程序中我们要用到网络相关的一系列功能,而幸运的是,node.js都帮我们封装了大量而丰富的相关的各种函数和方法,这些都可以通过npm模块管理器去下载这些模块包,本文中,需要使用的是socket.io和node-static两个模块,其中node-static模块是专门针对HTML,CSS和js而用到的。我们在命令行中,输入如下命令,就可以马上完成安装了。

  npm install socket.io node-static

  如何运行程序

  本文的示例代码在如下地址可以下载:http://demo.tutorialzine.com/2012/08/nodejs-drawing-game/node-drawing-game.zip

  ,可以将下载后的代码解压缩,然后打开node.js的命令行,进入该目录,然后执行:

  node app.js

  然后打开浏览器,输入http://localhost:8080,马上就可以感受这个游戏了!
   编写HTML页面部分

  接下来,我们首先编写页面部分的HTML代码。首先,在页面中,我们使用HTML5的canvas去绘画游戏的背景界面,并且使用div来设定每一个游戏绘画者的鼠标的指针,这个指针的形状使用的是一个.pointer的css样式,并且使用绝对定位。详细的css文件,请参考assets/css/styles.css文件。下面是

  index.html的代码,如下:
  
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Node.js Multiplayer Drawing Game | Tutorialzine Demo</title>

<!-- The stylesheets -->
<link rel="stylesheet" href="assets/css/styles.css" />

<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>

<body>
<div id="cursors">
<!-- The mouse pointers will be created here -->
</div>

<canvas id="paper" width="1900" height="1000">
Your browser needs to support canvas for this to work!
</canvas>

<hgroup id="instructions">
<h1>Draw anywhere!</h1>
<h2>You will see everyone else who's doing the same.</h2>
<h3>Tip: if the stage gets dirty, simply reload the page</h3>
</hgroup>

<!-- JavaScript includes. Notice that socket.io.js is served by node.js -->
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script src="assets/js/script.js"></script>

</body>
</html>



   可以看到,上面的canvas画布的尺寸有点大,有的用户的屏幕大小关系可能看不完整,但这个没关系,开发者可以去调节其大小。此外在页面中也包括了socket.io.js这个文件了,但在下载的代码文件中其实读者是找不到这个文件的,因为其实这个其实是服务端生成的文件而已,这个有点象著名的AJAX框架DWR的原理一样。下图就是运行index.html后的效果:
  
   客户端的代码
     跟我们平时在Javascript中进行调用不同,这次node.js需要在客户端和服务端同时都运用上Javascript。在下面提到的代码中,使用了socket.io去连接服务端,并且当发生了相关事件后,就通知用户。事件的传递都是以消息的形式进行的,并且统一交由node.js处理。事件消息中包含了鼠标的坐标,每一个操作者的唯一的id,以及判断用户当前是否正在绘画。
   
$(function(){
// 判断浏览器是否支持canvas功能
if(!('getContext' in document.createElement('canvas'))){
alert('Sorry, it looks like your browser does not support canvas!');
return false;
}
// web服务器地址,端口在app.js中设置
var url = 'http://localhost:8080';
var doc = $(document),
win = $(window),
canvas = $('#paper'),
ctx = canvas[0].getContext('2d'),
instructions = $('#instructions');
// 产生一个唯一的用户id
var id = Math.round($.now()*Math.random());
// 判断是否正在绘图
var drawing = false;
var clients = {};
var cursors = {};
var socket = io.connect(url);
socket.on('moving', function (data) {
if(! (data.id in clients)){
// 发现一个新的用户加入了游戏在线绘画,给新用户一个可以绘画的画笔光标
cursors[data.id] = $('<div class="cursor">').appendTo('#cursors');
}
// 移动光标
cursors[data.id].css({
'left' : data.x,
'top' : data.y
});
// 判断用户是否还在绘画
if(data.drawing && clients[data.id]){
// 在画布中画线条,其中clients[data.id]数组中包含了用户之前的光标的位置
drawLine(clients[data.id].x, clients[data.id].y, data.x, data.y);
}
// 保存当前光标状态
clients[data.id] = data;
clients[data.id].updated = $.now();
});
var prev = {};
canvas.on('mousedown',function(e){
e.preventDefault();
drawing = true;
prev.x = e.pageX;
prev.y = e.pageY;
// 隐藏操作指引
instructions.fadeOut();
});
//当光标移开时,设置停止绘画标记
doc.bind('mouseup mouseleave',function(){
drawing = false;
});
//获取当前时间
var lastEmit = $.now();
doc.on('mousemove',function(e){

//30秒后通过socket发送广播消息
if($.now() - lastEmit > 30){
socket.emit('mousemove',{
'x': e.pageX,
'y': e.pageY,
'drawing': drawing,
'id': id
});
lastEmit = $.now();
}
// 如果在绘画中的状态的话,则允许用户继续绘画
if(drawing){
drawLine(prev.x, prev.y, e.pageX, e.pageY);
prev.x = e.pageX;
prev.y = e.pageY;
}
});
// 对超过10秒依然不绘画的用户进行移除
setInterval(function(){
for(ident in clients){
if($.now() - clients[ident].updated > 10000){
//删除该不活跃的用户
cursors[ident].remove();
delete clients[ident];
delete cursors[ident];
}
}
},10000);
//标准画线的方法
function drawLine(fromx, fromy, tox, toy){
ctx.moveTo(fromx, fromy);
ctx.lineTo(tox, toy);
ctx.stroke();
}
});

 
     在上面的代码中,使用了socket.emit方法去发送消息给node.js,因为要求多个用户同时各自在绘画图时,都要把其当前光标状态等广播给其他人,因此会带来大量的数据包,所以这里每30秒才将用户的绘画状态包装成消息体的形式发送出去,并且对超过10秒不进行绘画的用户进行清除。

   服务端代码的编写

   现在我们进入服务端代码的编写,读者可能会以为,会否服务端代码会比客户端的代码多很都长,但在nodejs的世界,却正好相反,服务端的代码更加简单,这都得益于nodejs对各种常用的功能进行的封装,服务端的app.js代码如下
   

// 包含http模块
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
static = require('node-static'); // 引入node-static模块专门处理相关的html和js等
// 创建一个web服务器,并在8080端口监听
var fileServer = new static.Server('./');

app.listen(8080);

function handler (request, response) {

request.addListener('end', function () {
fileServer.serve(request, response); });
}

// 如果需要看调试信息删除这行
io.set('log level', 1);

// 监听客户端的请求
io.sockets.on('connection', function (socket) {

// 开始监听鼠标的移动事件
socket.on('mousemove', function (data) {

// 广播消息到各客户端
socket.broadcast.emit('moving', data);
});
});



      就这么简单!我们的服务端程序就编写完毕了,现在可以按前文说到的方法进行运行了。

  小结

  在本文中,简单为大家介绍了如何使用node.js开发一个多人同时在线涂鸦的小游戏,可以看到,由于node.js的特点,使得编写该类型的程序变得十分简单,node.js还有大量特性需要开发者去挖掘和学习,敬请期待itpub的相关文章介绍。
4
1
分享到:
评论

相关推荐

    node.js实战 pdf+源码

    《Node.js实战》是一本深度剖析Node.js技术的实战教程,旨在帮助读者掌握构建高效、可扩展的服务器端应用所需的知识和技能。本书的核心内容围绕JavaScript的非阻塞I/O模型,利用Node.js的异步事件驱动架构,来实现高...

    node.js实战(第2版)PDF&源码.zip

    《Node.js实战(第2版)》是一本深入探讨Node.js技术的实战指南,适合有一定JavaScript基础并希望进一步掌握Node.js开发的读者。本书详细介绍了如何利用Node.js的强大功能进行后端开发,以及如何与其他技术栈配合,...

    node开发实战

    node实战开发,知识点全面,从环境搭建到实战演练,教你全面运用node.js

    pdf版,Node.js开发实战详解

    Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它让JavaScript开发者可以在服务器端执行代码,打破了传统的JavaScript只能在浏览器端运行的限制。这本《Node.js开发实战详解》电子书,显然是为了帮助那些...

    Node.js硬实战 115个核心技巧.pdf

    《Node.js硬实战 115个核心技巧》是一本深度挖掘Node.js技术的书籍,旨在帮助开发者掌握Node.js的核心技能并提升实际开发能力。Node.js是基于Chrome V8引擎的JavaScript运行环境,它以其非阻塞I/O、事件驱动的特性在...

    node js 实战 源码

    在深入探讨Node.js实战源码之前,我们先理解Node.js本身。Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它让开发者可以在服务器端使用JavaScript编写应用,打破了JavaScript只能在浏览器端使用的限制。Node...

    Node.js开发实战详解 part1

    Node.js开发实战详解 第一部分 总共3部分

    nodejs实战pdf+源码_nodejs_nodejs实战pdf+源码_

    《Node.js实战》是一本深度探讨Node.js技术的书籍,由知名Node.js核心框架贡献者、社区活跃分子Mike Cantelon撰写。作为一名资深的培训师和演讲人,Cantelon以其丰富的经验与深入的理解,为读者提供了全面而实用的...

    Node.js开发实战详解.zip

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它允许开发者使用JavaScript进行服务器端编程,打破了传统的客户端脚本语言限制。在"Node.js开发实战详解"这个资源中,你将深入学习如何利用Node.js的强大功能...

    Node.js开发实战详解.pdf

    《Node.js开发实战详解》是一本深度探讨Node.js开发技术的专业书籍,旨在为读者提供一个全面、详实的学习路径,引领他们深入理解并熟练运用Node.js进行web开发。本书不仅适合初学者,也对有一定经验的开发者有很高的...

    Node.js开发实战详解源代码

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它允许开发者使用JavaScript进行服务器端编程,打破了JavaScript只能在浏览器中运行的传统。本“Node.js开发实战详解源代码”压缩包提供了丰富的学习材料,...

    Next.js+React+Node系统实战视频教程

    课程分享——Next.js+React+Node系统实战视频教程,搞定SSR服务器渲染,2022年4月完结新课,提供有配套的源码和电子书下载!完整版12章! Next.js是新兴的Web开发王牌工具, 更是React的经典拍档,帮你专注于核心...

    《Node.js权威指南 (实战)》陆凌牛(作者)epub

    第三部分(第16章)讲解了两个综合案例,如何结合使用Node.js与Socket.IO类库制作一个聊天室应用程序的服务器端及客户端,以及如何结合使用Node.js与Express框架制作一个Web应用程序的服务器端及客户端。

    vue.js+node.js 实战项目视频及源码

    在本资源中,你将学习如何结合 Vue.js 和 Node.js 进行实战项目的开发,具体是构建一个播放器应用。Vue.js 是一个轻量级的前端JavaScript框架,它以其组件化、易上手和高性能而受到广泛欢迎。Node.js 则是一个基于...

Global site tag (gtag.js) - Google Analytics