Portage de jeux ActionScript sur iOS avec le SDK Corona partie 2

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..

Ce tutoriel reprend où la première partie a commencé.

Créer le navire

Commencez par porter la syntaxe à partir du fichier source "de / pixelate / flixelprimer / Ship.as" comme décrit
dans le jour un post. Plus précisément, vous devrez:

  • Débarrassez-vous des déclarations de paquet et de classe.
  • Supprimer les déclarations de type.
  • Ajouter "local" à toutes les variables.
  • Remplacer les crochets conditionnels par "then" et "end".
  • Supprimer tous les points-virgules et tout commenter.

Maintenant, ajoutez la déclaration de module en haut du fichier afin que nous puissions importer le fichier dans PlayState.
En outre, encapsulez tout le code avec une fonction de constructeur Ship (). Votre code devrait maintenant être arrangé comme ceci:

 module (?, package.seeall) function Expédier ()? tout le code commenté va ici? fin

Nous n'avons pas flixel, alors supprimez la déclaration d'importation correspondante. Maintenant, regardez les lignes du haut de notre
Fonction Ship ():

 function Ship () - [Intégrer (source = "? /? /? /? /assets/png/Ship.png")] private var ImgShip: Classe - [[fonction Ship () -: void super (50 , 50, ImgShip) end -]]? fin

La première ligne charge l'image du navire et la stocke dans la variable ImgShip. Les prochaines lignes sont
l'ancienne méthode constructeur. Lorsque le navire a été créé, cette fonction lui a attribué l'image ImgShip et les coordonnées (50, 50). Nous pouvons faire la même chose en créant une variable Ship contenant une image. Nous pouvons charger l'image à l'aide du module d'affichage que nous avons utilisé dans la leçon 1. Ensuite, nous pouvons définir les propriétés des variables x et y sur 50. Remplacez les lignes ci-dessus pour obtenir ce qui suit:

 fonction Ship () local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? code commenté? fin

Maintenant, faisons en sorte que notre fonction Ship () retourne Ship afin que notre PlayState puisse l'utiliser.

 fonction Ship () local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? code commenté? retour fin de navire

Dans notre source ActionScript, un navire est créé dans PlayState en appelant "new Ship ()". Tant que nous sommes à
faisons cela, faisons une fonction new () qui retourne Ship ().

 fonction Ship () local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50? code commenté? return Ship end, fonction new () return Ship () end

Vraiment, cela n’a aucun besoin technique, mais cela rend notre code un peu plus lisible..

Retournez sur PlayState.lua et demandez à notre module Expéditions en haut..

 module (?, package.seeall) local Ship = require ("Ship"), fonction PlayState ()? 

Nous pouvons maintenant créer un nouveau navire. Tout d'abord, déplacez toutes les déclarations de variable commentées du haut du fichier vers la fonction create ().

 module (?, package.seeall) local Ship = require ("Ship"), fonction PlayState () local PlayState = ? un tas de code commenté? function create () -: void PlayState._inGame = true --local _ship --local _aliens --local _bullets --local _scoreText --local _gameOverText --local _spawnTimer --local _spawnInterval = 2.5 PlayState._background = display.newRect (0, 0, display.contentWidth, display.contentHeight) PlayState._background: setFillColor (171, 204, 125)? commenté la logique create ()? end create () end

En les laissant commentés, faites-en des propriétés de PlayState. Définissez les propriétés sans valeur sur nil. Pendant que nous y sommes, nous devons faire une déclaration _background.

? PlayState._background = nil --PlayState._ship = nil --PlayState._aliens = nil --PlayState._bullets = nil --PlayState._scoreText = nil --PlayState._GameOverText = nil --PlayState._spawnTate = _pawnState = PlayState = ._spawnInterval = 2.5? 

Décommentez la déclaration de la variable _ship et créez un nouveau vaisseau comme celui-ci:

 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 - affectations de variables PlayState._background = display.newRect (0, 0, display.contentWeight) PlayState._background: setFillColor , 204, 125) PlayState._ship = Ship.new ()? commenté la logique create ()? fin

Notez ici que nous attribuons d'abord _background. En effet, les objets d’affichage dans Corona sont ordonnés.
par quand ils sont créés. Nous ne serions pas en mesure de voir _ship si nous l'avions créé avant _background.

