Este tutorial le mostrará cómo trasladar un juego Flash / Flex al Corona SDK. Específicamente, estaremos portando de ActionScript a Lua, con el objetivo final de jugar juegos anteriormente solo para Flash en el iPhone. Además de demostrar las diferencias de idioma y API, esta serie de tutoriales también tendrá en cuenta las restricciones de hardware, como el tamaño de la pantalla y la falta de botones físicos en el iPhone..
Ahora comenzaremos a trabajar con nuestro enemigo: "de / pixelate / flixelprimer / Alien.as". Como siempre, la sintaxis se convierte primero..
Cuando haya terminado con eso, agregue la decleración del módulo y ajuste todas las funciones dentro de Alien ().
module (?, package.seeall) - [Embed (source = "? /? /? /? /assets/png/Alien.png")] private var ImgAlien: Class function Alien (x, y) -: void super (x, y, ImgAlien) velocity.x = -200 función actualizar () -: void velocity.y = Math.cos (x / 50) * 50 super.update () end end
El extraterrestre funciona muy parecido a nuestra bala. Crea una imagen, establece su x y y.
Coordina, y le da una velocidad. Entonces, lo abordaremos de la misma manera. Las dos líneas superiores dentro de la función se pueden reemplazar con casi el mismo código que usamos para la bala. Esta vez usaremos una imagen aunque.
módulo (?, package.seeall) función Alien (x, y) -: void local Alien = display.newImage ("Alien.png") Alien.x = x Alien.y = y function update () -: void ? final fin
Ahora que tenemos la imagen cargada y configurada, hagamos que se mueva hacia la izquierda. Nuevamente, crearemos algo como el código de actualización () de nuestra bala. Deja las líneas antiguas dentro de actualización () comentada..
Función de módulo (?, package.seeall) Alien (x, y) -: void? función update () -: anular si Alien entonces if (Alien.x> 0 - Alien.contentWidth) entonces Alien.x = Alien.x - 2 end end? código comentado? end Runtime: addEventListener ("enterFrame", actualizar) end
Ahora hagamos una función kill () y hagamos que Alien devuelva un Alien.
Función de módulo (?, package.seeall) Alien (x, y) -: void? función de actualización () -: void? función final Alien: kill () Alien.parent: remove (Alien) Alien = nil end Tiempo de ejecución: addEventListener ("enterFrame", actualización) return Alien end
Ahora podemos matar () a nuestro alienígena si es x está fuera de la pantalla a la izquierda. También podemos agregar una nueva función () como una conveniencia..
módulo (?, package.seeall) función Alien (x, y) -: void local Alien = display.newImage ("Alien.png") Alien.x = x Alien.y = y function update () -: void si Alien entonces si (Alien.x> 0 - Alien.contentWidth) entonces Alien.x = Alien.x - 2 más Alien: kill () end end end end end función Alien: kill () Alien.parent: remove (Alien) Alien = nil end Runtime: addEventListener ("enterFrame", actualizar) return End Alien end nueva (x, y) return Alien (x, y) end
Crear al alienígena fue bastante fácil. Ahora necesitamos comenzar a agregarlos al juego a través de PlayState..
Primero, importa el módulo en PlayState.lua.
módulo (?, package.seeall) Local Ship = require ("Ship") local Bullet = require ("Bullet") local Alien = require ("Alien") local Buttons = require ("Buttons")
Ahora tenemos que configurar un temporizador. El código original tenía una variable _spawnInterval que se usó para establecer _spawnTimer. Cada vez que _spawnTimer llegó a 0, se restablecería al valor de _spawnInterval._spawnInterval se reduciría en .1, lo que daría como resultado que los alienígenas se engendraran más rápido.
Para comenzar, elimine el comentario de las decleraciones de propiedad _spawnInterval y _spawnTimer en create ().
function create () -: void - declaraciones de variables PlayState._inGame = true PlayState._background = nil PlayState._ship = nil --PlayState._aliens = nil PlayState._bullets = nil --PlayState._scoreText = nil --PlayState. _gameOverText = nil PlayState._spawnTimer = nil PlayState._spawnInterval = nil --PlayState.SoundExplosionShip = nil --PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? fin
Ahora en las asignaciones de variables, establezca _spawnTimer en 0 y _spawnInterval en 2.5. También agregue una llamada a resetSpawnTimer (). Vamos a crear esta función en un segundo.
funcion create () -: void? - asignaciones variables PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ("Bullet.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer () end
Ahora encuentra la función comentada resetSpawnTimer (). Se verá algo como esto.
function resetSpawnTimer () -: void _spawnTimer = _spawnInterval _spawnInterval = _spawnInterval * 0.95 if (_spawnInterval < 0.1) then _spawnInterval = 0.1 end end
Sorprendentemente, eso es exactamente lo que necesitamos. Solo necesitamos hacer las propiedades de las variables de PlayState. De esa manera la función sabrá de qué _spawnInterval y _spawnTimer estamos hablando.
function resetSpawnTimer () -: void PlayState._spawnTimer = PlayState._spawnInterval PlayState._spawnInterval = PlayState._spawnInterval * 0.95 if (PlayState._spawnInterval < 0.1) then PlayState._spawnInterval = 0.1 end end
Ahora necesitamos agregar algo de código a update (). En el código original, el juego creó alienígenas incluso si el juego terminaba y la nave estaba muerta. Para hacer lo mismo, pongamos nuestro código de manejo de alienígenas fuera de donde comprobamos si el juego ha terminado.
función de actualización () PlayState._spawnTimer = PlayState._spawnTimer - (30/1000) if (PlayState._spawnTimer < 0) then spawnAlien() resetSpawnTimer() end if PlayState._inGame then? end end
Este código funciona igual que el código fuente. Resta el tiempo de 1 fotograma de _spawnTimer. A continuación, comprueba si _spawnTimer es menor que cero. Si es así, restablece el temporizador y genera un nuevo alienígena..
Antes de que podamos engendrar alienígenas, necesitamos un grupo de visualización para agregarlos. Al igual que _bullets, elimine el comentario de la decleración de los alienígenas y asigne un nuevo grupo de visualización.
function create () -: void - declaraciones de variables PlayState._inGame = true PlayState._background = nil PlayState._ship = nil PlayState._aliens = nil PlayState._bullets = nil --PlayState._scoreText = nil --PlayState._gameOverText = nil PlayState._spawnTimer = nil PlayState._spawnInterval = 2.5 --PlayState.SoundExplosionShip = nil --PlayState.SoundExplosionAlien = nil PlayTrack.Tratamiento de la persona no está en línea. display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._aliens = display.newGroup () PlayState._bullets = display.newGroup () PlayState. SoundBullet = media.newEventSound ("Bullet.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer ()? fin
Ahora encuentre su función spawnAlien () y descoméntela. Debería verse algo como esto:
función spawnAlien () -: void local x = FlxG.width local y = Math.random () * (FlxG.height - 100) + 50 _aliens.add (nuevo Alien (x, y)) end
Este código crea un alienígena justo a la derecha de la pantalla y en una altura aleatoria. Luego agrega el nuevo alien al grupo de visualización. Podemos hacer lo mismo con este código:
función spawnAlien () -: void local x = display.contentWidth local y = math.random () * (display.contentHeight - 240) + 50 PlayState._aliens: insert (Alien.new (x, y)) final
Si ejecutamos el código ahora, funciona casi como el original. Los alienígenas aparecen a alturas aleatorias, y aparecen lentamente con más frecuencia. Cuando salen de la pantalla, llaman a kill () sobre sí mismos. Ahora solo necesitamos hacer que se muevan como lo hicieron en el código original. En el juego original, los alienígenas siguieron la ruta de una onda de coseno que se generó en función de su ubicación x. Tenemos este código comentado en la función de actualización de alienígenas (). Este código tomó un poco de juego con. Debido a que no tenemos velocidad para trabajar, es difícil usar el código original. Este es el momento de portar donde solo tendrás que jugar con los números. Encontré este código trabajado más cercano al original:
function update () -: void si Alien entonces if (Alien.x> 0 - Alien.contentWidth) entonces Alien.x = Alien.x - 2 Alien.y = Alien.y + math.cos (Alien.x / 10 ) * 2 else Alien: kill () end end end end
Ahora que tenemos todos nuestros objetos de juego funcionando como los originales, necesitamos verificar las colisiones entre las balas y los alienígenas, y los alienígenas y la nave. En el código original, las colisiones se verificaron en la función update (). Si se produjo una colisión, los dos objetos se pasaron a las funciones overlapAlienBullet () y overlapAlienShip (). Vamos a crear esas funciones primero. Si descomentimos overlapAlienBullet (), tenemos un código que se ve así:
function overlapAlienBullet (alien, bullet) -: void local emitter = createEmitter () emitter.at (alien) alien.kill () bullet.kill () FlxG.play (SoundExplosionAlien) FlxG.score = FlxG.score + 1 _scoreText. text = FlxG.score.toString () final
Este código crea un emisor de partículas, mata ambos objetos, reproduce un efecto de sonido y actualiza la partitura. La recreación del sistema de partículas flixel está fuera del alcance de este tutorial, y aún no hemos implementado un sistema de puntaje. Por ahora, solo comentemos esas líneas y matemos los objetos..
function overlapAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () --FlxG.play (SoundExplosionAlien) --FlxG.score = FlxG.score + 1 --_ scoreText.text = FlxG.score. toString () end
Haga lo mismo con overlapAlienShip ():
function overlapAlienShip (alien, ship) -: void ship: kill () alien: kill () --FlxG.play (SoundExplosionShip) --_ gameOverText = new FlxText (0, FlxG.height / 2, FlxG.width, "GAME OVER \ nPRESS ENTER TO PLAY OTRA VEZ ") --_ gameOverText.setFormat (null, 16, 0xFF597137," center ") --add (_gameOverText) end
Ahora vamos a crear el efecto de sonido para usar en esas funciones. Descomentar las declaraciones de variables de sonido en create ().
function create () -: void - declaraciones de variables PlayState._inGame = true PlayState._background = nil PlayState._ship = nil PlayState._aliens = nil PlayState._bullets = nil --PlayState._scoreText = nil --PlayState._gameOverText = nil PlayState._spawnTimer = nil PlayState._spawnInterval = 2.5 PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? fin
Ahora asignalos a sus sonidos:
funcion create () -: void? - asignaciones variables PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._aliens = display.newGroup () PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ("Bullet.caf") PlayState.placas en las partes de las partes de las partes de las personas. media.newEventSound ("ExplosionAlien.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer () end
Reproducir los sonidos es tan fácil como una línea por función ().
function overlapAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () media.playEventSound (PlayState.SoundExplosionAlien) --FlxG.score = FlxG.score + 1 --_ scoreText.text = FlxG.score. toString () end function overlapAlienShip (alien, ship) -: void ship: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) --_ gameOverText = new FlxText (0, FlxG.height / 2, FlxG. ancho, "GAME OVER \ nPRESS ENTER TO PLAY OTRA VEZ") --_ gameOverText.setFormat (null, 16, 0xFF597137, "center") --add (_gameOverText) end
Ahora que tenemos nuestras funciones de superposición en su lugar, necesitamos verificar las colisiones en cada cuadro. En Corona, no tenemos una forma fácil de verificar si hay objetos de visualización superpuestos. Tendremos que hacer las comprobaciones manualmente. Este es un concepto bastante fácil, pero se vuelve bastante complicado en la implementación. Pensemos en esto por un segundo. ¿Qué define una superposición? Su primer instinto puede ser verificar si un objeto está dentro de otro. Esto funcionaría, pero en este caso, una superposición puede ser solo parte de los objetos. Un objeto no necesita estar completamente dentro de otro para superponerse. ¿Cómo se ve esto en el código? Todo lo que tenemos que hacer es verificar si el valor máximo de x de un objeto es mayor que el mínimo x
Valor del otro objeto. Luego verificamos si el valor x mínimo del mismo objeto es menor que el valor x máximo de los otros objetos. Esto se volverá verdadero para cada superposición. A continuación realizamos las mismas comprobaciones en los valores y de los objetos. Si recorremos todos los objetos en los grupos de visualización que creamos anteriormente, deberíamos tener un sistema de colisión que funcione..
Probemos esto con las balas y los alienígenas. Necesitamos realizar estos controles solo en el juego. Así que ponga este código dentro de la parte adecuada de la función update ():
función de actualización () -: void? si PlayState._inGame entonces si PlayState._shoot == true y PlayState._ship entonces local p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) finaliza si PlayState._bullets.numChildren> 0 y PlayState._alien.numChildren> 0 para entonces b = 1, PlayState._bullets.numChildren do local bulletXMax = PlayState._bullets [b] .contentBounds.xMax local bulletXMin = PlayState._bullets [b] .contentBounds.xMin local bulletYMax = PlayState._bullets [b]. bulletYMin = PlayState._bullets [b] .contentBounds.yMin para a = 1, PlayState._aliens.numChildren do (PlayState._aliens [a] .contentBounds.xMin <= bulletXMax) then if (PlayState._aliens[a].contentBounds.xMax >= bulletXMin) entonces if (PlayState._aliens [a] .contentBounds.yMin <= bulletYMax) then if (PlayState._aliens[a].contentBounds.yMax >= bulletYMin) luego se superponen AlienBullet (PlayState._aliens [a], PlayState._bullets [b]) end end end end end end end end end end end end end
Como dije, este código parece un poco desordenado, pero funciona. Entonces que hace esto? Primero, verifica si existe una bala o un alienígena. Este código puede llegar a ser realmente un gran uso de memoria, por lo que tenemos que revisar todo. No queremos perder tiempo si ni siquiera tenemos los dos tipos de objetos. Una vez que ese código pasa, comenzamos un bucle for. Este bucle establece una variable ("b" nombrada después de "viñetas") en 1 y ejecuta el resto del código para cada viñeta en _bullets. Las siguientes cuatro líneas de código crean una copia local de los valores mínimo y máximo de la viñeta. Como dije antes, necesitamos guardar memoria aquí. No necesitamos estar calculando los valores de las viñetas xey una y otra vez si no están cambiando. La siguiente línea comienza con otro bucle. Este se repite para todos los alienígenas en los extraterrestres. El código dentro del segundo bucle for solo realiza las comprobaciones de las que hablamos anteriormente. ¿Es el valor máximo x de la bala mayor que el valor mínimo x del extranjero? No puedo enfatizar lo suficiente la memoria aquí, que
Es por eso que estamos verificando cada condición en una declaración if separada. Si una de esas pruebas falla, podemos abandonar el ciclo. No hay necesidad de continuar verificando si no hay colisión. Finalmente, en el mismo centro, si todas esas comprobaciones pasan, llamamos a nuestra función overlapAlienBullet () con la bala y alienígena en colisión..
Uf. Eso fue un montón de código. Ahora solo tenemos que hacer lo mismo para el barco..
función de actualización () -: void? si PlayState._inGame entonces si PlayState._shoot == true y PlayState._ship entonces local p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) end? Si PlayState._aliens.numChildren> 0 entonces local shipXMax = PlayState._ship.contentBounds.xMax local shipXMin = PlayState._ship.contentBounds.xMin local.P.P.P.P.P.P.P.P.P. a = 1, PlayState._aliens.numChildren hacer si (PlayState._aliens [a] .contentBounds.xMin <= shipXMax) then if (PlayState._aliens[a].contentBounds.xMax >= shipXMin) entonces if (PlayState._aliens [a] .contentBounds.yMin <= shipYMax) then if (PlayState._aliens[a].contentBounds.yMax >= shipYMin) luego se superponen AlienShip (PlayState._aliens [a], PlayState._ship) end end end end end end end end end end end end end
Este código es idéntico al código de bala y extranjero. La única diferencia es que solo tenemos un barco. Sabemos que hay una nave, de lo contrario PlayState._inGame sería falso. No necesitamos recorrer un grupo de barcos de visualización porque solo tenemos uno.
Antes de que podamos probar este código, debemos hacer que el juego termine en overlapAlienShip (). Cambia _injuego a falso.
function overlapAlienShip (alien, ship) -: void ship: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false --_ gameOverText = new FlxText (0, FlxG.height / 2, FlxG .width, "GAME OVER \ nPRESS ENTER TO PLAY OTRA VEZ") --_ gameOverText.setFormat (null, 16, 0xFF597137, "center") --add (_gameOverText) end
Ejecutar el código ahora muestra que nuestro arduo trabajo ha dado sus frutos. Ahora tenemos un puerto completamente funcional del juego original. Todavía tenemos que recrear el sistema de puntuación, y necesitamos poder reiniciar el juego, pero la adaptación dura ha finalizado..
Vamos a empezar con el sistema de puntuación. Esto es tan simple como crear una etiqueta de texto y actualizarla cuando cambia la puntuación. Descomente la línea _scoreText y agregue una nueva propiedad _score en las declaraciones de create ().
function create () -: void - declaraciones de variables PlayState._inGame = true PlayState._background = nil PlayState._ship = nil PlayState._aliens = nil PlayState._bullets = nil PlayState._score = nil PlayState._scoreText = nil --PlayState ._gameOverText = nil PlayState._spawnTimer = nil PlayState._spawnInterval = 2.5 PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? fin
Ahora tenemos que asignarles algunos valores. _score solo se puede establecer en 0. _scoreText debe asignarse un nuevo objeto de texto ubicado en la parte superior izquierda de la pantalla.
funcion create () -: void? - asignaciones variables PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125) PlayState._ship = Ship.new () PlayState._shoot = false PlayState._aliens = display.newGroup () PlayState._bullets = display.newGroup () PlayState._score = 0 PlayState._scoreText = display.newText ("0", 10, 8, nil, 32) PlayState._scoreText: setTextColor (89 , 113, 55) PlayState.SoundBullet = media.newEventSound ("Bullet.caf") PlayState.SoundExplosionShip = media.newEventSound ("ExplosionShip.asf.asf") Pops.A. = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer () final
La API newText es simple: display.newText ("texto para mostrar", posición x, posición y, fuente, tamaño). "PlayState._scoreText: setTextColor (89, 113, 55)" solo establece el color de relleno en el mismo color verde que las viñetas. Todo lo que necesitamos ahora es actualizar la puntuación en overlapAlienBullet ():
function overlapAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () media.playEventSound (PlayState.SoundExplosionAlien) PlayState._score = PlayState._score + 1 PlayState._scoreText.text = PlayState._score end
Esto simplemente agrega 1 a la propiedad _score cuando una bala mata a un extranjero. Luego cambia la propiedad de texto de _scoreText al valor de la puntuación.
Antes de terminar este juego, necesitamos alguna forma de reiniciarlo. De esa manera, el usuario puede comenzar de nuevo cuando muera. Tendremos que hacer esto en dos pasos. Primero, debemos detener todo lo que el usuario pueda controlar tan pronto como el barco muera. Luego, tenemos que restablecer todo lo demás cuando el usuario toca para comenzar un nuevo juego..
Apaguemos todos los botones en la función overlapAlienShip (). Además, vamos a quitar la propiedad de la nave. Podemos hacer esto estableciendo todos los valores a nil.
function overlapAlienShip (alien, ship) -: void ship: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = nil PlayState._upButton.onPress = nil PlayState._upButton. onRelease = nil PlayState._downButton.onPress = nil PlayState._downButton.onRelease = nil PlayState._leftButton.onPress = nora del estado de la embarcación de la embarcación. = nil PlayState._shootButton.onRelease = nil --_ gameOverText = new FlxText (0, FlxG.height / 2, FlxG.width, "GAME OVER \ nPRESS ENTER TO PLAY AGAIN") --_ gameOverText.setFormat (null, 16, 0xFF597 , "centro") --add (_gameOverText) fin
Este código simplemente asigna todos los valores onPress y onRelease a nil. Los botones seguirán
pantalla, pero no llamarán ningún código cuando se presionan.
Ahora vemos que la función original de superposición Alienal () mostraba una etiqueta de texto para decirle al usuario que el juego había terminado. Haremos lo mismo. Primero elimine el comentario de nuestra propiedad _gameOverText en la función create ().
function create () -: void - declaraciones de variables PlayState._inGame = true PlayState._background = nil PlayState._ship = nil PlayState._aliens = nil PlayState._bullets = nil PlayState._score = nil PlayState._scoreText = nil PlayState._gameOest = nil PlayState._spawnTimer = nil PlayState._spawnInterval = 2.5 PlayState.SoundExplosionShip = nil PlayState.SoundExplosionAlien = nil PlayState.SoundBullet = nil? fin
De vuelta en overlapAlienShip (), necesitamos reemplazar el código comentado con estas líneas.
function overlapAlienShip (alien, ship) -: void ship: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = nil PlayState._upButton.onPress = nil PlayState._upButton. onRelease = nil PlayState._downButton.onPress = nil PlayState._downButton.onRelease = nil PlayState._leftButton.onPress = nora del estado de la embarcación de la embarcación. = nil PlayState._shootButton.onRelease = nil PlayState._gameOverText = display.newText ("GAME OVER TAP TO PLAY OTRA VEZ", 35, display.contentHeight / 2 - 50, nil, 16) PlayState._gameOverText: setTextColor (89) 55) fin
Este es el mismo código que usamos para crear y rellenar el texto de puntuación. La posición se cambia para centrar el texto en la pantalla, y el texto dice "TAP TO PLAY TO REAIN" en lugar de "PRESS ENTER TO RE OIN".
Como vamos a hacer tapping para reiniciar el juego, necesitamos agregar un nuevo detector de eventos. Podemos hacer esto de la misma manera que agregamos el oyente enterFrame, pero esta vez el evento que estamos escuchando es "tap". También necesitamos agregar una función para que el oyente llame. En la parte inferior de overlapAlienShip (), agregue este detector de eventos:
function overlapAlienShip (alien, ship) -: void ship: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = nil PlayState._upButton.onPress = nil PlayState._upButton. onRelease = nil PlayState._downButton.onPress = nil PlayState._downButton.onRelease = nil PlayState._leftButton.onPress = nora del estado de la embarcación de la embarcación. = nil PlayState._shootButton.onRelease = nil PlayState._gameOverText = display.newText ("GAME OVER TAP TO PLAY OTRA VEZ", 35, display.contentHeight / 2 - 50, nil, 16) PlayState._gameOverText: setTextColor (89) 55) Runtime: addEventListener ("tap", tap) end
Este código busca un toque en cualquier lugar de la pantalla. Cuando se produce un "toque", llama a la función tap (). Hagamos una función de toque () vacía para que llame. Ponlo justo encima de crear ().
? function tap (evento): solo necesitamos esto como marcador de posición para ahora end function create ()? fin
Hagamos una función remove () para manejar la limpieza de todos los objetos del juego. Ponga esta función por encima de nuestra nueva función tap ().
? function remove () - end function tap (event) - solo necesitamos esto como un marcador de posición para ahora end function create ()? fin
Para empezar, deberíamos matar a todos los alienígenas y balas restantes. Para hacer esto, simplemente podemos recorrer los respectivos grupos de visualización. Esta es la forma correcta de eliminar objetos en Corona:
Función remove () para i = PlayState._bullets.numChildren, 1, -1 do PlayState._bullets [i]: kill () end para i = PlayState._aliens.numChildren, 1, -1 do PlayState._aliens [i]: kill () end PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil end
Estos bucles funcionan de una manera especial. Cada bucle comienza con "i" establecido en el último objeto en los grupos de visualización. Entonces el bucle mata ese objeto y resta 1 de "i". El bucle se repite hasta que "i" sea igual a 1. La razón por la que estamos restando de "i" es que cada vez que eliminamos un objeto, este se elimina del grupo de visualización. Esto significa que hay un objeto menos en el grupo de visualización. Si tuviéramos que agregar 1 a "i", terminaríamos llamando a kill () en objetos que ya no existen. Para solucionar esto, contamos hacia atrás cada vez que eliminamos un objeto..
Después de eliminar todos los objetos de los grupos, eliminamos los grupos. También establecemos las propiedades que mantenían a los grupos en cero. Ahora se pueden usar de nuevo..
Vamos a establecer todas las variables utilizadas en cero. De esta manera el recolector de basura puede liberar la memoria. Esto también asegurará que todas las variables se reinicien antes de comenzar un nuevo juego. Quite todos los botones primero:
Función remove () para i = PlayState._bullets.numChildren, 1, -1 do PlayState._bullets [i]: kill () end para i = PlayState._aliens.numChildren, 1, -1 do PlayState._aliens [i]: kill () final PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil PlayState._upButton: removeSelf. = nil PlayState._leftButton: removeSelf () PlayState._leftButton = nil PlayState._rightButton: removeSelf () PlayState._rightButton = nil PlayState._shootButton: removeSelf () PlayState._shootButton = nil end
Primero debemos eliminarlos de la pantalla y luego establecerlos en cero. Cuidemos nuestros sonidos ahora.
Función remove () para i = PlayState._bullets.numChildren, 1, -1 do PlayState._bullets [i]: kill () end para i = PlayState._aliens.numChildren, 1, -1 do PlayState._aliens [i]: kill () final PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil PlayState._upButton: removeSelf. = nil PlayState._leftButton: removeSelf () PlayState._leftButton = nil PlayState._rightButton: removeSelf () PlayState._rightButton = n ión de la gástrica SoundBullet = nil end
Ahora nuestros objetos de texto:
función eliminar ()? PlayState._scoreText: removeSelf () PlayState._scoreText = nil PlayState._gameOverText: removeSelf () PlayState._gameOverText = nil end
Para terminar de limpiar, necesitamos eliminar a nuestros oyentes de eventos. Después de eso, finalmente podemos restablecer PlayState a una matriz vacía:
función eliminar ()? Tiempo de ejecución: removeEventListener ("enterFrame", actualización) Tiempo de ejecución: removeEventListener ("toque", toque) PlayState = nil PlayState = fin
Reiniciar el juego es tan simple como llamar a remove () y luego a create () en nuestra función tap ().
función tap (evento) remove () create () end
Casi terminamos. Solo tenemos que hacer algunos toques finales. Comience por eliminar todas las líneas comentadas del código fuente antiguo. Esto limpiará nuestros archivos una tonelada.
Otro ajuste rápido que podemos hacer es habilitar multitouch. No notará el cambio en el simulador, pero es bueno poder presionar varios botones a la vez en el dispositivo real. Este es un ajuste de una línea. Solo necesitamos que suceda una vez, así que vamos a agregarlo al archivo main.lua.
local PlayState = requiere ("PlayState") función Main () system.activate ("multitouch") display.setStatusBar (display.HiddenStatusBar) PlayState.PlayState () end Main ()
También estaba teniendo problemas con el módulo ui.lua. Los botones no cuentan para sacar el dedo del dispositivo y soltarlo, a menos que el último lugar tocado sea el botón. Esto no siempre funciona correctamente para este juego en particular, y algunas veces la nave parece moverse solo porque la función de liberación no se llama. Esta fue una solución simple. Retiré la comprobación para ver si se presionaba el botón cuando se soltó el dedo de los usuarios. Esto solo significaba comentar las declaraciones if y end en las líneas 91 y 98.
? si "terminó" == fase entonces - Solo considere esto como un "clic" si el usuario levanta el dedo dentro de stageBounds del botón - si esWithinBounds entonces si onEvent entonces buttonEvent.phase = "release" result = onEvent (buttonEvent) elseif onRelease then result = onRelease (evento) end --end end?
Estos cambios se incluyen en el archivo ui.lua incluido en este tutorial..
Terminamos. Ahora tenemos una réplica completamente funcional del juego flash original. Tenemos una nave que se mueve y dispara, alienígenas y un sistema de puntuación. El juego gestiona la memoria de todos los objetos, y tiene la capacidad de reiniciar y comenzar de nuevo. Aparte del sistema de partículas, este juego es un puerto idéntico. Ahora que ha completado este tutorial, debe tener conocimientos suficientes para conectar casi cualquier juego flash / actionscript al iPhone.
A muchos desarrolladores les gusta agregar funcionalidad o cambiar un poco la jugabilidad cuando se transfiere un juego a un dispositivo móvil. Me gustaría desafiarte a mejorar / modificar este juego para hacerlo más como una aplicación real. Puede cambiar el esquema de control a cualquiera de los tipos de los que hablamos en la lección 2. Puede crear un menú con configuraciones o niveles múltiples. Puedes añadir diferentes tipos de enemigos. Puede agregar un sistema local o en línea de puntuación más alta. Las posibilidades son infinitas. Afortunadamente, Corona hace que el desarrollo sea realmente rápido y realmente suave. Espero que hayas disfrutado este tutorial y, lo que es más importante, hayas aprendido mucho. Deja un comentario aba