Portage de jeux ActionScript sur iOS avec le SDK Corona troisième partie

Ce tutoriel examinera le portage d’un jeu Flash / Flex dans le SDK Corona. Plus précisément, nous allons transférer d'ActionScript vers Lua, l'objectif final étant de jouer à des jeux autrefois uniquement Flash sur l'iPhone. En plus de démontrer les différences de langage et d'API, cette série de didacticiels tiendra également compte des restrictions matérielles telles que la taille de l'écran et le manque de boutons physiques sur l'iPhone..

Ajout d'ennemis

Nous allons maintenant commencer à travailler avec notre ennemi: "de / pixelate / flixelprimer / Alien.as". Comme toujours, la syntaxe est convertie en premier.

Lorsque vous avez terminé, ajoutez la décélération du module et enveloppez toutes les fonctions à l'intérieur de Alien ().

 module (?, package.seeall) - [Embed (source = "? /? /? /? /assets/png/Alien.png")] private var ImgAlien: Fonction de classe Alien (x, y) -: void super (x, y, ImgAlien) vélocité.x = -200 fonction update () -: void vélocité.y = Math.cos (x / 50) * 50 super.update () fin fin

L'étranger fonctionne très semblable à notre balle. Il crée une image, définit ses x et y
coordonnées, et lui donne une vitesse. Donc, nous allons l'aborder de la même manière. Les deux lignes supérieures de la fonction peuvent être remplacées par le même code que celui utilisé pour la puce. Cette fois, nous utiliserons une image si.

 module (?, package.seeall) fonction Alien (x, y) -: void local Alien = display.newImage ("Alien.png") Alien.x = x Alien.y = y fonction update () -: void ? fin fin

Maintenant que l'image est chargée et définie, faisons en sorte qu'elle se déplace vers la gauche. Encore une fois, nous allons créer quelque chose comme le code update () de notre puce. Laissez les anciennes lignes dans update () commenté.

 module (?, package.seeall) fonction Alien (x, y) -: void? function update () -: void if Alien then if (Alien.x> 0 - Alien.contentWidth), puis Alien.x = Alien.x - 2 end end? code commenté? end Runtime: addEventListener ("enterFrame", update) end

Faisons maintenant une fonction kill () et faisons en sorte que Alien retourne un Alien.

 module (?, package.seeall) fonction Alien (x, y) -: void? function update () -: void? fonction d'extrémité Alien: kill () Alien.parent: remove (Alien) Alien = nil end Durée d'exécution: addEventListener ("enterFrame", update) retourne Alien end

Maintenant, nous pouvons tuer () notre extraterrestre s'il est hors de l'écran à gauche. Nous pouvons aussi ajouter une nouvelle fonction () comme commodité.

 module (?, package.seeall) fonction Alien (x, y) -: void local Alien = display.newImage ("Alien.png") Alien.x = x Alien.y = y fonction update () -: void si Alien, puis si (Alien.x> 0 - Alien.contentWidth), alors Alien.x = Alien.x - 2 sinon Alien: kill () end end function, Alien: kill () Alien.parent: remove (Alien) Alien = nil end Runtime: addEventListener ("enterFrame", update) retourne la fonction de fin Alien new (x, y) retourne la fin de Alien (x, y)

Utiliser les timers pour contrôler les extraterrestres

Créer l'extraterrestre était assez facile. Nous devons maintenant commencer à les ajouter au jeu via PlayState.

Commencez par importer le module dans PlayState.lua..

 module (?, package.seeall) local Ship = require ("Ship") local Bullet = require ("Bullet") local Alien = require ("Alien") local Buttons = require ("Boutons")

Nous devons maintenant configurer une minuterie. Le code d'origine avait une variable _spawnInterval utilisée pour définir _spawnTimer. Chaque fois que _spawnTimer atteint 0, il sera réinitialisé à la valeur _spawnInterval._spawnInterval sera alors diminué de .1, ce qui accélérera l'apparition des extraterrestres..

Pour commencer, décommentez les déclerations de la propriété _spawnInterval et _spawnTimer dans create ().

 function create () -: void - déclarations 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

