Créez des Space Invaders avec Swift et Sprite Kit: Finition du gameplay

Dans la partie précédente de cette série, nous avons fait bouger les envahisseurs, le joueur et les envahisseurs tirent des balles et implémenté la détection de collision. Dans la quatrième et dernière partie de cette série, nous ajouterons la possibilité de déplacer le joueur à l’aide de l’accéléromètre, de gérer les niveaux et de garantir que le joueur meurt lorsqu’il est touché par une balle. Commençons.

1. Terminer le Player Classe

Étape 1: Ajout de propriétés

Ajoutez les propriétés suivantes au Player classe en dessous du canFire propriété.

le invincible La propriété sera utilisée pour rendre le joueur temporairement invincible lorsqu’il perd une vie. le lives propriété est le nombre de vies que le joueur a avant d’être tué.

Nous utilisons un observateur de propriété sur le lives property, qui sera appelée à chaque fois que sa valeur est définie. le didSet observer est appelé immédiatement après la définition de la nouvelle valeur de la propriété. En faisant cela, chaque fois que nous décrémentons le lives propriété il vérifie automatiquement si lives est inférieur à zéro, appelant le kill méthode si c’est le cas. Si le joueur a encore des vies, le respawn méthode est appelée. Les observateurs de propriétés sont très pratiques et peuvent économiser beaucoup de code supplémentaire.

Étape 2: respawn

le respawn La méthode rend le joueur invincible pendant une courte période et fait disparaître le joueur pour indiquer qu’il est temporairement invincible. La mise en œuvre du respawn La méthode ressemble à ceci:

Nous fixons invincible à true et créez un certain nombre de SKAction objets. À présent, vous devez savoir comment le SKAction travaux de classe.

Étape 3: die

le die La méthode est assez simple. Il vérifie si invincible est false et, si c’est le cas, décrémente le lives variable.

Étape 4: kill

le kill réinitialisation de la méthode invaderNum à 1 et ramène l’utilisateur au StartGameScene afin qu’ils puissent commencer une nouvelle partie.

Ce code devrait vous être familier car il est presque identique au code que nous avons utilisé pour passer au GameScene du StartGameScene. Notez que nous forçons le déballage du scene pour accéder à la scène size et scaleMode Propriétés.

Ceci complète le Player classe. Nous devons maintenant appeler le die et kill méthodes dans le didBeginContact(_:) méthode.

Nous pouvons maintenant tout tester. Un moyen rapide de tester le die méthode consiste à commenter le moveInvaders appeler le update(_:) méthode. Une fois que le joueur meurt et réapparaît trois fois, vous devez être ramené au StartGameScene.

Pour tester le kill méthode, assurez-vous que moveInvaders l’appel n’est pas commenté. Met le invaderSpeed propriété à une valeur élevée, par exemple, 200. Les envahisseurs devraient atteindre le joueur très rapidement, ce qui entraîne une mise à mort instantanée. Changement invaderSpeed retour à 2 une fois que vous avez terminé le test.

2. Finir les envahisseurs de tir

Dans l’état actuel du jeu, seule la rangée inférieure d’envahisseurs peut tirer des balles. Nous avons déjà la détection de collision pour quand une balle de joueur frappe un envahisseur. Dans cette étape, nous supprimerons un envahisseur qui est touché par une balle et ajouterons l’envahisseur d’une rangée au tableau d’envahisseurs qui peuvent tirer. Ajoutez ce qui suit au didBeginContact(_:) méthode.

Nous avons supprimé le NSLog déclaration et vérifiez d’abord si contact.bodyA.node?.parent et contact.bodyB.node?.parent ne sont pas nil. Ils seront nil si nous avons déjà traité ce contact. Dans ce cas, nous revenons de la fonction.

Nous calculons le invadersPerRow comme nous l’avons fait avant et mis theInvader à firstBody.node, en le jetant à un Invader. Ensuite, nous obtenons le newInvaderRow en soustrayant 1 et le newInvaderColumn, qui reste le même.

