Java – Juego de rol 2d – 15 – Creando bufferStrategy

Hola amigos bienvenidos al décimo quinto episodio de esta serie sobre el desarrollo de un juego de rol 2d en Java.

En el último episodio creamos un indicador que nos permite mostrar en el título de la ventana la cantidad de veces por segundo que se ejecutan los métodos encargados de actualizar el estado y los gráficos de nuestro juego.

En este episodio crearemos una serie de bufferes que usaremos para refrescar los gráficos del canvas de nuestro juego en el método refrescarCanvas();.

Hasta el momento hemos escrito unas cuantas líneas de código y ya tenemos preparada la estructura básica de nuestro juego.

Si ejecutamos lo que tenemos hasta el momento, recordaréis, que aparece esta ventana vacía y ese es precisamente el problema

Está vacía, no tenemos gráficos, y así, nuestro juego, no se parece en nada a un juego.

Así que, a partir de este momento, vamos a dedicar todos nuestros esfuerzos en obtener gráficos en la pantalla.

Probablemente tardemos unos cuatro episodios, porque no es un proceso demasiado rápido, pero veréis, que no es tampoco tan complicado como pueda parecer en un principio.

Así que, vamos a cerrar esta ventana.

Y antes de empezar a escribir código, necesito explicaros cómo vamos a obtener los gráficos en pantalla

Ya que vamos a utilizar una manera bastante primitiva pero también muy rápida comparado con lo que suele hacerse habitualmente.

Estoy en GIMP.

Lo voy a usar para explicaros.

Por ejemplo, abrimos un nuevo archivo, da igual la configuración.

Vale, tenemos una imagen, que por cierto se parece un poco a la s de superman, por casualidad, pero la cuestión es,

Normalmente, cuando se hacen juegos, la mayoría de los programadores que podéis ver en youtube o incluso en algunos libros

Suelen manipular estas imágenes de forma global, es decir, para ellos toda esta imagen es una cosa completa, es un todo, y ellos, por ejemplo

Si tuvieran que desplazarla, lo moverían como lo estoy haciendo yo, entera, pero en realidad, la imagen, no es un todo, está formada por muchas piezas más pequeñas, que son los píxeles.

¿Qué son los píxeles?

Si empiezo a hacer zoom, veréis, que aparece la rejilla de píxeles.

Como veis, un pixel, no es más que un cuadrado de un color concreto, y todos estos cuadrados juntos, crean un mosaico que desde lejos da la impresión de un dibujo.

Evidentemente, esto, no es más que un icono negro sobre un fondo blanco, pero si abriera una foto de un coche, de un paisaje o de cualquier otro tipo, sería lo mismo.

Si nos acercamos lo suficiente, podríamos ver los píxeles en la pantalla.

Pues bien, en nuestro juego, no vamos a manipular toda la imagen de golpe porque eso hace que la ejecución sea muy lenta.

En vez de eso, manipularemos los píxeles uno por uno individualmente.

Esto, nos dará un resultado mucho más rápido y ágil, y nuestro juego funcionará con menos recursos de ordenador.

Lo que al final significa que, podrá funcionar en equipos con muy poca potencia, que es uno de los objetivos de la programación, realizar nuestros programas de la forma más eficiente posible.

Pero lo importante que quería que entendiérais, es que vamos a manipular precisamente estos pequeños cuadraditos que se ven si hago zoom, no toda la imagen de golpe.

Una vez explicado esto, vamos a escribir un poco de código.

Bien, programaremos lo que será el sistema que va a refrescar el canvas, que, como ya dijimos, es la clase especializada de Java en mostrar gŕaficos en la pantalla

Entonces, lo que vamos a hacer es programar un sistema de refresco sobre lo que sería el thread encargado de procesar los gráficos.

Hasta el momento, solo hemos estado programando en la clase juego, y esto, no es demasiado fiel al paradigma de la programación orientado a objetos, ya que la gracia es tener varios objetos que se comuniquen entre ellos.

A partir de ahora empezaremos a hacerlo así.

Ya que hasta ahora, solo hemos estado preparando la base.

Así que vamos a crear un nuevo paquete para tenerlo todo muy ordenado, y lo vamos a llamar gráficos.

Por cierto, aquí os voy explicar una cosa, no es muy importante pero está bien que lo sepáis.

Si observáis, nos da un aviso, y es que no se recomienda que el nombre del paquete empiece por mayúsculas, es una convención de java,podéis hacer lo que queráis evidentemente, pero no suele estar demás seguir estás convenciones por comodidad, entonces, vamos a seguir su consejo, y lo vamos a escribir en minúscula.

Entonces, ¿qué tenemos por aquí?

El proyecto sigue igual, solo tenemos un paquete gráficos nuevo que hemos creado, porque ahí vamos a crear luego una clase

Ya la vereis más adelante y qué más tenemos en el programa,

¿qué más ha cambiado?

Lo que está comentado es lo que hay nuevo en el programa

¿vale?

Por aquí todo va bien, tenemos estas siete lineas que son nuevas, ahora las explicaremos, tenemos este método detener, que por el momento no lo estamos usando, por eso está en amarillo, lo que hace es, pone juegoEstaEnFuncionamiento a false, interrumpe el thread de gráficos y sale del system con status igual a cero.