Maintenant, dans les affectations de variable, définissez _spawnTimer sur 0 et _spawnInterval sur 2,5. Ajoutez également un appel à resetSpawnTimer (). Nous allons créer cette fonction dans une seconde.

 function create () -: void? - affectations de 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

Recherchez maintenant la fonction commentée resetSpawnTimer (). Ça va ressembler à quelque chose comme ça.

 function resetSpawnTimer () -: void _spawnTimer = _spawnInterval _spawnInterval = _spawnInterval * 0.95 si (_spawnInterval < 0.1) then _spawnInterval = 0.1 end end

Étonnamment, c'est exactement ce dont nous avons besoin. Nous devons juste faire les propriétés variables de PlayState. De cette façon, la fonction saura de quoi on parle _spawnInterval et _spawnTimer.

 function resetSpawnTimer () -: void PlayState._spawnTimer = PlayState._spawnInterval PlayState._spawnInterval = PlayState._spawnInterval * 0,95 si (PlayState._spawnInterval < 0.1) then PlayState._spawnInterval = 0.1 end end

Nous devons maintenant ajouter du code pour mettre à jour (). Dans le code original, le jeu créait des extraterrestres même si le jeu était terminé et que le navire était mort. Afin de faire la même chose, mettons notre code de manipulation extraterrestre en dehors de l'endroit où nous vérifions si le jeu est terminé..

 function update () PlayState._spawnTimer = PlayState._spawnTimer - (30/1000) si (PlayState._spawnTimer < 0) then spawnAlien() resetSpawnTimer() end if PlayState._inGame then? end end

Ce code fonctionne exactement comme le code source. Il soustrait une durée de 1 image à _spawnTimer. Il vérifie ensuite si _spawnTimer est inférieur à zéro. Si c'est le cas, il réinitialise le chronomètre et génère un nouvel extraterrestre.

Un autre groupe d'affichage

Avant de pouvoir engendrer des extraterrestres, nous avons besoin d'un groupe d'affichage pour les ajouter. Tout comme _bullets, décommentez la décleration de _aliens et affectez-les à un nouveau groupe.

 function create () -: void - déclarations de variable 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 - attributions variables PlayState._background = display.newRect (0, 0, display) 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

Maintenant, trouvez votre fonction spawnAlien () et décommentez-la. Ça devrait ressembler a quelque chose comme ca:

 function spawnAlien () -: void local x = FlxG.width local y = Math.random () * (FlxG.height - 100) + 50 _aliens.add (nouvel Alien (x, y)) fin

Ce code crée un étranger juste à la droite de l'écran et à une hauteur aléatoire. Ensuite, il ajoute le nouvel étranger au groupe d'affichage. Nous pouvons faire la même chose avec ce code:

 function spawnAlien () -: void local x = display.contentWidth local y = math.random () * (display.contentHeight - 240) + 50 PlayState._aliens: insert (Alien.new (x, y)) fin

Recréer un mouvement original basé sur une onde cosinus pour les étrangers

Si nous exécutons le code maintenant, cela fonctionne presque comme l'original. Les extraterrestres apparaissent à des hauteurs aléatoires, et ils apparaissent lentement plus fréquemment. Quand ils sortent de l'écran, ils appellent kill (). Maintenant, nous devons simplement les amener à se déplacer comme ils l’ont fait dans le code original. Dans le jeu original, les extraterrestres suivaient le trajet d'une onde cosinus générée en fonction de leur emplacement x. Nous avons commenté ce code dans la fonction alciens update (). Ce code a pris un peu de jeu avec. Parce que nous n’avons pas de vélocité pour travailler, il est difficile d’utiliser le code original. C’est l’heure du portage où il ne vous reste plus qu’à jouer avec les chiffres. J'ai trouvé que ce code fonctionnait le plus près de l'original:

 function update () -: void if Alien alors if if (Alien.x> 0 - Alien.contentWidth), puis Alien.x = Alien.x - 2 Alien.y = Alien.y + math.cos (Alien.x / 10 ) * 2 else Alien: kill () fin fin fin

Traitement des collisions

