×

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
  • /
  • [Module API] [Tutorial] Free For All
[Module API] [Tutorial] Free For All
Gaston
« Censeur »
1380986580000
    • Gaston#1499
    • Profil
    • Derniers messages
    • Tribu
#1
  0
En este tutorial vamos a abarcar el minijuego FFA/Deathmatch, y los diferentes aspectos que se deben tener en cuenta. Esto incluye tiros de cañones, la conjugación de ellos, impedir que la gente dispare constantemente, y que cada jugador tenga sus propios ajustes personalizados.


http://i.imgur.com/4vSFf.png
Vamos a empezar por la unión de las teclas que necesitamos para cada usuario que está en la sala y que se una. Para hacerlo con eficacia pondremos el código en eventNewPlayer, y a continuación, ejecutamos esa función para todos en la sala ya que comienza.

Los códigos de teclas que se van a utilizar son 32, 40 y 83, que son el espacio, flecha hacia abajo y S, respectivamente. Estas teclas dispararán un cañón cuando alguien lo presiona. El circuito de las teclas a través de éstas se escribirán con tfm.exec.bindKeyboard una vez hecho.

a dit :

function eventNewPlayer(name)
for i,key in ipairs({32,40,83}) do
tfm.exec.bindKeyboard(name,key,true,true)
end
end

for name,player in pairs(tfm.get.room.playerList) do
eventNewPlayer(name)
end

http://i.imgur.com/4vSFf.png
Ahora que las teclas están vinculadas, tienen que ser utilizadas, el cañón se enviará en la dirección en la que el usuario se enfrenta. Primero debemos verificar la tecla para ver si el script será útil para que no tenga más claves en el futuro.

La tabla playerList tiene una variable llamada "isFacingRight". Este "boolean" (tipo de dato lógico) es verdadero si el jugador se enfrenta a la derecha en el tiempo, y falso si no lo es. Con esto se puede determinar la dirección en la que el usuario se enfrenta y en qué dirección se dispararán los cañones.

Durante la conjugación de los cañones, el ID 19 se creará a la derecha, mientras que el 20 se creará a la izquierda. Tiene que ser generado con las coordenadas del jugador, ya que pulsa la tecla, cual eventKeyboard vuelve a nosotros cuando un jugador pulsa la tecla.

Una cosa adicional a tener en cuenta es que los jugadores no deberían ser capaces de disparar cuando están muertos, lo que es una cosa esencial en el juego, por lo que el control de boolean para cada jugador se almacena en playerList para detectar si están muertos o no.

a dit :

function eventKeyboard(name,key,down,x,y)
if (key==32 or key==40 or key==83) and not tfm.get.room.playerList[name].isDead then
if tfm.get.room.playerList[name].isFacingRight then
tfm.exec.addShamanObject(19,x,y)
else
tfm.exec.addShamanObject(20,x,y)
end
end
end

http://i.imgur.com/4vSFf.png
En este punto tenemos una guía de trabajo de script free-for-all (gratis para todos) en donde cualquier persona puede disparar cañones cuando guste.

El siguiente paso es detener a los jugadores a disparar tan rápido. Para ello, vamos a comprobar el os.time() siempre que el jugador presione una tecla; esta función da la hora actual del sistema en minisegundos, por ejemplo 1380530062. Si el tiempo ha incrementado en 1000, un segundo ha pasado, así que podremos usar esto para almacenar la información que necesitamos, para determinar cuan frecuente el usuario puede disparar.

Cada jugador tendrá este valor almacenado de forma individual, por lo que una tabla puede almacenar esto, llamémosle "jugadores". Cada jugador tendrá su propia tabla donde deberá almacenar la información que necesitemos, así que podemos añadir el eventNewPlayer().

a dit :

players={}

function eventNewPlayer(name)
players[name]={
timestamp=os.time()
}
end

Como se puede ver, la variable llamada "timestamp" (marca de tiempo) dentro de esta tabla se utiliza para mantener el tiempo necesario.