Nous voulons seulement permettre aux envahisseurs de tirer si le newInvaderRow est supérieur ou égal à 1, sinon nous essaierions de placer un envahisseur en ligne 0 pour pouvoir tirer. Il n’y a pas de ligne 0 donc cela provoquerait une erreur.

Ensuite, nous énumérons les envahisseurs, à la recherche de l’envahisseur qui a la bonne ligne et colonne. Une fois qu’il est trouvé, nous l’ajoutons au invadersWhoCanFire tableau et appel stop.memory à true donc l’énumération s’arrêtera tôt.

Nous devons trouver l’envahisseur qui a été touché par une balle dans le invadersWhoCanFire tableau afin que nous puissions le supprimer. Normalement, les tableaux ont une sorte de fonctionnalité comme un indexOf méthode ou quelque chose de similaire pour y parvenir. Au moment de la rédaction de cet article, il n’existe pas de méthode de ce type pour les tableaux en langage Swift. La bibliothèque standard Swift définit un find fonction que nous pourrions utiliser, mais j’ai trouvé une méthode dans les sections sur les génériques du Guide du langage de programmation Swift cela accomplira ce dont nous avons besoin. La fonction porte bien son nom findIndex. Ajoutez ce qui suit au bas de GameScene.swift.

En relation :  Comment supprimer, modifier et définir des applications par défaut dans Android

Si vous êtes curieux de savoir comment cette fonction fonctionne, je vous recommande d’en savoir plus sur les génériques dans le Guide du langage de programmation Swift.

Maintenant que nous avons une méthode que nous pouvons utiliser pour trouver l’envahisseur, nous l’invoquons en passant le invadersWhoCanFire tableau et theInvader. Nous vérifions si invaderIndex n’est pas égal à nil et retirez l’envahisseur du invadersWhoCanFire tableau en utilisant le removeAtIndex(index: Int) méthode.

Vous pouvez maintenant tester si cela fonctionne comme il se doit. Un moyen simple serait de commenter où l’appel à player.die dans le didBeginContact(_:) méthode. Assurez-vous de supprimer le commentaire lorsque vous avez terminé le test. Notez que le programme plante si vous tuez tous les envahisseurs. Nous allons résoudre ce problème à l’étape suivante.

L’application plante, car nous avons un SKAction repeatActionForever(_:) appelant les envahisseurs à tirer des balles. À ce stade, il n’y a plus d’envahisseurs pour tirer des balles, donc les jeux se bloquent. Nous pouvons résoudre ce problème en vérifiant le isEmpty propriété sur le invadersWhoCanFire tableau. Si le tableau est vide, le niveau est terminé. Entrez ce qui suit dans le fireInvaderBullet méthode.

Le niveau est complet, ce qui signifie que nous incrémentons invaderNum, qui est utilisé pour les niveaux. Nous invoquons également levelComplete, que nous devons encore créer dans les étapes à venir.

3. Terminer un niveau

Nous devons avoir un certain nombre de niveaux. Si nous ne le faisons pas, après plusieurs tours, nous aurons tellement d’envahisseurs qu’ils ne rentreront pas à l’écran. Ajouter une propriété maxLevels à la GameScene classe.

Maintenant, ajoutez le levelComplete méthode au bas de GameScene.swift.

Nous vérifions d’abord si invaderNum est inférieur ou égal à maxLevels nous avons mis. Si tel est le cas, nous passons au LevelCompletScene, sinon on réinitialise invaderNum à 1 et appeler newGame. LevelCompleteScene n’existe pas encore et le newGame méthode alors abordons-les un par un au cours des deux prochaines étapes.

4. Mise en œuvre du LevelCompleteScene Classe

Créer un nouveau Classe Touch Cocoa nommé LevelCompleteScene c’est une sous-classe de SKScene. L’implémentation de la classe ressemble à ceci:

La mise en œuvre est identique à la StartGameScreen classe, sauf que nous définissons le name propriété de startGameButton à "nextlevel". Ce code doit être familier. Sinon, revenez à la première partie de ce didacticiel pour un rappel.

5. newGame

le newGame revient simplement à la méthode StartGameScene. Ajoutez ce qui suit au bas de GameScene.swift.