Maintenant que tous nos objets de jeu fonctionnent comme les originaux, nous devons vérifier les collisions entre les balles et les extraterrestres, ainsi que les extraterrestres et le navire. Dans le code d'origine, les collisions étaient vérifiées dans la fonction update (). En cas de collision, les deux objets sont passés aux fonctions overlapAlienBullet () et overlapAlienShip (). Créons ces fonctions en premier. Si nous ne commentons pas overlapAlienBullet (), nous avons un code qui ressemble à ceci:

 function overlapAlienBullet (alien, bullet) -: void émetteur local = createEmitter () emitter.at (alien) alien.kill () bullet.kill () FlxG.play (SoundExplosionAlien) FlxG.score = FlxG.score + 1 _scoreText. text = FlxG.score.toString () end

Ce code crée un émetteur de particules, tue les deux objets, joue un effet sonore et met à jour la partition. Recréer le système de particules flixel dépasse le cadre de ce didacticiel, et nous n’avons pas encore mis en place de système de partition. Pour le moment, commentons ces lignes et éliminons les objets.

 function overlapAlienBullet (alien, bullet) -: void alien: kill () bullet: kill () --FlxG.play (SoundExplosionAlien) --FlxG.score = FlxG.score + 1 --_ scoreText.text = FlxG.score. toString () end

Faites de même pour overlapAlienShip ():

 function overlapAlienShip (alien, ship) -: void navire: kill () alien: kill () --FlxG.play (SoundExplosionShip) --_ gameOverText = nouveau FlxText (0, FlxG.height / 2, FlxG.width, "GAME OVER \ nappuyez sur Entrée pour jouer à nouveau ") --_ gameOverText.setFormat (null, 16, 0xFF597137," center ") --add (_gameOverText) end

Créons maintenant l’effet sonore à utiliser dans ces fonctions. Décommentez les déclarations de variables audio dans create ().

 function create () -: void - déclarations de variable 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

Maintenant, assignez-les à leurs sons:

 function create () -: void? - affectations de 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.SoundExplosionShip = media.newEventSound ("ExplosionShip.caf") media.newEventSound ("ExplosionAlien.caf") PlayState._spawnTimer = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer () end

Jouer les sons est aussi simple qu’une ligne par fonction ().

 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 navire: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) --_ gameOverText = nouveau FlxText (0, FlxG.height / 2, FlxG. width, "GAME OVER \ nPRESSENTEZ POUR ENTREE A NOUVEAU") --_ gameOverText.setFormat (null, 16, 0xFF597137, "center") --add (_gameOverText)

Rouler notre propre code de collision

Maintenant que nos fonctions de chevauchement sont en place, nous devons vérifier les collisions à chaque image. Dans Corona, nous ne disposons pas d'un moyen facile de vérifier les objets d'affichage qui se chevauchent. Nous devrons faire les vérifications manuellement. Ceci est un concept assez facile, mais sa mise en œuvre devient assez compliquée. Pensons à ce sujet pendant une seconde. Qu'est-ce qui définit un chevauchement? Votre premier instinct peut être de vérifier si un objet est à l'intérieur d'un autre. Cela fonctionnerait, mais dans ce cas, un chevauchement peut simplement être une partie des objets. Un objet n'a pas besoin d'être complètement à l'intérieur d'un autre pour se chevaucher. Qu'est-ce que cela ressemble dans le code? Tout ce que nous avons à faire est de vérifier si la valeur x maximale d’un objet est supérieure au minimum x
valeur de l'autre objet. Ensuite, nous vérifions si la valeur x minimale du même objet est inférieure à la valeur x maximale des autres objets. Cela reviendra vrai pour chaque chevauchement. Nous effectuons ensuite les mêmes contrôles sur les valeurs y des objets. Si nous parcourons tous les objets des groupes d’affichage que nous avons créés précédemment, nous devrions avoir un système de collision fonctionnel..