Ahora que el valor se guardó, cuando el os.time() es comprobado nuevamente pulsando una tecla que se puede comparar con el valor almacenado que es mayor de 1000 anteriormente, vamos a conocer que un segundo ha pasado, así que podemos permitir a los jugadores disparar. Veremos esto con "players[name].timestamp < os.time()-1000" y sólo basta con conjugar un cañón si es verdad.

Una vez que el jugador ha disparado con éxito, el valor almacenado en la tabla tendrá que ser ajustado a la hora actual para asegurarse de que el jugador no pueda tirar durante un segundo, por lo que vamos a redefinir eso mediante "players[name].timestamp=os.time()".

a dit :

function eventKeyboard(name,key,down,x,y)
if (key==32 or key==40 or key==83) and not tfm.get.room.playerList[name].isDead then
if players[name].timestamp < os.time()-1000 then
if tfm.get.room.playerList[name].isFacingRight then
tfm.exec.addShamanObject(19,x,y)
else
tfm.exec.addShamanObject(20,x,y)
end
players[name].timestamp=os.time()
end
end
end

http://i.imgur.com/4vSFf.png
Los cañones que estén en el mapa pueden conllevar a severos problemas; siguen siendo añadidos a objectList, pueden quedar atrapados en los mapas, pueden haber cientos en la pantalla en el primer momento que hay lag. Necesitan ser eliminados.

Hay varias maneras posibles de eliminar cañones, utilizando temporizadores, borrar el siguiente disparo del jugador, comprobando os.time() de nuevo, o muchas otras cosas. Para este ejemplo vamos a estar comparando os.time() a la vez que el cañón fue disparado.

Cierta información sobre el cañón deberá estar disponible hasta que se desconjugue, tanto el tiempo de conjugación y el ID del objeto. Esto se mantendrá en otra tabla.

a dit :
toDespawn={}

Afortunadamente tfm.exec.addShamanObject devuelve el ID del objeto que genera, por lo que establecer una variable para esto mantendrá el ID en la variable, listo para su uso en otros lugares.

También necesitará la hora actual para su almacenamiento, para ser revisados y comparados con una fecha posterior -al igual que lo que se hizo con el timestamp del jugador.

Ambas cosas se insertarán en la tabla de toDespawn cuando un jugador dispara con un cañón.

a dit :

local id
if tfm.get.room.playerList[name].isFacingRight then
id=tfm.exec.addShamanObject(19,x,y)
else
id=tfm.exec.addShamanObject(20,x,y)
end
players[name].timestamp=os.time()
table.insert(toDespawn,{os.time(),id})

Ahora que la tabla almacena información sobre cada cañón, necesitan ser removidos. Usando temporizadores podría ser el método más exacto para determinar cuándo desaparecerá un cañón, aunque puede requerir demasiados recursos y serán limitados a sólo 40.

La segunda mejor opción sería la de eliminarlos en eventLoop, que consigue ejecutando cada 500ms. Dentro de esta función que vamos a hacer todos los objetos deberán estar en la tabla de toDespawn.

Primeramente tenemos que comprobar el tiempo de los cañones como antes. Para que todos los cañones tengan como última opción unos 3 segundos, la hora almacenada en el momento de recibir un disparo del cañón puede ser comparado con la hora actual, de menos de 3000 milisegundos, entonces el cañón es eliminado.

La entrada en toDespawn también debe ser eliminada cada vez que un cañón es desconjugado con éxito, y el uso de la función table.remove() para librarse de la tecla que está actualmente circulando puede realizar esta acción. Ten en cuenta que removiendo un ítem de la tabla, que está siendo colocada, puede causar un error, ya que no puede circular a través de ese elemento, pero utilizando la función ipairs() ayuda a que la medida se incremente a las teclas numéricas que recorre, lo que significa que no se romperá.

a dit :