Si vous testez l’application, vous pouvez jouer à quelques niveaux ou perdre quelques parties, mais le joueur n’a aucun moyen de bouger et cela en fait un jeu ennuyeux. Corrigeons cela à l’étape suivante.

6. Déplacement du lecteur à l’aide de l’accéléromètre

Nous utiliserons l’accéléromètre pour déplacer le joueur. Nous devons d’abord importer le CoreMotion cadre. Ajoutez une instruction d’importation pour le framework en haut de GameScene.swift.

Nous avons également besoin de quelques nouvelles propriétés.

Ensuite, ajoutez une méthode setupAccelerometer en bas de GameScene.swift.

Ici, nous définissons le accelerometerUpdateInterval, qui est l’intervalle en secondes pour fournir des mises à jour au gestionnaire. j’ai trouvé 0,2 fonctionne bien, vous pouvez essayer différentes valeurs si vous le souhaitez. À l’intérieur du gestionnaire; une fermeture, nous obtenons le accelerometerData.acceleration, qui est une structure de type CMAcceleration.

Nous ne sommes intéressés que par x propriété et nous utilisons la conversion de type numérique pour le convertir en un CGFloat pour notre accelerationX propriété.

Maintenant que nous avons le accelerationX ensemble de propriétés, nous pouvons déplacer le joueur. Nous faisons cela dans le didSimulatePhysics méthode. Ajoutez ce qui suit au bas de GameScene.swift.

Invoquer setupAccelerometer dans didMoveToView(_:) et vous devriez pouvoir déplacer le lecteur avec l’accéléromètre. Il n’y a qu’un seul problème. Le joueur peut se déplacer hors de l’écran de chaque côté et cela prend quelques secondes pour le récupérer. Nous pouvons résoudre ce problème en utilisant le moteur physique et les collisions. Nous faisons cela à l’étape suivante.

sept. Restreindre le mouvement du joueur

Comme mentionné à l’étape précédente, le joueur peut se déplacer hors de l’écran. Il s’agit d’une solution simple utilisant le moteur physique de Sprite Kit. Tout d’abord, ajoutez un nouveau CollisionCategory nommé EdgeBody.

Définissez ceci comme celui du joueur collisionBitMask dans son init méthode.

En relation :  5 façons de crypter votre vie quotidienne avec très peu d'effort

Enfin, nous créons un physicsBody sur la scène elle-même. Ajoutez ce qui suit au didMoveToView(view: SKView) méthode dans GameScene.swift.

Nous initialisons un corps physique en invoquant init(edgeLoopFromRect:), passant dans la scène frame. L’initialiseur crée une boucle de bord à partir de l’image de la scène. Il est important de noter qu’une arête n’a ni volume ni masse et est toujours traitée comme si la propriété dynamique était égale à false. Les arêtes peuvent également entrer en collision uniquement avec des corps physiques basés sur le volume, ce que notre lecteur est.

Nous définissons également le categoryBitMask à CollisionCategories.EdgeBody. Si vous testez l’application, vous remarquerez peut-être que votre vaisseau ne peut plus se déplacer hors de l’écran, mais qu’il pivote parfois. Lorsqu’un corps physique entre en collision avec un autre corps physique, il est possible que cela entraîne une rotation. Ceci est le comportement par défaut. Pour y remédier, nous définissons allowsRotation à false dans Player.swift.

8. Champ d’étoiles

Étape 1: Création du champ d’étoiles

Le jeu a un champ d’étoiles en mouvement en arrière-plan. Nous pouvons créer le champ de départ en utilisant le moteur de particules de Sprite Kit.

Créez un nouveau fichier et sélectionnez Ressource du iOS section. Choisir Fichier de particules SpriteKit comme modèle et cliquez sur Prochain. Pour le Gabarit de particules choisir pluie et enregistrez-le sous StarField. Cliquez sur Créer pour ouvrir le fichier dans l’éditeur. Pour voir les options, ouvrez le Inspecteur SKNode à droite à droite.

