Tercera entrega del capítulo del curso de iniciación a Lua, en ella finalizaremos nuestra escena de entrada introduciendo los conceptos de los operadores lógicos, la lectura de controles y el borrado de variables.

Para finalizar nuestra escena de entrada añadiremos una última funcionalidad, que de nuevo nos permitirá definir otro concepto: la interacción del usuario. Básicamente dicha interacción se realizará mediante los botones (controles) de la consola psp, por lo tanto deberemos definir los métodos que Lua nos ofrece para recibir la información que el usuario nos envia al pulsarlos.

Esta información en el contexto de un botón especifico nos llegará en forma de valor booleano: true si ha sido pulsado y false si no lo ha sido. Sin embargo antes deberemos leer, recibir y almacenar todos los controles para después acceder a cada uno de los datos con lo métodos diferentes para cada botón. Para ello usaremos el método Controls.read() que nos dará una información en forma de array al que tan sólo podremos acceder con unos métodos determinados para cada control, asignándose tal y como se muestra en la imagen.

El resto es tan sólo aplicar lo que conocemos sobre el esquema condicional a partir de las instrucciones if. Si un botón es pulsado, tan sólo deberemos evaluar la expresión booleana que devuelve su método tal y como se muestra en el ejemplo:

pad = Controls.read()

if pad:circle() then

end

En nuestro caso determinaremos que si el botón x es pulsado, el usuario desea saltar la escena de entrada. Por lo que al condicional que controla si ha pasado el tiempo necesario (3000 milisecs) le añadiremos mediante la operador lógica “or” la comprobación de si dicho botón ha sido pulsado. Así el condicional se cumplirá como verdadero si una de las dos comprobaciones es cierta.

if Tiempo >= 3000 or pad:cross() then

Juego.Estado = 1

Temporizador:reset(0)

Temporizador:stop()

end

Hemos visto por primera vez el concepto de operador lógico, que se encargan de establecer un nexo entre dos variables booleanas, que tan sólo pueden recibir como valor verdadero o falso, y que según el significado del operador determina si la expresión formada por dos evaluaciones booleanas unidas por él es cierta o es falsa. Por ejemplo, el operador AND sólo es verdadero cuando las dos expresiones que enlaza son ciertas.

OR

Se establece como nexo de unión entre dos o más expresiones booleanas, siendo su valor true cuando al menos una de ellas es también true.

AND

Se establece como nexo de unión entre dos o más expresiones booleanas, siendo su valor true cuando ambas también lo son.

NOT

Complementa o niega el valor al que precede. EJ: not true sería falso.

if 1 == 1 and 0 ~= 1 then

— Nexo and:Ambas comprobaciones son ciertas, por tanto toda la expresión también.

end

if 1 == 1 or 0 == 1 then

— Nexo or: Una de las dos comprobaciones es cierta, por lo tanto se cumple

end

if not false then

— Verdadera, ya que falso negado o complementado es el valor contrario (verdadero)

end

En principio ya habríamos acabado con las operaciones o objetivos que hemos definido para nuestra escena de entrada. Pero hasta el momento hemos obviado un detalle: que pasa con los datos que hemos definido para nuestra escena de entrada. La respuesta es sencilla y es que borraremos todos aquellos que ya no sean útiles para el resto del juego, ya que en caso contrario se convertirían en basura ocupando una RAM que podríamos necesitar.

Por tanto debemos especificar que variables no son dependientes o especificas de la escena de entrada. En este caso tan sólo la tabla Logo que almacena los datos de la imagen, el resto de variables nos es útil ya que es común a todo el juego. Comenzaremos definiendo el método para borrar una variable simple, y después pasaremos al método para borrar un vector (array).

Una variable es borrada o vacía desde el momento en que le asignamos el valor nil, sin embargo su como entidad sigue existiendo y por tanto ocupando un espacio en memoría. Para borrarla completamente llamaremos a un ciclo de limpiado mediante el método collectgarbage() que buscará estos valores basura o muertos y los eliminará.

Variable = 1 — variable creada

Variable = nil –contenido variable borrado

collectgarbage() –ciclo de limpieza que borra completamente la variable

Para borrar una tabla limpiamente deberemos eliminar uno a uno sus valores, o bien arriesgarnos a borrar tan sólo la referencia general arriesgándonos a errores que aparecerán sobretodo sobre variables de tipo userdata (tipos específicos de los módulos) como por ejemplo la imágenes. Dependiendo de la tabla asaremos métodos diferentes, pero en general iterativos que simplificarán el proceso. De momento no entraremos en detalles sobre como borrar eficientemente tablas, tan sólo borraremos la del ejemplo que nos ocupa eliminando cada uno de sus subíndices.

Logo.x = nil

Logo.y = nil

Logo.Img = nil

Logo = nil

collectgarbage()

Tras haber aplicado todo lo comentado hasta el momento el código de nuestra escena de entrada debería ser similar a este:

Negro = Color.new(0,0,0)

Blanco = Color.new(255,255,255)

Juego = {Estado = 0}

Logo = {x = 0, y = 40, Img = Image.load(“IMG/Logo.png”)}

Temporizador = Timer.new()

Temporizador:stop()

while Juego.Estado == 0 do

screen:clear()

pad = Controls.read()

Tiempo = Temporizador:time()

screen:blit(Logo.x, Logo.y, Logo.Img)

screen:print(120,220, “FMCDev”,Blanco)

screen:print(120,240, “http://fmcdev.es”,Blanco)

if Logo.x >= 160 then

Temporizador:start()

else

Logo.x = Logo.x + 2

end

if Tiempo >= 3000 or pad:cross() then

Temporizador:reset(0)

Temporizador:stop()

Logo.x = nil

Logo.y = nil

Logo.Img = nil

Logo = nil

Juego.Estado = 1

collectgarbage()

end

screen.flip()

screen.waitVblankStart()