[Tutorial] Cargar elementos del juego desde el XML de un mapa |
0 | ||||||
Hola. En este tutorial enseñaré un ejemplo simple de cómo leer elementos del XML para agregar objetos del juego. Estos objetos pueden ser cualquier cosa desde objetos de chamán que quieras poner al inicio de la ronda, puntos de inicio de los ratones o lugares donde quieras poner textAreas. I. ¿Cuándo necesito esto? Digamos que estás haciendo un module y quieres que spawneen cañones desde ciertas partes en el mapa. Y necesitas que disparen en una dirección específica que será izquierda o derecha. Llamaremos a esos lugares "puntos de spawn". Y básicamente queremos que cada mapa tenga sus propios puntos de spawn, cada uno disparando a la izquierda o a la derecha. II. ¿¡Cómo hacemos esto!? Necesitarás definir la posición de cada punto de spawn y guardarla dentro del mismo mapa. Hay infinitas formas de lograr esto pero para este tutorial usaremos lo que yo considero la solución más práctica para este ejemplo simple. Usaremos objetos de chamán. Usaremos cierto objeto de chamán para indicar la posición de cada punto de spawn. Yo escogeré motores rojos. Y para distinguir entre puntos de spawn disparando a la derecha y a la izquierda, usaremos ambos motores rojos, de esta forma:
Así es como se verán los mapas: Hasta ahora hemos definido la forma en que identificaremos los puntos de inicio en el mapa. La cual es bastante conveniente porque podemos simplemente poner motores en el editor de mapas y veremos dónde aparecerán los cañones. Pero ahora viene la parte de programar. III. Implementación En resumen, necesitamos que nuestro module lea el XML del mapa al comienzo de cada ronda, lea los elementos de objeto de chamán y busque ambos motores rojos. Luego guarde sus coordenadas en una tabla donde se almacenarán todos los puntos de spawn de cañones. Y eso sería todo. Ahora entraremos en detalle sobre cómo hacer todo eso. 1. Código inicial Comienza con este script básico que cargará el mapa y respawneará a los jugadores cuando mueran y entren a la sala. Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 local map = '<C><P /><Z><S><S X="110" Y="390" L="220" H="60" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="690" Y="390" L="220" H="60" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="770" Y="140" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="30" Y="140" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="770" Y="250" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="30" Y="250" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="400" Y="410" L="140" H="140" T="0" P="0,0,0.3,0.2,45,0,0,0" /><S X="442" Y="82" L="40" H="160" T="2" P="0,0,0,1.2,45,0,0,0" /><S X="358" Y="82" L="160" H="40" T="2" P="0,0,0,1.2,45,0,0,0" /><S X="400" Y="35" L="800" H="50" T="0" P="0,0,0.3,0.2,0,0,0,0" /></S><D><DS X="400" Y="305" /></D><O><O X="20" Y="100" P="0" C="12" /><O X="20" Y="210" P="0" C="12" /><O X="780" Y="100" P="0" C="13" /><O X="780" Y="210" P="0" C="13" /></O></Z></C>' 2. Librería XML Para poder leer la información en el XML usaremos la Librería XML de Makinit. La cuál hará las cosas mucho más fáciles y rápidas que teniendo que parsear nosotros mismos el XML del mapa. (Y nos ahorrará la explicación). Yo usaré una versión reducida de la librería, la cual no puede generar mapas. Puedes pegar la librería en cualquier parte antes de la llamada a main() al final del script. Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 local map = '<C><P /><Z><S><S X="110" Y="390" L="220" H="60" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="690" Y="390" L="220" H="60" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="770" Y="140" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="30" Y="140" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="770" Y="250" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="30" Y="250" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="400" Y="410" L="140" H="140" T="0" P="0,0,0.3,0.2,45,0,0,0" /><S X="442" Y="82" L="40" H="160" T="2" P="0,0,0,1.2,45,0,0,0" /><S X="358" Y="82" L="160" H="40" T="2" P="0,0,0,1.2,45,0,0,0" /><S X="400" Y="35" L="800" H="50" T="0" P="0,0,0.3,0.2,0,0,0,0" /></S><D><DS X="400" Y="305" /></D><O><O X="20" Y="100" P="0" C="12" /><O X="20" Y="210" P="0" C="12" /><O X="780" Y="100" P="0" C="13" /><O X="780" Y="210" P="0" C="13" /></O></Z></C>' 3. Leyendo los elementos Ahora vamos a usar las herramientas en la librería para obtener lo que queremos del XML. Añade lo siguiente a eventNewGame: Code Lua 1 2 3 4 function eventNewGame() La función parseXml guarda el mapa en una tabla. Vamos a iterar por todos los objetos de chamán en el mapa: Code Lua 1 2 3 4 5 6 7 8 function eventNewGame() La función path nos ayuda a iterar por un tipo de elemento específico. En este caso buscamos todos los elementos <O> (objetos de chamán), los cuales están dentro del grupo <O>, el cual está dentro del elemento <Z>. Por lo tanto entregamos los argumentos "Z", "O", "O" como ruta. 4. Leyendo los atributos Ahora necesitamos comprobar si el objeto es un motor rojo. Para hacer eso, revisaremos los atributos del objeto. Recuerda que los objetos de chamán tienen su ID de objeto definido en el XML como un atributo llamado C (ej: C="12" es un motor rojo en sentido horario). La librería de Makinit convenientemente agrupa todos los atributos en un elemento dentro de la tabla attribute. La tabla está dentro del elemento mismo y contiene los nombres y valores de sus atributos. Podemos accederlos y revisar si el atributo C corresponde al de un motor rojo: Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 function eventNewGame() Primero usamos objectAttributes para apuntar a la tabla attribute, necesitaremos acceder a esos atributos de nuevo más tarde. Luego guardamos el atributo C y revisamos si es el ID de un motor rojo (12 o 13). Nótese que usamos comillas aquí puesto que todos los atributos en el dom tienen valores de tipo string. 5. Guardando puntos de spawn Antes de empezar a hacer algo útil con los elementos en el XML, necesitamos una tabla para almacenar los puntos de inicio. Añade lo siguiente en alguna parte al comienzo del script: Code Lua 1 2 local spawnSpots La primera es la tabla, mientras que la otra es un contador para llevar seguimiento de los elementos en dicha tabla. (También puedes usar #spawnSpots para obtener ese valor si la optimización no es de tu agrado). Debemos inicializar ambas variables al comienzo de cada ronda antes de empezar a añadir los puntos de spawn desde el XML. Para añadirlos simplemente hacemos una tabla con las coordenadas del elemento y la añadimos. Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function eventNewGame() Hasta ahora todo bien, pero nos falta un detalle. Necesitamos una forma de saber la dirección en la que disparará cada punto. 6. Dirección del spawner Ahora comprobaremos si el objeto es un motor rojo en sentido horario o antihorario. Una vez más revisaremos su atributo C y guardaremos esta información como un valor boolean diciéndonos si el spawner está mirando a la izquierda o no (facingLeft). Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 function eventNewGame() ✩ You can shorten the previous if sentence by using the Lua version of a ternary operator: ✩ Puedes achicar la sentencia if anterior usando la versión Lua de un operador ternario: Code Lua 1 spot.facingLeft = C == "13" and true or false 7. Usando la tabla Ahora puedes hacer lo que quieras con la tabla spawnSpots. Para este ejemplo añadiré algo de código en un eventLoop para lanzar cañones desde un spawner al azar cada segundo. Añade el siguiente código al script: Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 local ticks = 0 Ahora tienes un module funcionando con spawners de cañones que son leídos desde el XML y pueden ser editados directamente en cualquier editor de mapas. :) IV. ¡Pruébalo! El script funcionará con cualquier mapa y puedes añadir todos los motores rojos que quieras. Aquí está el script completo por si te faltó un paso o algo: Code Lua 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 local map = '<C><P /><Z><S><S X="110" Y="390" L="220" H="60" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="690" Y="390" L="220" H="60" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="770" Y="140" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="30" Y="140" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="770" Y="250" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="30" Y="250" L="60" H="40" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S X="400" Y="410" L="140" H="140" T="0" P="0,0,0.3,0.2,45,0,0,0" /><S X="442" Y="82" L="40" H="160" T="2" P="0,0,0,1.2,45,0,0,0" /><S X="358" Y="82" L="160" H="40" T="2" P="0,0,0,1.2,45,0,0,0" /><S X="400" Y="35" L="800" H="50" T="0" P="0,0,0.3,0.2,0,0,0,0" /></S><D><DS X="400" Y="305" /></D><O><O X="20" Y="100" P="0" C="12" /><O X="20" Y="210" P="0" C="12" /><O X="780" Y="100" P="0" C="13" /><O X="780" Y="210" P="0" C="13" /></O></Z></C>' Espero que te haya gustado este tutorial. La gente que está empezando en los modules a menudo pregunta sobre este tema así que pensé que era hora de hacer una guía simple sobre ello. La utilidad y posibilidades de trabajar con el XML de un mapa van mucho más allá de solo hacer spawners de cañones. Así que se creativ@ y ve a hacer algo con ello! Traducido de aquí. |
Tocutoeltuco « Censeur » 1482790320000
| 0 | ||
La verdad que yo había hecho un script parecido, pero mucho menos optimizado que este. Buen tutorial. me robo la pole |
Miiiclaroo « Citoyen » 1482938100000
| 0 | ||
tocutoeltuco a dit : No creo que necesite pole xd |