Создание приложения для рисования с помощью Node.js / Скачать Node.js

Вы наверняка, слышали о node.js. Это асинхронный веб-сервер построенный на движке OnTop от Google V8 JavaScript (тот самый, на котором работает Chrome lighning). При помощи node-static Вы сможете добавить масштабируемые веб-сервисы в JavaScript, которые могут обработать огромное число одновременных соединений, что делает его прекрасным инструментом для серверных игр, веб-чатов и других задач.

Сложность

Идея

Сегодня мы создадим простую онлайн игру - рисование. Приложение позволит пользователям рисовать на странице при помощи мыши, и отображать результаты на холсте - canvas. В отличие от аналогичных работ, наш проект будет работать в режиме реального времени, то есть люди будут видеть, как Вы рисуете. Для реализации нашей цели мы добавим библиотеку socket.io для node.js, которая использует различные технологии от websockets до AJAX. Она долгое время разрабатывалась, чтобы сейчас предоставить нам поток данных в реальном времени.Этот пример работает во всех современных браузерах.

Установка node.js

Для создания игры, необходимо установить node.js. Это займет всего несколько минут. Если у Вас Windows, можете зайти на официальный сайт и скачать node.js. Если у Вас Linux или OSX, то нужно выполнить тот набор команд в терминале (выполните только первый script: node-and-npm-in-30-seconds.sh).

После установки Вы получите доступ к npm (менеджеру пакетов узла). С помощью данной утилиты Вы можете установить полезные библиотеки и скрипты, которые можно импортировать в node.js. Как я упоминал выше, нам потребуются библиотека socket.io и node-static, который будет работать HTML, CSS и JS файлами для приложения рисования. Снова откройте терминал (или новое окно командной строки, если у вас Windows) и запишите следующую команду:

npm install socket.io node-static

Для выполнения процесса может понадобиться несколько минут.

Запускаем приложение

Если вы хотите просто скачать файлы и запустить приложение на вашем компьютере, вам нужно скачать архив и распаковать его в любую папку. После этого откройте командную строку/терминал и перейдите к этой папке при помощи команды cd. После этого введите следующую команду:

node app.js

После этого, должны увидеть сообщение отладки socket.io (если у вас не появилось данное сообщение, то скорее всего вы сделали что то не правильно! Попробуйте проверить правильность написания команды cd). Если Вы увидели сообщение, значит все хорошо работает! Теперь откройте http://localhost:8080 и вы увидите с копию нашего демо. Отлично!

В этом уроке мы пошагово разберем, как с нуля разработать приложение рисования.

HTML

Первый шаг, как обычно, HTML разметка. В которую добавим элемент canvas, который послужит в качестве полотна и контейнер для курсора мыши. В данном уроке мы не будем описывать все этапы стилизации нашего проекта, но вы можете взглянуть на стили в файле - assets/css/styles.css, для общего понимания.

<!DOCTYPE html>
  <html>
  <head>
  <meta charset="utf-8" />
  <title>Node.js Multiplayer Drawing Game | Tutorialzine Demo</title>

 <!-- CSS -->
  <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">

  </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>
 
  <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>

Обратите внимание, что поле для рисования имеет фиксированные размеры, ширину 1900px и высоту 1000px, но пользователи с экранами меньших размеров будут видеть только часть полотна. Возможно лучше было бы увеличить или уменьшить поле относительно размера экрана, но я оставлю это на Ваше усмотрение.

В режиме реального времени создается канал связи между браузером пользователя и node.js. При работе мы должны включить библиотеку socket.io с обоих сторон.

Сторона клиента

В других уроках, как правило, называли этот раздел JavaScript, но на этот раз у нас есть JavaScript со стороны клиента (в виде браузера) и сервер (node.js).

Код ниже, работает в браузере пользователя. Он использует socket.io для подключения к серверу и уведомляет нас, когда происходит событие. Это событие представляет собой сообщение, передаваемое другими клиентами, которое поступает к нам через node.js. Сообщения содержат координаты курсора, уникальный идентификатор для пользователя и показывают рисует сейчас пользователь или нет.

assets/js/script.js

$(function(){

 // Это демо зависит от графического элемента
  if(!('getContext' in document.createElement('canvas'))){
  alert('Sorry, it looks like your browser does not support canvas!');
  return false;
  }

 // URL Вашего сервера (Порт расположен в 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]){

 // Нарисуйте линию на холсте. клиенты содержатся в[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){
  if($.now() - lastEmit > 30){
  socket.emit('mousemove',{
  'x': e.pageX,
  'y': e.pageY,
  'drawing': drawing,
  'id': id
  });
  lastEmit = $.now();
  }
 
// Нарисуйте линию для текущего пользователя, похожую на эту
  
 // не получил события выше в socket.on ('движение') 
 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){
 
// Последнее обновление было сделано более 10 секунд назад. 
 
  // Пользователь по какой то причине закрыл страницу 
 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 мс (функция $.now() определяется в JQuery и возвращает количество миллисекунд).

Событие движения мыши не вызывается на каждый пиксель, но мы используем трюк, чтобы соединять всё сплошными линиями, а не отдельными точками. Особенно, когда рисуем на холсте, мы используем метод LineTo, так что расстояние между координатами мыши соединяется в сплошную линию.

Теперь перейдем к серверной части!

Сторона сервера

Код стороны сервера намного короче и проще. Когда люди получают доступ к URL приложения, в браузере отображается сообщение socket.io.

app.js

// Включение библиотек

var app = require('http').createServer(handler),
   io = require('socket.io').listen(app),
   static = require('node-static'); // for serving files

// Это будет содержать все файлы в текущей папке
// доступной из Интернета
var fileServer = new static.Server('./');

// Это порт для нашего веб-сервера.
// Вы должны пойти по http://localhost:8080, чтобы увидеть его
app.listen(8080);

// Если URL сервера открыт в браузере
function handler (request, response) {

   request.addListener('end', function () {
        fileServer.serve(request, response); // this will return the correct file
    });
}

//Удалите эту строку, если вы хотите видеть отладочные сообщения
io.set('log level', 1);

// Прослушивать входящие соединения от клиентов
io.sockets.on('connection', function (socket) {

   // Начать обнаружение события перемещения мыши
   socket.on('mousemove', function (data) {

      // Эта линия отправляет событие
      // для всех, кроме исходного клиента.
      socket.broadcast.emit('moving', data);
   });
});

На этом создание приложения для рисования закончено!

Заключение

Рисовать становится гораздо интересней, когда вы это делаете со своими друзьями. Не стесняйтесь экспериментировать с примером и улучшать его! Вот вам некоторые идеи: было бы здорово использовать различные кисти, ластики, цвета и формы, или даже использование флагов стран, которые будут отображаться рядом с курсором.

ДЕМО СКАЧАТЬ Перевод статьи Let's Make a Drawing Game with Node.js

 

Тэги: node.jssocket.ioapp

Вход

Уважаемый пользователь! Мы обнаружили, что вы используете AdBlock и вынуждены скрыть часть материалов на нашем сайте. Siteacademy существует и развивается за счет доходов от рекламы. Просим внести наш сайт в список исключений или отключить Блокировщик рекламы на нашем сайте.