Aprende a crear juegos en HTML5 Canvas

lunes, 16 de enero de 2012

Parte 1. Dibujando en el canvas.

Para crear un juego en canvas, necesitaremos dos archivos: Una página HTML para mostrarlo, y el código en JavaScript del juego. Comencemos creando un archivo llamado “index.html”, lo abrimos para editar (Clic derecho » Abrir con » Notepad++, o el que uses) y copiemos dentro el siguiente código:
<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <!--[if lte IE 8]><meta http-equiv="X-UA-Compatible" content="chrome=1" /><![endif]-->
        <title>My First Canvas Game</title>
    </head>

    <body>
        <h1>My First Canvas Game</h1>

        <p><canvas id="canvas" width="300" height="150" style="background:#999">
            Canvas not supported by your browser.
        </canvas></p>

        <script type="application/javascript" src="game.js"></script>
    </body>
</html>
No me detendré a explicar el código HTML, ya que no es necesario para comprender el desarrollo de juegos. Digamos que el código arriba es lo básico para mostrar una página web donde mostraremos nuestro juego. Solo hay dos líneas importantes que debes comprender:

        <script type="application/javascript" src="game.js"></script>
Mediante esa etiqueta “script”, llamamos al archivo game.js, que contendrá todo el código de nuestro juego.
        <canvas id="canvas" width="300" height="150" style="background:#999">
            Canvas not supported by your browser.
        </canvas>
En esta etiqueta canvas, será donde dibujaremos nuestro juego, el ancho de 300px y alto de 150px son los valores predeterminados, por lo que se creará un lienzo del mismo tamaño en caso de no especificarse estos atributos. Puedes personalizarlos de acuerdo al juego que desarrolles, mas para este ejemplo, los dejaremos así.

El ID es el nombre único de nuestro elemento en la página, y es necesario para hacer referencia a él desde el juego; podemos cambiarlo al que deseemos, pero necesitaremos también cambiarlo en nuestro código (Que veremos en un momento).

Por último, agregamos un fondo gris para identificar dónde se encuentra nuestro lienzo (canvas). Si hay un problema con tu código, únicamente se mostrará el fondo gris, funcionando esto como una alerta. Posteriormente podrás borrarlo o cambiarlo, pero por ahora, será mejor dejarlo ahí.

Ahora, crearemos el código para nuestro juego. Comenzaremos por lo más sencillo: Dibujar un rectángulo dentro de él. Para ello, crearemos un segundo archivo de nombre “game.js”, y copiaremos el siguiente código dentro:
var canvas = null,
    ctx = null;

function paint(ctx) {
    ctx.fillStyle = '#0f0';
    ctx.fillRect(50, 50, 100, 60);
}

function init() {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    paint(ctx);
}

window.addEventListener('load', init, false);
Analizaremos el código por partes, para hacerlo más entendible, empezaremos por el final.

En la última línea, se agrega un escucha a la ventana, para que en cuanto termine de cargar la página, comience a ejecutar “init” (Que es donde comenzamos nuestro código). Es importante que indiquemos que el código comience hasta que se cargue la página, de lo contrario, el código podría no encontrar nuestro lienzo, y generaría una serie de errores que no nos permitirían reproducir nuestro juego.

Posteriormente en el bloque anterior, empezamos con la función “init”. En la primer línea de su contenido se obtiene el lienzo, buscándolo por su ID “canvas” (Si pusiste otro nombre a tu lienzo, es aquí donde debes poner el mismo nombre). Después de esto, se obtiene el contexto 2D de dicho lienzo. Este contexto es necesario ya que es nuestra herramienta para pintar dentro del lienzo; podríamos imaginar que es como nuestro pincel. Por último, se llama a la función “paint”, al que se le pasa dicho contexto para dibujar en él.

El siguiente bloque superior es la función “paint”. Aquí se indica que será usado el color hexadecimal de relleno '#0f0' (verde), y debajo, se rellenará un rectángulo desde la coordenada x,y 50,50, con 100 de ancho y 60 de alto.

Finalmente, al comienzo se crea las dos variables nulas donde se guardará el lienzo y su contexto.

Guardemos el archivo. Si lo hemos hecho todo bien, al hacer doble clic en index.html, se abrirá una página web donde se mostrará el lienzo con el rectángulo verde que hemos creado.