Essayons cela avec les balles et les extraterrestres. Nous devons effectuer ces vérifications uniquement dans le jeu. Mettez donc ce code à l'intérieur de la partie appropriée de la fonction update ():

 function update () -: void? si PlayState._inGame, alors si PlayState._shoot == true et PlayState._ship, puis local p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) se termine si PlayState._bullets.numChildren> 0 et PlayState._aliens.numChildren> 0 puis pour 0 b = 1, PlayState._bullets.numChildren fait 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 pour a = 1, PlayState._aliens.numChildren faire si (PlayState._aliens [a] .contentBounds.xMin <= bulletXMax) then if (PlayState._aliens[a].contentBounds.xMax >= bulletXMin) alors si (PlayState._aliens [a] .contentBounds.yMin <= bulletYMax) then if (PlayState._aliens[a].contentBounds.yMax >= bulletYMin) puis overlapAlienBullet (PlayState._aliens [a], PlayState._bullets [b]) fin fin fin fin fin fin fin fin fin

Comme je l'ai dit, ce code semble un peu brouillon, mais cela fonctionne. Alors qu'est-ce que cela fait? Tout d'abord, il vérifie si une balle ou un étranger existe même. Ce code peut devenir très gourmand en mémoire, nous devons donc tout vérifier. Nous ne voulons pas perdre de temps si nous n'avons même pas les deux types d'objets. Une fois que ce code est passé, nous commençons une boucle for. Cette boucle définit une variable ("b" nommée d'après "puces") sur 1 et exécute le reste du code pour chaque puce de _bullets. Les quatre lignes de code suivantes créent une copie locale des valeurs minimale et maximale de la puce. Comme je l'ai déjà dit, nous devons économiser de la mémoire ici. Nous n'avons pas besoin de calculer les valeurs de puces x et y à plusieurs reprises si elles ne changent pas. La ligne suivante commence une autre boucle for. Celui-ci se répète pour tous les extraterrestres d'Aliens. Le code à l'intérieur de la seconde boucle for effectue uniquement les vérifications dont nous parlions plus tôt. La valeur max x de la balle est-elle supérieure à la valeur min x de l'extraterrestre? Je ne saurais trop insister sur la mémoire, que
C’est pourquoi nous vérifions chaque condition dans une instruction if distincte. Si l'un de ces tests échoue, nous pouvons simplement sortir de la boucle. Il n'est pas nécessaire de continuer à vérifier s'il n'y a pas de collision. Enfin, au centre même, si toutes ces vérifications sont satisfaites, nous appelons notre fonction overlapAlienBullet () avec la balle en collision et alien..

Ouf. C'était beaucoup de code. Maintenant, nous devons juste faire la même chose pour le navire.

 function update () -: void? si PlayState._inGame, puis si PlayState._shoot == true et PlayState._ship, puis local p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) end? si PlayState._aliens.numChildren> 0 alors local shipXMax = PlayState._ship.contentBounds.xMax local shipXMin = PlayState._ship.contentBounds.xMin localYYMax = PlayState._ship.contentBounds.yMax local ShipYMin a = 1, PlayState._aliens.numChildren faire si (PlayState._aliens [a] .contentBounds.xMin <= shipXMax) then if (PlayState._aliens[a].contentBounds.xMax >= shipXMin) alors si (PlayState._aliens [a] .contentBounds.yMin <= shipYMax) then if (PlayState._aliens[a].contentBounds.yMax >= shipYMin) puis overlapAlienShip (PlayState._aliens [a], PlayState._ship) fin fin fin fin fin fin fin fin

Ce code est identique aux codes bullet et alien. La seule différence est que nous n'avons qu'un seul navire. Nous savons qu'il y a un navire, sinon PlayState._inGame serait faux. Nous n'avons pas besoin de parcourir un groupe de navires d'affichage car nous n'en avons qu'un.

Avant de pouvoir tester ce code, nous devons faire en sorte que le jeu se termine par overlapAlienShip (). Change _inGame en false.

 function overlapAlienShip (alien, ship) -: void navire: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false --_ gameOverText = new FlxText (0, FlxG.height / 2, FlxG .width, "GAME OVER \ n IMPRIMEZ DE NOUVEAU POUR REJOINDRE") --_ gameOverText.setFormat (null, 16, 0xFF597137, "center") --add (_gameOverText)

