Aprende a crear juegos en HTML5 Canvas

lunes, 10 de septiembre de 2012

Estirar el canvas y llenar la pantalla

Los que han creado proyectos antes en Flash, recordarán una de sus características singulares, que a veces podía ser funcional y otras veces molesto, dependiendo el efecto que se deseaba hacer. Hablo de la peculiar propiedad que, si ponías el contenedor de diferente tamaño al proyecto original, este se escalaba para ajustarse al nuevo tamaño.

Los HTML5 Canvas aparentan en un comienzo no tener esta propiedad, pues si cambiamos el ancho o alto de uno, solo nos da un escenario más grande o chico, pero este no se escala. Lo que ocurre, es que aprovecha una segunda propiedad para escalar el canvas, de forma aparte a poner su tamaño inicial. Lo hace mediante la etiqueta Style.

Para comprobar esto, tomaremos el juego de la serpiente, y buscaremos al comienzo donde creamos la etiqueta canvas que contiene nuestro juego. Lo modificaremos agregando en el atributo style, las propiedades width y height:
<canvas id="canvas" width="300" height="150" style="background:#999; width:600px; height:300px;">
    [Canvas not supported by your browser]
</canvas>
Podemos comprobar que al comienzo, tenemos los atributos width y height:
width="300" height="150"
Pero posteriormente, los tenemos como propiedad dentro del style, con valores al doble que en su atributo:
width:600px; height:300px;
Al abrir el archivo, notaremos que nuestro juego está ahora escalado al doble. De esta forma, es como podemos escalar un juego a diferentes tamaños.

[Canvas not supported by your browser]

Llenar la pantalla.


Supondré que ahora que has visto como escalar un juego, has pensado en llenar la pantalla de tu navegador con él para aprovechar mejor los monitores de los usuarios. Lo primero que viene a nuestra mente, es darle ancho y alto del 100%, con el siguiente código:
<canvas id="canvas" width="300" height="150" style="background:#999; width:100%; height:100%;">
    [Canvas not supported by your browser]
</canvas>
Pero al hacerlo, descubrimos dos problemas. El primero es que existe un pequeño margen predeterminado en nuestra página, por lo que realmente no estamos llenando nuestra pantalla con el lienzo. Para quitar este margen, solo debemos eliminar el "margin" y "padding" de nuestra etiqueta "body":
    <body style="margin:0; padding:0;">
El segundo problema que descubrimos, es que la imagen se estira de forma no proporcionada. Y hay que tomar en cuenta que no todas las pantallas tienen la misma proporción, por lo que en pantallas más cuadradas se verá la imagen aun más achatada que en pantallas widescreen.

Para hacer que llene lo mayor posible la pantalla de forma proporcional tendremos que crear una función en Javascript, a la que llamaremos "resize". Lo primero que hará esta función, es encontrar la proporción de nuestra pantalla, y determinar la escala a la cual debe ser estirado, dependiendo del ancho y alto de la pantalla:
            var w = window.innerWidth / canvas.width;
            var h = window.innerHeight / canvas.height;
            var scale = Math.min(h, w);
Una vez obteniendo este valor, asignamos el ancho y alto al estilo de nuestro lienzo de acuerdo a la escala resultante:
            canvas.style.width = (canvas.width * scale) + 'px';
            canvas.style.height = (canvas.height * scale) + 'px';
Ahora tan solo debemos llamar a la función "resize" desde nuestra función "init", y tendremos nuestro juego llenando la máxima área disponible en el navegador. Dado que esta función solo se llama al comienzo del código, si el usuario cambia el tamaño de la ventana más tarde, el lienzo no se re-ajustará al nuevo tamaño. Podemos evitar ese problema, agregando un escucha al evento de cambio de tamaño del navegador, llamando de nuevo a la función en tal caso:
    window.addEventListener('resize', resize, false);
Para complementar mejor este efecto, recomiendo que pongas el color de fondo de la página en negro modificando el estilo de la etiqueta "body", así como centrar su contenido, para el caso en que el lienzo extendido sea más alto que ancho:
    <body style="margin:0; padding:0; background:#000; text-align:center">
Con esto, concluimos esta lección. Puedes ver el resultado final en el siguiente enlace: http://canvas.ninja/?js=snake-full

Felices códigos. ¡Hasta la siguiente semana!

3 comentarios:

  1. Hola! Tengo una pregunta, usando este metodo como seria la entrada por mouse? Es decir, como puedo escalar la posicion del mouse dentro de las coordenadas del canvas? :O
    Gracias!

    ResponderBorrar
    Respuestas
    1. Revisa el código enableInputs de esta entrada, el principio es el mismo:

      http://juegos.canvas.ninja/2013/09/pantalla-completa-en-dispositivos.html

      Si tienes dudas de como aplicarlo, avísame. ¡Suerte!

      Borrar
  2. Hola, hago todo pero el juego completa la pantalla de derecha a izquierda, pero de arriba hacia abajo hay que utilizar la ruedita del mouse para bajar y ver el juego completo.
    cree la funcion y agrege la escucha al init.
    function resize() {

    var w = window.innerWidth / canvas.width;
    var h = window.innerHeight / canvas.height;
    var scale = Math.min(h, w);

    canvas.style.width = (canvas.width * scale) + 'px';
    canvas.style.height = (canvas.height * scale) + 'px';
    }

    ResponderBorrar