Si vous exécutez le code, il y a maintenant un vaisseau affiché à (50, 50).

Un regard sur les restrictions matérielles

Nous devons pouvoir déplacer le navire pour pouvoir jouer, mais comment pouvons-nous? Le jeu original a été conçu pour être contrôlé par un clavier. Un iPhone n'a pas de clavier. Comment pouvons-nous contourner cela? C’est l’un des nombreux facteurs à prendre en compte lors de la création d’une application pour un appareil mobile, que vous portiez du code existant ou que vous créiez une application à partir de rien. Nous en avons déjà un avec la taille de l’écran. Sur un ordinateur, les programmes sont de différentes tailles. La plupart d'entre eux sont même redimensionnables. Sur un iPhone, les applications ont toutes la même taille..

La résolution de ces problèmes peut être difficile. Contourner ces restrictions nécessite de réfléchir
en dehors de la boîte. Par exemple, nous pourrions contrôler notre navire avec des boutons à l'écran. Nous pourrions également appuyer sur l’emplacement où nous voulons que le navire se déplace. Nous pourrions même utiliser l'appareil
accéléromètre pour contrôler le navire en fonction de l'inclinaison de l'appareil. Peut-être que nous changeons un peu le gameplay et faisons en sorte que le vaisseau se contrôle lui-même. Ensuite, le joueur serait juste en charge du tir. Comme vous pouvez le constater, il existe de nombreuses possibilités pour de nouveaux styles de jeu sur iPhone.

Création de boutons virtuels

Même si bon nombre de ces idées étaient, nous allons créer des boutons à l'écran pour contrôler le vaisseau. De cette façon, le jeu sera le plus en ligne avec l'original. Je vous laisse explorer ces autres options.

Ansca Mobile a créé une bibliothèque open source pour créer des boutons virtuels. Au lieu de
construire la bibliothèque dans Corona, ils l’ont incluse en option sur leur site Web. j'ai
a inclus la nouvelle version au moment de l'écriture dans le code source de ce tutoriel. Ajouter le
"ui.lua" dans votre dossier de projet.

Rendez-vous sur votre fichier Ship.lua afin que nous puissions procéder à l’installation. Ajoutons quelques propriétés à notre variable Ship. Juste en dessous du code où nous définissons les coordonnées du navire à (50, 50), ajoutez ceci:

? local Ship = display.newImage ("Ship.png") Ship.x = 50 Ship.y = 50 Ship._up = false Ship._down = false Ship._left = false Ship._right = false? 

Nous allons les utiliser pour indiquer au navire quand il doit bouger. Si les valeurs deviennent vraies, cela signifie que vous appuyez sur les boutons correspondants..

De retour dans PlayState.lua, nous devons créer une nouvelle fonction pour gérer la création de boutons. Nous allons gérer cela en dehors de PlayState () car cela va devenir un peu compliqué. Avant de passer à autre chose,
assurez-vous que toutes les images de bouton de la source sont incluses dans ce didacticiel. Maintenant, créez une fonction buttonHandler () sous PlayState ().

? fonction PlayState ()? fin de la fonction buttonHandler (PlayState) end

Notez que buttonHandler () prend un argument: PlayState. C'est parce que nous créons
buttonHandler () en dehors de la fonction PlayState (). Si vous vous souvenez de la première leçon, cela signifie
buttonHandler () n'a aucune idée de ce qu'est la variable PlayState, car PlayState est local à la
Fonction PlayState (). Nous appellerons buttonHandler () depuis PlayState (). En passant
PlayState à buttonHandler (), nous permettons à buttonHandler () de voir et de modifier l’ensemble de PlayState et ses propriétés. Comme _ship est une propriété de PlayState, buttonHandler () pourra définir
_ship_up, _ship._down, etc..

Nous allons importer le module ui.lua dans notre fonction buttonHandler au lieu d’être en haut de
PlayState.lua. Vous verrez pourquoi plus tard.

? fonction PlayState ()? fin de la fonction buttonHandler (PlayState) local ui = require ("ui") end

