×

Langue

Fermer
Atelier 801
  • Forums
  • Dev Tracker
  • Connexion
    • English Français
      Português do Brasil Español
      Türkçe Polski
      Magyar Română
      العربية Skandinavisk
      Nederlands Deutsch
      Bahasa Indonesia Русский
      中文 Filipino
      Lietuvių kalba 日本語
      Suomi עברית
      Italiano Česky
      Hrvatski Slovensky
      Български Latviešu
      Estonian
  • Langue
  • Forums
  • /
  • Transformice
  • /
  • Modules
  • /
  • Guías y Tutoriales
  • /
  • Serie Tuttorials - Tutoriales de Hina
1 / 2 › »
Serie Tuttorials - Tutoriales de Hina
Haku
« Sénateur »
1410199260000
    • Haku#0807
    • Profil
    • Derniers messages
#1
  3
  • Inicio
  • Contenido
  • Capítulo 0
  • 1.1
  • 1.2
  • 1.3
  • 1.4
  • 2.1
  • 10.1

Serie Tuttorials
Serie de tutoriales sobre la creación de Scripts
por Hinakagiyama


Bienvenido a la Serie Tuttorials de Hina. Esta será una serie de tutoriales enfocados a enseñarte a programar scripts, entender el lenguaje Lua y últimamente ayudarte a desarrollar tus propios minijuegos. Todo esto se intentará lograr por medio de un método práctico de guías que te harán crear distintos scripts explicando todo lo que está ocurriendo, un paso a la vez. Si eres un completo principiante en Lua o no sabes nada, este es un buen lugar para comenzar. También habrá tutoriales intermedios o avanzados con diferentes temáticas para que todos podamos aprender algo.

El lema de este proyecto será 'hágalo usted mismo' y 'prueba y aprende'. También es importante mencionar por si no es obvio que tienes que leer lo que está escrito a lo largo de los tutoriales. Si nunca has creado un script y quieres crear un minijuego pero no quieres leer, puedes ir olvidándote de todo. Leer es fundamental para cualquier cosa que quieras aprender.

Espero que estos tutoriales te resulten útiles. Recuerda que esta será una serie de guías que iré escribiendo periódicamente por lo que puede que en un comienzo no haya mucho que leer aún. Pero conforme vaya sacando nuevos capítulos podrás ir aprendiendo más cosas. Mientras esperas el siguiente puedes seguir aprendiendo por tu cuenta y seguir practicando lo último que has visto.



¿A quién está dirigida esta guía?

  • Personas que no sepan nada sobre scripts en TFM y quieran aprender.
  • Personas que quieran conocer mejor la API de TFM o el lenguaje Lua.
  • Personas interesadas en llegar a desarrollar un minijuego.



NOTA para iniciados: Aprender a programar requiere tiempo y dedicación. No esperes aprender todo en dos semanas ni hacer un minijuego en dos días. Por último recuerda que también debes poner de tu parte y practicar o aprender por tu cuenta.


Contenido


La idea de este proyecto es crear una guía que vaya desde cero hasta el punto en que eres capaz de desarrollar tus propias ideas y seguir por tu cuenta. Es por eso que en los primeros capítulos se verán cosas muy básicas y lo más interesante quizás venga después. No obligo a nadie a comenzar por ningún lugar y si quieres puedes echar un vistazo a los capítulos de más adelante, sin embargo lo recomendable sería que leyeras las cosas básicas y llegues a entenderlas.

