Este es el curso/documentación de LuaPlayer HM7 de pipagerardo. Lo he subido debido a que su página web no está disponible debido a causas desconocidas.
Como lo he guardado en txt por mi comodidad, no tiene el mismo formato que en la web, por lo que iré editándolo poco a poco, modificando algunas cosas pero respetando la organización original del propio autor.
CURSO LUAPLAYERHM7 PARA PSP
LUAPLAYERHM7 por Homemister & PickDaT
http://luaplayerhm.xtreemhost.com/
http://www.homemister.axspace.com/LuaPlayerHM7.zip
http://luaplayerhm.xtreemhost.com/upload/LuaPlayerHM8.zip
TUTORIAL CREADO POR PIPAGERARDO.
Fecha de actualización: 4 - 6 - 2012
GRACIAS ESPECIALES A:
MIS JUEGOS LUA
CAÑONES CORAZAS: http://psp.scenebeta.com/noticia/ca-ones-corazas
http://dl.qj.net/Guns-Armors-v2.01-PSP-Homebrew-Games/pg/12/...
http://dl.qj.net/LUA-Games/pg/12/fid/17074/catid/194
ASTEROID BARRIER: http://psp.scenebeta.com/noticia/asteroid-barrier
http://pspupdates.qj.net/NeoFlash-Spring-Competition-08-Aste...
CABALLO DE COPAS: http://psp.scenebeta.com/noticia/caballo-de-copas
Palabras y caracteres reservados en LUA: (Índice)
Estas palabras y caracteres no pueden o no deben usarse para crear variables ni funciones, LUA hace distinción entre mayúsculas y minúsculas de tal manera que si se podría usar AND o AnD como nombre valido.
and break do else elseif end false for function if in local nil not or repeat return then true until while ^ # - * / % + .. < > <= >= ~= == [ ] { } "" '' ,
Palabras frecuentes en este tutorial LUA: (Índice)
nil Nulo, vacío o no existe. boolean true, false, variable de dos estados, verdadero y falso. number Cualquier número. string Cualquier carácter o cadena de caracteres. table Cualquier tabla o array. metatable Tipo especial de table. var Variable genérica, boolean, number, string o table. function Variable de Función. thread Función creada como corrutina, multiprocesos. userdata Datos cargados por el usuario como con "image.load()" color Variable de Color gráfico. table_color[r,g,b,a] Tipo especial de tabla con los componentes de un color. image Imagen, superficie gráfica, screen, archivo gráfico "PNG" o "JPG" font Fuente de texto tipo "TTF" path Dirección donde se encuentra un archivo. filename Nombre de Archivo. file Variable de Archivo, descriptor de archivo.. data Datos cargados desde un archivo. [ ] Entre corchetes opcional, salvo que sea una tabla[índice]. x Number generalmente entre 0 y 480, coordenadas X de pantalla. y Number generalmente entre 0 y 272, coordenadas Y de pantalla. ancho Number la anchura de algo. alto Number la altura de algo. timer Temporizador. music Musica tipo UNI, IT, XM, S3M, MOD, MTM, STM, DSM, MED, FAR, ULT o 669 sound Sonido tipo PCM WAV monoaural. Máximo 16 bit 22050 KHz UMD Es el disco que se inserta en la PSP. Puede ser UMD-Game, UMD-Video y UMD-Demo. firm Es el sistema operativo de la PSP, está firmado por Sony lo cual lo hace "no manipulable". kernel Es el conjunto de funciones de bajo nivel de un sistema operativo. En la PSP el más famoso es el kernel 1.50, pero actualmente se utilizan los kernel 3.xx y 4.xx. Hablando claro, si el programa "Eboot.pbp" usa funciones del kernel 1.50 y la PSP solo tiene instalado el Kernel 3.xx pues no funciona o lo hace mal. eboot.pbp Archivo ejecutable de la PSP. Consta de: param.sfo Información del eboot.pbp, nombre, tipo, firm, etc... icon0.png Icono de 144x80p que se muestra al seleccionar el eboot.pbp icon1.pmf Animación del icon0.png pic0.png Foto de 480x272p que se muestra al arrancar el eboot.pbp pic1.png Foto de 480x272p que se muestra al seleccionar el eboot.pbp snd0.at3 Música que se escucha al seleccionar el eboot.pbp data.psp Código ejecutable, realmente es un elf. data.psar Código firmado por Sony, no se puede modificar ni un solo bit. elf Es la parte de un "Eboot.pbp" donde se encuentra el código ejecutable. prx Es código auxiliar, usado para drivers y plugins adicionales.
string type( variable )
Retorna el tipo de su único argumento, codificado como string. Los posibles resultados de esta función son "nil" (un string, no el valor nil), "number", "string", "boolean, "table", "function", "thread" y "userdata".
screen:print( 10, 10, "Tipo = " .. type( "Hola" ), blanco ) -- Tipo = string screen:print( 10, 20, "Tipo = " .. type( 123 ), blanco ) -- Tipo = number
nil
Variable nula, vacía, sin definir. Dicho esto vamos a ver nuestra primera variable:
_variable = nil
El nombre de la variable es "_variable" y su contenido es indefinido y nulo. Si se asigna "nil" a una variable anteriormente asignada, borra los datos que esta tuviera:
_nombre = "Gerardo" -- Asigna "Gerardo" a la variable _nombre. _nombre = nil -- Borra el contenido de la variable _nombre.
boolean
Variable de solo dos estados [true/false], verdad o falso. Es utilizada por los comparadores para decir si una comparación es cierta o falsa. También algunas funciones la utilizan para retornar si ha habido fallo u para activar laguna opción. Recuerda la función "screen:blit()
" y su parámetro "Alpha".
_boolean = ( 5 > 3 ) -- true _boolean = ( 5 < 3 ) -- false _musica = false -- variable utilizada como interruptor para apagar la música. _casado = false -- Variable con dos opciones, casado o soltero. _activo = true
number
Variable para contener números, cualquier tipo de número.
_entero = 3 _negativo = -5 _real = 3.1416 _exponencial = 314.16e-2 _EXPONENCIAL = 0.31416E1 _hexadecimal = 0xff3a -- en decimal 65338
string
Variable para contener caracteres alfanuméricos, esto es letras u números. Se pueden definir de tres maneras: con dobles comillas, comilla simple y doble corchete. Como podéis imaginar hay caracteres especiales que podrían causar problemas, para evitarlo se utilizan las siguientes secuencias de escape dentro de un "string" :
\a -- campana \b -- backspace \f -- form feed \n -- nueva línea \r -- retorno de carro \t -- tabulador horizontal \v -- tabulador vertical \\ -- contrabarra \" -- comillas dobles \' -- comilla simple \[ -- abre corchete \] -- cierra corchete
En el LuaPlayer para PSP no funcionan las siguientes secuencias de escape a la hora de escribirlas en pantalla con la función screen:print()
, pero si son válidas cuando se trabaja con archivos:
\a \b \f \n \r \t \v
Ejemplos:
_string_1 = "Hola mundo!" _string_2 = 'Hola mundo!' _string_3 = [[Hola mundo!]] _string_4 = 'Me dijo: "Hola" y se fue.' _string_5 = [[Me dijo: "Hola" y se fue.]] _string_6 = "1974" -- Ojo no es un "number" es un "string" _string_7 = "En 1974 nací." _string_8 = string.char( 65, 66, 67 ) -- _string_8 = "ABC" _string_9 = "\\ \" \' \[ \]" -- Mostraría esto: \ " ' [ ]
userdata
Son variables no gestionadas por el "LUA" sino por algún módulo exterior, generalmente hecho en "C". Por ejemplo los colores, las imágenes o superficies, los sonidos y las músicas, fuentes de texto, etc...
_color = Color.new( _rojo, _verde, _azul ) -- "userdata" _imagen = Image.createEmpty( _ancho, _alto ) -- "userdata"
function
Las funciones tienen un nombre y este al fin y al cabo es una variable. Realmente contiene la dirección de memoria donde ha sido alojada la función propiamente dicha.
suma = function( a, b ) return a + b end -- suma -> "function"
thread
Mas adelante veremos como pueden ejecutarse varias funciones a la vez gracias a las corrutinas, este tipo de función multitarea es llamada "thread":
co = coroutine.create( function ( n, m ) for i = 1, m do n = n + m coroutine.yield() end return n end ) -- co -> "thread"
table
Este tipo de variable lo es todo. Una tabla no es más que una variable que contiene un grupo de variables de cualquier tipo. Una tabla puede contener varios "numbers", varios "string", incluso una tabla puede contener otra tabla. Es mas puede contener diferentes tipos de variables. Ejemplo:
_table_1 = {} --> variable de tipo "table" vacía, nula. _table_1 = { 3, 4, 6 } --> tabla "number" de tres elementos. _table_1[3] = 6 --> Asignación del valor 6 al tercer índice de la tabla. _table_3 = { { 1, 2, 3 }, --> tabla "number" de 6 elementos dispuestos en 2 { 4, 5, 6 } } --> columnas. También llamado "Array" de 2 dimensiones _table_3[2][3] = 6 _table_2 = { {},{} } -- Constructor de tabla de dos dimensiones _table_2[1][1] = 1 -- Asignación de valores. _table_2[1][2] = 2 _table_2[1][3] = 3 _table_2[2][1] = 4 _table_2[2][2] = 5 _table_2[2][3] = 6 _table_4 = {} -- Constructor primera dimensión. _table_4[3] = 5 _table_4[3] = {} -- Constructor segunda dimensión. _table_4[3][2] = 6 _punto = { nombre = "A", --> "string" x = 120, --> "number" y = 100, --> "number" color = Color.new( 255, 0, 0 ) --> "userdata" } _punto.nombre = "A" _punto.x = 120 _punto.y = 100 _punto.color = Color.new( 255, 0, 0 )
local
do ... end
El sufijo "local
" delante de una variable la hace accesible solo dentro de un área local. Un área local suele estar definida por la palabra clave "do
" al comienzo y "end
" al final. También es una área local el cuerpo de las funciones, siendo aquí donde realmente es super útil. Terminada la ejecución del código que hay dentro del área local, las variables locales son destruidas y sus valores perdidos.
x = 3 do --> Comienzo área local local x = 7 screen:print( 0,10, x, blanco) --> 7 end --> Fin área local screen:print( 0, 20, x, blanco ) --> 3
function diferencia_entre_suma_y_resta( a, b ) local suma = a + b local resta = a - b return suma - resta end
En LUA no existe la palabra clave "static" para crear variables estáticas dentro de una función. Esto son variables que guardan su valor entre llamadas y solo son visibles dentro de la función. Lo más parecido sería el siguiente ejemplo con el fallo de que la variable es accesible desde fuera de la propia función:
function variable_estatica() var = var or 0 -- Si no existe la crea asignándole el valor 0 var = var + 1 -- Incrementa var return var + 1 -- Retorna el valor de la variable end for x = 1, 40, 10 do screen:print( x, 0, variable_estatica(), blanco) end -- Este código imprimiría en la pantalla: 1 2 3 4
Expresiones, operadores booleanos y lógicos: (Índice)
Expresiones
Son la forma más elemental de interactuar con las variables. La mayoría solo son válidos para variables tipo "number" aunque usando metatablas se pueden especificar su comportamiento respecto a los distintos tipos de variables del LUA. Toman uno o dos operadores y les asignan una expresión matemática simple ( +, -, *, /, %, ^ )
=
"Asignación"
Asignación (no confundir con "==" igual ), como su nombre indica sirve para asignar algo a una variable, puede ser otra variable o un valor introducido directamente.
a = 125 -- Asignamos directamente el valor 125 a la variable a a, b = 125, 5 -- Igual que: a = 125; b = 50 a, b, c = 125, 50 -- Igual que: a = 125, b = 50, c = nil a, b = b, a -- Intercambia los valores de a y b, ahora: a = 50; b = 125
+
"Suma" Adición, operación matemática simple. "number"
a = 3 + 5 -- Igual a: a = 8 b = a + 1 -- Igual a: b = 9 c = "Hola" + 5 -- Error d = 5 + "5" -- Igual a: d = 10 -- Auto conversión a number "tonumber()" e = "6" + "6" -- Igual a: e = 12 -- Auto conversión a number "tonumber()"
-
"Resta" Substracción, operación matemática simple. "number"
x = 5 - 3 -- Igual a: x = 2 y = 3 - 5 -- Igual a: y = -2 z = x + y -- Igual a: z = 0
-
"Unario" Cambia el signo a un número. "number"
x, y = 7, -4 x = -x -- Igual a: x = -7 y = -y -- Igual a: y = 4
*
"Multiplicación" Operación matemática simple. "number"
d = 4 * 5 -- Igual a: d = 20 d = d * 2 -- Igual a: d = 40 n = 5 * -1 -- Igual a: n = -5 p = -5 * -1 -- Igual a: p = 5
/
"División" Operación matemática simple. "number"
d = 10 / 2 -- Igual a: d = 5 e = 7 / 2 -- Igual a: e = 3.5 f = 5 / 0.5 -- Igual a: f = 10
%
"Resto división" Calcula el resto de una división. "number"
a % b == a - math.floor(a/b)*b r = 7 % 2 -- Igual a: r = 1 r = 10 % 2 -- Igual a: r = 0 f = 5 / 0.5 -- Igual a: f = 10
^
"Potencia" Multiplica el primer operador entre sí tantas veces como el segundo operando. "number"
p = 2 ^ 3 -- Igual a: p = 2 * 2 * 2 p = 4 ^0.5 -- Igual a: p = 2
#
"Tamaño" Obtiene el tamaño de una "table" o "string"
pstring = "Hola" table = {1, 2, 4, 7} x = #string -- Igual a: x = 4 x = #table -- Igual a: x = 4
..
"Concatenación" Junta sus factores creando un string que es la unión de ellos.
"Mari" .. "posa" -- Igual a: "Mariposa" "File_" .. 5 -- Igual a: "File_5" 5 .. 5 -- Igual a: "55" "A" .. "B" .. "C" -- Igual a: "ABC"
OPERADORES BOOLEANOS
Sirven para comparar dos expresiones y siempre retornan uno de estos dos estados, verdadero o falso. Por eso se les llama operadores booleanos.
==
"Igualdad" Verifica la igualdad de las dos expresiones.
5 == 5 -- Igual a: true 5 == 6 -- Igual a: false 5 + 3 == 8 + 2 -- Igual a: true a = 5 -- Asignamos el valor 5 a la variable a. a == 5 -- Igual a: true
~=
"Distinto" Es lo contrario de la igualdad.
5 ~= 6 -- Igual a: true 5 ~= 5 -- Igual a: false
>
"Mayor" Verifica si el primer operador es mayor que el segundo.
5 > 2 -- Igual a: true 5 > 8 -- Igual a: false 5 > 5 -- Igual a: false
>=
"Mayor o igual" Verifica si el primer operador es mayor o igual que el segundo.
5 >= 2 -- Igual a: true 5 >= 8 -- Igual a: false 5 >= 5 -- Igual a: true
<
"Menor" Verifica si el primer operador es menor que el segundo.
5 < 2 -- Igual a: false 5 < 8 -- Igual a: true 5 < 5 -- Igual a: false
<=
"Menor o igual" Verifica si el primer operador es menor o igual que el segundo.
5 <= 2 -- Igual a: true 5 <= 8 -- Igual a: true 5 <= 5 -- Igual a: false
OPERADORES LOGICOS
Son tres: "or
", "and
" y "not
". Equivalen a "O", "Y", "Negación". Trabajan evaluando una lógica entre sus dos operadores.
or
"O"
Si una de las dos expresiones es cierta o existe la retorna. Si las dos son ciertas o existen retorna la primera.
false or false --> false false or true --> true truo or false --> true true or true --> true false or nil --> nil true or nil --> true nil or false --> false nil or true --> true 10 or 20 --> 10 20 or 10 --> 20 nil or 20 --> 20 20 or nil --> 20
x = nil x = x or 5 --> x = 5 x = 8 x = x or 5 --> x = 8
and
"Y"
Las dos expresiones deben ser ciertas para retornar "true". Si dos expresiones existen retorna la segunda.
false and false --> false false and true --> false true and false --> false true and true --> true false and nil --> false true and nil --> nil nil and false --> nil nil and true --> nil 10 and 20 --> 20 20 and 10 --> 10 nil and 20 --> nil 20 and nil --> nil
a = 8 ; b = 3 c = 3; d = 8 c = ( a > b ) and a or b --> c = a d = ( c > d ) and a or b --> d = b
not
"Negación" Niega la expresión.
not false --> true not true --> false not nil --> true not 20 --> false
PRIORIDAD ENTRE EXPRESIONES Y OPERADORES:
En LUA al igual que en otros lenguajes existe una prioridad entre Expresiones y Operadores. Algunos tienen prioridad sobre otros y viceversa. Si son del mismo rango se aplican empezando por la izquierda hasta llegar a otro de diferente rango.
1º or 2º and 3º < > <= >= ~= == 4º .. 5º + - 6º * / % 7º not # - (unario) 8º ^
Ejemplos :
a = 5 > 2 + 4 Es igual a: false porque: ( 5 > 2 ) a = 5 > (2 + 4 ) Es igual a: true porque: ( 5 > 7 ) a = 5 + 2 * 2 Es igual a: a = 5 + ( 2 * 2 ) Resultado: 9 no 14 Cuidado: 5 + 2 * 2 No es igual que: ( 5 + 2 ) * 2
Control de flujo del programa: (Índice)
if _exp then ... end
if _exp then ... else ... end
if _exp1 then ... elseif _exp2 then ... else ... end
Es el condicional por excelencia, significa: "Si se cumple tal expresión entonces haz esto, sino haz lo otro." Tiene tres posibles formas desde la más simple hasta los condicionales encadenados:
if _exp then ... end
Es la más simple forma de "if
" dice así: "Si se cumple la expresión haz lo siguiente."
x , y = 2, 7 if x < y then x = y -- Si se cumple: x = y end -- Igual a: x = ( x < y ) and y or x Resultado: x = 7
if _exp then ... else ... end
Igual que la anterior pero si no se cumple la condición también hace algo: "Si se cumple la expresión haz esto, si no haz lo otro."
x , y = 7 , 2 if x < y then x = y -- Si se cumple: x = y else y = y +1 -- Si no se cumple: y = y + 1 end Resultado: y = 3
if _exp1 then ... elseif _exp2 then ... else ... end
Este es un "if
" encadenado en el cual se evalúan múltiples expresiones hasta que se cumple una.
x = 2 if x == 1 then y = 8 elseif x == 2 then y = 12 elseif x == 3 then y = 24 else y = 56 end Resultado: y = 12
for _var =_exp1 , _exp2 do ... end
for _var_1, ..., _var_n in _funcion_iteradora do ... end
Los bucles "for
" sirven para recorrer variables en un intervalo. Si el intervalo no es especificado se asume como un incremento de una unidad. Vamos a ver un ejemplo con el bucle "for
" más simple posible.
y = 0 for x = 1, 10, 2 do -- Asignará a x los valores 1, 3, 5, 7 y 9. screen:print( 0, y, "x = " .. x, blanco ) y = y + 10 end
Un intervalo negativo sirve para realizar una cuenta atrás:
y = 0 for x = 10, 1, -1 do -- Asignará a x los valores 10, 9, 8, 7, 6, 5, 4, 3, 2 y 1. screen:print( 0, y, "x = " .. x, blanco ) y = y + 10 end
Para casos más complejos el bucle "for
" admite usar una función iteradora que le diga la forma de recorrer una variable. El LUA tiene funciones iteradoras para recorrer tablas y archivos como: ipairs()
, pairs()
, next()
, files()
, etc. Para esto hay que usar la palabra clave "in
" dentro de la construcción "for
". Ver el siguiente ejemplo que imprime en pantalla todos los elementos de una tabla de índices numéricos:
y = 0 table = {"one", "two", "three"} for indice, valor in ipairs( table ) do screen:print( 0, y, indice .."-".. valor, blanco ) y = y + 10 end
Esta función viene ya hecha, pero vamos ha hacerla nosotros para ver como funciona. Primero haremos una función iteradora que dada una tabla y un índice, incrementa el índice y lo retorna más el valor al índice asignado dentro de la tabla.
function iteradora(table, indice) indice = indice + 1 local valor = table[indice] if valor then return indice, valor end end
Luego creamos la función "nuestra_ipairs()
" que va ha hacer lo mismo que la función estándar del LUA "ipairs()
". Toma una tabla y si el índice es valido retorna la función iteradora, sino retorna la propia tabla y 0 como índice:
function nuestra_ipairs( table ) return iteradora, table, 0 end
Con las dos funciones anteriores ahora hacemos la siguiente construcción que funcionará exactamente igual que si usamos la función estándar "ipairs()
" :
y = 0 a = {"one", "two", "three"} for i, v in nuestra_ipairs(a) do screen:print( 0, y, i .."-".. v, blanco ) y = y + 10 end
while _expresion do ... end
Este comando del LUA repite un área local o bloque mientras es verdadera una expresión. Traducido significa: Mientras se cumpla la expresión haz esto. Si no se cumple la condición al menos una vez, no ejecuta el código de la área local. En el primer ejemplo hacemos lo mismo que usando "for x = 1, 10, do ... end
", imprimirá en pantalla los valores de x desde el 1 al 10:
while true do código end -- Bucle infinito ejecutando "código" while false do código end -- No ejecuta ni una vez el "código"
x , y = 1 , 0 while x <= 10 do screen:print( 0, y, "x = " .. x, blanco ) -- x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 y 10 ] x , y = x + 1, y + 10 end screen:print( 0, y, "x = " .. x, blanco ) -- x = 11
Veamos el siguiente ejemplo para ver que pasa si no se cumple la expresión ni una sola vez, como x es mayor o igual que 10, no se ejecutará el código del área local ni se imprimirá nada en pantalla:
x , y = 15 , 0 while x <= 10 do screen:print( 0, y, "x = " .. x, blanco ) -- Nada será imprimido en pantalla. x , y = x + 1, y + 10 end screen:print( 0, y, "x = " .. x, blanco ) -- x = 15
repeat ... until _expresion
Este comando es prácticamente igual que el anterior "while
", la diferencia es que la evaluación de la expresión se realiza al final del área local, por lo cual aunque no se cumpla la expresión ni una sola vez, por lo menos se ejecuta el código del área local una vez. Significa: Repite esto hasta que se cumpla la expresión.
repeat código until false -- Bucle infinito ejecutando "código" repeat código until true -- Ejecuta una vez "código"
x , y = 1 , 0 repeat screen:print( 0, y, "x = " .. x, blanco ) -- x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 y 10 ] x , y = x + 1, y + 10 until x > 10 -- Ahora solo ">" en vez de "<=" screen:print( 0, y, "x = " .. x, blanco ) -- x = 11
Ahora veremos que pasa si no se cumple ni una sola vez la expresión. Si no se cumple, al estar la evaluación al final del área local, el código se ejecuta una vez. Esta es la gran diferencia entre "while
" y "repeat
" :
x , y = 20 , 0 repeat screen:print( 0, y, "x = " .. x, blanco ) -- x = 20 x , y = x + 1, y + 10 until x > 10 screen:print( 0, y, "x = " .. x, blanco ) -- x = 2
break
Rompe los bucles "for
", "repeat ... until
" y "while
"
y = 0 for x = 1, 10 do -- Imprimirá: x = [ 1, 2, 3, 4, 5 y 6 ] screen:print( 0, y, "x = " .. x , blanco) y = y + 10 if x > 5 then break end -- Si x > 5 rompe el bucle "for" end
x, y = 1, 0 while true do -- Bucle infinito, siempre verdadero. screen:print( 0, y, "x = " .. x , blanco) -- Imprimirá: x = [ 1, 2, 3, 4 y 5 ] x, y = x + 1, y + 10 if x > 5 then break end -- Si x > 5 rompe el bucle "while" end
x, y = 1, 0 repeat screen:print( 0, y, "x = " .. x , blanco) -- Imprimirá: x = [ 1, 2, 3, 4 y 5 ] x, y = x + 1, y + 10 if x > 5 then break end -- Si x > 5 rompe el bucle "repeat" until false -- Bucle infinito, siempre verdadero.
Controls.read()
Esta función captura las teclas pulsadas en el teclado de la PSP. Depende del uso retorna un "boolean
", "true
" o "false
" si se a pulsado la tecla, o un "number
". Si se opera con "number
" a través de las máscaras de bits "Mask" se pueden conseguir combinaciones de botones más fácilmente que de la otra forma.
El mando analógico siempre retorna "number
" en un rango de [-127 a 128] para sus dos ejes.
pad = Controls.read() boolean pad:select() boolean Controls.read():select() boolean pad:start() boolean Controls.read():start() boolean pad:up() boolean Controls.read():up() boolean pad:right() boolean Controls.read():right() boolean pad:down() boolean Controls.read():down() boolean pad:left() boolean Controls.read():left() boolean pad:l() boolean Controls.read():l() boolean pad:r() boolean Controls.read():r() boolean pad:triangle() boolean Controls.read():triangle() boolean pad:circle() boolean Controls.read():circle() boolean pad:cross() boolean Controls.read():cross() boolean pad:square() boolean Controls.read():square() boolean pad:home() boolean Controls.read():home() boolean pad:hold() boolean Controls.read():hold() boolean pad:note() boolean Controls.read():note() number pad:analogX() number Controls.read():analogX() -- Rango de -127 a 128. number pad:analogY( number Controls.read():analogY() -- Rango de -127 a 128.
pad = Controls.read() -- Version "number" con máscaras de bits. number pad:buttons() number Controls.read():buttons() number Controls.selectMask number Controls.triangleMask number Controls.startMask number Controls.circleMask number Controls.upMask number Controls.crossMask number Controls.rightMask number Controls.squareMask number Controls.downMask number Controls.homeMask number Controls.leftMask number Controls.holdMask number Controls.ltriggerMask number Controls.noteMask number Controls.rtriggerMask
LuaPlayerHM8:
number Controls.wlan() Interruptor WLAN. Retorna 1 para encendido y 0 para apagado.
Ejemplo, el teclado de la PSP:
blanco = Color.new( 255, 255, 255 ) negro = Color.new( 0, 0, 0 ) while true do screen:clear( negro ) pad = Controls.read() if pad:up() then screen:print( 10, 0, "Arriba", blanco ) end if pad:down() then screen:print( 10, 10, "Abajo", blanco ) end if pad:right() then screen:print( 10, 20, "Derecha", blanco ) end if pad:left() then screen:print( 10, 30, "Izquierda", blanco ) end if pad:cross() then screen:print( 10, 40, "Cruz", blanco ) end if pad:circle() then screen:print( 10, 50, "Circulo", blanco ) end if pad:triangle() then screen:print( 10, 60, "Triangulo", blanco ) end if pad:square() then screen:print( 10, 70, "Cuadrado", blanco ) end if pad:r() then screen:print( 10, 80, "Gatillo Derecho", blanco ) end if pad:l() then screen:print( 10, 90, "Gatillo Izquierdo", blanco ) end if pad:start() then screen:print( 10, 100, "Start", blanco ) end if pad:select() then screen:print( 10, 110, "Select", blanco ) end if pad:home() then screen:print( 10, 120, "Home", blanco ) end if pad:note() then screen:print( 10, 130, "Note", blanco ) end if pad:hold() then screen:print( 10, 140, "Hold", blanco ) end analogico_x = pad:analogX() ; analogico_y = pad:analogY() screen:print( 10, 150, "Analogico_X = " .. analogico_x, blanco ) screen:print( 10, 160, "Analogico_Y = " .. analogico_y, blanco ) screen.flip() ; screen.waitVblankStart( 2 ) end
Ejemplo de una pausa hasta pulsar "X":
screen:print( 10, 10, 'Pulse "X" para continuar.' , blanco ) screen.waitVblankStart( ) ; screen.flip() repeat screen.waitVblankStart( 2 ) until Controls.read():cross()
Ejemplo de un MENU de selección:
pad, oldad = Controls.read(), pad blanco = Color.new ( 255, 255, 255 ) ; negro = Color.new ( 0, 0, 0 ) patada = Controls.crossMask ; n_patada = 0 golpe = Controls.circleMask ; n_golpe = 0 combo_1 = Controls.rightMask + Controls.crossMask ; n_combo_1 = 0 combo_2 = Controls.downMask + Controls.rightMask + Controls.crossMask ; n_combo_2 = 0 esp_combo = Controls.leftMask esp_combo = esp_combo + Controls.leftMask + Controls.downMask esp_combo = esp_combo + Controls.downMask esp_combo = esp_combo + Controls.downMask + Controls.rightMask esp_combo = esp_combo + Controls.rightMask esp = 0 ; n_esp = 0 esp_t = Timer.new() ; tiempo = Timer.new() ; tiempo:start() repeat pad = Controls.read() screen:clear( negro ) screen:print(110, 36, "Haz 5 golpes de cada en 20 segundos." , blanco) screen:print(120, 46, "Tiempo = ".. math.floor( tiempo:time() / 1000 ) , blanco) screen:print(120, 66, "Patada ( X ) = ".. n_patada , blanco) screen:print(120, 76, "Golpe ( O ) = ".. n_golpe , blanco) screen:print(120, 86, "Combo 1 ( > + X ) = ".. n_combo_1 , blanco) screen:print(120, 96, "Combo 2 ( V + > + X ) = ".. n_combo_2 , blanco) screen:print(120, 106, "Especial ( < + v + > ) = ".. n_esp , blanco) screen:print(120, 126, "Mascara = " .. pad:buttons() , blanco) if pad:buttons() == Controls.leftMask then esp = Controls.leftMask esp_t:stop(); esp_t:reset(0); esp_t:start() elseif esp_t:time() < 500 and pad:buttons() ~= oldpad:buttons() then esp = esp + pad:buttons() elseif esp_t:time() >= 500 then esp_t:stop(); esp_t:reset(0); esp = 0 end if esp == esp_combo then esp = 0 ; n_esp = n_esp + 1 elseif pad:buttons() == patada and oldpad:buttons() ~= patada then n_patada = n_patada + 1 elseif pad:buttons() == golpe and oldpad:buttons() ~= golpe then n_golpe = n_golpe + 1 elseif pad:buttons() == combo_1 and oldpad:buttons() ~= combo_1 then n_combo_1 = n_combo_1 + 1 elseif pad:buttons() == combo_2 and oldpad:buttons() ~= combo_2 then n_combo_2 = n_combo_2 + 2 end oldpad = pad screen.waitVblankStart(2); screen.flip() until tiempo:time() > 20500 tiempo:stop(); esp_t:stop(); screen.waitVblankStart(120) System.Quit()
System.message()
Imprime un mensaje a la pantalla con las opciones: "Yes, No and back." "Sí, no, y volver".
System.message("Hola",0) -- muestra solo la opcion de " back" "volver". System.message("Hola",1) -- muestra las opciones: "Yes, No and back." "Sí, no, y volver".
System.buttonPressed()
Retorna la acción de la opción seleccionada en la función System.message(). Utilice "1" para retornar un string "Yes/No" o "0" para retornar "number" "1/0".
button = System.buttonPressed(1) ; If button == "yes" then System.Quit() end button = System.buttonPressed(0) ; If button == 1 then System.Quit() end
string System.startOSK( string_defecto , string_mensaje )
Muestra el teclado en pantalla.
isoname = System.startOSK( "ms0:/ISO/*.ISO", "Enter Name and Path" ) screen:print( 1, 1, isoname, red )
color = Color.new( rojo_0-255 , verde_0-255 , azul_0-255 [ , alpha_0-255 ] )
Crea un color a base de sus componentes roja, verde y azul. Además se puede definir la opacidad o la transparencia del color con una tercera componente llamada "alpha". Estas componentes tienen un valor numérico entre 0 y 255, siendo 0 la ausencia de color u opacidad y 255 la máxima cantidad de color u opacidad. Un color con opacidad 0 es totalmente transparente.
blanco = Color.new( 255, 255, 255 ) negro = Color.new( 0, 0, 0 ) gris = Color.new( 127, 127, 127 ) rojo = Color.new( 255, 0, 0 ) verde = Color.new( 0, 255, 0 ) azul = Color.new( 0, 0, 255 ) gris_translucido = Color.new( 127, 127, 127, 127 )
nil image:clear( color )
Pinta o borra una imagen con el color dado.
azul = Color.new( 0, 0, 255 ) screen:clear( azul ) -- Borra una imagen rellenándola con un color. screen.flip() -- Muestra la pantalla pintada de azul.
nil image:print( x, y, var, color)
Escribe en la posición dada de una imagen y con un color definido un "string", "number" o "table". Si la variable es del tipo "boolean" escribirá "true" o "false" según su estado. También permite la concatenación ".." de dos "string" u operaciones matemáticas "+, -, *, /, etc"
"Mari" .. "posa" == "Mariposa" == 'Mariposa' == [[Mariposa]] "Archivo_" .. 2 == "Archivo_2" "Dijo: \"Adiós\" y se fue." == 'Dijo: "Adiós" y se fue.' == [[Dijo: "Adiós" y se fue.]]
Por desgracia para nosotros de momento no son soportados ciertos caracteres en LUA, aunque no muestren error si que muestran caracteres extraños cuando se intenta escribir los siguientes:
ñ, Ñ, ¿, ¡, á, é, í, ó, ú, ü, Á, É, Í, Ó, Ú, Ü, ...
blanco = Color.new( 255, 255, 255 ) texto = "Script de ejemplo" numero = 134.56 screen:print( 0, 0, texto, blanco ) -- Muestra: Script de ejemplo screen:print( 0, 10, numero, blanco ) -- Muestra: 134.56 screen:print( 0, 20, "Mari" .. "posa", blanco ) -- Muestra: Mariposa screen:print( 0, 30, "Cara\\Cruz", blanco ) -- Muestra: Cara\Cruz screen:print( 0, 30, 2 + 5 , blanco ) -- Muestra: 5 screen:print( 0, 40, math.floor( 5.6 ), blanco ) -- Muestra: 5 screen.flip()
Como hemos visto antes la función "screen:print()
" no es muy buena para nuestro idioma, así que adjunto una función llamada "escribe()
" que además de corregir los acentos y las "ñ", centra el texto en pantalla cuando las coordenadas están fuera de rango, asume como blanco el color por defecto y permite cambiar el tamaño de la letra automáticamente solo dando su tamaño en pixels:
-- escribe( [imagen,] x, y, texto [,color] [, tamanno] ) -- Función programada por pipagerado. function escribe( imagen, x, y, texto, color, tamanno ) if type( imagen ) == "number" then -- El primer argumento "imagen" es opcional if type( texto ) == "userdata" then -- El "color" y "tammano" también. tamanno = color or 8 color = texto or Color.new( 255, 255, 255 ) else tamanno = texto or 8 color = Color.new( 255, 255, 255 ) end texto = y or "nil" y = x or -1; x = imagen or -1 imagen = screen else if type( color ) == "userdata" then tamanno = tamanno or 8 color = color or Color.new( 255, 255, 255 ) else tamanno = color or 8 color = Color.new( 255, 255, 255 ) end texto= texto or "nil" y = y or -1; x = x or -1 imagen = imagen or screen end if tamanno < 8 then tamanno = 8 elseif tamanno > 80 then tamanno = 80 end if type(texto) ~= "string" then texto = tostring(texto) end local acentos, ennes, texto_f, caracter = "", "", "", "" local longitud = string.len( texto ) for c = 1, longitud do caracter = string.sub( texto, c, c ) if caracter == "á" then caracter = "a"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "é" then caracter = "e"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "í" then caracter = "i"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "ó" then caracter = "o"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "ú" then caracter = "u"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "ü" then caracter = "u"; acentos = acentos .. "^"; ennes = ennes .. " " elseif caracter == "Á" then caracter = "A"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "É" then caracter = "E"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "Í" then caracter = "I"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "Ó" then caracter = "O"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "Ú" then caracter = "U"; acentos = acentos .. "'"; ennes = ennes .. " " elseif caracter == "Ü" then caracter = "U"; acentos = acentos .. "^"; ennes = ennes .. " " elseif caracter == "¿" then caracter = "?"; acentos = acentos .. " "; ennes = ennes .. " " elseif caracter == "¡" then caracter = "!"; acentos = acentos .. " "; ennes = ennes .. " " elseif caracter == "ñ" then caracter = "n"; acentos = acentos .. " "; ennes = ennes .. "~" elseif caracter == "Ñ" then caracter = "N"; acentos = acentos .. " "; ennes = ennes .. "~" else acentos = acentos .. " "; ennes = ennes .. " " end texto_f = texto_f .. caracter end if tamanno == 8 then if x < 0 or x > 480 then x = (484 - ( longitud * tamanno )) / 2 end if y < 0 or y > 272 then y = 133 end imagen:print( x, y - 3, ennes , color ) imagen:print( x, y - 2, acentos, color ) imagen:print( x, y, texto_f, color ) else tamanno = math.floor( math.abs( tamanno ) ) if x < 0 or x > 480 then x = ( 480 - (longitud * tamanno / 1.66 ) ) / 2 end if y < 0 or y > 272 then y = 136 + ( tamanno / 2.5 ) end local z = math.ceil( y - ( tamanno / 3.5 ) ) local w = math.ceil( y - ( tamanno / 1.8 ) ) local letra = Font.createMonoSpaced() letra:setPixelSizes(0, tamanno ) imagen:fontPrint( letra, x, w, ennes, color) imagen:fontPrint( letra, x, z, acentos, color) imagen:fontPrint( letra, x, y, texto_f, color) z, w,letra = nil, nil, nil end acentos, ennes, texto_f, caracter, longitud = nil, nil, nil, nil, nil collectgarbage() end
Ejemplo de uso de la función personalizada "escribe" :
blanco = Color.new( 255, 255, 255 ) rojo = Color.new( 255, 255, 255) imagen = Image.createEmpty( 480, 272 ) escribe( screen, 10, 10, "Hola Peseperos.", blanco, 8 ) -- Color blanco, tamaño 8 pixels. escribe( 10, 10, "Hola Peseperos." ) -- Versión abreviada de la de arriba. escribe( -1, 10, "Texto centrado en horizontal.", rojo) -- Color rojo, tamaño 8 pixels escribe( 10, -1, "Texto centrado en vertical.", 20 ) -- Color blanco, tamaño 20 pixels escribe( -1, -1, "Texto centrado en pantalla.", rojo, 20 ) -- Color rojo, tamaño 20 pixels. escribe( imagen, -1, -1, 123.56 ) -- Color blanco, tamaño 20 pixels. screen:blit( 0, 0, imagen ) screen.waitVblankStart() ; screen.flip()
Fuentes de texto hasta LuaPlayerHM7
En construcción...
NekeOS, el nuevo shell para PSP
PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.
Sony Xperia Z1 Compact con Android 5.1.1
Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).
By Jorge_97
Genial!!! Muy bien Nekerafa :D Sin duda buenos tutoriales... yo los vi en su momento los del Ad Hoc, viene bien repasarlos
Un saludo
Have a nice day
Dos años en SCENEBETA
Click aquí para ver la Entrada de Bitácora.
XD
Agradeceselo a pipagerardo, jejeje, y a mi astucia de guardarlo en mi HDD (Es que cuando iba de viaje no tenía una tarifa plana en el movil como ahora, y así podría verlo desde la propia PSP)
NekeOS, el nuevo shell para PSP
PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.
Sony Xperia Z1 Compact con Android 5.1.1
Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).
yo lo tengo en .html, si
yo lo tengo en .html, si quieres te lo paso.
Oh!
Mucho mejor estaría, aunque estoy editandole para dejarlo mejor, creo que avanzaría más rápido. Ok, pasamelo.
aqui esta
aqui esta http://www.mediafire.com/view/?ja0l7z86lqn0tbd
Mmm...
Muchísimas gracias.
Aún así tengo que editar algunas cosas del tutorial original para que se vea bién en SceneBeta
Me parece bn que hagas esto
Me parece bn que hagas esto Neke lastima porque nos irian bn unos en luadev ,a mi sobre todo sobre la manipulacion de archivos,(conste que prometiste hacer unos tutos sobre algunos modulos xD)
Suerte amigo.
Mmm...
Pues ya no me acuerdo...
Lo que me acuerdo es que dije que iba a volver a colgar este tutorial (Aunque sale para LuaPlayer HM7, muchos módulos sirven en LuaDEV, como los de archivos, sockets, tablas, strings, etc...), acabar los tutos de PS3 (a ver cuando me pongo a ello), subir una documentación entera de todo lo que conocemos de LuaDEV (a ver cuando me pongo a ello XD), y subir todos mis proyectos (Tengo más de dos) y actualizarlos.
Pero como te dije, los módulos generales, que sirven para todos, los puedes ver en la documentación oficial de Lua (No me canso de repetirlo XD), donde sale toda la documentación sobre manipulación de archivos.
NekeOS, el nuevo shell para PSP
PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.
Sony Xperia Z1 Compact con Android 5.1.1
Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).
Ok Ok ya entendi
Ok Ok ya entendi