Maintenant, ça va devenir un peu brouillon. Nous allons créer deux fonctions pour chaque bouton. Un
pour quand le bouton est enfoncé, et un pour quand le bouton est relâché. Quand ceux-ci sont appelés, ils définissent les propriétés du navire sur true ou false.

 function buttonHandler (PlayState) local ui = require ("ui") function upPressed () PlayState._ship._up = vrai fin fonction upReleased () PlayState._ship._up = faux fin fonction downPressed () PlayState._ship._down = vrai fin function downReleased () PlayState._ship._down = false fin function leftPressed () PlayState._ship._left = true fin function leftReleased () PlayState._ship._left = false fin fonction rightPressed () PlayState._ship._right = true fin fonction rightReleased () PlayState._ship._right = false end end

Parce que nous passons PlayState à buttonHandler (), et _ship et toutes ses propriétés appartiennent à
PlayState, nous pouvons les changer de true à false et vice-versa. Nous devons maintenant créer les boutons réels. Avec le module d'interface utilisateur importé, nous pouvons utiliser l'une de ses méthodes: newButton. Cela a une syntaxe intéressante, alors accrochez-vous.

 PlayState._upButton = ui.newButton defaultSrc = "up.png", defaultX = "50", defaultY = "50", overSrc = "up.png", overX = "50", overY = "50", onPress = upPressed, onRelease = upReleased, id = "_upButton"

Ce code appelle newButton et affecte le résultat à _upButton (une propriété de PlayState). En premier,
vous vous demandez peut-être pourquoi il y a des crochets. Ce n'est pas une exception aux règles de la syntaxe Lua.
En réalité, les crochets contiennent un tableau de paramètres transmis à la méthode newButton. Il y a beaucoup de paramètres ici, alors examinons-les un à la fois. Le premier, defaultSrc, est l'emplacement de l'image à utiliser lorsque vous n'appuyez pas sur le bouton. defaultX et defaultY sont les dimensions de l'image. overSrc est l'emplacement de l'image à afficher lorsque vous appuyez sur le bouton. Dans ce cas, nous allons utiliser la même image. overX et overY fonctionnent exactement comme defaultX et defaultY, mais ce sont les dimensions de overSrc. onPress est la fonction à appeler lorsque le bouton est enfoncé. C'est l'une des fonctions que nous avons créées précédemment. onRelease est identique à onPress, mais il est appelé à la libération du bouton. id est une chaîne nommée pour distinguer ce bouton des autres. Chaque bouton a une propriété x et y, exactement comme les autres objets d'affichage pouvant être ajustés à tout moment..

Maintenant que nous savons comment fonctionnent les boutons, faisons-en le reste. Ajoutez ceci au bas de
buttonHandler ():

 bouton de fonctionHandler ()? PlayState._upButton = ui.newButton defaultSrc = "up.png", defaultX = "50", defaultY = "50", overSrc = "up.png", overX = "50", overY = "50", onPress = upPressed, onRelease = upReleased, id = "_upButton" PlayState._upButton.x = display.contentWidth - 100 PlayState._upButton.y = display.contentHeight - 100 PlayState._downButton = ui.newButton = default.pw, defaultX = "50", defaultY = "50", overSrc = "down.png", overX = "50", overY = "50", onPress = downPressed, onRelease = downReleased, id = "_downButton" PlayState._downButton. x = display.contentWidth - 100 PlayState._downButton.y = display.contentHeight - 50 PlayState._leftButton = ui.newButton defaultSrc = "left.png", defaultX = "50", defaultY = "50", defaultY = "50", overSrc = "left .png ", overX =" 50 ", overY =" 50 ", onPress = leftPressed, onRelease = leftReleased, id =" _leftButton " PlayState._leftButton.x = display.contentWidth - 150 PlayState._leftButton.y = display.contentHeight - 75 PlayState._rightButton = ui.new Bouton defaultSrc = "right.png", defaultX = "50", defaultY = "50", overSrc = "right.png", overX = "50", overY = "50", onPress = rightPressed, onRelease = rightReleased, id = "_rightButton" PlayState._rightButton.x = display.contentWidth - 50 PlayState._rightButton.y = display.contentHeight - 75 fin

Si nous ajoutons un appel à buttonHandler () dans la fonction create () de PlayState (), nous aurons quatre
flèches placées en bas à droite de l'écran.

 fonction PlayState ()? fonction create ()? PlayState._ship = Ship.new () buttonHandler (PlayState)? fin

La boucle du jeu