Nótese que los nuevos capítulos que vaya sacando seguirán el orden pero también haré algunos más adelantados para que la gente que sabe un poco más pueda aprovechar también la guía. (Y para los impacientes). Ten en cuenta que este índice está sujeto a cambios, puesto que algunas cosas las tengo planeadas muy anticipadamente.


  • 0. Preparativos previos

    • 1. Quesos y variables
      • 1.1 Variables con nombres
      • 1.2 Variables con números
      • 1.3 Operaciones
      • 1.4 Parámetros y argumentos

    • 10. Minijuegos
      • 10.1 Rotación de mapas
      • 10.2 Bootcamp
      • 10.3 Cañones
      • 10.4


    Capítulo 0
    Preparativos previos


    En este capítulo veremos algunos requisitos o pasos previos que debemos cumplir antes de empezar a trabajar con Lua y programar nuestros scripts. Los preparativos que veremos son los siguientes:

    • Permisos para usar /lua.
    • Editor de código.
    • Prueba de /lua
    • Fiel acompañante


    Permisos para usar /lua

    Para usar el comando /lua primero necesitas estar en una tribu, tener permisos para cargar mapa y también puede que necesites el permiso de tus compañeros de tribu para cargar scripts. A nadie le gustaría que pusieran un script cuando están viendo una película o se cambie el mapa inesperadamente. Además un requisito para usar /lua es tener 100 quesos en el perfil y no haber usado hack anteriormente. Si has usado hacks en una cuenta es probable que no tengas derecho a usar el comando con esa cuenta.


    Editor de código

    Para usar /lua simplemente debes pegar o escribir directamente el código en la ventana. Pero esto es poco práctico, incómodo y no es lo ideal. Lo recomendable es usar un editor externo. Puedes usar cualquier editor de texto, incluyendo el bloc de notas de Windows, pero para hacer las cosas más prácticas y sencillas usaremos un editor más sofisticado. Yo recomiendo Notepad++ del cual tengo un hilo con más información: http://atelier801.com/topic?f=6&t=573436


    Prueba de /lua

    Cuanto tengas todo listo haremos una primera prueba para comprobar si puedes usar el comando en tu casa de tribu. Simplemente entra a tu tribu, abre la ventana de /lua y pega el siguiente código:

      print("Hola ratas")

    Deberías ver en el chat una pestaña Lua y en ella el mensaje "Hola ratas". Si todo ha funcionado correctamente entonces ya estás listo para comenzar a trabajar con /lua. Recuerda no cerrar nunca la pestaña Lua o no se volverá a abrir. Aquí aparecen los mensajes del sistema al ejecutar scripts y también los mensajes de error, además de los mensajes que mostremos con print.


    Fiel acompañante

    Para varios ejemplos a lo largo de esta serie necesitarás de otro ratón en la sala que te sirva para hacer las pruebas. Lo indicaré al comienzo del capítulo. El mejor acompañante que puedes tener es otra cuenta tuya. Si no dispones de otra cuenta simplemente puedes crear una cuenta nueva e invitarlo a tu tribu; ni si quiera es necesario reclutarlo a la tribu, basta con usar el comando /inv nombre_del_ratón para que pueda entrar a la casa. También será necesario que uses dos ventanas/pestañas con Transformice para esto.

    Capítulo 1
    Quesos y variables

    1.1
    Variables con nombres


    /!\ Se recomienda tener a un ratón acompañante para este capítulo. /!\


    En este capítulo conoceremos algunas de las funciones más sencillas de la API de TFM. Funciones para entregar queso, matar al jugador, convertirlo en chamán, en vampiro, etc. Y aprenderás de manera práctica qué es una variable y cómo se usa.


    Nota: de ahora en adelante siempre que en alguna parte veas "Hinakagiyama" reemplázalo por tu nombre de usuario, entre comillas.
    También reemplaza "Violetanose" por el nombre de tu acompañante.



    Para empezar probaremos la siguiente línea de código:

      tfm.exec.giveCheese("Hinakagiyama")

    Al ejecutar ese código en tu tribu, tu ratón instantáneamente obtendrá el queso. Ahora que tienes queso intentemos esto:

      tfm.exec.playerVictory("Hinakagiyama")

    Tu ratón automáticamente entrará a la madriguera (¡aún si no hay ninguna en el mapa!). Esto solo funciona cuando el ratón tiene queso.




    Ahora usaremos la siguiente función para convertir a tu ratón en chamán:

      tfm.exec.setShaman("Hinakagiyama")

    Intenta poner el nombre de tu acompañante en lugar del tuyo y verás que también puedes convertirlo en chamán.

      tfm.exec.setShaman("Violetanose")




    Y ahora comenzaremos a usar variables. Primero comenzemos probando la función para matar a un ratón:

      tfm.exec.killPlayer("Hinakagiyama")

    Esto matará al instante a tu ratón. Puedes cambiar el nombre por el de tu acompañante pero en lugar de eso haremos lo siguiente:

      mouse = "Hinakagiyama"

      tfm.exec.killPlayer(mouse)

    Lo que hemos hecho aquí es crear una variable llamada mouse, dentro de ella hemos guardado el nombre de nuestro ratón. Y luego hemos usando la función para matar a nuestro ratón, pero en lugar de entregarle el nombre escrito, le hemos entregado la variable anterior. ¿Suena complicado?

    Una variable es simplemente un baúl que almacena cualquier dato. Puede ser un número, un texto como en este caso, o una tabla de datos. Intenta cambiar el contenido de la variable usando el nombre de tu acompañante:

      mouse = "Violetanose"

      tfm.exec.killPlayer(mouse)

    Como puedes ver solo hemos cambiado la primera línea, guardando el otro nombre en lugar del nuestro en la variable mouse.




    Algo importante que debes tener en cuenta es que los textos en el código, como "Violetanose", siempre van con comillas. Estos textos se llaman literales. Los nombres de las variables en cambio no son literales, son nombres que identifican a la variable en el código, y debes escribirlo siempre igual.

    No es lo mismo mouse que mOUSe o Mouse. Si hubieras escrito en el código lo siguiente:

      mouse = "Violetanose"

      tfm.exec.killPlayer(Mouse)

    Daría error porque en la segunda línea estás usando una variable que no existe (Mouse) y al no existir no contiene ningún nombre válido de ratón. También debes tener en cuenta que las variables pueden tomar el nombre que tú quieras, pero hay algunas reglas:

    • No pueden comenzar con un número
    • Solo pueden contener letras, números y guion bajo
    • Puede comenzar con guion bajo
    • No puede ser igual a una palabra clave del lenguaje Lua

    Por lo tanto algunos nombres válidos de variable serían:

      mouse
      Rata
      cajaGrande
      _TEXTO3

    Mientras que algunos nombres inválidos de variable serían:

      123mouse
      caja-grande
      ratón (las letras con tilde no se reconocen como un caracter válido en el código, pero sí puedes usar tilde en los textos)
      and (palabra clave en Lua)




    Ahora que ya sabes más sobre variables intentaremos hacer otra cosa, usando dos variables:

      mouse1 = "Hinakagiyama"
      mouse2 = "Violetanose"

      tfm.exec.setVampirePlayer(mouse1)
      tfm.exec.giveMeep(mouse2)

    El código anterior convertirá a mouse1 en un vampiro y a mouse2 le otorgará el poder de usar Meep. Primer guardamos los nombres de los jugadores dentro de las variables mouse1 y mouse2. Puedes cambiar los nombres al comienzo si quieres usar a otros jugadores, o puedes cambiar los números de las variables abajo si quieres intercambiar los roles.




    Intenta practicar con estas y otras funciones de la API usando variables. Aquí tienes una lista con las funciones simples que puedes probar de la misma forma que hemos hecho a lo largo de este capítulo:

      tfm.exec.killPlayer
      tfm.exec.respawnPlayer
      tfm.exec.setShaman
      tfm.exec.setVampirePlayer
      tfm.exec.giveCheese
      tfm.exec.playerVictory
      tfm.exec.giveMeep

    En el siguiente capítulo usaremos variables para guardar números y veremos algunas otras funciones de TFM que utilicen valores numéricos.

    Capítulo 1
    Quesos y variables

    1.2
    Variables con números


    En este capítulo usaremos valores numéricos en las nuevas funciones que vamos a ver. Y usaremos variables para almacenar estos datos numéricos. También miraremos brevemente las operaciones aritméticas.




    Comenzaremos usando movePlayer, una función para mover a un jugador al punto especificado:

      tfm.exec.movePlayer("Hinakagiyama", 700, 60)

    Esto moverá a nuestro ratón a las coordenadas (700,60) en el mapa. Más adelante veremos más sobre las coordenadas pero en este ejemplo nos mandaría a la esquina superior derecha del mapa.




    Ahora usaremos variables:

      name = "Hinakagiyama"
      x = 700
      y = 60

      tfm.exec.movePlayer(name, x, y)

    Este ejemplo hará exactamente lo mismo que el anterior, pero esta vez estamos usando variables para almacenar el nombre del jugador y ambas coordenadas a donde lo enviaremos.




    Quizás llegado a este punto ya te habrás preguntado qué ventajas puede tener usar variables. Pues imagina que no solo quieres mover al jugador a ese sitio; también quieres convertir al mismo jugador en chamán e invocar una pelota en la misma posición. Y además crear un efecto visual de teletransporte en ese mismo lugar. Si hacemos esto sin usar variables, nos quedaría lo siguiente:

      tfm.exec.movePlayer("Hinakagiyama", 700, 60)
      tfm.exec.setShaman("Hinakagiyama")
      tfm.exec.addShamanObject(6, 700, 60)
      tfm.exec.displayParticle(36, 700, 60, 0, 0, 0, 0)

    Imagina ahora que decides cambiar de jugador o modificar la posición (700,60). Tendrás que editar estos tres valores en cada línea. Imagina que no son cuatro líneas sino 300, y que en lugar de esos 3 valores tienes 8.

    En cambio si usamos variables para almacenar estos valores, tendríamos:

      name = "Hinakagiyama"
      x = 700
      y = 60

      tfm.exec.movePlayer(name, x, y)
      tfm.exec.setShaman(name)
      tfm.exec.addShamanObject(6, x, y)
      tfm.exec.displayParticle(36, x, y, 0, 0, 0, 0)

    Y ahora es muchísimo más fácil modificar los valores. Simplemente editamos las tres primeras líneas en donde declaramos nuestras variables. Cambiando el nombre "Hinakagiyama" y cambiando los números con las coordenadas.

    No te preocupes si por ahora no sabes qué es lo que hacen esas funciones abajo. Más adelante las iremos viendo en detalle. Por ahora basta con saber que hacen simplemente las cuatro cosas que nombramos antes: mover al jugador, convertirlo en chamán, añadir un objeto y mostrar un efecto visual (partícula).





    En el siguiente capítulo veremos algunas de las cosas interesantes que podemos hacer con las variables y con los números o textos en general.

    Capítulo 1
    Quesos y variables

    1.3
    Operaciones


    Ahora manipularemos las variables que ya aprendimos a usar, utilizando lo que llamamos operadores. Los operadores son símbolos que nos permiten indicarle al script que se haga una operación aritmética (matemática) o de otro tipo.



    Operadores aritméticos

    Operador DescripciónEjemplo
    +Suma: suma dos variables numéricas variable = 10 + 5 
    -Resta: resta dos variables numéricas, también sirve para indicar números negativos vidas = vidas - 1
    *Multiplicación: multiplica dos variables numéricas c = a * b
    /División: divide dos variables numéricas, entrega resultados con decimales x = 240 / i
    ^Potenciación: eleva un número a un exponente dado cuadrado = x^2


    Como puedes ver en los ejemplos, no solo utilizamos números. También usamos variables que deberían contener valores numéricos. Uno de los ejemplos es uno que aplicaremos en la práctica a la hora de hacer minijuegos donde nuestros ratones tengan vidas:

     vidas = vidas - 1

    El símbolo = no es un operador, sino un símbolo de asignación. Nos permite asignar un valor a una variable, en otras palabras guardar un valor como hemos hecho en los capítulos anteriores. Nótese que en este caso estamos usando la misma variable a la que le estamos asignando un valor. La idea es que queremos reducir el número de vidas en 1 (cuando un ratón ha muerto), entonces el nuevo valor de vidas será igual a ese valor menos 1.

    Otro de los ejemplos, en cambio, será uno que nunca usaremos en la práctica:

     variable = 10 + 5

    Simplemente podemos guardar directamente el número 15 dentro de nuestra variable, en lugar de decirle al script que haga la suma. Esto es importante porque incluso una pequeña suma consumirá tiempo y recursos a la API, por lo que idealmente querremos poner la menor cantidad de operaciones posibles y asignar directamente el número que ya sabemos que vamos a guardar (10 + 5, o sea 15).


    Asociatividad, agrupamiento y prioridad

    En primaria probablemente habrás escuchado de la propiedad asociativa de la suma y la multiplicación. Esas cosas también se aplican aquí a la hora de hacer operaciones aritméticas. El uso de paréntesis también te permite agrupar números y darles prioridad a esas operaciones, al igual que ocurre en la aritmética o álgebra convencional. Veamos el siguiente ejemplo:

     a = 2 * (4 * 3)

     b = (2 * 4) * 3

    Ambos casos entregan el mismo resultado (24). Sin embargo con la resta y división no ocurre lo mismo.

     a = (4 - 2) - 1

     b = 4 - (2 - 1)

    El resultado para a será 1 y para b será 3. Aquí es donde hablamos de la prioridad de las operaciones. Siempre aquellas operaciones que ocurren entre paréntesis tendrán prioridad sobre las que están más afuera. También algunas operaciones tienen prioridad sobre otras: la división y multiplicación siempre se calcularán antes que la suma y la resta. Por último, las operaciones siempre se harán de izquierda a derecha cuando tengan la misma prioridad.

     a = 6 - 2 - 1 * 2 + 9 / (2 + 1)

    Si puedes ver claramente el resultado de esa operación, entonces vamos por buen camino. No trabajarás con tantos números generalmente en TFM pero sí con muchas operaciones y variables. Es importante que tengas en mente siempre la prioridad o el orden de las operaciones.


    Operador de concatenación

    En casi todos los lenguajes de programación encontrarás un operador de concatenación. Concatenar es unir dos o más variables para formar una sola variable de texto (cadena). Las variables que vas a unir no necesariamente tienen que ser dos cadenas, puede ser una cadena y un número o incluso dos números. Pero vamos a los ejemplos para que veas lo que hace la concatenación.

    En Lua se concatena usando como símbolo dos puntos seguidos: ..

     texto = "Tigrounette tiene " .. 45 .. " quesos."

     -- resultado: "Tigrounette tiene 45 quesos."


    El símbolo .. ha unido tres valores en una sola variable de texto. El primero es una cadena ("Tigrounette tiene "), el segundo es un valor numérico (45) y luego otro texto ("quesos.").

    ¿Pero y no habría sido más fácil y rápido guardar directamente el texto completo dentro de la variable? Sí. Es por eso que ahora pondremos un ejemplo mucho más realista y práctico para los minijuegos:

     texto = name .. " tiene " .. quesos .. " quesos."

     -- resultado: "Hinakagiyama tiene 234 quesos."


    Aquí ya no estamos usando números, sino que usamos la variable numérica quesos en la que deberíamos tener guardado un número de quesos (por ejemplo, 234). Y también usamos una variable para poner el nombre del jugador, name. El símbolo de concatenación está uniendo una variable de texto con otro texto, una variable numérica y luego otro texto.

    Como puedes darte cuenta, la concatenación es especialmente útil para mostrar mensajes, aunque le daremos varios usos más a lo largo de nuestra experiencia con lua y la API.


    Existen más operadores además de los mencionados aquí. Hay operadores lógicos y operadores relacionales, pero los veremos más adelante cuando estudiemos las sentencias condicionales.

    Capítulo 1
    Quesos y variables

    1.4
    Parámetros y argumentos


    Hasta ahora a lo largo del tutorial hemos trabajado con varias funciones de la API, como setShaman, giveCheese o killPlayer. A todas estas funciones le hemos entregado ciertas variables, a las anteriores tres por ejemplo le entregamos el nombre de un ratón. En este capítulo aprenderemos más sobre esas variables, cómo funcionan y cómo las usaremos.



    Esos valores que entregamos a una función se llaman argumentos. Cada función en TFM y en lua tiene definida una serie de parámetros, que indican la clase de valores que debemos entregarles como argumentos.

    Analicemos la función killPlayer, según la documentación:

    • tfm.exec.killPlayer ( playerName )
       Mata al jugador seleccionado.
       Parámetros:
        - playerName (String) : el jugador a matar


    La función solo tiene un parámetro, playerName. Los parámetros de una función siempre nos indicarán algo específico que tenemos que entregarle a la hora de utilizarla. En este caso es el nombre del jugador a matar.

    Ahora, cuando llamamos a la función:

     tfm.exec.killPlayer("Hinakagiyama")

    Estamos entregándole como argumento el nombre de mi rata. Básicamente para entender la diferencia entre parámetro y argumento: una función tiene una serie de parámetros que te indica los argumentos que tienes que entregarle, qué son, cómo deben ser y para qué sirven. Para conocer los parámetros de una función, el programador debe dirigirse a la documentación de la API y buscar la función para informarse sobre su uso. En el caso de las funciones propias del lenguaje Lua, tendría que dirigirse al manual de referencia de Lua.

    Ahora has aprendido a entender la documentación, por lo que quizás puedas aventurarte a probar por tu cuenta algunas funciones, leyendo sus parámetros para saber qué argumentos tienes que entregarle.


    Los parámetros suelen ser de un tipo de datos. Los tipos de datos no los hemos mencionado pero hemos estado trabajando con ellos: los números son de tipo Int, los textos son String. También tenemos el tipo Boolean que consiste en valores verdadero o falso (true y false) y también está el tipo Table. Más adelante analizaremos mejor estos tipos.

    La idea de los tipos en los parámetros es que te indican qué tipo de argumento debes entregarle a la función. En el ejemplo anterior, killPlayer tiene un parámetro de tipo String (cadena). Por lo que no le puedes entregar un argumento de tipo Int, como tfm.exec.killPlayer(5).

    En otros lenguajes de programación las variables suelen tener un tipo fijo que no se puede cambiar. Por lo que si tienes una variable quesos = 5, no puedes decidir de pronto guardar un texto en la variable quesos. Sin embargo en Lua técnicamente no existen los tipos y todas las variables pueden poseer cualquier tipo de valor. Por lo que puedes tener una variable en la que almacenes distintos tipos de datos a lo largo del script. Esta es una de las cosas que hacen de Lua un lenguaje muy versatil y flexible.


    Ahora veremos un ejemplo con varios parámetros. La función addShamanObject que vimos algunos capítulos atrás:

     tfm.exec.addShamanObject(33, 400, 200)

    La sentencia anterior pondrá un pollo (el objeto de chamán usado como consumible) en medio de la pantalla (coordenadas 400,200 es más o menos el centro de un mapa de tamaño normal).

    Si analizamos los parámetros que usa la función mirando la documentación, verás que addShamanObject recibe muchos más argumentos de los que nosotros hemos puesto. Tiene 7 parámetros y solo le hemos pasado 3 argumentos.

    Cuando hacemos esto, lo que hace la API es recibir esos 3 argumentos, y el resto los deja con su valor por defecto (default). En este caso, los parámetros que nos han faltado son angle, xSpeed, ySpeed y ghost, que tienen valores por defecto 0, 0, 0, false, como puedes ver en la documentación.

    Siempre que una función tenga valores por defecto, estos los puedes omitir si no necesitas cambiarlos. Así te ahorras escribir la función completa, que sería esto, lo cual es equivalente a la línea anterior:

     tfm.exec.addShamanObject(33, 400, 200, 0, 0, 0, false)

    Te ahorrarás unos cuantos caracteres de código enviando solo los argumentos que necesites, siempre y cuando los parámetros tengan valor por defecto. Ten en cuenta que los parámetros tienen un orden y no puedes enviar los argumentos en el orden que quieras ni saltarte parámetros, solamente puedes omitir los que estén al final. En otros lenguajes existen formas alternativas de saltarse parámetros porque tienen tipos de datos, pero en Lua no existen estos tipos así que no puedes saltarte argumentos.

    Ahora bien, ¿qué hacen estos parámetros? ¡Puedes verlo tú mismo en la documentación! El primer parámetro es el id del objeto de chamán que queremos invocar, en este caso el 33 corresponde a un pollo. Luego vienen las coordenadas donde quieres poner el objeto, como dijimos antes, 400,200 es el centro del mapa. Luego viene el ángulo en que quieres que aparezca el objeto (0 equivale a sin rotación), velocidades x e y del objeto (0 hará que el objeto aparezca estático, aunque luego se pueda mover por efecto de gravedad, viento o fuerza), y ghost nos permite invocar el objeto fantasma/transparente (poniendo true como argumento).

    Puedes experimentar más con addShamanObject ahora que conoces mejor sus parámetros.


    Ejemplo popup

    Algunas funciones tienen parámetros que aceptan ciertos valores para hacer ciertas cosas. A veces es un número que ayuda a escoger cierta configuración o a veces podemos entregar un valor específico para que haga algo. En la API de TFM uno de estos casos muy común es el de entregar nil a ciertas funciones para que la acción se realice para todos los jugadores. A continuación se explicará mejor esta idea.

     ui.addPopup ( id, type, text, targetPlayer, x, y, width, fixedPos )

    addPopup nos permite mostrar una pequeña ventana o cuadro 'popup' en la pantalla. Existen 3 tipos de popups: cuadros de mensaje simples con un botón, cuadros con botones "sí" y "no" y cuadros de entrada de texto donde el jugador podrá escribir un texto y enviarlo.

    Para escoger entre esos tres tipos, la función usa el parámetro type, donde podemos ingresar como argumento los valores 0, 1 o 2. Cada valor corresponde a los tres tipos antes mencionados.

    El cuadro popup se mostrará en la pantalla del jugador que indiquemos en el parámetro targetPlayer. Pero si queremos enviar el cuadro a la pantalla de todos los jugadores, podemos entregar nil como argumento.

      Nota rápida:
      En Lua además de los tipos numéricos, cadenas, booleans y tablas, una variable también puede contener un valor nulo. Es decir, no poseer ningún valor, o directamente no existir. Esto se representa por la palabra clave nil. Cuando una variable no existe, su valor es nil. Pero también puedes asignar el valor nil a una variable para que deje de existir.


    Para poner en práctica lo anterior, intenta cargar este script en una sala con varios ratones:

     ui.addPopup(0, 1, "¿Te gusta el queso?", "Hinakagiyama", 300, 100, 200, true)

    Recuerda cambiar el nombre de mi rata por el tuyo. El script enviará el cuadro a tu pantalla pero el resto de jugadores no podrá verlo. Si quisieras enviar el cuadro a todos, podrías repetir la sentencia varias veces con el nombre de cada jugador, pero para eso podemos usar la utilidad que nos entrega la función de pasarle el valor nil para enviar el mensaje a todos:

     ui.addPopup(0, 1, "¿Te gusta el queso?", nil, 300, 100, 200, true)

    Solo con esa línea de código el mensaje se mostrará a todos los jugadores. Son varias las funciones en TFM que te permiten entregar nil para usar la función con todos los jugadores, como addTextArea, displayParticle, showColorPicker, entre otras.

    En unos capítulos más se explicará cómo darle una utilidad a estos mensajes de "Sí" o "No", haciendo que ocurra algo cuando el jugador conteste a la pregunta.


    Ahora ya sabes qué son los parámetros de una función y cómo saber qué argumentos debes entregarle. También deberías ser capaz de entender la documentación por tu cuenta (recuerda que Thetroz tiene la documentación traducida al español para tu comodidad). Además debes saber omitir los últimos argumentos que no necesites y saber utilizar ciertos parámetros que reciben argumentos especiales como el anterior targetPlayer que acepta el argumento nil.

    Entender el uso de las funciones de la API es una de las cosas más importantes para poder hacer todo lo que tenga que ver con TFM. Y saber entender por tu cuenta la documentación te ayudará muchísimo.

    Capítulo 2
    Estructuras de control

    2.1
    Sentencia IF


    Pero qué son todas esas palabras raras. Primero, una sentencia es una instrucción que le damos a un programa, generalmente una línea de código en nuestros scripts es una sentencia, o una llamda a una función. Las estructuras de control son herramientas que te permiten controlar el flujo de un programa. En nuestros scripts lua las instrucciones se van ejecutando por orden desde la primera línea hasta el final, pero para controlar el orden o el flujo de las cosas, usamos estas herramientas.

    En este capítulo aprenderás a usar la sentencia condicional IF, las condiciones y los operadores que usan.



    Expresión condicional

    La sentencia IF básicamente te permite hacer determinadas acciones según se cumpla una cierta condición. Esta condición puede ser que el jugador sea chamán, que el tiempo sea igual a cero, o simplemente que un número sea mayor que otro.

     if cheese == 0 then
      print("¡Se acabaron los quesos!")
    end


    Para entender esto vamos por partes. La sentencia IF tiene la siguiente estructura:

     if <condición> then
      <bloque de instrucciones>
     end


    Primero tenemos una <condición>. Una condición es una expresión que Lua evalua como verdadera o falsa. Si la condición se cumple (verdadera), se ejecutará el código que hay en el bloque de instrucciones. El bloque comienza luego de la palabra clave then y termina con el cierre end.

    Si volvemos a mirar el ejemplo anterior, veremos que nuestra condición es la siguiente:

     quesos == 0

    Esto quiere decir que la condición es que los quesos sean iguales a cero. Aquí tenemos un operador nuevo y es el de doble signo igual. En Lua == es un operador de comparación, que verifica que las variables o valores a ambos lados del signo sean iguales. Si son iguales, devolverá verdadero, en caso contrario el resultado será falso.

      Nota rápida:
      Nunca confundas == con =. El primero es un operador de comparación (igualdad). El segundo es un símbolo de asignación que guarda o asigna un valor a una variable.


    Luego de eso se ejecuta nuestro bloque de instrucciones que solo consiste en una línea para imprimir el mensaje. Ahora, ¿qué pasa si quieremos imprimir otro mensaje en caso de que sí queden quesos?


    IF, ELSE, ELSEIF

    Retomemos el ejemplo anterior y modifiquémoslo para mostrar el segundo mensaje:

     if cheese == 0 then
      print("¡Se acabaron los quesos!")
     else
      print("Aún quedan quesos.")
    end


    Ahora hemos expandido la sentencia IF añadiendo la palabra clave ELSE, que nos dirige a otro bloque de instrucciones que se ejecutará cuando la condición no se cumpla. Es decir que podríamos escribir lo anterior como pseudo-código de la siguiente forma:

     SI hay cero quesos ENTONCES
      <bloque>
     SI NO
      <bloque>


    Nótese que todo lo que está "dentro" de IF o de sus secciones ELSE lo estamos espaciando un poco agregando espacios o tabs al comienzo de la línea, esto se llama indentación y es sumamente importante para mantener el orden en el código y saber dentro de qué bloque está cada cosa. En otro capítulo hablaremos más sobre la indentación.

    Hay una última pieza del bloque IF, y son los bloques opcionales ELSEIF que nos permiten evaluar más de una condición. Iremos directo a un ejemplo:

     if time == 60 then
      print("¡Queda 1 minuto!")
     elseif time == 10 then
      print("¡Se acaba el tiempo!")
     elseif time == 0 then
      print("¡Tiempo! Se ha terminado la ronda")
     end


    Ahora el bloque cuenta con varios ELSEIF además del IF inicial. Estos cumplen básicamente la misma función pero se evalúan solo cuando la condición anterior no se ha cumplido. Es decir, si la condición en el primer IF es falsa, se salta al siguiente ELSEIF, y si esta condición tampoco se cumple, se salta al siguiente, y así.

    Nótese que en cada condición hemos evaluado el valor de time, pero podríamos evaluar cosas completamente diferentes en cada condición.

    Por último, podemos añadir también un ELSE al final de nuestro bloque IF...ELSEIF:

     if key == _up then
      print("Has pulsado la tecla arriba.")
     elseif key == _down then
      print("Has pulsado la tecla abajo.")
     elseif key == _space then
      print("Has pulsado la tecla espacio.")
     else
      print("Has pulsado otra tecla.")
     end


    El ejemplo se debería entender por sí mismo. Este bloque IF está comprobando la pulsación de teclas. Si detecta que se ha pulsado la tecla arriba, mostrará el mensaje correspondiente. Si no, se salta al siguiente elseif y comprueba si se ha pulsado la tecla abajo, si no vuelve a repetir el proceso con espacio. Por último, si no se ha cumplido ninguna de las condiciones anteriores, entonces se ejecuta el bloque ELSE, mostrando el mensaje de que se ha pulsado otra tecla.

    El bloque IF es quizás la herramienta más fundamental de todas en el control del flujo de nuestros programas. Es lo que nos ayuda a que el script tome decisiones y ejecute unas instrucciones en lugar de otras. Nos permite evaluar condiciones y analizar lo que ocurre con nuestro juego. Un ejemplo de ello es lo que acabamos de ver, pulsación de teclas.


    Operadores relacionales

    Si estuviste en el capítulo 1 recordarás que mencionamos estos operadores. En los ejemplos anteriores trabajamos con el operador ==. Este es un operador relacional o de comparación que en este caso evalúa igualdad. Ahora hablaremos sobre otros operadores.

    Estos son todos los operadores de comparación en Lua:

    Símbolo Función 
    <Menor que
    >Mayor que
    <=Menor o igual que
    >=Mayor o igual que
    ==Igual que
    ~=Distinto que


    Todos estos operadores comparan el valor a su izquierda con el valor a su derecha y, siguiendo el criterio mostrado en la tabla, devuelven verdadero o falso según se cumpla.

    Ahora hablaremos un poco sobre lo que significa verdadero y falso. En capítulos atrás hablamos sobre los tipos de datos. Los valores o variables pueden ser de tipo numérico, decimal, cadenas o incluso tablas. Y también están los valores booleanos (Boolean). Un booleano solo puede tener dos valores: true o false.

    Los operadores de la tabla reciben dos valores cuales quiera (a ambos lados del signo) y como resultado entregan un boolean que será true si la comparación se cumple y false en caso contrario.

    Puedes ver y comprobar todo esto usando un print para mostrar directamente los valores booleanos:

     bool = 5 > 2
     print(bool)


    Dentro de la variable bool guardaremos el resultado de la comparación (5 > 2). Cinco es mayor que dos por lo tanto el operador devolverá true. Si intentamos imprimir nuestro boolean se mostrará el texto true. Lua es inteligente para imprimir textos en pantalla y mostrará los booleans escritos como true o false.

    Ahora intenta el mismo ejemplo poniendo una condición que no se cumpla:

     bool = 40 < 1
     print(bool)


     bool = 7 == 6
     print(bool)


     bool = (3+1) ~= 4
     print(bool)


    Todos estos ejemplos devolverán false. El último ejemplo primero hace una suma (está entre paréntesis y además casi todas las operaciones tienen prioridad por encima de las comparaciones), y luego compara el resultado de esa suma con el valor al otro lado del símbolo. Este es el símbolo de desigualdad, por lo tanto los valores tienen que ser distintos para que se cumpla la condición. 3+1 es igual a 4 por lo tanto el resultado es falso.

    Hasta ahora ya debes tener una idea más o menos clara de cómo se escriben expresiones condicionales usando estos operadores, pero hay más cosas que pueden haber en una condición que solo estos símbolos.


    Operadores lógicos

    ¿Qué pasa si quiero comparar más de un número o evaluar más de una condición dentro de una misma expresión? ¿O si quiero comprobar que una condición se cumpla y otra no? Aquí es donde entra la magia de los operadores lógicos. Solo existen tres operadores lógicos:

     and or not

    Estos operadores hacen lo que su nombre dice. Al igual que los operadores anteriores, siempre devuelven true o false.

    AND devolverá true cuando ambas expresiones a sus lados sean verdaderas
    OR devolverá true cuando al menos una de las expresiones a sus lados sea verdadera
    NOT devolverá true cuando la expresión a su derecha sea falsa

    Todo esto se entiende mejor con ejemplos y teniendo en cuenta el significado de los operadores:

     bool = 3 < 5 and 20 < 30
     print(bool)

     -- resultado: true


     bool = 3 < 5 and 2 == 5
     print(bool)

     -- resultado: false


    En el último caso, and devolverá false porque la segunda expresión es falsa, y deben cumplirse ambas condiciones para que and devuelva verdadero.

     bool = 5 == 6 or 5 == 5
     print(bool)

     -- resultado: true


     bool = 22 > 0 or 41 > 0
     print(bool)

     -- resultado: true


     bool = 2 > 30 or 1 ~= 1
     print(bool)

     -- resultado: false


    Esta vez solo hace falta que una de las expresiones sea cierta. En el primer la segunda condición es verdadera por lo tanto devuelve true. En el segundo caso ambas son verdaderas lo cual también devuelve true. En el último caso ambas son falsas por lo tanto el resultado es false.

     bool = not 4 == 5
     print(bool)

     -- resultado: true


     bool = not true
     print(bool)

     -- resultado: false


    Primero tenemos 4 == 5, lo cual es falso. El operador not invierte el resultado de la evaluación, convirtiéndolo en true. En el segundo caso tenemos true, y el operador not lo convierte el false.

    El operador not trabaja con solo 1 expresión a su derecha. Puedes decir que es como el signo menos de los operadores lógicos.

    Como viste en el último ejemplo, podemos usar directamente las palabras true y false dentro de nuestras expresiones.

    La magia de los operadores lógicos no termina aquí. Puedes utilizar varios operadores en una misma expresión, creando condiciones como las siguientes y usarlas en bloques IF. Espero que se autoentiendan:

     if time == 0 or mice == 1 then
      print("Se ha terminado la ronda.")
     end


     if vidas > 0 and (key == _espacio or key == _s) then
      disparar(name, x, y)
     end


     if comando == "ban" and not admin[name] then
      print("Debes ser admin para poder usar este comando.")
     end


    Quizás veas algo nuevo en el último ejemplo. Más adelante veremos qué es esto, cuando hablemos sobre las tablas, una de las cosas más útiles, versátiles y quizás también complicadas de Lua.

    Si has entendido todo hasta aquí en este largo capítulo, ya tendrás una idea bastante buena de como se manejan los operadores lógicos y relacionales, y de cómo armar condiciones con ellos. Además de usarlas en bloques IFs que es donde más las usarás.

    En el siguiente capítulo haremos un ejemplo práctico donde usaremos todo lo que hemos visto en este capítulo, o casi todo, creando algo jugable. (spoilers: ratas voladoras que explotan)


    Cosas que se quedaron fuera y veremos más adelante:

    • Operadores de comparación con los distintos tipos de datos
    • Evaluar variables directamente sin operadores
    • Forma interna de evaluar todo tipo de valores en el lenguaje Lua
    • Trabajando con nil en las operaciones lógicas
    • Usando operadores lógicos con valores que no sean booleans
    • Anidamiento de sentencias IF
    • Uso de funciones dentro de una expresión condicional

    Capítulo 10
    Minijuegos

    10.1
    Rotación de mapas


    Una de las cosas más esenciales para todo minijuego que pretendamos hacer es un sistema de rotación de mapas, que vaya poniendo un nuevo mapa al finalizar una ronda según unos criterios definidos por nosotros.

    Algunas cosas que encontramos normalmente en una rotación de mapas:

      Cambio de mapa al acabar el tiempo
      Cambio de mapa al no quedar ratones vivos
      Los mapas no se repiten dos veces seguidas


    Comenzaremos haciendo la base de nuestro script con una función main y una función startGame:

      function main()
        tfm.exec.disableAutoNewGame(true)
        startGame()
      end

      function startGame()
      end

      main()

    Primero desactivamos el cambio automático de mapa, porque queremos controlar la manera en que se escoge el siguiente mapa. Si no hacemos esto los mapas cambiarán automáticamente y no nos permitirá tener nuestra propia lista de mapas a cargar. Luego llamamos a una función startGame() que usaremos para iniciar una nueva ronda. En esta función es donde controlaremos la carga del mapa.



    Ahora viene lo importante, los mapas. Para este tutorial haremos un minijuego que solo cargue mapas de Pokémon. Lo primero que haremos será añadir una lista de mapas dentro de una tabla, luego añadiremos un poco de código a nuestra función startGame para que cargue un mapa de esa lista:

      local maps = {1810386,1864223,1729924,2372033,1700658,1484328,2706423,1738989,3295997}

      function main()
        tfm.exec.disableAutoNewGame(true)
        startGame()
      end

      function startGame()
        local newMap
        newMap = math.random(#maps)
        tfm.exec.newGame(maps[newMap])
      end

      main()

    Nótese que en los mapas no hace falta añadir el @ ni usar comillas puesto que son valores numéricos. Además también pueden usarse números de mapas vanilla como 0, 1, 200, 15, 61, etc.

    En nuestra función startGame primero generaremos un número al azar entre 1 y el número de mapas (#maps). Y luego usaremos tfm.exec.newGame para cargar el mapa. Para entregarle a newGame el código del mapa simplemente utilizamos la tabla maps y le entregamos como índice el número que acabamos de generar.

    Por ejemplo si tenemos 9 mapas, nuestra función generará un número al azar entre 1 y 9. Si escogiera el 6, luego cargaría el mapa maps[6], que en este caso es 1484328.



    Si pruebas ahora el script verás como se carga un mapa al azar entre nuestra lista de mapas de Pokémon. Sin embargo ese será el único mapa que verás porque aún no hemos hecho que se termine la ronda y se cargue el siguiente mapa. Para eso ahora crearemos una función endGame:

      local maps = {1810386,1864223,1729924,2372033,1700658,1484328,2706423,1738989,3295997}

      function main()
        tfm.exec.disableAutoNewGame(true)
        startGame()
      end

      function startGame()
        local newMap
        newMap = math.random(#maps)
        tfm.exec.newGame(maps[newMap])
      end

      function endGame()
        startGame()
      end

      function eventLoop(t, tr)
        if tr <= 0 then
          endGame()
        end
      end


      main()

    Nuestra función endGame simplemente llamará a startGame para iniciar una nueva ronda. La razón para tener una función endGame es que en algún momento del desarrollo de cualquier minijuego vas a necesitar hacer cosas adicionales a la hora de finalizar la ronda (mostrar un mensaje con el ganador, borrar variables, aumentar stats, etc.).

    También añadimos eventLoop para controlar el tiempo. Como vimos al comienzo una de las cosas que buscamos es que se cambie el mapa cuando se acabe el tiempo. Para esto simplemente comprobamos que el tiempo restante (tr) sea menor o igual a cero, si es así llamamos a endGame para que finalice la ronda y se repita el ciclo.

    Ahora tienes un script que continua poniendo mapas de Pokémon en cada ronda. Pero solo se cambia el mapa al acabarse el tiempo, también debe cambiar cuando se acaben los jugadores vivos.



    Para controlar la cantidad de jugadores vivos, crearemos una variable en donde guardaremos este valor. Debemos contar la cantidad de jugadores al inicio de la ronda y restarle 1 cada vez que alguien muera o entre a la madriguera:

      local maps = {1810386,1864223,1729924,2372033,1700658,1484328,2706423,1738989,3295997}
      local playersAlive

      function main()
        tfm.exec.disableAutoNewGame(true)
        startGame()
      end

      function startGame()
        local newMap
        newMap = math.random(#maps)
        tfm.exec.newGame(maps[newMap])
      end

      function endGame()
        startGame()
      end

      function eventNewGame()
        playersAlive = 0
        for _ in pairs(tfm.get.room.playerList) do
          playersAlive = playersAlive + 1
        end
      end

      function eventPlayerRespawn(name)
        playersAlive = playersAlive + 1
      end

      function eventPlayerDied(name)
        playersAlive = playersAlive - 1
      end

      function eventPlayerWon(name)
        playersAlive = playersAlive - 1
      end


      function eventLoop(t, tr)
        if tr <= 0 then
          endGame()
        end
      end

      main()

    Primero definimos la variable. Luego dentro de eventNewGame la inicializamos a cero y contamos los jugadores, para que se haga al inicio de cada ronda. Le restamos 1 dentro de eventPlayerDied y eventPlayerWon, para que se reduzca cuando los jugadores mueran o entren a la madriguera. No hace falta hacer esto para los jugadores que dejen la sala (eventPlayerLeft) puesto que al hacerlo automáticamente morirán. También tenemos que sumarle 1 cuando alguien reviva (eventPlayerRespawn), en nuestro caso esto es necesario porque el chamán puede revivir usando una habilidad.

    Ahora añadiremos una función que revise si quedan cero jugadores para que termine la ronda:

      local maps = {1810386,1864223,1729924,2372033,1700658,1484328,2706423,1738989,3295997}
      local playersAlive

      function main()
        tfm.exec.disableAutoNewGame(true)
        startGame()
      end

      function startGame()
        local newMap
        newMap = math.random(#maps)
        tfm.exec.newGame(maps[newMap])
      end

      function endGame()
        startGame()
      end

      function eventNewGame()
        playersAlive = 0
        for _ in pairs(tfm.get.room.playerList) do
          playersAlive = playersAlive + 1
        end
      end

      function eventPlayerRespawn(name)
        playersAlive = playersAlive + 1
      end

      function eventPlayerDied(name)
        playersAlive = playersAlive - 1
        checkPlayers()
      end

      function eventPlayerWon(name)
        playersAlive = playersAlive - 1
        checkPlayers()
      end

      function checkPlayers()
        if playersAlive == 0 then
          endGame()
        end
      end


      function eventLoop(t, tr)
        if tr <= 0 then
          endGame()
        end
      end

      main()

    Esta función la llamaremos dentro de eventPlayerDied y eventPlayerWon, para que se compruebe cada vez que baje la cantidad de jugadores vivos. La función simplemente comprueba que el valor sea igual a cero (nunca debería bajar más abajo de cero).



    Llegado a este punto ya tienes una rotación de mapas funcionando. ¡Felicidades! Pero aún falta un pequeño detalle. Si tienes suficiente suerte (o mala suerte) te encontrarás con que tu script carga el mismo mapa consecutivamente. Esto es posible debido a que solo le indicamos que cogiera un mapa al azar, pero no le dijimos que escogiera uno distinto al actual.

    Para lograr esto crearemos una variable en donde guardaremos el índice del mapa actual (en este caso, un número del 1 al 9). Y a la hora de escoger uno nuevo al azar, comprobaremos que no sea igual al mapa actual que guardamos anteriormente. Solo modificaremos startGame y añadiremos la variable al comienzo:

      local maps = {1810386,1864223,1729924,2372033,1700658,1484328,2706423,1738989,3295997}
      local currentMap
      local playersAlive

      function startGame()
        local newMap
        repeat
          newMap = math.random(#maps)
        until newMap ~= currentMap
        currentMap = newMap

        tfm.exec.newGame(maps[newMap])
      end

    Lo que hará startGame ahora será básicamente seguir generando números al azar hasta que salga uno diferente al índice del mapa actual. Luego de eso guardará ese número dentro de currentMap para poder repetir el proceso en la ronda siguiente.



    Con eso ha terminado el tutorial para una rotación de mapas básica. Ahora tienes un minijuego estilo tradicional de Transformice con mapas de Pokémon solamente. A continuación tienes el código resultante completo: Rotación de mapas

    Espero que te haya servido. A partir de esta rotación base puedes elaborar todo tipo de minijuegos. Más adelante intentaremos modificarlo para crear un script de bootcamp y también un racing.



    Dernière modification le 1458688560000
    Haku
    « Sénateur »
    1410199740000
      • Haku#0807
      • Profil
      • Derniers messages
    #2
      1
    *pwet*

    (reservo)
    Musugas
    « Citoyen »
    1410201120000
      • Musugas#0000
      • Profil
      • Derniers messages
      • Tribu
    #3
      0
    Muy buena idea, espero que les sirva a muchos usuarios (incluyendome)

    Hinakagiyama a dit :
    El lema de este proyecto será 'hágalo usted mismo' y 'prueba y aprende'.

    Me encantó el lema

    Suerte :)

    Dernière modification le 1410201540000
    Bracomg
    « Citoyen »
    1410279300000
      • Bracomg#0000
      • Profil
      • Derniers messages
      • Tribu
    #4
      1
    Este hilo me esta ayudando mucho a entender lua. Muchas gracias.
    O_o
    « Censeur »
    1410378780000
      • O_o#6079
      • Profil
      • Derniers messages
    #5
      0
    Por fin un buen tutorial de lua.

    Ya que todo el resto de tutorial, bueno "tutorial" eran solo copy y paste. Con copy paste no se aprende mucho. Capaz ahora si me ponga a hacer cositas con lua.
    Barohe
    « Citoyen »
    1410543060000
      • Barohe#0000
      • Profil
      • Derniers messages
      • Tribu
    #6
      2
    El pueblo pide las siguientes partes :(
    Nicor22
    « Censeur »
    1410565740000
      • Nicor22#0000
      • Profil
      • Derniers messages
      • Tribu
    #7
      0
    Leer todo y sentir que nunca has aprendido lo necesario sobre Lua. Pues, ¡felicitaciones por el tema! Esperaré los próximos temas.
    Neelfr
    « Consul »
    1410566100000
      • Neelfr#0000
      • Profil
      • Derniers messages
    #8
      0
    Muy buen hilo, aunque no pueda usar lua, me parece genial un tutorial asi :]
    Franco
    « Citoyen »
    1410895440000
      • Franco#6354
      • Profil
      • Derniers messages
      • Tribu
    #9
      0
    Mis dieses al creador.
    Meekymoose
    « Citoyen »
    1411102680000
      • Meekymoose#0000
      • Profil
      • Derniers messages
      • Tribu
    #10
      0
    Genial tema, esperaré las siguientes partes!
    Jdkdffedogifk
    « Citoyen »
    1412890080000
      • Jdkdffedogifk#0839
      • Profil
      • Derniers messages
    #11
      0
    Buen Hilo ,Siempre Sorprendiendo xD
    Mori
    « Citoyen »
    1412993760000
      • Mori#4778
      • Profil
      • Derniers messages
      • Tribu
    #12
      0
    Apenas repaso el 1 por que no entiendo tanto el lua ... pero cuándo tenga un acompañante, lo podré hacer sin ningún problema ^^. Trataré de entender el capítulo 1 y luego empiezo con el 2.

    Gran tema
    Carocp
    « Citoyen »
    1413571140000
      • Carocp#0000
      • Profil
      • Derniers messages
      • Tribu
    #13
      0
    Muchas gracias, estaba buscando un tutorial simple y bien explicado y pues lo he encontrado. Avanza con los capítulos, adoro la manera que explicas. Felicidades ^^
    Francocpm
    « Citoyen »
    1436641320000
      • Francocpm#0000
      • Profil
      • Derniers messages
      • Tribu
    #14
      0
    Esto me ayuda a hacer un script, o a ver pokemons? .-.
    Keltcon
    « Citoyen »
    1436641920000
      • Keltcon#0000
      • Profil
      • Derniers messages
      • Tribu
    #15
      0
    ¡Excelente tutorial! Espero los próximos cápitulos.

    Barohe a dit :
    El pueblo pide las siguientes partes :(

    +1
    Luciadoseas
    « Censeur »
    1439410380000
      • Luciadoseas#0000
      • Profil
      • Derniers messages
    #16
      0
    creo que es muy basico deberias continuar el tutorial :v
    Rpaolor
    « Citoyen »
    1443223440000
      • Rpaolor#0000
      • Profil
      • Derniers messages
      • Tribu
    #17
      0
    Continua el tutorial :D, aprendi mucho
    Electra
    « Citoyen »
    1447352040000
      • Electra#2694
      • Profil
      • Derniers messages
      • Tribu
    #18
      0
    Muchas gracias, estoy desarrollando #VampireRace y la verdad este hilo me ha servido mucho.
    Ellautiy
    « Citoyen »
    1448116740000
      • Ellautiy#0000
      • Profil
      • Derniers messages
    #19
      0
    exijo la siguiente parte.
    Explicas bien ~
    Sincabellera
    « Citoyen »
    1448991360000
      • Sincabellera#0000
      • Profil
      • Derniers messages
      • Tribu
    #20
      0
    Se los comandos ,tambien como modificarlos
    pero nose como ordenarlos o terminarlos!!! e empieze un nuevo codigo
    • Forums
    • /
    • Transformice
    • /
    • Modules
    • /
    • Guías y Tutoriales
    • /
    • Serie Tuttorials - Tutoriales de Hina
    1 / 2 › »
    © Atelier801 2018

    Equipe Conditions Générales d'Utilisation Politique de Confidentialité Contact

    Version 1.27