L'exécution du code montre maintenant que notre travail acharné a porté ses fruits. Nous avons maintenant un portage complet du jeu original. Nous avons toujours besoin de recréer le système de score et de pouvoir redémarrer le jeu, mais le portage dur est terminé..

Mise en place d'un système de partition

Commençons par le système de score. C’est aussi simple que de créer une étiquette de texte et de la mettre à jour lorsque la partition change. Décommentez la ligne _scoreText et ajoutez une nouvelle propriété _score dans les déclarations create ().

 function create () -: void - déclarations 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

Nous devons maintenant leur attribuer des valeurs. _score peut simplement être défini sur 0. _scoreText doit recevoir un nouvel objet texte situé en haut à gauche de l'écran..

 function create () -: void? - affectations de 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 = display.newText ("0", 10, 8, nil, 32) PlayState._scoreText: setTextColor (89) , 113, 55) PlayState.SoundBullet = media.newEventSound ("Bullet.caf") PlayState.SoundExplosionShip = media.newEventSound ("ExplosionShip.caf") PlayState.SoundExplosionAlien = media.newEventSound ("ExplosionShip.caf") PlayState.SoundExplosionAlien = media.newEventSound ("ExplosionShip.caf") = 0 PlayState._spawnInterval = 2.5 resetSpawnTimer () end

L'API newText est simple: display.newText ("texte à afficher", position x, position y, police, taille). "PlayState._scoreText: setTextColor (89, 113, 55)" définit simplement la couleur de remplissage sur la même couleur verte que les puces. Tout ce dont nous avons besoin maintenant, c'est de mettre à jour le score dans 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

Cela ajoute simplement 1 à la propriété _score lorsqu'un étranger est tué par une balle. Ensuite, la propriété text de _scoreText est remplacée par la valeur de la partition..

Jeu terminé

Avant de terminer ce jeu, nous avons besoin d’un moyen de le réinitialiser. De cette façon, l'utilisateur peut recommencer lorsqu'il meurt. Nous devrons le faire en deux étapes. Tout d’abord, nous devons arrêter tout ce que l’utilisateur peut contrôler dès que le navire meurt. Ensuite, nous devons réinitialiser tout le reste lorsque l'utilisateur appuie sur pour démarrer un nouveau jeu..

Désactivons tous les boutons de la fonction overlapAlienShip (). En outre, supprimons la propriété du navire. Nous pouvons le faire en définissant toutes les valeurs sur nil.

 function overlapAlienShip (alien, ship) -: void navire: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = nil PlayState._upButton.on_Press / nil PlayState._upButton. onLelease = nil PlayState._downButton.onPress = nil PlayState._LeButton.onRease = nil PlayState._RightButton = nil PlayState._shootButton.onRelease = nil --_ gameOverText = new FlxText (0, FlxG.height / 2, FlxG.width, "GAME OVER \ nPRESSAY DE JOUER À NOUVEAU") --_ gameOverText.setFormat (null, 16, 0xFF59713) , "center") --add (_gameOverText) end

Ce code affecte simplement toutes les valeurs onPress et onRelease à nil. Les boutons seront toujours
afficher, mais ils n'appellent pas de code quand on appuie dessus.

Message de fin de partie

Nous voyons maintenant que la fonction originale overlapAlienShip () affichait une étiquette de texte pour informer l'utilisateur que le jeu était terminé. Nous ferons la même chose. Décomment tout d'abord notre propriété _gameOverText dans la fonction create ().

 function create () -: void - déclarations de variable 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

De retour dans overlapAlienShip (), nous devons remplacer le code commenté par ces lignes.

 function overlapAlienShip (alien, ship) -: void navire: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = nil PlayState._upButton.on_Press / nil PlayState._upButton. onLelease = nil PlayState._downButton.onPress = nil PlayState._LeButton.onRease = nil PlayState._RightButton = nil PlayState._shootButton.onRelease = nil PlayState._gameOverText = display.newText ("JEU TAP TO PLAY AGAIN", 35, display.contentHeight / 2 - 50, nil, 16) PlayState._gameOverText: setTextColor (89, 113, 55) fin