Nous devons maintenant créer une boucle pour gérer le gameplay. Dans le code d'origine, la fonction update () était utilisée à cette fin. Nous ferons la même chose avec notre code. Comme nous l'avons fait avec la fonction create (), décommentez la fonction update () et placez les commentaires sur une seule ligne avant toutes les lignes intérieures..

 function update () -: void --FlxU.overlap (_aliens, _bullets, overlapAlienBullet) --FlxU.overlap (_aliens, _ship, overlapAlienShip) --if (FlxG.keys.justPressed ("SPACE") et _ship.dead == false) then - spawnBullet (_ship.getBulletSpawnPosition ()) --end --if (FlxG.keys.ENTER et _ship.dead) then - FlxG.state = new PlayState (); --end --_ spawnTimer = _spawnTimer - FlxG.elapsed --if (_spawnTimer < 0) then -- spawnAlien() -- resetSpawnTimer() --end --super.update() end

À l'écoute des événements

Afin d’obtenir la fonction update () appelée à plusieurs reprises comme dans flixel, nous devons ajouter un événement.
auditeur. Cette ligne de code définira update () pour qu’elle soit appelée à chaque nouvelle image. Ajoutez-le dans le create ()
une fonction.

 function create () -: void? buttonHandler (PlayState) Runtime: addEventListener ("enterFrame", mise à jour)? fin

Vérifier si le jeu est terminé

Vérifions si le jeu est toujours en cours d'exécution avant de laisser la boucle de jeu s'en aller. Rappelez-vous cette variable
"PlayState._inGame"? Nous allons l'utiliser pour vérifier si le jeu est terminé. Donc, entourez le code update () commenté avec cette instruction.

 function update () -: void if PlayState._inGame alors? code commenté? fin fin

Gestion du mouvement des navires

Pour que le navire bouge, nous devons utiliser la fonction update () de Ship.lua. Comme auparavant, changez les commentaires pour que la déclaration de fonction ne soit plus commentée, mais que tout le reste. Ajouter le même écouteur d'événement juste avant la fin de Ship ().

 fonction Ship ()? Durée: addEventListener ("enterFrame", update) retourne la fin d'expédition

Nous devons également vérifier que la variable "Ship" existe et qu'elle n'est pas nulle. Envelopper le commenté
code avec cette instruction if.

 function update () si expédier alors? code commenté? fin fin

Commençons maintenant par les lignes commentées. Les deux premiers fixent la vitesse du navire à 0.
Corona n'a pas la vélocité comme flixel, nous allons donc travailler avec les x et y du vaisseau
directement. Les huit lignes suivantes vérifient si les touches fléchées gauche ou droite sont enfoncées sur le clavier. nous
peut remplacer ceci par des contrôles pour les variables _left et _right. Puisque nous n’avons pas de vitesse à
travailler avec, nous allons simplement définir la valeur x du navire à plus ou moins 5.

 if (Ship._left) alors Ship.x = Ship.x - 5 elseif (Ship._right) alors Ship.x = Ship.x + 5 end

Même chose pour monter et descendre.

 si (Ship._up) alors Ship.y = Ship.y - 5 elseif (Ship._down) alors Ship.y = Ship.y + 5 end

Vous pouvez supprimer "super.update ()"

Garder le jeu dans une frontière

Si vous deviez lancer le jeu maintenant, le navire se déplacerait correctement. Le problème est, il va voler
directement sur l'écran ou dans les contrôles si nous le laissons. Le jeu original avait aussi ce problème. Alors,
les lignes de code suivantes dans la fonction update () empêchent le navire de quitter une limite. Il
accomplit cela en vérifiant si le navire est en dehors de la limite après que tous ses changements x et y ont changé
sont à travers. Si le navire est à l'extérieur, il est ramené à la valeur maximale autorisée. Nous allons faire la même chose, et nous pouvons utiliser les mêmes propriétés display.contentWidth et contentHeight comme avec l'arrière-plan pour trouver la taille de l'écran..

 if (Ship.x> display.contentWidth-Ship.contentWidth-16), alors Ship.x = display.contentWidth-Ship.contentWidth-16 elseif (Ship.x < Ship.contentWidth+16) then Ship.x = Ship.contentWidth+16 end if(Ship.y > display.contentHeight-Ship.contentHeight-150), puis Ship.y = display.contentHeight-Ship.contentHeight-150 elseif (Ship.y). < Ship.contentHeight+16) then Ship.y = Ship.contentHeight+16 end