Au lieu de passer en revue chaque paramètre ici, ce qui prendrait beaucoup de temps, il serait préférable de lire la documentation pour en savoir plus sur chaque paramètre individuel. Je n’entrerai pas non plus dans les détails sur les paramètres du champ de départ. Si vous êtes intéressé, ouvrez le fichier dans Xcode et regardez les paramètres que j’ai utilisés.

Étape 2: Ajout du champ d’étoiles aux scènes

Ajoutez ce qui suit à didMoveToView(_:) dans StartGameScene.swift.

Nous utilisons un SKEmitterNode pour charger le StarField.sks fichier, définissez son position et lui donner un faible zPosition. La raison du faible zPosition est de s’assurer que cela n’empêche pas l’utilisateur d’appuyer sur le bouton de démarrage. Le système de particules génère des centaines de particules, donc en le réglant très bas, nous surmontons ce problème. Vous devez également savoir que vous pouvez configurer manuellement toutes les propriétés des particules sur un SKEmitterNode, bien qu’il soit beaucoup plus facile d’utiliser l’éditeur pour créer un .sks fichier et chargez-le lors de l’exécution.

Ajoutez maintenant le champ étoile à GameScene.swift et LevelCompleteScene.swift. Le code est exactement le même que ci-dessus.

9. Mettre en œuvre le PulsatingText Classe

Étape 1: Créez le PulsatingText Classe

le StartGameScene et LevelCompleteScene ont du texte qui grossit et rétrécit à plusieurs reprises. Nous sous-classerons SKLabeNode et utilisez quelques SKAction instances pour obtenir cet effet.

Créer un nouveau Classe Touch Cocoa c’est une sous-classe de SKLabelNode, nomme le PulsatingTextet ajoutez-y le code suivant.

L’une des premières choses que vous avez peut-être remarquées est qu’il n’y a pas d’initialiseur. Si votre sous-classe ne définit pas d’initialiseur désigné, elle hérite automatiquement de tous ses initialiseurs désignés par superclasse.

Nous avons une méthode setTextFontSizeAndPulsate(theText:theFontSize:), qui fait exactement ce qu’il dit. Il définit le SKLabelNodede text et fontSize propriétés et crée un certain nombre de SKAction instances pour augmenter l’échelle du texte, puis le redescendre, créant un effet de pulsation.

Étape 2: ajouter PulsatingText à StartGameScene

Ajoutez le code suivant à StartGameScene.swift dans didMoveToView(_:).

Nous initialisons un PulsatingText exemple, invaderTextet invoquer setTextFontSizeAndPulsate(theText:theFontSize:) dessus. Nous définissons ensuite son position et ajoutez-le à la scène.

Étape 3: ajouter PulsatingText à LevelCompleteScene

Ajoutez le code suivant à LevelCompleteScene.swift dans didMoveToView(_:).

C’est exactement la même chose que l’étape précédente. Seul le texte que nous transmettons est différent.

dix. Faire avancer le jeu

Ceci termine le jeu. J’ai quelques suggestions sur la façon dont vous pourriez développer davantage le jeu. À l’intérieur de images dossier, il y a trois images d’envahisseurs différentes. Lorsque vous ajoutez des envahisseurs à la scène, choisissez au hasard l’une de ces trois images. Vous devrez mettre à jour l’initialiseur de l’envahisseur pour accepter une image comme paramètre. Se référer au Bullet classe pour un indice.

Il y a aussi une image d’OVNI. Essayez de le faire apparaître et de vous déplacer sur l’écran toutes les quinze secondes environ. Si le joueur le touche, donnez-lui une vie supplémentaire. Vous voudrez peut-être limiter le nombre de vies qu’ils peuvent avoir si vous faites cela. Enfin, essayez de créer un HUD pour la vie des joueurs.

Ce ne sont que quelques suggestions. Essayez de personnaliser le jeu.

Conclusion

Cela met fin à cette série. Vous devriez avoir un jeu qui ressemble beaucoup au jeu original Space Invaders. J’espère que vous avez trouvé ce tutoriel utile et que vous avez appris quelque chose de nouveau. Merci d’avoir lu.

Moyens Staff
Moyens I/O Staff vous a motivé, donner des conseils sur la technologie, le développement personnel, le style de vie et des stratégies qui vous aider.