C'est le même code que nous avons utilisé pour créer et remplir le texte de la partition. La position est modifiée pour centrer le texte à l'écran et le texte indique "APPUYER POUR JOUER ENCORE" au lieu de "APPUYER SUR ENTREE POUR JOUER ENCORE"..

Ajouter un écouteur

Comme nous allons appuyer sur pour redémarrer le jeu, nous devons ajouter un nouvel écouteur d'événement. Nous pouvons faire cela de la même manière que nous avons ajouté le listener enterFrame, mais cette fois l'événement que nous écoutons est "tap". Nous devons également ajouter une fonction pour que l’auditeur appelle. Au bas de overlapAlienShip (), ajoutez cet écouteur d'événement:

 function overlapAlienShip (alien, ship) -: void navire: kill () alien: kill () media.playEventSound (PlayState.SoundExplosionShip) PlayState._inGame = false PlayState._ship = nil PlayState._upButton.on_Press / nil PlayState._upButton. onLelease = nil PlayState._downButton.onPress = nil PlayState._LeButton.onRease = nil PlayState._RightButton = nil PlayState._shootButton.onRelease = nil PlayState._gameOverText = display.newText ("JEU TAP TO PLAY AGAIN", 35, display.contentHeight / 2 - 50, nil, 16) PlayState._gameOverText: setTextColor (89, 113, 55) Durée: addEventListener ("tap", tap) fin

Ce code vérifie si vous appuyez sur n’importe où sur l’écran. Lorsqu'un "tap" se produit, il appelle la fonction tap (). Faisons une fonction tap () vide pour qu'elle appelle. Mettez-le juste au-dessus de create ().

? function tap (event) - nous avons juste besoin de cela en tant qu'espace réservé pour maintenant end function create () fin

Tout nettoyer

Créons une fonction remove () pour gérer le nettoyage de tous les objets du jeu. Placez cette fonction au-dessus de notre nouvelle fonction tap ().

? function remove () - end function tap (événement) - nous en avons simplement besoin comme espace réservé pour l'instant end function create ()? fin

Supprimer des objets et des groupes d'affichage

Pour commencer, nous devrions tuer tous les extraterrestres et les balles restants. Pour ce faire, nous pouvons simplement parcourir les groupes d’affichage respectifs. Voici le moyen approprié pour supprimer des objets dans Corona:

 function remove () pour i = PlayState._bullets.numChildren, 1, -1 dans PlayState._bullets [i]: kill () end pour i = PlayState._aliens.numChildren, 1, -1 dans PlayState._aliens [i]: kill () end PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil fin

Ces boucles fonctionnent de manière spéciale. Chaque boucle commence par "i" défini sur le dernier objet des groupes d'affichage. Ensuite, la boucle tue cet objet et soustrait 1 de "i". La boucle se répète jusqu'à ce que "i" soit égal à 1. La raison pour laquelle nous soustrayons de "i" est que chaque fois que nous éliminons un objet, il se supprime du groupe d'affichage. Cela signifie qu'il y a un objet de moins dans le groupe d'affichage. Si nous devions ajouter 1 à "i", nous finirions par appeler kill () sur des objets qui n'existent plus. Pour résoudre ce problème, nous comptons en arrière chaque fois que nous supprimons un objet.

Une fois que tous les objets ont été supprimés des groupes, nous les supprimons. Nous avons également défini les propriétés contenant les groupes sur nil. Maintenant, ils peuvent être utilisés à nouveau.

Nil-ing out variables pour le ramasse-miettes

Définissons toutes les variables utilisées sur nil. De cette façon, le ramasse-miettes peut libérer de la mémoire. Cela permettra également de s'assurer que toutes les variables sont réinitialisées avant de commencer une nouvelle partie. Supprimez tous les boutons en premier:

 function remove () pour i = PlayState._bullets.numChildren, 1, -1 dans PlayState._bullets [i]: kill () end pour i = PlayState._aliens.numChildren, 1, -1 dans PlayState._aliens [i]: kill () end PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil PlayState._upButton: removeSelf () PlayState._upButton = nil PlayState._downButton: removemental () = nil PlayState._leftButton: removeSelf () PlayState._leftButton = nil PlayState._rightButton: removeSelf () PlayState._rightButton = nil PlayState._shootButton: removeSelf () PlayState._shootButton:

Nous devons d'abord les supprimer de l'écran, puis les régler sur nil. Prenons soin de nos sons maintenant.

 function remove () pour i = PlayState._bullets.numChildren, 1, -1 dans PlayState._bullets [i]: kill () end pour i = PlayState._aliens.numChildren, 1, -1 dans PlayState._aliens [i]: kill () end PlayState._bullets: removeSelf () PlayState._bullets = nil PlayState._aliens: removeSelf () PlayState._aliens = nil PlayState._upButton: removeSelf () PlayState._upButton = nil PlayState._downButton: removemental () = nil PlayState._leftButton: removeSelf () PlayState._leftButton = nilS'il vous plaît SoundBullet = nil end

Maintenant nos objets texte:

 fonction remove ()? PlayState._scoreText: removeSelf () PlayState._scoreText = nil PlayState._gameOverText: removeSelf () PlayState._gameOverText = nil fin

Supprimer les écouteurs d'événement

Pour terminer le nettoyage, nous devons retirer nos écouteurs d'événements. Après cela, nous pouvons enfin réinitialiser PlayState sur un tableau vide:

 fonction remove ()? Durée: removeEventListener ("enterFrame", mise à jour) Durée: removeEventListener ("taper", taper) PlayState = nil PlayState =  end

Jeu de redémarrage

Redémarrer le jeu est aussi simple qu'appeler remove () puis create () dans notre fonction tap ().

 function tap (événement) remove () create () end

Final Tweaks

On a presque fini. Nous avons juste besoin de mettre quelques touches finales. Commencez par supprimer toutes les lignes commentées de l'ancien code source. Cela va nettoyer nos fichiers une tonne.

Activer le multitouch

Un autre ajustement rapide que nous pouvons faire est d'activer le multitouch. Vous ne remarquerez pas le changement sur le simulateur, mais il est agréable de pouvoir appuyer sur plusieurs boutons à la fois sur le périphérique réel. Ceci est un ajustement d'une ligne. Nous avons seulement besoin que cela se produise une fois, ajoutons-le au fichier main.lua.

 local PlayState = require ("PlayState") fonction Main () system.activate ("multitouch") display.setStatusBar (display.HiddenStatusBar) PlayState.PlayState () et fin ()

Modification de la bibliothèque d'interface utilisateur pour répondre à nos besoins

J'avais aussi des problèmes avec le module ui.lua. Les boutons ne comptent pas en tirant un doigt sur l'appareil, sauf si le dernier endroit touché est le bouton. Cela ne fonctionne pas toujours correctement pour ce jeu en particulier, et parfois le vaisseau semble bouger tout seul car la fonction de libération n’est pas appelée. C'était une solution simple. J'ai retiré le chèque pour voir si le bouton était enfoncé lorsque le doigt de l'utilisateur a été relâché. Cela signifiait simplement commenter les déclarations if et end aux lignes 91 et 98..

? si "terminé" == phase alors - Ne considérez ceci comme un "clic" que si l'utilisateur lève son doigt à l'intérieur du stageBounds du bouton --si isWithinBounds puis si onEvent puis buttonEvent.phase = "release" result = onEvent (buttonEvent) elseif onRelease resultat = onRelease (event) end - end end? 

Ces modifications sont incluses dans le fichier ui.lua inclus dans ce tutoriel..

Conclusion

Nous avons finis. Nous avons maintenant une réplique entièrement fonctionnelle du jeu flash original. Nous avons un navire qui bouge et tire, des extraterrestres et un système de pointage. Le jeu gère la mémoire de tous les objets, et a la possibilité de réinitialiser et de recommencer. Autre que le système de particules, ce jeu est un port identique. Maintenant que vous avez terminé ce didacticiel, vous devez disposer de suffisamment de connaissances pour porter presque tous les jeux flash / actionscript