J'ai légèrement changé les chiffres pour que le navire ne chevauche pas les boutons.

Balles et groupes d'affichage

Maintenant, nous devons faire tirer notre navire. Jetons un coup d'oeil à "de / pixelate / flixelprimer / Bullet.as". Aller
à travers le processus de conversion de syntaxe normale. Heureusement, celui-ci est vraiment facile. Supprimez tout sauf le constructeur Bullet (). Ajoutez la déclaration du module et enregistrez-la sous Bullet.lua dans votre dossier de projet..

Nous avons maintenant une fonction Bullet () qui prend une valeur X et une valeur Y. Il crée un rectangle vert à ceux
coordonnées, et il définit sa vitesse à 1000.

Créons le rectangle qui agit comme la balle de la même manière que nous avons créé le fond dans le premier
leçon.

 module (?, package.seeall) fonction Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) --super (x, y) --createGraphic (16, 4, 0xFF597137) --velocity.x = 1000 fin

Ce code crée un carré de 16 x 4 pixels et définit ses coordonnées X et Y sur les nombres passés à Bullet (x, y). Maintenant, changeons la couleur de remplissage de la balle. # 587137 converti en RVB est (89, 113, 55).

 module (?, package.seeall) fonction Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) --velocity.x = 1000 fin

Ajoutons une nouvelle fonction () pour plus de commodité, comme nous l'avons fait avec Ship.lua.

 module (?, package.seeall) fonction Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) --velocity.x = 1000 return Bullet end function nouveau (x, y) return Bullet (x, y) end

Ce code accepte uniquement les valeurs X et Y et renvoie une nouvelle puce à cet emplacement. Assurez-vous de
ajoutez "return Bullet" à la fin de Bullet () pour que PlayState puisse l'utiliser.

Nous devons maintenant recréer la vitesse. Créons une fonction update () comme nous l'avons fait pour le vaisseau.

? function Bullet (x, y) -: void local Bullet = display.newRect (x, y, 16, 4) Bullet: setFillColor (89, 113, 55) fonction update () si Bullet, puis Bullet.x = Bullet.x + 10 end end runtime: addEventListener ("enterFrame", update) renvoie la fin de la puce? 

Maintenant, la balle se déplace de dix pixels vers la droite chaque image.

Code du bouton de refactoring: Ajout d’un bouton Fire

Maintenant, nous allons avoir besoin d’une méthode pour tirer les balles. Ajoutons un autre bouton. Tout d'abord, nous avons besoin d'une variable pour garder une trace si le bouton est enfoncé ou non. Au lieu de gérer cela dans le fichier Ship.lua, créons cette variable dans la fonction create () de PlayState.lua au bas de la fenêtre.
déclarations de variables.

? 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._shoot = nil? fin? 

Allez-y et réglez-le sur false sous la nouvelle ligne de navire dans les affectations de variables.

? 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 ? fin? 

Nous devons maintenant ajouter quelques lignes à notre fonction buttonHandler (). Nous avons besoin de deux autres fonctions pour manipuler et relâcher le nouveau bouton. Ajoutez ces deux fonctions après rightPressed () et
rightReleased ().

? bouton de fonctionHandler (PlayState)? function leftPressed () PlayState._ship._left = true fin fonction leftReleased () PlayState._ship._left = false fin fonction rightPressed () PlayState._ship._right = vraie fin fonction rightReleased () PlayState._ship._right = false fin fonction shootPressed () PlayState._shoot = vrai fin fonction shootReleased () PlayState._shoot = faux fin? fin? 

Maintenant, charge le bouton comme avant.

? bouton de fonctionHandler (PlayState)? PlayState._shootButton = ui.newButton defaultSrc = "shoot.png", defaultX = "100", defaultY = "100", overSrc = "shoot.png", overX = "100", overY = "100", onRelease = shootReleased, onPress = shootPressed, id = "_shootButton" PlayState._shootButton.x = 75 PlayState._shootButton.y = display.contentHeight - 75 end? 

Notre code de bouton devient un peu brouillon. Déplaçons tout buttonHandler () dans un nouveau fichier appelé
Buttons.lua. N'oubliez pas la décélération du module.