Diviértete cambiando los colores y dibujando más rectángulos, hasta que te familiarices con el lienzo. Puedes usar strokeStyle y strokeRect para dibujar el contorno en lugar de rellenarlos.

Código final:

[Canvas not supported by your browser]
var canvas = null,
    ctx = null;

function paint(ctx) {
    ctx.fillStyle = '#0f0';
    ctx.fillRect(50, 50, 100, 60);
}

function init() {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    paint(ctx);
}

window.addEventListener('load', init, false);

Depuración


Si solo se muestra en la pantalla un rectángulo gris, probablemente hay un error en tu código. Para encontrar el origen del problema, debes depurarlo.

Dependiendo del navegador que uses, puedes depurar tu código como se muestra a continuación:

Chrome:
Presiona F12 o Ctrl + Shift + I y selecciona la pestaña "consola".

Firefox:
Peesiona Ctrl + Shift + K y selecciona la pestaña "Consola web". Te recomiendo deshabilitar todas las notificaciones excepto las de JS para depurar mas fácil el código de tu videojuego.

Internet Explorer:
Presiona F12 y selecciona la pestaña "consola".

Opera:
Presiona Ctrl + Shift + I y selecciona la pestaña "consola".

Safari:
Presiona Ctrl + Shift + I y selecciona la pestaña "consola".  Debes habilitar antes "Mostrar menú de desarrollo en la barra de menú" en la pestaña "Avanzados" en "Preferencias" para usar esta opción.

Con esta información, podrás resolver cualquier problema que puedas encontrarte mientras estás desarrollando tus juegos.

