Aprende a crear juegos en HTML5 Canvas

domingo, 10 de noviembre de 2013

Introducción a Node.js

Una de las características más apreciadas de jugar en Internet, es el poder jugar con otras personas alrededor del mundo. Para poder programar un juego de esta naturaleza, es necesario conectar a cada uno de los jugadores mediante un servidor, el cual se encarga de manejar los datos de cada jugador y enviarlos a los demás mediante sockets.

Hoy día, la forma más sencilla de crear un servidor así es mediante Node.js y Socket.io, los cuales aprenderemos a usar en este tema. Aun cuando este blog se enfoca directo a los juegos, y deja los conocimientos extra de tecnologías de Internet para otros sitios, es importante comprender las bases de Node.js para poder crear nuestro servidor con Socket.io, por lo que dedicaremos una considerable parte inicial del tema a su comprensión y uso básico para nuestro propósito con él.

Comenzamos descargando Node.js desde su página oficial (http://nodejs.org/download/) y seguimos los pasos para su instalación.

Para probar que funciona correctamente, crearemos un programa básico. La mayor ventaja de Node.js para nosotros, es que también funciona con JavaScript, por lo que todo te parecerá muy familiar. Si nunca antes has trabajado con servidores, todo esto te parecerá muy fácil de comprender; por otro lado, si lo has hecho antes, te recomiendo que olvides todo lo que crees saber al respecto, o esto te resultará quizá demasiado confuso dentro de su simplicidad.

Habiendo ya advertido esto, crearemos un nuevo archivo de nombre "server.js", y en su interior, copiaremos el siguiente código:
/*global console, require */
(function () {
    'use strict';
    var serverPort = 5000,
        server = null;
    
    function MyServer(request, response) {
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.end('<h1>It\'s working!</h1>');
    }
    
    server = require('http').createServer(MyServer);
    server.listen(serverPort, function () {
        console.log('Server is listening on port ' + serverPort);
    });
}());
Para ejecutarlo, necesitarás entrar a tu interfaz de línea de comandos, navegar hasta la carpeta donde está tu archivo "server.js" y ejecutar dentro de ella el siguiente comando:
node ./server.js
¿Esto te parece complicado de hacer? Existe una solución más sencilla y automática de hacerlo, a través de un archivo de procesamiento por lotes.

Para los usuarios de Mac, creamos un archivo llamado "run-server.command", dándole permisos de ejecución, y agregándole las siguientes líneas:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")"
node ./server.js
read
Este archivo funciona también para Linux, aunque comúnmente se le pone la extensión ".sh" en lugar de ".command". Algunas versiones de Linux como Ubuntu, utilizan el comando "nodejs" en lugar de "node", por lo que es necesario cambiar ese detalle en el archivo.

En el caso de los usuarios de Windows, creamos un archivo llamado "run-server.bat", y le ponemos las siguientes líneas:
call node ./server.js
pause
En caso que exista un error en nuestro código, la línea "read" o "pause" en cada caso, prevendrá que la línea de comandos se cierre, permitiéndonos de esta forma que podamos leer dicho error para corregirlo.

Ahora sí, hacemos doble clic en nuestro archivo de procesamiento por lotes, la consola nos mostrará que Node.js está corriendo en el puerto 5000. Para comprobarlo, abrimos nuestro navegador, y dentro de él, abrimos nuestro servidor local en dicho puerto (http://localhost:5000). De funcionar correctamente, aparecerá una página con el texto "It's working". Nota que si cierras la consola, Node.js se cerrará y la página ya no se mostrará.

Ahora que comprobamos que nuestro código se ejecuta sin problemas, es tiempo de estudiarlo detenidamente, para comprender mejor como funciona Node.js.

Al comienzo, veremos comentada una línea que empieza con la palabra "global", seguida por las variables "console" y "require". Esto indicará a JSLint que estas variables vienen de un recurso externo (Node.js en ese caso), y por tanto, no debe advertirnos sobre haber olvidado declarar dichas variables.

Entrando en la función autoejecutable, ponemos en una variable el puerto que usaremos para nuestro servidor. Es común ver en los ejemplos de Node.js que usan el puerto 5000, y es por tanto el que usamos también para estos ejemplos, aunque puedes elegir cualquier puerto desde el 1024 hasta el 49151. También puedes usar el puerto predeterminado para http (80), y de esta forma no tener que especificarlo en la dirección, siempre y cuando no exista ya otro servidor ocupando el mismo, aunque es más conveniente usar un servidor de otro lenguaje como el principal, por facilidad.

Posteriormente tenemos una variable nula que contendrá el manejador de nuestro servidor, y después la función "MyServer" con la cual será construido. Analicemos con detalle esta función:
    function MyServer(request, response) {
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.end('<h1>It\'s working!</h1>');
    }
En esta función, escribimos un encabezado con respuesta 200 (Petición correcta) y contenido de tipo "text/html". En la siguiente línea, se finaliza la respuesta, mandando como contenido un titular "It's working!" para notificar que el servidor está activo a quien entre en esta URL. Esto sería el equivalente en una sola línea a escribir dicho contenido y cerrar la respuesta, como se muestra en el siguiente ejemplo:
        response.write('<h1>It\'s working!</h1>');
        response.end();
Finalmente creamos nuestro servidor con la función previa a través de la librería "http", y le indicamos que escuche el puerto que declaramos en un comienzo; al ser activado de forma exitosa, imprimiremos en la consola un texto que nos indique en que puerto nuestro servidor ha sido activado:
    server = require('http').createServer(MyServer);
    server.listen(serverPort, function () {
        console.log('Server is listening on port ' + serverPort);
    });
Con esto, hemos iniciado de forma exitosa y comprendido nuestro primer ejemplo de Node.js. En la siguiente entrega, aprenderemos como utilizar Socket.io con Node.js para poder crear nuestro juego multijugador masivo.

61 comentarios:

  1. Muy Interesante, espero que seguir muy de cerca este tutorial....

    ResponderBorrar
  2. excelente lo que andaba buscando gracias por compartir tus conocimientos con nosotros

    ResponderBorrar
  3. amigo como eso de lineas de comando en el interfas

    ResponderBorrar
    Respuestas
    1. Supondré que usas Windows. En este sistema operativo se llama Símbolo de Sistema, y lo encuentras en la carpeta de Aplicaciones en el menú inicio.

      Borrar
  4. yo lo primero ya esta y lo segundo como es eso de lines de comando

    ResponderBorrar
  5. amigo me puedes ayudar a crear un juego por q solo no lo voy a poder a ser

    ResponderBorrar
    Respuestas
    1. Con gusto te ayudaré en lo posible. ¿Que es lo que necesitas?

      Borrar
  6. nose si conoceras dragunbound el juego q quiero q me ayudes a crear es identico pero con diferentes cosas q podemos poner nosotros

    ResponderBorrar
    Respuestas
    1. Comentame que tienes y que te hace falta para poder ayudarte. Si prefieres hacerlo mas rápido y directo, contáctame por Hangouts.

      Borrar
  7. amigo no se como es Hangouts. por eso quiero comunicarme pore face

    ResponderBorrar
    Respuestas
    1. Tan solo entra a tu cuenta de Google Plus y ahi estará el chat, de forma similar a como lo hace Facebook.

      Borrar
  8. Saludos,
    el tutorial esta claro siempre que instales en servidor en un ordenador con lampp o xampp pero si quieres instalar el servidor en un servidor web (no un servidor dedicado sino un servidor web común y corriente) como procedería?

    ResponderBorrar
    Respuestas
    1. Es necesario que tu servidor soporte Node.js. Si tienes dudas, puedes preguntar a quien te ofrece el servicio.

      Sin embargo, interpreto tu definición de un "servidor web común y corriente" como un servidor económico, de esos que soportan tan solo PHP y a veces otro lenguaje en forma limitada. Si este es el caso, es muy probable que ese servidor no soporte Node.js...

      Borrar
    2. Mil gracias Karl no pensé que contestaras tan pronto

      Borrar
  9. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  10. Hola mucho gusto soy ingeniero colombiano..

    Primero muchas gracias por compartir tus conocimientos es algo muy valioso.

    Una pregunta tengo ganas de desarrollar un juego multi jugador no se que tan factibles veas que desarrolle este en html5 ..Si jugaran muchas personas el navegador no se podría lento ?..Claro por cuestiones del servidor

    ResponderBorrar
  11. Hola mucho gusto soy ingeniero colombiano..

    Primero muchas gracias por compartir tus conocimientos es algo muy valioso.

    Una pregunta tengo ganas de desarrollar un juego multi jugador no se que tan factibles veas que desarrolle este en html5 ..Si jugaran muchas personas el navegador no se podría lento ?..Claro por cuestiones del servidor

    ResponderBorrar
    Respuestas
    1. El servidor de las conexiones del juego es independiente del servidor del juego en sí, por lo que en realidad es lo mismo un juego HTML5 que un juego descargable, la conexión al servidor será igual de veloz dependiendo de sus capacidades, cómo lo configures y optimices.

      La única diferencia, será el tiempo de descarga del juego para iniciar, pues si planeas hacer un juego AAA de varios gigas de descarga, es muy posible que no convenga hacerlo en HTML5 por la cantidad de datos que deben descargarse cada que se va a jugar.

      Espero esto resuelva tus dudas.

      Borrar
  12. Hola, buenas noches, mmm no se si sería posible que me ayudará con un juego, tengo las bases pero no puedo hacerlo funcionar con node

    ResponderBorrar
    Respuestas
    1. Podemos intentarlo. ¿Qué es lo que llevas y en donde te has quedado?

      Borrar
    2. lo tengo en html, es que no se bien como explicarme. Se supone que debe ser multiplayer pero no funciona en otra ventana

      Borrar
    3. ¿Sí tienes encendido el servidor? ¿La consola de Javascript reporta algún error?

      Borrar
    4. Mmm creo que no he hecho esa parte, no se como D:, bueno tengo una idea pero no claramente

      Borrar
    5. Es posible que sea eso. Es lo mismo que explico en esta entrega. Lo haces a través de esta línea en la consola:

      node ./server.js

      Borrar
    6. No me deja hacerlo, marca este error "server is not define", creo que se debe a socket.io

      Borrar
    7. ¿En donde te da este error? ¿No te da más información?

      Borrar
    8. No me deja hacerlo, marca este error "server is not define", creo que se debe a socket.io

      Borrar
    9. Creo que ya solucione esa parte o al menos ya no la marca XD, el servidor parece correr bien, entonces según lo que entiendo el que debo abrir es el html para ver ya el juego no?...pero al abrirlo me marca en la consola que io no esta definido y este otro error " Uncaught TypeError: Cannot read property 'on' of undefined "

      Borrar
    10. ¿Si inicializaste tu variable antes de utilizarla? Me suena a que puede ser ese el problema.

      Y en caso de haberla inicializado correctamente, ¿Si tienes configurada la librería de Socket.io apuntando al servidor correcto en tu archivo HTML?

      Borrar
    11. Según yo si, pero no funciona y me marca los mismos errores, en el html lo tengo así script src="http://localhost:3000/socket.io/socket.io.js"

      Borrar
    12. ¿Puedes compartirme tu código Javascript para analizarlo?

      Borrar
    13. ¿Cómo te lo puedo compartir? :O

      Borrar
    14. https://jsfiddle.net/bsoan8u1/

      Borrar
  13. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  14. Hola Karl, tengo un servidor cloud en linux pero ni se que descargarme ni como instalarlo :(

    ResponderBorrar
    Respuestas
    1. ¿Es un servidor compartido, o uno privado? En caso del segundo ¿Qué distribución es?

      Borrar
  15. Es privado se que es linux pero no mas, lo tengo en ran.es

    ResponderBorrar
    Respuestas
    1. En la sección de servidores dedicados avisa que hay variedad de distribuciones a consultar. Sí no sabes cual tienes, muy posiblemente sea CentOS.

      La línea de comando para instalar Node.js en CentOS es la siguiente:

      yum -y install nodejs

      Puedes ver más información en la página oficial de Node.js:

      https://nodejs.org/en/download/package-manager/#enterprise-linux-and-fedora

      Borrar
    2. Gracias Karl! perdona por no contestar antes! Supongo que tengo que acceder a la consola pero desde ran no funciona hay alguna forma de ejecutar la consola? o acceder a ella?

      Borrar
    3. Accedí con putty y paso esto

      -bash-3.2# yum -y install nodejs
      Loaded plugins: fastestmirror
      Determining fastest mirrors
      * addons: centos.mirror.xtratelecom.es
      * base: centos.mirror.xtratelecom.es
      * extras: centos.mirror.xtratelecom.es
      * updates: centos.mirror.xtratelecom.es
      addons | 1.9 kB 00:00
      addons/primary_db | 1.1 kB 00:00
      base | 1.1 kB 00:00
      base/primary | 1.3 MB 00:00
      base 3667/3667
      extras | 2.1 kB 00:00
      extras/primary_db | 173 kB 00:00
      updates | 1.9 kB 00:00
      updates/primary_db | 602 kB 00:00
      Excluding Packages in global exclude list
      Finished
      Setting up Install Process
      No package nodejs available.
      Nothing to do

      Borrar
    4. He logrado instalar la version 0.8.12 de node, necesitaba actualizar python . Con esa vale?

      Borrar
  16. Se queda pillado en server is listening on port 1337 y no pasa nada mas

    ResponderBorrar
    Respuestas
    1. Con eso debería estar ya activa y funcionando. Si entras al sitio, en ese puerto, ¿Se lee el mensaje "It's working"? De ser así, ya tienes todo configurado correctamente.

      Borrar
  17. ok soy un TOPO! Funciona perfectamente! Ahora Socket, intentaré leer con mas atención que las prisas no son buenas!!
    Muchas gracias Karl, nos salvas

    ResponderBorrar
    Respuestas
    1. ¡Que bueno saber que ya está todo funcionando correctamente! Mucha suerte con tu progreso.

      Borrar
  18. hola, tengo unapregunta, creare un juego con phaser.js y quisiera guardar los datos de los personajes en una base de datos pero no tengo muy bien claro como hacer la conexion a la base de datos, quisiera saber si con nodeJS podria, gracias

    ResponderBorrar
    Respuestas
    1. Cualquier lenguaje de lado servidor funciona para hacer esta conexión, incluyendo PHP, Python, Ruby o Node.js.

      Yo lo que te recomendaría, sí no conoces ninguno, es ver en qué servidor planeas subir tu juego, para que veas qué lenguajes soporta, y en base a ello, crear tu código de conexión entre tu juego y la base de datos.

      De momento no tenemos material para esto en el blog, pero hay mucha información en Internet, que podría ayudarte dependiendo del lenguaje que elijas para tu conexión.

      Borrar
  19. Hola quisiera hacer en mi página un tipo de multijugador lo que quiero es que conecte de dos en dos y les de dos botones uno de Victoria y otro de derrota pero no sé hacerlo con node js con PHP me podrías dar un consejo?

    ResponderBorrar
    Respuestas
    1. Para poner a los usuarios en grupos (o en este caso, en parejas), lo que debes hacer es crear una variable arreglo de cuartos, dentro de los cuales agregues los usuarios al conectarse hasta el máximo límite de usuarios por cuarto. De esta forma, puedes mantener múltiples usuarios manejados en grupos más pequeños.

      Borrar
    2. Pero si deseo obtener el userName, puntos, etc. De una base de datos MySQL como le haría?

      Borrar
    3. Para usar MySQL desde Node.js, puedes seguir este ejemplo: http://www.nodehispano.com/2011/11/acceso-a-mysql-desde-node-js-nodejs/

      Borrar
  20. Y para utilizar node js nececito tener la computadora prendida o que?

    ResponderBorrar
    Respuestas
    1. Para hacer pruebas locales, sí. Una vez que lo subas a un servidor, será la conexión a través del mismo.

      Borrar
  21. Y ya la ultima pregunta(soy demasiado preguntón) como puedo cambiar la fuente del texto con una personalizada?

    ResponderBorrar
    Respuestas
    1. Eso lo haces con la propiedad font en el contexto:

      ctx.font='30px Arial';

      Para que está propiedad funcione, debes usar una fuente que el usuario tenga instalada; busca "web safe fonts" para obtener la lista de fuentes seguras.

      En caso que desees una fuente menos común, deberás precargarla antes con CSS mediante la propiedad @font-face

      ¡Éxito! ¡Felices códigos!

      Borrar
    2. Gracias por todo te lo agradezco muchísimo buena suerte con tu blog, vida, etc(por horita no tengo preguntas).

      Borrar
  22. Hola. En lugar de la consola (de Firefox) me aparece:

    La codificación de caracteres del documento HTML no ha sido declarada. El documento se mostrará con texto "basura" en algunas configuraciones de navegador si el documento contiene caracteres externos al rango US-ASCII. La codificación de caracteres de la página debe ser declarada en el documento o en el protocolo de transferencia.

    ResponderBorrar