Importez le nouveau module Button en haut de PlayState. Pendant que nous y sommes, importons aussi Bullet.

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

Modifiez la ligne buttonHandler () dans create () pour appeler la fonction du module..

 function create () -: void? PlayState._ship = Ship.new () PlayState._shoot = false Boutons.buttonHandler (PlayState)? fin

Placer les balles par rapport au navire

Nous devons maintenant recréer certaines des fonctions de traitement des balles. Regardons getBulletSpawnPosition ()
dans Ship.lua.

 --[[fonction getBulletSpawnPosition () -: FlxPoint local p = nouveau FlxPoint (x + 36, y + 12) renvoie p-end -]]

La fonction d'origine était une méthode d'instance de navire. Il a renvoyé une valeur X et une valeur Y pour créer une nouvelle puce. Puisqu'il est supposé être une méthode d'instance, nous devons le faire fonctionner comme tel. Faisons en sorte que la variable Ship en soit propriétaire.

 function Expédier: getBulletSpawnPosition () -: FlxPoint local p = nouveau FlxPoint (x + 36, y + 12) renvoie p-end

Puisque FlxPoint est un type exclusif à Flixel, retournons un tableau à la place..

 Fonction Ship: getBulletSpawnPosition () local p = x = Ship.x + 36, y = Ship.y + 2 retourne p end

Ce code ajoute 36 à la valeur X du navire et 2 (j’en ai utilisé 2 au lieu de 12 pour ajuster la balle
position pour Corona) à la valeur Y du navire. Ceux-ci sont stockés dans un tableau associatif. Nous pouvons maintenant
accéder à chaque numéro avec p.x et p.y.

Dans le code d'origine, une variable du PlayState nommée _bullets contenait toutes les instances de la puce.
Nous pouvons faire la même chose avec un groupe d'affichage. Un groupe d’affichage dans Corona contient simplement un ensemble d’objets d’affichage et les affiche. Ceci est utile pour suivre un groupe du même genre de
objet. Lorsque des objets sont ajoutés pour afficher des groupes, ils sont affichés dans l’ordre dans lequel ils sont affichés.
des groupes sont créés. Par exemple, si nous avons un groupe de balles et d’aliens, et si nous voulons que tous les aliens soient au-dessus, nous pourrions créer un groupe d’affichage des puces, puis un groupe d’affichage des extraterrestres. Si nous ajoutons toutes les instances bullet et alien à leurs groupes, elles s'afficheront toujours dans le bon ordre. Cela se produira même si, par exemple, une balle est créée après un extraterrestre. L'étranger sera au top parce que le groupe d'affichage contrôle l'ordre d'affichage.

Décommentez la ligne "--PlayState._bullets = nil" dans la fonction create () de PlayState.lua..

 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 = 2.5 PlayState._shoot = nil? fin

Faire de _bullets un nouveau groupe d'affichage dans les affectations de variables.

 function create () -: void? PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGroup () Boutons.buttonHandler (PlayState)? fin

Maintenant, jetez un oeil à spawnBullet ().

 --[[fonction spawnBullet (p) -: annule la puce locale = nouvelle puce (p.x, p.y) _bullets.add (bullet) FlxG.play (SoundBullet) end -]]

Ce code est en réalité assez proche de ce que nous voulons. Faites-le ressembler à ceci:

 function spawnBullet (p) -: void local _bullet = Bullet.new (p.x, p.y) PlayState._bullets: insert (_bullet) PlayState._shoot = false --FlxG.play (SoundBullet) end

Lorsque la puce est créée, _shoot doit être redéfini sur false. De cette façon, l'utilisateur doit soulever
leur doigt avant qu'ils tirent à nouveau.

Traitement des sons de base

Corona a une API de base pour jouer des effets sonores courts. Pour l'utiliser, il faut utiliser le son .caf
des dossiers. La version convertie des effets sonores MP3 originaux est incluse dans le source de cette
Didacticiel.

