viernes, 11 de marzo de 2016

Sobre como mantener diferentes escenas en love2d (Las escenas)


Si ya lo has intentado, te habrás dado cuenta, como yo, que para un juego en el que se ha de gestionar un mínimo de elementos, con un load, un update y un draw no es suficiente. Si nos ponemos en el supuesto de un juego con pantalla inicial, menú de opciones y la pantalla del juego en si, nos podemos dar cuenta de lo descalabrado que puede resultar incluir todo esto dentro del main.lua; tanto por orden, como por control. Yo no soy un diestro en la materia, pero voy a intentar contar lo que yo aprendí sobre estos aspectos.


Escenas y gestor de escenas, estos son los conceptos que vamos a manejar para poder construir un pequeño ejemplo, que nos permita cambiar entre diferentes pantallas y comportamientos dentro de nuestro juego.

Separaré este texto en tres partes una para las escena, otra para el gestor y una tercera para un pequeño ejemplo funcional.

Escena


Una escena va a representar una de las pantallas de nuestro juego; menú, opciones, créditos... La escena contiene parte de los mismos métodos que la estructura principal de love2d, load, update y draw y al igual que en la estructura principal estas han de ser sobre escritas, por nosotros, para que trabajen según nuestras necesidades. A demás de las funciones ya descritas, la escena también va a contener otras cuatro funciones más show, hidden, destroy y pause. Estas cuatro funciones también han de ser sobre escritas por nosotros, pero en esta entrada aún no las vamos a usar.

Dicho todo esto, empecemos. Creamos una nueva carpeta y dentro, creamos nuestro archivo main.lua y el archivo Escena.lua.

Dentro de main.lua construimos la estructura básica de nuestro programa en love.

function love.load()

     --Aquí crearemos las variables y cargaremos los recursos

end



function love.update(dt)

     --Aquí realizaremos la actualización lógica de la aplicación

end



function love.draw()

     --Aqui se realizara todo el proceso de dibujar la pantalla

end


Dentro de escena.lua escribimos lo siguiente

--[[Tabla que representa la escena de un posible juego]]--

Escena=

{

      --nombre de la escena

      nombre="",

     --Estos dos valores serán usados por el gestor de escenas

     --Para controlar el ciclo de actualización de la escena.

     estaViva=false,

     estaEnPantalla=false

}



--[[Función encargada de generar una nueva escena.

Es método replica la tabla en u nuevo objeto, mediante setmetatable y la retorna

como un objeto nuevo e independiente. De este modo podremos generar cuantas

escenas queramos a partir de la original.]]--

function Escena:new()

     obj = { };

    setmetatable(obj, self);

     self.__index = self;

    return obj;

end



--[[Declaramos las funciones vacías para posteriormente

sobre escribirlas a nuestro antojo]]--

function Escena.load() end



function Escena.show() end



function Escena.hidden() end



function Escena.update(dt) end



function Escena.draw() end



function Escena.destroy() end



return Escena



Todas las funciones que quedan vacías, al final, serán controladas por el gestor de escenas que las llamará, cuando este lo precise.

  • Escena.load: Esta función será llamada si es la primera vez que el gestor carga la escena
  • Escena.show: Esta función es llamada cada vez que se recupera la escena para ponerla en pantalla
  • Escena.hidden: Esta función es llamada cada ve que se oculta la escena, si se intercambia por otra
  • Escena.update: Esta función sera llamada por el gestor periódicamente para controlar la lógica de la escena
  • Escena.draw: Esta función será llamada por el gestor, cada vez que necesite dibujar la escena
  • Escena.destroy: Esta función será llamada por el gestor, justo ante de eliminar la escena

En la siguiente entrada implementaré el gestor. Por ahora, un ejemplo de todo esto,
seria el siguiente:

Creamos un nuevo archivo llamado EscenaPrueba.lua y incluimos en el nuestro archivo Escena.lua


Escena=require "Escena"

Luego llamamos a Escena:new() Para generar una nueva instancia de una escena


EscenaPrueba=Escena:new()

Sobre escribimos los métodos load, update y draw escribiendo lo siguiente:


function EscenaPrueba.load()

     --generamos la estructura de un cuadrado

     cuadrado={100,200,100,100}

end



function EscenaPrueba.update(dt)

     --Recogemos la posición del cursor

     mX=love.mouse.getX()

     mY=love.mouse.getY()

     --actualizamos la posición del cuadrado

     cuadrado[1]=mX

     cuadrado[2]=mY

end



function EscenaPrueba.draw()

     --dibujamos el cuadrado

     x=cuadrado[1]

     y=cuadrado[2]

     w=cuadrado[3]

     h=cuadrado[4]

    love.graphics.rectangle("fill",x,y,w,h)

end

--retornamos la escena diseñada

return EscenaPrueba
--Aquí crearemos las variables y cargaremos los recursos
Una vez hecho todo esto, regresamos al archivo main.lua y dentro de love.load escribimos lo siguiente:

function love.load()

     --incluimos el archivo EscenaPrueba

     escena=require("EscenaPrueba")

     --llamamos a la función load de la escena

     escena.load()

end

ya sólo nos queda incluir el resto de funciones, apoyándonos del flujo natural de love2d

function love.update(dt)

     --actualizamos la escena

     escena.update(dt)

end



function love.draw()

     --dibujamos la escena

     escena.draw()

end


Al ejecutar este ejemplo, podremos ver un cuadrado que sigue las posiciones del cursor.

Sin ver el gestor, ya nos damos cuenta de lo fácil que es manejar, de este modo, las diferentes pantallas de nuestro juego.

En otro post, explicaré como implementar el gestor, mientras tanto hasta la próxima.

No hay comentarios:

Publicar un comentario