Créer un jeu Space Invaders dans Corona Terminer le gameplay

Ce que vous allez créer

Dans la partie précédente de cette série, nous avions le vaisseau du joueur en mouvement, les envahisseurs en mouvement et la détection du moment où une balle du joueur avait touché un envahisseur. Dans cette dernière partie de la série, les envahisseurs attaqueront le joueur, géreront les niveaux et ajouteront la possibilité pour le joueur de mourir..

1. balles de tir

De temps en temps, l'un des envahisseurs tire une balle. Nous allons utiliser une minuterie pour accomplir cela. Ajoutez le code suivant à gamelevel.lua.

function fireInvaderBullet () if (#invadersWhoCanFire> 0) alors local randomIndex = math.random (#invadersWhoCanFire) local randomInvader = invadersWhoCanFire [randomIndex] local tempInvaderBullet = display.newImage ("laser.png", emplacement). invaderSize / 2) tempInvaderBullet.name = "invaderBullet" scene.view: insert (tempInvaderBullet) physics.addBody (tempInvaderBullet, "dynamique") tempInvaderBullet.gravityScale = 0 tempInvaderBullet.isBullet = true tempInvaderBullet.isSenseur table.insert (invaderBullets, tempInvaderBullet) else levelComplete () end end

Dans cette fonction, nous vérifions d’abord si le envahisseursWhoCanFire La table contient au moins un élément. Si c'est le cas, nous exécutons le code dans l'instruction if. Sinon, cela signifie que le niveau est terminé et nous invoquons le niveau complet une fonction.

Il y aura toujours au moins un envahisseur qui peut tirer une balle jusqu'à ce que vous tuiez le dernier envahisseur, à quel point le envahisseursWhoCanFire la table sera vide.

À l'intérieur de l'instruction if, nous générons un nombre aléatoire randomIndex en fonction du nombre d'articles dans le envahisseursWhoCanFire table. Nous choisissons ensuite cet article, randomInvader, du envahisseursWhoCanFire table.

Nous créons une image de balle, lui donnons une prénom propriété afin que nous puissions l'identifier ultérieurement, l'insérer dans la scène et définir les mêmes propriétés que nous avons définies pour la balle du lecteur. Enfin, nous insérons la balle dans le invaderBullets table afin que nous puissions le référencer plus tard.

Nous devons maintenant configurer la minuterie. Ajouter ce qui suit au scène: spectacle méthode.

scène de la fonction: show (événement) if (phase == "fait") puis --SNIP-- Durée: addEventListener ("collision", onCollision) invaderFireTimer = timer.performWithDelay (1500, fireInvaderBullet, -1) end end

Toutes les 1500 millisecondes fireInvaderBullet est invoqué. Notez que le dernier paramètre que nous passons est -1, ce qui signifie que la minuterie se répète pour toujours. Chaque fois que vous créez une minuterie qui se répète éternellement, vous devriez éventuellement l'annuler. Nous faisons cela dans lescène: cacher fonctionne comme indiqué ci-dessous.

scène de fonction: masquer (événement) si (phase == "sera") puis --SNIP-- Durée: removeEventListener ("collision", onCollision) timer.cancel (invaderFireTimer) end end

2. Retrait des balles

Comme les balles du joueur, les balles des envahisseurs sortiront de l'écran et continueront à bouger, occupant une mémoire précieuse. Pour remédier à cela, nous les supprimons comme nous l'avons fait avec les balles du joueur..

function checkInvaderBulletsOutOfBounds () if (#invaderBullets> 0), puis pour i = # invaderBullets, 1, -1 do if (invaderBullets [i] .y> display.contentHeight), puis pour invaderBullets [i]: removeSelf () invaderBullets [i] = nil table.remove (invaderBullets, i) fin fin fin fin

Ce code est très similaire à vérifier si les puces du joueur sont hors limites, je ne discuterai donc pas de son implémentation en détail.

3. Détecter un coup

Étape 1: Détection de collision

L'étape suivante consiste à détecter si la balle d'un envahisseur a atteint le joueur. Ajoutez le code suivant au onCollision une fonction.

function onCollision (event) if (event.phase == "commencé") puis --SNIP-- if (event.object1.name == "player" et event.object2.name == "invaderBullet"), puis table.remove (invaderBullets, table.indexOf (invaderBullets, event.object2)) event.object2: removeSelf () event.object2 = nil si (playerIsInvincible == false) puis killPlayer () end retour end end if (event.object1.name == " invaderBullet "et event.object2.name ==" player ") puis table.remove (invaderBullets, table.indexOf (invaderBullets, event.object1)) event.object1: removeSelf () event.object1 = nil si (playerIsInvincible == false ) puis killPlayer () end retour end end end end

Comme avant, on ne sait pas quel objet event.object1 et event.object2 sera donc nous utilisons deux déclarations if pour vérifier les deux situations. Nous retirons la balle de l'envahisseur du invaderBullets tableau, retirez-le de l'écran et réglez-le sur néant. Si le joueur n'est pas invincible, on le tue.

Étape 2: Tuer le joueur

Lorsque nous tuons le joueur, nous lui donnons un court temps d'invincibilité. Cela donne à l'utilisateur le temps de se concentrer à nouveau sur le jeu. Si la nombre de vies variable est égale à 0, nous savons que le jeu est terminé et la transition à la début scène où l'utilisateur peut commencer un nouveau jeu.

fonction killPlayer () numberOfLives = numberOfLives- 1; if (numberOfLives <= 0) then gameData.invaderNum = 1 composer.gotoScene("start") else playerIsInvincible = true spawnNewPlayer() end end

Étape 3: Générer un nouveau joueur

le spawnNewPlayer Cette fonction permet au lecteur d’entrer et de disparaître en fondu pendant quelques secondes. C'est un bel effet de faire savoir à l'utilisateur que le vaisseau est temporairement invincible..

function spawnNewPlayer () local numberOfTimesToFadePlayer = 5 local numberOfTimesPlayerHasFaded = 0 fonction locale fadePlayer () player.alpha = 0; transition.to (player, time = 400, alpha = 1,)

Nous utilisons une fonction locale, fadePlayer, qui utilise la bibliothèque de transition pour modifier le alpha valeur de la joueur. Nous gardons une trace de combien de fois le joueur s'est évanouie et a mis l'invincibilité du joueur à faux une fois que nous atteignons le numberOfTimesToFadePlayer. Nous utilisons une minuterie pour appeler le fadePlayer fonctionner pour cependant plusieurs fois numberOfTimesToFadePlayer est égal à.

Exécutez le jeu pour tester cela. le joueur devrait mourir quand la balle d'un envahisseur frappe le navire. Si trois balles touchent le navire, vous devriez être conduit au début scène où vous pouvez commencer un nouveau jeu.

Pour que cela soit plus facile à tester, commentez l'appel à moveInvaders dans le gameLoop fonctionne comme indiqué ci-dessous.

fonction gameLoop () checkPlayerBulletsOutOfBounds () --moveInvaders () checkInvaderBulletsOutOfBounds () end

4. Terminer un niveau

Si vous avez réussi à tuer chaque envahisseur, le jeu aurait appelé le niveau complet fonction, qui n'existe pas encore. Laisse réparer ça. Ajouter le bloc de code suivant.

fonction levelComplete () gameData.invaderNum = gameData.invaderNum + 1 if (gameData.invaderNum <= gameData.maxLevels) then composer.gotoScene("gameover") else gameData.invaderNum = 1 composer.gotoScene("start") end end

Nous incrémentons gameData.invaderNum et, s'il est inférieur à gameData.maxLevels, nous passons au jeu terminé scène. Sinon, le joueur a terminé tous les niveaux et nous réinitialisons gameData.invaderNum à 1. Nous passons au début scène où le joueur peut commencer un nouveau jeu.

Un moyen simple de tester cela consiste à commenter l'appel à moveInvaders dans le gameLoop fonction et utilisez les boutons pour déplacer le navire. Si cela reste trop difficile, vous pouvez également commenter les deux appels à killPlayer dans le onCollision méthode.

5. Fin du jeu

Ajoutez le code suivant à gameover.lua mettre en œuvre la scène game over.

compositeur local = require ("composer") scène locale = composer.newScene () starFieldGenerator local = require ("starfieldgenerator") local pulsatingText = require ("pulsatingtext") local nextLevelButton local fonction starGenerator: create (événement) groupe local = auto .view starGenerator = starFieldGenerator.new (200, groupe, 5) envahisseurs locauxText = pulsatingText.new ("LEVEL COMPLETE", display.contentCenterX, display.contentCenterY-200, "Conquête", 20, groupe) invadersText: setColor (1, 1, 1) invadersText: pulsate () nextLevelButton = display.newImage ("next_level_btn.png", display.contentCenterX, display.contentCenterY) groupe: insert (nextLevelButton) fonction de fin scène: show (événement) phase locale = événement.pha compositeur .removeScene ("gamelevel") if (phase == "did"), puis nextLevelButton: addEventListener ("tap", startNewGame) Runtime: addEventListener ("enterFrame", starGenerator) end end scène de fonction: masquer (événement) phase locale = événement .phase if (phase == "will") puis Runtime: removeEventListener ("enterF rame ", starGenerator) nextLevelButton: removeEventListener (" tap ", startNewGame) end end fonction startNewGame () composer.gotoScene (" gamelevel ") scène finale: addEventListener (" créer ", scène) scène: addEventListener (" show ", scène) scene: addEventListener ("hide", scene) retourne la scène

Ce code est très similaire à la début scène de sorte que vous devriez être au courant maintenant.

6. Collision avec un envahisseur

La dernière vérification de collision que nous devons effectuer est une collision entre le joueur et l'un des envahisseurs. Ajoutez le bloc de code suivant au onCollision méthode que nous avons vue plus tôt.

function onCollision (event) --SNIP-- if (event.phase == "commencé") puis --SNIP-- if (event.object1.name == "player" et event.object2.name == "invader" ) then numberOfLives = 0 killPlayer () end if ((event.object1.name == "invader" et event.object2.name == "player"), alors numberOfLives = 0 killPlayer () end end

Comme d'habitude, nous devons vérifier les deux situations de collision. Nous avons mis le nombre de vies à 0 et appeler killPlayer. En mettant nombre de vies à 0 et invoquer killPlayer, le jeu est terminé et le jeu passe à la début scène.

7. Plus de fonctionnalités

Ceci termine notre jeu, mais je vous suggère d’essayer de développer le jeu avec quelques fonctionnalités supplémentaires. Par exemple, vous pouvez afficher la vie du joueur dans un HUD..

J'ai également inclus un graphique UFO dans les fichiers source. Vous pouvez essayer de faire apparaître un OVNI au hasard et si le joueur le frappe avec une balle, donnez-lui une vie supplémentaire.

Si vous avez besoin d'aide avec ces concepts, consultez ma série de jeux de combat d'avion sur Tuts+.

Conclusion

Si vous avez suivi cette série, vous devriez maintenant avoir un jeu entièrement fonctionnel similaire aux Space Invaders d’origine. Développez-le et faites-le vôtre. J'espère que vous avez trouvé ce tutoriel utile et que vous avez appris de nouvelles techniques. Merci d'avoir lu.