Nous devons d’abord créer des variables pour contenir les sons. Il y a trois lignes en haut de PlayState.
Déplacez-les vers les déclarations de variables 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 = 2.5 PlayState._shoot = nil - [Incorporer (source = "? /? /? /? /assets/mp3/ExplosionShip.mp3")] private var SoundExplosionShip: Class - [Intégrer (source = "? /? /? /? /Assets/mp3/ExplosionAlien.mp3")] private var SoundExplosionAlien: Class - [Intégrer (source = "? /? /? /? / assets / mp3 / Bullet.mp3 ")] private var SoundBullet: Classe? fin

Nous voulons juste que les noms soient les mêmes. Faites-en des propriétés de PlayState et définissez-les sur nil.
Ne commentez pas la dernière ligne.

 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 = 2.5 PlayState._shoot = nil --PlayState.SoundExplosionShip = nil --PlayState.SoundExplosionAlien: Class = nil PlayState.SoundBullet = nil? fin

Nous allons maintenant utiliser le module média pour charger un nouveau son. Placez ceci au bas des tâches:

 function create () -: void? PlayState._ship = Ship.new () PlayState._shoot = false PlayState._bullets = display.newGroup () PlayState.SoundBullet = media.newEventSound ("Bullet.caf") Boutons.buttonHandler (PlayState)? fin

Retournez à spawnBullet (). Nous pouvons remplacer la dernière ligne pour jouer notre nouveau son.

 function spawnBullet (p) -: void local _bullet = Bullet.new (p.x, p.y) PlayState._bullets: insert (_bullet) PlayState._shoot = false media.playEventSound (PlayState.SoundBullet) fin

Nous devons maintenant modifier notre fonction update () pour obtenir des balles de tir. Vérifiez si _shoot est
vrai et si _ship existe. Si tel est le cas, appelez notre méthode d'instance getBulletSpawnPosition () pour notre navire.
et spawnBullet () à cet endroit.

 function update () si PlayState._inGame puis si PlayState._shoot == true et PlayState._ship puis local p = PlayState._ship: getBulletSpawnPosition () spawnBullet (p) end? fin fin

Gestion de base de la mémoire

À Flixel, la mémoire a été prise en charge pour nous. À Corona, nous allons devoir nettoyer des objets que nous
sont fait avec. Ajoutons une méthode d'instance kill () à chaque puce pour nous aider. kill () est le
fonction que flixel appelle automatiquement quand un objet n'est plus nécessaire. Ajoutez ceci à Bullet.lua:

 fonction Bullet (x, y)? fonction update ()? fonction de fin Bullet: kill () Bullet.parent: remove (Bullet) Bullet = nil end? fin

C’est la bonne façon de nettoyer un objet dans Corona. Tout d'abord, nous avons supprimé tous les liens en supprimant
il du groupe d'affichage. Ensuite, nous définissons la variable Bullet sur nil. Faisons la même chose pour Ship.
Ajoutez ceci ci-dessous getBulletSpawnPosition () dans Ship.lua:

 function Expédier: kill () Expédier: removeSelf () Expédier = nil Durée d'exécution: removeEventListener ("enterFrame", update) end

Notez que nous avons arrêté la mise à jour de chaque mise à jour (car le vaisseau n’existe pas).
plus).

Traitement des balles hors écran

De retour dans Bullet.lua, ajoutons une vérification à chaque image pour voir si la puce est en dehors de l'affichage..
Actuellement, notre code continue de tirer des puces même si elles ne peuvent pas être vues. C'est un gaspillage des ressources limitées de l'appareil. Remplacez update () par ceci:

 function update () if Bullet puis if (Bullet.x < display.contentWidth) then Bullet.x = Bullet.x + 10 else Bullet:kill() end end end

Maintenant, la balle ne se déplacera vers la droite que si elle peut être vue. Sinon, il nous appellera à portée de main
kill () fonction.

Ramassage des ordures

Lua dispose d'un récupérateur de déchets automatique qui traite les déchets comme des variables inutilisées, les objets d'affichage supprimés de l'affichage et tout ce qui n'est plus nécessaire. Nous pouvons dire à Lua de collecter les ordures en ajoutant cette ligne à la fin de create dans notre PlayState:

 fonction create ()? collectgarbage ("collect") end

Conclusion

Cela commence à ressembler à un jeu maintenant. Notre navire peut se déplacer à l'écran et tirer des balles. le
les balles prennent soin d’elles-mêmes quand elles ne sont plus nécessaires. Maintenant, nous avons juste besoin d'ennemis.