65 comentarios:

  1. ¿Como hacer para mostrar codigo html en una web?

    <pre>
    <code>
    <html> </html>
    </code>
    </pre>

    ResponderBorrar
    Respuestas
    1. Primero, tu código HTML debes cambiar todos los "<" por "&lt;", puedes hacer esto con el reemplazador automático de tu editor de textos. Una vez que el código tiene este formato, ya solo debes envolverlo con la etiqueta <pre>. <code> es opcional, aunque bien recomendado.

      Suerte ;)

      Borrar
  2. "Guardemos el archivo. Si lo hemos hecho todo bien, al hacer doble clic en index.html, se abrirá una página web donde se mostrará el lienzo con el rectángulo ---rojo--- que hemos creado."

    Creo que ahí confundiste el color del rectángulo.
    De cualquier manera, te agradezco la página, esta muy bien hecha y explicada.

    ResponderBorrar
    Respuestas
    1. Este pequeño curso se modificó varias veces en un comienzo para ajustarse mejor a las lecciones siguientes, parece que detectaste un pequeño error de edición en los mismo. ¡Muchas gracias! Y me complace saber que ha sido útil para ti ;)

      Borrar
  3. Arriba con estoo!! Muy buena la pagina todo muy bien explicado! Saludos desde Uruguay!

    ResponderBorrar
  4. Guardemos el archivo. Si lo hemos hecho todo bien, al hacer doble clic en index.html, se abrirá una página web donde se mostrará el lienzo con el rectángulo rojo que hemos creado.
    no era verde??, buen tutoo, gracias...

    ResponderBorrar
    Respuestas
    1. Repito: Error durante la actualización del código... ¡Lo malo es que no lo he corregido! XD

      ¡Gracias por recordarme este detalle!

      Borrar
  5. no debería ser , no pasa nada como tu lo pusistes:
    me refiero por el slash

    ResponderBorrar
  6. no salio en el comentario de arriba, te decía si no es necesario hacer el cierre de la tag meta (cuarta linea del primer codigo)

    ResponderBorrar
    Respuestas
    1. Esto es obligatorio en XHTML, pero en HTML es opcional. Aun así, es parte de las buenas prácticas, tienes mucha razón en ello. Lo editaré para quien lo use de aquí en adelante, se lleve el mejor ejemplo. Gracias.

      Borrar
  7. una preg....
    X que es mejor animar y hacer games en CANVAS y no usando el Dom y animando DIVS con jquery??

    ResponderBorrar
    Respuestas
    1. Tengo comprendido que Canvas esta especialmente desarrollado para esta clase de tareas, por lo que debería ser más veloz en cuanto a sus procesos. Teóricamente la velocidad del Canvas se ve comprometida únicamente por el tamaño del mismo, mientras que en el caso de los DIVs y otros objetos, su velocidad se ve afectada en función a la cantidad de objetos en pantalla. Sin embargo, he visto juegos de mucho tiempo antes al surgimiento de Canvas, y que no muestra problema alguno.

      Por otro lado, está la forma en que se programa con cada uno. En teoría (Y siento yo) es más fácil programar usando el Canvas que con DOM, aunque claro, esto puede cambiar dependiendo las habilidades de la gente; puede haber quienes se acomoden mejor usando DOM...

      Canvas fue creado especialmente para esta clase de tareas, y en general, son mejores para dichos objetivos, pero tampoco tiene nada de malo usar DOM. También depende de con qué te acomodes mejor. Si alguien tiene otras experiencias a compartir, es bienvenido ;)

      Borrar
  8. Muchísimas gracias por este blog tuyo, he aprendido muchísimo de el. a tal punto que por fin pude hacer mi juego.

    http://dl.dropbox.com/u/5894824/Diez%20Dias/index.html

    Solo como un comentario si es posible me gustaria abordararas un poco mas sobre la POO en javascript y sobre la Herencia, para que estuviera un poco mas completo el tema.

    ResponderBorrar
    Respuestas
    1. Me ha gustado tu adaptación de este clásico juego, ¡Me alegra que este blog haya podido ayudar en tu tarea!

      Aun faltan muchos temas por tocar en este blog, más adelante, se verá sobre esto y más a mayor detalle. Gracias por tu comentario :)

      Borrar
  9. Para controles Touch hay algo? por ejmplo para un juego en iPad?

    muchas gracias, estoy aprendiendo mucho en esta pagina.

    ResponderBorrar
    Respuestas
    1. ¡Lo hay! Y justamente estoy trabajando en el primero de esos tutoriales. En una semana o dos estarán ya en el blog, para que puedas revisarlos, o si lo prefieres, puedes buscar en Google sobre TouchEvents. ¡¡Suerte!!

      Borrar
    2. Magnífico, gracias.

      Borrar
  10. necesito un juego de damas y nose como hacerlo me puedes ayudar en eesoo xfas...con html5 con canvas..xfas...es mi trabajo final ayudame

    ResponderBorrar
    Respuestas
    1. Que es lo que llevas de él y que has aprendido al respecto para tu trabajo final? Me parece un trabajo final complejo si no tienes las bases al respecto...

      Borrar
  11. Ola quisiera saber como crear un juego este juego esta HECHO en HTML5 y quiero crear un juego parecido a este
    aqui esta el link
    www.dragonbound.net

    ResponderBorrar
    Respuestas
    1. ¡Claro que es posible! Espero ya hayas leído el resto del curso para que te des una clara idea de como hacerlo. Primero necesitarás la lógica del juego (Como se mueven y disparan), que con los cursos actuales, ya podrás hacerlo.

      Después, requerirás un lenguaje lado servidor con soporte de Sockets, para comunicarse a través de Internet y mandar las instrucciones entre jugadores. Esto aun no lo cubrimos en el curso, pero puedes investigar sobre ello por tu cuenta entre tanto.

      Si durante el desarrollo tienes dudas, no dudes en contactar de nuevo. ¡Éxito!

      Borrar
    2. Muchas gracias. pero con que programas se puede crear este juego dragonbound.net para requerir un lenguaje a través de Internet y mandar las instrucciones entre jugadores. y crear servidores

      Borrar
    3. solo quisiera saber cual es ese programa lo demas me encargo yo

      Borrar
    4. Puede ser PHP, Python, Perl... Lo que está de moda y creo sería más sencillo, es node.js + socket.io, aunque como es tecnología nueva, es más limitado en cuanto a soporte de servidores... Pero sin duda, mi mejor recomendación ;)

      Borrar
  12. Excelente Blog!!! (Y) Saludos desde Nicaragua!!!

    ResponderBorrar
  13. como crear un segundo archivo de nombre “game.js”, para copiar el codigo:
    window.addEventListener('load',init,false);
    var canvas=null,ctx=null;

    etc.
    etc.

    ResponderBorrar
    Respuestas
    1. De la misma forma que creaste el primero; eso depende del editor que uses.

      Borrar
    2. ayudame, no se porque me saleel fondo gris y nada más..

      Borrar
    3. Has revisado la consola de JavaScript? No reporta ningún error?

      Borrar
  14. Excelente Uno aprende mucho si le explica de la mejor forma. Gracias!
    De colombia. ;)

    ResponderBorrar
  15. Muy buen blog, voy a mirarme todos tus tutoriales!

    ResponderBorrar
  16. Seria bueno que tuviera un enlase a la siguiente leccion

    ResponderBorrar
    Respuestas
    1. El titulo es un enlace que lleva al índice, donde puedes ver todas las lecciones.

      Borrar
  17. Simplemente hago este comentario para agradecerte por tu tiempo en desarrollar todo este contenido, que no te das una idea lo valioso que es, es muy dificil encontrar este tipo de cosas y menos tan bien explicadas, gracias :)

    ResponderBorrar
  18. Disculpa otra vez yo molestando para que utilizas el "false" en window.addEventListener('load',init,false); estaba leyendo en otra pagina que mmm... por lo que entendi da el flujo al DOM, ahi ponen un ejemplo con un buttom dentro de una div, la div esta dentro del body, cuando esta en true es body-div-buttom, cuando esta en false es inverso, buttom-div-body, algo asi entendi, pero aqui para que sirve el false cual es el flujo?

    ResponderBorrar
    Respuestas
    1. Los detalles sobre este tercer parámetro puedes leerlos en https://developer.mozilla.org/es/docs/DOM/elemento.addEventListener

      Básicamente es un parámetro que se ha vuelto opcional, pero antiguamente era obligatorio, por lo que es recomendado universalmente siempre usarlo como false, a menos que hagas uso de él. En resumen, es solo una buena práctica sin uso para evitar errores en algunos navegadores antiguos.

      Borrar
  19. Hola, muy buenos días.
    Como se haría mostrar una imagen hasta que se carge todas las imágenes y sonido del juego?
    Muchas gracias por todo tu tiempo.

    ResponderBorrar
    Respuestas
    1. Agrega un EventListener de tipo 'load' a cada asset que tengas, sumando a un contador en 1 cuando se ejecute esta función, y mientras el contador sea menor al total de assets, puedes mostrar esta imagen.

      Borrar
  20. Leí muy por arriba esta primera "clase", pero desde ya, muchas gracias no sólo por volcar conocimientos, sino por tomarte el tiempo de que otros aprendan..!! Abrazos digitales y mas adelante te diré como me fue con tu "curso".. !!!

    ResponderBorrar
  21. Como puedo hacer para que el cuadro cuando llegue al limite de "x"empiece a bajar por la variable "y" he intentado de varias maneras y no puedo lo estoy intentando cpn el canvas.width y canvas.heigth Agradezco la ayuda

    ResponderBorrar
    Respuestas
    1. No estoy muy seguro de lo que intentas, pero me suena que es una condicional así lo que quieres:

      if(x < canvas.width-10)
      x+=10;
      el se
      y+=10;

      ¿Es algo así lo que estás buscando?

      Borrar
    2. lo que necesito es que cuando el cuadro en el eje X = canvas.width
      llegue a esa posición empiece a sumar o restar no estoy seguro en eje y canvas.height lo que quiero es que el cuadro de vueltas alrededor del canvas por los limites del mismo muchas gracias
      por tu ayuda pero lo que me respondiste no funciona solo le aumento la velocidad a x

      Borrar
    3. ¿Tu variable x es la que controla la velocidad o la posición de tu cuadro? Por lo que me comentas, creo que es la primera, cuando yo hice el ejemplo como si fuera la segunda.

      Cuando ejeX == canvas.width, eso será ya fuera de la pantalla, así que debes de restar a este último, el ancho de tu cuadrado para que aún se vea.

      Para hacer lo que quieres, necesitas una variable para desplazamiento x y desplazamiento y. Cuando se cumpla la condicional, cambias estos valores por el nuevo formato de movimiento que deseas. No es tan sencillo, pero una vez que lo consigues, descubres que tampoco es demasiado complejo.

      Borrar
  22. hola, segui los pasos que dijiste pero al darle doble click a index.html se me abre el editor de texto, hay algun pre requisito que se necesite o algo para que se abra la web?

    ResponderBorrar
    Respuestas
    1. Posiblemente hayas configurado algo para que no abra predeterminado con el navegador.

      Prueba clic derecho > abrir con, y selecciona tu navegador en este caso.

      Borrar
    2. probe hacer eso tambien y cuando abro con el navegador se me abre el codigo en la ventana del navegador :S

      Borrar
    3. ¿Que editor de texto usaste para guardarlo? Existe la posibilidad que se haya guardado como índex.html.txt, y Windows normalmente NL muestra las extensiones.

      Borrar
    4. jajajaj era eso :P gracias

      Borrar
  23. Hola, recien empece a ver los tutoriales y me parecen muy buenos, muchas gracias. Solo tengo una duda, si declaraste las variables canvas y ctx de manera global para que le pasas parametros a la funcion paint? Esto no es necesario

    ResponderBorrar
    Respuestas
    1. Es parte de buenas prácticas desde inicios de la programación de videojuegos, especialmente funcionales cuando se comienza a trabajar con doble buffer, que se verá más tarde. Prefiero mantener el estándar de eventos desde el comienzo para evitar confusiones más tarde y hacer la transición con naturalidad.

      Borrar
    2. gracias por la aclaracion, muy buenos los ejemplos.

      Borrar
  24. Excelente curso

    Muy buena dedicación en este curso excelente material

    ResponderBorrar
  25. Excelente!!
    Siento que siguiendo tus tutoriales aprendere mas, que haciendo los trabajos que los maestros me dan.

    ResponderBorrar
  26. Llevo tiempo encontrando buenos tutoriales, hasta que me tope con el tuyo, y lo he visto varias ocaciones hasta que al fin me puse serio en leerlo y practicar. Por eso te agradezco mucho porque tus explicaciones son 100% exactas y concisas. Uno puede aprender de inmediato (obio que hay que saber javascript, HTML y CSS).

    Un abrazo grande y que tengas muchos exitos y mas seguidores.

    Buen día! :)

    ResponderBorrar
  27. hola, excelente tutorial. me ha servido mucho. gracias.

    ResponderBorrar
  28. Hola, buenas muy buen tuto, por casualidad haces videos en youtube?

    ResponderBorrar
    Respuestas
    1. De momento todo el material que tengo es escrito. Espero te sirva mientras tanto.

      Borrar
  29. heey, necesito ayuda, lo hice todo y no encuentro fallos de sintaxis en los codigos, pero al cargar la pagina solo sale el titulo y el texto de h1 ("My First Canvas Game") y los rectangulos no, que hago :d

    ResponderBorrar
    Respuestas
    1. Debería aparecer por lo menos el cuadro gris si fuera error del script. Tal vez sea algún detalle en el HTML. ¿La consola no muestra ningún error? ¿Puedes mandarme un screenshot de tu código para ver si puede haber un problema en él?

      Borrar
    2. jajaja, al parecer pense que me mandaria una notificacion cuando respondieras a mi correo pero no :b, ya lo arregle, se me hizo raro que la consola no mostrara errores pero me habia equivocado en cerrar un parentesis, no se que paso pero ya quedo, ya voy en la parte cuatro de todos modos

      Borrar
    3. Posiblemente olvidaste activar abajo la casilla que dice "notificarme", suele pasarme a mi también.

      Y me extraña también que no te haya notificado de ese error, pero me alegra que hayas logrado identificarlo y resolverlo. ¡Éxito en lo demás temas!

      Borrar
  30. heey, necesito ayuda, lo hice todo y no encuentro fallos de sintaxis en los codigos, pero al cargar la pagina solo sale el titulo y el texto de h1 ("My First Canvas Game") y los rectangulos no, que hago :d

    ResponderBorrar
  31. Hola!
    tengo un problema copie todo como en el blog pero a la hora de abrir el archivo en mi navegador solo aparece "My First Canvas Game" y el cuadro gris. pero el cuaro verde no y en la consola no hay ningun problema

    PD:Se que se subio hace ya una decada.

    ResponderBorrar