Como lo vamos a necesitar pues ya lo he puesto

Más adelante, lo usaremos para que nos deje de salir esta advertencia

¿de acuerdo?

Y tenemos lo que sería el refresh sistem, que estaría aquí con los buferes

Okey continuamos eeemm, vamos a ir descomentando un poco, vamos a ejecutar para que veáis, ejecutamos y como veis está como en el episodio anterior

¿vale?

Se nos mostrarán los dibujos por segundo y las actualizaciones por segundo.

Vamos a crear aquí lo que será el bufferStrategy

¿de acuerdo?

Entonces, tenemos el treahd de gráficos, que es el hilo o la hebra que se va a encargar de procesar los gráficos de nuestro juego.

Hasta aquí, todo bien, entonces vamos a ir descomentando, mmm, voy a descomentar aquí

¿vale?

Como es lógico, esto requiere de los imports

vamos a descomentar

¿de acuerdo?

Nos sale amarillo debido a que no lo estamos usando entonces, vamos a explicar ahora en qué consisten estas siete líneas

¿vale?

Voy a ejecutar para que veáis que todo está funcionando bien,

vale, funciona bien

¿qué vamos a hacer?

Bueno, descomentamos estas siete lineas que son nuevas.

Para que funcione descomentamos también los imports y vamos a necesitar dos objetos para manipular los pixeles del juego, y estos van a ser en primer lugar, private static bufferedImage y lo vamos a llamar imagen igual a new bufferedImage y aquí le tenemos que pasar unos cuantos parámetros a esta clase de Java, que van a ser el ancho, el alto y bufferedImage punto y aquí necesitamos una opción que se llama type_int_rgb, la escribimos, punto y coma, vale

¿Qué hemos hecho aquí?

Hemos creado una imagen en buffer y, lo normal sería cargar esta imagen desde un archivo, por ejemplo, de una carpeta, una foto que tengamos, o cualquier cosa, pero aquí, en vez de cargar la imagen, hemos hecho una nueva imagen con fondo negro, con este tamaño, ancho, alto y el modo de color rgb, es decir, con el modo de color que usan los monitores, pero nosotros usaremos este, es el más útil para nuestro caso

Ahora, para poder manipular esta imagen, necesitaremos pixeles, no queremos manipular la imagen entera, de golpe, necesitaremos romperla en sus pixeles

Así que para eso, private static int[] y de nuevo adivinad pixelesCanvas,

, igual y aquí viene una cossa un poco larga

Aquí tenemos dataBufferInt, dentro de ella del primer parentesis escribimos img.getRaster()

¿De acuerdo?

writableRaster.getDataBuffer(), y fuera de este segundo parentesis dataBufferInt.getData();

De acuerdo

¿Qué hemos hecho aquí?

Lo que hemos hecho es acceder a esta imagen en forma de un array de pixeles

Todos estos objetos, lo que hacen es devolvernos un array de ints, que representa los pixeles de la imagen, nos devuelve la rasterización de la imagen, eso, es la secuencia de pixeles

Esto de aquí, que está entre parentesis es una conversión dataBufferInt.getData(), porque estos datos no nos sirven, hay que convertirlos

Parece un poco complicado, pero es la única manera de hacer que nuestro array de pixeles pueda manipular los números que provienen de la imagen

Y además a partir de este momento, las dos cosas quedan enlazadas, es decir, si la imagen sufre algún cambio lo sufrirá también el array de pixeles

¿De acuerdo?

Bien, vamos a implementar estas nuevas lineas,

Y esto es, básicamente, lo que me implementa el resfresh sistem, descomentamos

Vale, necesitamos importar, arriba donde están los imports

Descomentamos aquí, y como veis, necesito otro import que es el de la clase color, color red,

okey, quitamos aquí, y ejecutamos para que veáis qué ocurre.

Bien, ahora, ya tenemos la pantalla negra.

Esto se debe, la pantalla está negra porque esta serie de bufferes que estamos creando por defecto es de color negro.

Explicando el eje de coordenadas minuto 21:22 Episodio 16 que conecta con el minuto 06:22 comienza la despedida

de acuerdo

¿Qué está pasando?

Pues que estamos refrescando el canvas básicamente

De hecho, si no mostramos el buffer, la pantalla se queda blanca

Okey, esta sería toda la lógica que se encarga de refrescar el canvas

Para terminar, vamos a ir a GIMP,

vale,

Aquí tengo un eje de coordenadas porque nuestro juego se va a basar en este eje de coordenadas

Este es el sistema de coordenadas de Java.

Tenemos que la X y la Y crecen en el cuarto cuadrante

Eeee, creo que voy a dejar esto por aquí en el estado en el que se encuentra

¿vale?

Y en el próximo episodio, lo que haremos será explicar los buferes que refrescan el canvas, crear y modularizar la clase capturador de pixeles, explicaremos un poquito más en profundidad cómo funciona la clase capturadorPixeles, y también explicaremos lo que es el concepto de sprite

Así que todo esto y mucho más en el próximo episodio de desarrollo de un juego de rol 2D en Java

Si os ha gustado el episodio, dadle a me gusta, y si os interesa la serie, suscribíos para obtener actualizaciones inmediatas.

Hasta la próxima chicos!

Deja un comentario