function eventLoop(time,remaining)
for i,cannon in ipairs(toDespawn) do
if cannon[1] <= os.time()-3000 then
tfm.exec.removeObject(cannon[2])
table.remove(toDespawn,i)
end
end
end

En conjunto, ahora tenemos un minijuego trabajado donde los jugadores puedan disparar 1 cañón por segundo, y los cañones se eliminan unos 3 segundos después de ser disparados.


http://i.imgur.com/4vSFf.png
Es necesario que haya un final del juego en cada ronda, y en FFA esto es usualmente cuando el último jugador vivo obtiene el queso. Hacer esto significa que debes necesitar saber cuántos jugadores están actualmente vivos -si solo un jugador está vivo se le puede dar queso.

Esto se puede hacer mediante un circuito a través de playerList e incrementando el número para cada "not isDead", el número resultante será el número de personas vivas.

El número de jugadores vivos se cambiará solamente cuando un jugador muera (o se regeneran, pero este minijuego no tiene esa función como sí lo tienen otros, ejemplo #pewpew), por lo que sólo necesita ser comprobado en eventPlayerDied.

El nombre del jugador se puede almacenar en una variable a utilizar -si hay sólo un jugador con vida será el único al que se le asigna la variable, dándole el nombre del ganador. También habrá que establecer el tiempo de juego inferior o iniciar una nueva ronda con el fin de garantizar que las rondas no continúen incluso si todos los ratones han muerto.

a dit :
function eventPlayerDied(name)
local i=0
local n
for pname,player in pairs(tfm.get.room.playerList) do
if not player.isDead then
i=i+1
n=pname
end
end
if i==1 then
tfm.exec.giveCheese(n)
tfm.exec.playerVictory(n)
tfm.exec.setGameTime(5)
end
end

http://i.imgur.com/4vSFf.png
Un problema que puede ocurrir cuando se tiran los cañones es que se pueden tirar durante la cuenta atrás antes de empezar la ronda, lo que significa que los cañones se conjugan y pueden mover a los jugadores antes de que puedan moverse a sí mismos.

Una forma de que esto pueda resolverse es establecer un boolean global que decide si la actual ronda ha comenzado o no. Esto va a establecerse como falso en eventNewGame, y los jugadores sólo podrán disparar si es verdadera.

eventLoop devuelve el número de los milisegundos que han pasado en la ronda actual, que se puede utilizar para determinar cuando la cuenta atrás de 3 segundos ha terminado.

a dit :

function eventLoop(time,remaining)
if time >= 3000 and not started then
started=true
end
end

function eventNewGame()
started=false
end

function eventKeyboard(name,key,down,x,y)
if started then
--Cannon Shooting
end
end

http://i.imgur.com/4vSFf.png
El #deathmatch de Baffler permite a los jugadores crear sus propios desplazamientos en donde los cañones se disparan en relación a las coordenadas del ratón, lo que permite que los usuarios lo personalicen a su gusto.

Los jugadores tendrán que tener sus propias variables de desplazamiento tanto para los ejes X e Y, que se puede almacenar dentro de la tabla de jugadores previamente realizada, añadiéndolo a eventNewPlayer para asegurar que todos tengan desplazamientos por defecto.

a dit :
function eventNewPlayer(name)
players[name]={
timestamp=os.time(),
offsets={x=2, y=10}
}
end

Estos desplazamientos pueden ser fácilmente utilizados por la adición de estos valores para la conjugación de las coordenadas de los cañones.

a dit :
if tfm.get.room.playerList[name].isFacingRight then
id=tfm.exec.addShamanObject(19,x+players[name].offsets.x,y+players[name].offsets.y)
else
id=tfm.exec.addShamanObject(20,x+players[name].offsets.x,y+players[name].offsets.y)
end

Así que puede ser útil, los jugadores tendrán acceso a un comando personalizado como "!off [x] [y]", por lo que tanto el X e Y se puede ajustar de forma independiente entre sí. En primer lugar cada argumento individual necesita estar separado para que puedan ser detectados de forma independiente, por lo que vamos a insertar cada argumento en una tabla, dividiéndolos en cada espacio.

a dit :
function eventChatCommand(name,command)
local arg={}
for argument in command:gmatch("[^%s]+") do
table.insert(arg,argument)
end
end

Los siguientes argumentos deben ser utilizados. Colocando "!off 10 20" hará los siguientes argumentos en una tabla:

arg[1] = "off"
arg[2] = "10"
arg[3] = "20"

Tendremos que comprobar si arg[1] es actualmente "off", en caso de que el módulo necesite usar ese comando en el futuro.

En el caso de que un jugador coloque "!off text", el script se bloquea al intentar disparar un cañón, ya que trata de añadir la serie y las coordenadas que se generaron en conjunto. Podemos comprobar escribiendo los números de ambos argumentos utilizando la función tonumber(), sino, entonces se omitirá ese bloqueo.

Para añadir un poco de funcionalidad adicional, si la gente da argumentos válidos para el comando en este ejemplo, va a restaurar los desplazamientos por defecto.

Para notificar a los jugadores que han conseguido cambiar sus desplazamientos, tfm.exec.chatMessage puede ser utilizado también para dar un mensaje que dice "Desplazamientos cambiados a X:2 Y:10", por ejemplo.


http://i.imgur.com/4vSFf.png
¡Ahora tenemos una versión de Free to All!

Ten en cuenta que otros ajustes deben realizarse también, por ejemplo, agregar tfm.exec.disableAutoShaman(true) para quitar el script de remover chamanes por la conjugación en los mapas.

Usando la rotación de los mapas de este hilo Topic-457950 y dándole una lista de mapas hechos para el juego, el minijuego se ha completado.

a dit :
tfm.exec.disableAutoNewGame(true)
tfm.exec.disableAutoShaman(true)
players={}
toDespawn={}
maps={521833,401421,541917,541928,541936,541943,527935,559634,559644,888052,878047,885641,770600,770656,772172,891472,589736,589800,589708,900012,901062,754380,901337,901411,907870,910078,1190467,1252043,1124380,1016258,1252299,1255902,1256808,986790,1285380,1271249,1255944,1255983,1085344,1273114,1276664,1279258,1286824,1280135,1280342,1284861,1287556,1057753,1196679,1288489,1292983,1298164,1298521,1293189,1296949,1308378,1311136,1314419,1314982,1318248,1312411,1312589,1312845,1312933,1313969,1338762,1339474,1349878,1297154,644588,1351237,1354040,1354375,1362386,1283234,1370578,1306592,1360889,1362753,1408124,1407949,1407849,1343986,1408028,1441370,1443416,1389255,1427349,1450527,1424739,869836,1459902,1392993,1426457,1542824,1533474,1561467,1563534,1566991,1587241,1416119,1596270,1601580,1525751,1582146,1558167,1420943,1466487,1642575,1648013,1646094,1393097,1643446,1545219,1583484,1613092,1627981,1633374,1633277,1633251,1585138,1624034,1616785,1625916,1667582,1666996,1675013,1675316,1531316,1665413,1681719,1699880,1688696,623770,1727243,1531329,1683915,1689533,1738601,3756146,912118,3326933,3722005,3566478,1456622,1357994,1985670,1884075,1708065,1700322,2124484,3699046,2965313,4057963,4019126,3335202,2050466}

function eventNewPlayer(name)
for i,key in ipairs({32,40,83}) do
tfm.exec.bindKeyboard(name,key,true,true)
end
players[name]={
timestamp=os.time(),
offsets={x=2, y=10}
}
end

function eventKeyboard(name,key,down,x,y)
if (key==32 or key==40 or key==83) and not tfm.get.room.playerList[name].isDead and started then
if players[name].timestamp < os.time()-1000 then
local id
if tfm.get.room.playerList[name].isFacingRight then
id=tfm.exec.addShamanObject(19,x+players[name].offsets.x,y+players[name].offsets.y)
else
id=tfm.exec.addShamanObject(20,x+players[name].offsets.x,y+players[name].offsets.y)
end
players[name].timestamp=os.time()
table.insert(toDespawn,{os.time(),id})
end
end
end

function eventChatCommand(name,command)
local arg={}
for argument in command:gmatch("[^%s]+") do
table.insert(arg,argument)
end
if arg[1]=="off" then
if tonumber(arg[2]) and tonumber(arg[3]) then
players[name].offsets.x=tonumber(arg[2])
players[name].offsets.y=tonumber(arg[3])
else
players[name].offsets.x=2
players[name].offsets.y=10
end
tfm.exec.chatMessage("Offsets changed to X:"..players[name].offsets.x.." Y:"..players[name].offsets.y,name)
end
end

function eventNewGame()
started=false
end

function eventLoop(time,remaining)
if time >= 3000 and not started then
started=true
end
if remaining<=0 then
tfm.exec.newGame(maps[math.random(#maps)])
end
for i,cannon in ipairs(toDespawn) do
if cannon[1] <= os.time()-3000 then
tfm.exec.removeObject(cannon[2])
table.remove(toDespawn,i)
end
end
end

function eventPlayerDied(name)
local i=0
local n
for pname,player in pairs(tfm.get.room.playerList) do
if not player.isDead then
i=i+1
n=pname
end
end
if i==0 then
tfm.exec.newGame(maps[math.random(#maps)])
elseif i==1 then
tfm.exec.giveCheese(n)
tfm.exec.playerVictory(n)
tfm.exec.setGameTime(5)
end
end

for name,player in pairs(tfm.get.room.playerList) do
eventNewPlayer(name)
end

tfm.exec.newGame(maps[math.random(#maps)])

Espero que este tutorial te haya ayudado a aprender algunos conceptos básicos como la configuración de cada jugador, con timestamps y circular a través de las tablas. Puede haber métodos más eficientes y eficaces de hacer las cosas, pero espero que hayas aprendido algunos conceptos básicos que se pueden utilizar en el desarrollo de sus propios módulos.

Personalmente quiero pedir perdón por el español que he manejado en este hilo, puesto a que -por lo menos para mí- el inglés manejado en el hilo original no es de mi preferencia, e hice lo posible. Nuevamente perdón.

Hilo original Topic-457951 hecho por Shamousey
Kioxo
« Citoyen »
1380987000000
    • Kioxo#0000
    • Profil
    • Derniers messages
#2
  0
*O* esta bueno
Mitsnara
« Citoyen »
1380987240000
    • Mitsnara#8643
    • Profil
    • Derniers messages
    • Tribu
#3
  0
Buen hilo aunque no se tanto del lua
Zutto
« Citoyen »
1380988800000
    • Zutto#4451
    • Profil
    • Derniers messages
    • Tribu
#4
  0
Wow muy buen hilo, ayer hablé con haku por si quería traducirlo conmigo, pero no quiso, y a mi me daba pereza xd.

Muy buen hilo de nuevo!

Y algunos scripts y el último están rotos, podrías coger todos los scripts del hilo de EN y pegalros en notepad, y luego los inplantas.
Phyrra
« Citoyen »
1381012200000
    • Phyrra#0000
    • Profil
    • Derniers messages
    • Tribu
#5
  0
Gracias por el hilo, si eso un dia me pongo a probar y tal (No tengo un especial interes que digamos).

Saludos
Norsewolf
« Citoyen »
1381053660000
    • Norsewolf#0000
    • Profil
    • Derniers messages
    • Tribu
#6
  0
Tenía pensado hacer yo algo parecido, pero con todos los tutoriales y guías en un solo hilo. Mejor dejarlo así xD Buen hilo. Muchas gracias Gastuu!!

Gastuu a dit :
Ahora que el valor se guardó, cuando el os.time() es comprobado nuevamente pulsando una tacla que se puede comparar con el valor almacenado que es mayor que antes de 1000, vamos a conocer que un segundo ha pasado, así que podemos permitir a los jugadores disparar. Vamos a comprobar esto con "players[name].timestamp < os.time()-1000" y sólo basta con conjugar un cañón si es verdad.

Una tacla jeje

Por cierto, deberías de releerte el hilo y sustituir algunas expresiones que has traducido demasiado literalmente por otras que se entiendan mejor.

En este mismo párrafo que he citado, lo de "mayor que antes de 1000" no se entiende muy bien, por ejemplo.
Gaston
« Censeur »
1381070940000
    • Gaston#1499
    • Profil
    • Derniers messages
    • Tribu
#7
  0
Norsewolf a dit :
Tenía pensado hacer yo algo parecido, pero con todos los tutoriales y guías en un solo hilo. Mejor dejarlo así xD Buen hilo. Muchas gracias Gastuu!!
Una tacla jeje

Por cierto, deberías de releerte el hilo y sustituir algunas expresiones que has traducido demasiado literalmente por otras que se entiendan mejor.

En este mismo párrafo que he citado, lo de "mayor que antes de 1000" no se entiende muy bien, por ejemplo.

En eso andaba. Se me hizo complicado entender el inglés. Gracias.
Trust
« Citoyen »
1381072980000
    • Trust#3045
    • Profil
    • Derniers messages
    • Tribu
#8
  0
hace doble post :D
Shinlero
« Citoyen »
1381072980000
    • Shinlero#0000
    • Profil
    • Derniers messages
    • Tribu
#9
  0
Buen hilo
Sera util en algun momento
Trust
« Citoyen »
1381073100000
    • Trust#3045
    • Profil
    • Derniers messages
    • Tribu
#10
  0
Shinlero a dit :
Buen hilo
Sera util en algun momento

ni lo leiste :/
Gaston
« Censeur »
1381073100000
    • Gaston#1499
    • Profil
    • Derniers messages
    • Tribu
#11
  0
Arregladas algunas cositas. Espero que les sea más fácil de entender. Perdón nuevamente.
Thetroz
« Citoyen »
1381073100000
    • Thetroz#0000
    • Profil
    • Derniers messages
    • Tribu
#12
  0
Buen tutorial Gastuu
<3
Shinlero
« Citoyen »
1381073100000
    • Shinlero#0000
    • Profil
    • Derniers messages
    • Tribu
#13
  0
Sansnano a dit :
ni lo leiste :/

¿Y tu como sabes?
Trust
« Citoyen »
1381073400000
    • Trust#3045
    • Profil
    • Derniers messages
    • Tribu
#14
  0
Shinlero a dit :
¿Y tu como sabes?

por que vi que pusieran un post para que no haga doble post y no le den una advertencia ya que el foro es la vida y la salvacion de muchos :/
Thetroz
« Citoyen »
1381076340000
    • Thetroz#0000
    • Profil
    • Derniers messages
    • Tribu
#15
  0
Sansnano a dit :
por que vi que pusieran un post para que no haga doble post y no le den una advertencia ya que el foro es la vida y la salvacion de muchos :/

Ya antes lo había leído
y no comenté
Altcarcarmar
« Citoyen »
1381083720000
    • Altcarcarmar#0000
    • Profil
    • Derniers messages
    • Tribu
#16
  0
Esperaba que alguien de ES como Haku hiciese su propia versión e incluso explicando mucho más, en fin, de algo me servirá aunque ya leí el hilo de EN.
Narutansi
« Citoyen »
1427305860000
    • Narutansi#0000
    • Profil
    • Derniers messages
#17
  0
No funciona :c
  • Forums
  • /
  • Transformice
  • /
  • Modules
  • /
  • Guías y Tutoriales
  • /
  • [Module API] [Tutorial] Free For All
© Atelier801 2018

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

Version 1.27