Créer des jeux rétro animés avec JavaScript | Frank Dvorak | Skillshare
Menu
Recherche

Vitesse de lecture


  • 0.5x
  • 1 x (normale)
  • 1.25x
  • 1.5x
  • 2x

Créer des jeux rétro animés avec JavaScript

teacher avatar Frank Dvorak, Creative Coding

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Leçons de ce cours

    • 1.

      Introduction du projet 1

      1:02

    • 2.

      Fonctionnalités de Project 1

      1:27

    • 3.

      Mise en place de projet

      4:24

    • 4.

      Objets de jeu et de joueur

      5:36

    • 5.

      Commandes du clavier

      7:26

    • 6.

      Pool d'objets

      13:01

    • 7.

      Vagues ennemies

      13:33

    • 8.

      Détection de collision

      8:05

    • 9.

      Texte de score et d'état

      12:48

    • 10.

      Méthode de redémarrage

      5:46

    • 11.

      Cours de Beetlemorph ennemi

      4:50

    • 12.

      Animation Sprite expliquée

      10:35

    • 13.

      Calendrier d'animation

      10:15

    • 14.

      Animation de joueurs

      13:08

    • 15.

      Caractéristiques supplémentaires : ennemis blindés

      0:57

    • 16.

      Cours de Rhinomorph ennemi

      9:24

    • 17.

      Caractéristiques supplémentaires : batailles de boss

      0:30

    • 18.

      Cours de Boss

      9:27

    • 19.

      Mouvement de boss

      10:22

    • 20.

      Collision entre boss et joueur

      7:07

    • 21.

      Caractéristiques supplémentaires : super armes

      0:43

    • 22.

      2 cours laser

      8:01

    • 23.

      Dommages au laser

      8:01

    • 24.

      Gestion des ressources

      7:05

    • 25.

      Cours d'Eaglemorph ennemi

      6:55

    • 26.

      Projectiles ennemis

      6:21

    • 27.

      Interactions de projectile

      4:48

    • 28.

      Cours d'ennemis de Squidmorph

      9:18

    • 29.

      Cours d'ennemis de Lobstermorph

      2:30

    • 30.

      Projet 2 : défense d'une planète JavaScript

      3:18

    • 31.

      Projet 2 : planète et cours de jeu

      8:10

    • 32.

      Projet 2 : Position de la souris

      6:18

    • 33.

      Projet 2 : Vaisseau spatial de joueur

      4:42

    • 34.

      Projet 2 : un peu de mathématiques

      7:47

    • 35.

      Projet 2 : comprendre la rotation sur toile

      6:15

    • 36.

      Projet 2 : mode de débogage

      2:25

    • 37.

      Projet 2 : pool d'objets

      12:22

    • 38.

      Projet 2 : Projectiles de joueurs

      6:10

    • 39.

      Projet 2 : Piscine ennemie

      7:25

    • 40.

      Projet 2 : détection de collision

      2:20

    • 41.

      Projet 2 : événements périodiques

      8:06

    • 42.

      Projet 2 : ennemi astéroïde

      4:21

    • 43.

      Projet 2 : Animation Sprite

      9:15

    • 44.

      Projet 2 : Ennemi de Lobstermorph

      9:15

    • 45.

      Projet 2 : texte de jeu

      5:26

    • 46.

      Projet 2 : Vie de joueurs

      5:09

    • 47.

      Projet 2 : Ennemi Beetlemorph

      1:36

    • 48.

      Projet 2 : ennemi rhinomorph

      2:43

    • 49.

      Projet 3 : jeu mobile JavaScript

      1:08

    • 50.

      Setup du projet 3

      2:02

    • 51.

      Rendre tout réactif

      6:15

    • 52.

      Cours d'ennemis

      7:58

    • 53.

      Motif de pool design d'objet

      3:35

    • 54.

      Déclencheurs périodiques

      6:50

    • 55.

      Commandes de la souris

      1:31

    • 56.

      Détection de collision

      7:50

    • 57.

      Événements tactiles

      1:37

    • 58.

      Texte de jeu

      7:04

    • 59.

      Commencer le redémarrage

      3:34

    • 60.

      Jeux plein écran

      4:11

    • 61.

      Membres d'équipage simples

      1:30

    • 62.

      Type d'ennemi simple

      4:23

    • 63.

      Animation Sprite

      4:20

    • 64.

      Timing d'animation

      4:08

    • 65.

      Mode de débogage

      2:09

    • 66.

      Variété ennemie

      4:29

    • 67.

      Équipe spatiale aléatoire

      3:47

    • 68.

      Gestion d'état dans les jeux

      4:27

    • 69.

      Motif d'état

      15:23

    • 70.

      Sons

      9:49

  • --
  • Niveau débutant
  • Niveau intermédiaire
  • Niveau avancé
  • Tous niveaux

Généré par la communauté

Le niveau est déterminé par l'opinion majoritaire des apprenants qui ont évalué ce cours. La recommandation de l'enseignant est affichée jusqu'à ce qu'au moins 5 réponses d'apprenants soient collectées.

66

apprenants

--

À propos de ce cours

Vieux est de l'or. S'inspirer des jeux classiques des années 80 et ajouter nos propres graphiques et fonctionnalités de jeu. Dans le premier projet, nous explorerons le vide interstellaire et utiliserons 3 types d'armes différents pour brûler des essaims de bugs de l'espace de différents types, certains plus grands que les autres.

Nous commencerons par un jeu vaguement inspiré par l'arcade classique de Space Invaders et nous expérimenterons différentes fonctionnalités supplémentaires telles que des batailles de boss, des super armes et différents types

d'ennemis.Explorons la programmation orientée objet avec JavaScript et mettons en œuvre un ensemble utile de techniques de développement de jeu 2D de base telles que le motif de pool d'objets, l'animation sprite, le timing et les techniques d'horodatage utilisant des horodatages et bien plus encore.

N'oubliez pas de télécharger tous les cadeaux bonus. Les étudiants de ce cours recevront un pack d'art de jeu 2D de qualité supérieure, cette fois dans un thème de l'espace de science-fiction. Vous pouvez également télécharger le code source de plusieurs étapes du projet, car nous ajoutons progressivement plus de fonctionnalités.

Nous allons implémenter plusieurs types d'ennemis :

Beetlemorph - ennemi de base, 1 coup suffit

Rhinomorph - ennemi blindé, vies multiples, états de dégâts multiples

Mantismorph - ennemi massif de la taille d'un boss, augmentation du nombre de vies

Eaglemorph - lorsqu'il est touché, il sacrifie un segment de corps et le recrachera

Squidmorph - Bug alien gonflable, il peut absorber nos armes

LobstermorphADN instable, se divise en plusieurs clones plus petits lorsqu'il est touché

Amusez-vous bien !

Rencontrez votre enseignant·e

Teacher Profile Image

Frank Dvorak

Creative Coding

Enseignant·e

Hello, I'm Frank. I'm a front-end web developer, owner of Frank's Laboratory YouTube channel. Come explore creative coding, game development and generative art with me.

Voir le profil complet

Level: Intermediate

Notes attribuées au cours

Les attentes sont-elles satisfaites ?
    Dépassées !
  • 0%
  • Oui
  • 0%
  • En partie
  • 0%
  • Pas vraiment
  • 0%

Pourquoi s'inscrire à Skillshare ?

Suivez des cours Skillshare Original primés

Chaque cours comprend de courtes leçons et des travaux pratiques

Votre abonnement soutient les enseignants Skillshare

Apprenez, où que vous soyez

Suivez des cours où que vous soyez avec l'application Skillshare. Suivez-les en streaming ou téléchargez-les pour les regarder dans l'avion, dans le métro ou tout autre endroit où vous aimez apprendre.

Transcription

1. Introduction: Voyageons dans le temps, à l'âge d'or des jeux vidéo d'arcade. Dans ce cours, nous utiliserons le HTML, le CSS et le Javascript pour créer un jeu inspiré des classiques, mais nous lui donnerons notre propre style artistique et des fonctionnalités personnalisées. Nous contrôlerons un vaisseau spatial qui doit se frayer un chemin à travers vagues d' ennemis de plus en plus importantes, avec des bustes occasionnels entre les Au fur et à mesure que nous progressons dans l'inconnu, nous débloquons de nouvelles armes et nous rencontrons des espèces extraterrestres encore plus dangereuses. cours ne sont pas destinés aux débutants, mais si vous comprenez déjà les bases telles que les variables, les tableaux et les boucles, venez découvrir développement de jeux et l'animation de scripts de discussion avec moi Les étudiants de cette classe recevront gratuitement une tonne d' illustrations de deux jeux de qualité supérieure. Vous pourrez également l'utiliser pour vos propres projets personnels plus tard et créer vos propres jeux avec lui. Vous pouvez également télécharger le code source complet à partir différentes étapes du projet au fur et à mesure que nous le développons et ajoutons de plus en plus de fonctionnalités. 2. Caractéristiques du projet: Nous allons d'abord implémenter trois types d'armes une attaque de base, un laser à longue portée et un super laser. Nous en aurons besoin car nous devrons nous frayer un chemin à travers cinq types d'ennemis différents. Au début, nous ne rencontrons qu' un espace arrière normal. Un seul coup de notre arme de base suffit. Au fur et à mesure que nous explorons, nous rencontrons des ennemis blindés. Nous devons les frapper cinq fois. Nous pourrons constater les dommages graduels subis par leur épais exosquelette après chaque impact. Si nous ne faisons pas attention, nous risquons de trouver un ennemi de grande taille doté de griffes dangereuses Chaque fois qu'un nouveau joueur apparaît, il aura plus de points de vie que celui-ci avant d'augmenter lentement le chal***ge pour Au fil du jeu, certaines espèces exotiques veulent se venger. Regarde celui-ci. Chaque fois que nous le touchons, il sacrifie un segment du corps et il nous le renvoie sous la forme d'un projectile mutant fait de glace, de boue Nous devrons également combattre un ennemi qui absorbe nos projectiles et gonfle jusqu'à ce qu'il éclate Avec celui-ci, je vais vous proposer une version normale et une version des deux tailles des feuilles de calcul pour rendre votre jeu encore plus diversifié et amusant à explorer. Nous allons tout coder à partir de zéro sans frameworks ni bibliothèques, comme d'habitude. J'espère que vous vous amuserez bien dans cette aventure spatiale en Java Script. Allons-y. 3. Paramétrage de projet: Dans l'index HTML, nous créons une simple page Web vierge. Je lui donne un titre. Je lie une feuille de style CSS, je crée un élément HTML à cinq canevas avec un identifiant de canevas un. Et je lie le script au fichier GS dans le style CSS. Je cible mon élément de toile et je lui donne une bordure. Je veux le centrer au milieu de la page Web verticalement et horizontalement. Une façon de le faire est d'utiliser ces quatre lignes de CSS. Nous pouvons utiliser transform translate, ou nous pouvons également simplement utiliser la propriété translate comme ceci. Attention à la syntaxe, il n'y a pas de virgule entre les valeurs Tout le reste de cette classe sera écrit en Javascript normal. Pas de frameworks ni de bibliothèques. Dans la programmation moderne, nous pouvons structurer notre code de différentes manières. Il existe quelques paradigmes de programmation courants et établis allant de quelque chose de très simple, comme la programmation procédurale, à la programmation fonctionnelle et orientée objet La programmation orientée objet est probablement le paradigme le plus populaire. Le concept de base est que nous organisons nos données en objets. Il repose généralement largement sur des classes qui nous permettent de créer de nombreux objets similaires sur la base d'un plan partagé Dans le cours d'aujourd'hui, nous allons garder notre code propre et organisé en transformant tout en objet. Et nous allons faire en sorte que ces objets communiquent entre eux. Par exemple, lorsqu'un projectile touche un objet ennemi, l'objet ennemi sera supprimé. L'un des grands principes de la programmation orientée objet est l'encapsulation, ce qui signifie que nous utilisons des données et des méthodes qui opèrent sur ces données en faisceaux séparés en Nous pouvons également restreindre l'accès à ces données en dehors des fermetures du bundle, des champs privés, etc. Nous allons encapsuler nos données dans quatre classes distinctes qui communiquent et travaillent ensemble pour créer le jeu final classe de joueur gérera le mouvement et l'animation du personnage principal, le vaisseau spatial robotique Cette classe n' aura qu'une seule instance. Les classes sont utilisées comme plans pour créer de nombreux objets similaires Dans ce cas, le joueur n'a pas besoin d'être une classe, nous pouvons simplement le déclarer comme un objet simple. Je vais en faire une classe pour garder la même structure de code dans toute la base de code. Je veux que ce soit facile à lire pour les débutants. La classe des projectiles manipulera lasers que le joueur tirera Nous allons apprendre comment en faire un pool d'objets réutilisables afin d'améliorer considérablement les performances Parce que créer et supprimer des milliers d'objets projectiles gaspillerait beaucoup de mémoire La classe ennemie dessinera et animera Space Invaders. Nous apprendrons comment les organiser en grilles et comment les faire apparaître en vagues de plus en plus grandes Au fur et à mesure du jeu, la classe Game contiendra la logique principale de la base de code. C'est le cerveau principal qui envoie des commandes partout et qui maintient tout cela ensemble. Nous utiliserons des graphismes de jeu professionnels raffinés que je vous propose entièrement gratuitement. Et nous devons nous assurer que Javascript ne fonctionne qu'une fois que toutes nos ressources artistiques sont chargées et disponibles. Je ne démarrerai et configurerai mon projet qu'après événement de chargement sur l'objet Windows lorsque toute la page sera chargée, y compris toutes les ressources dépendantes telles que les feuilles de style , les scripts, les images, etc. Dans la fonction de rappel sur l'écouteur d'événements de chargement, nous pouvons configurer notre élément de canevas Comme d'habitude, j'utilise quatre lignes de code simples. Tout d'abord, je pointe le script Java vers mon élément de canevas en utilisant son identifiant. J'enregistre cette référence dans une variable, variable CTX context canvas dot get context et je la transmets au Cela créera une instance intégrée à l'API du canevas, nous donnant accès à toutes les méthodes de dessin et aux propriétés du canevas, telles que le style de remplissage ou la largeur de ligne. Parce que nous voulons nous assurer que les dessins sur toile ne sont pas déformés. Nous ne définissons pas la taille du canevas avec du CSS car cela ne définirait la taille de l'élément que si je définissais la largeur et la hauteur du canevas comme ceci. Avec Javascript, nous définissons les à la fois pour la taille de l'élément et pour la taille de la surface du dessin mêmes valeurs à la fois pour la taille de l'élément et pour la taille de la surface du dessin. Le canevas HTML a deux tailles, elles doivent être définies sur la même valeur pour éviter les distorsions. 4. Objets de jeu et de joueur: L'objet du jeu devra être conscient de la taille du canevas. Le constructeur s' attendra donc à une référence pointant vers l'élément canvas comme argument À l'intérieur, nous le convertissons en propriété de classe. Prenez le canevas passé en argument et convertissez-le en cette propriété de canevas à points sur cette instance de classe de jeu. À partir de là, nous pouvons extraire une largeur de toile de 600 pixels et une hauteur de toile de 800 pixels. C'est très important. Et ces valeurs seront nécessaires dans l'ensemble de notre base de code. Parce que par exemple, le joueur et le projectile doivent savoir s'ils se trouvent à l'intérieur ou à l' extérieur de la zone de toile visible L'objet du jeu aura une méthode personnalisée. J'appelle par exemple render. Cette méthode s'exécutera 60 fois par seconde, dessinant et mettant à jour tout. Tout d'abord, il suffit d'y mettre une console. Je crée une instance de classe de jeu en utilisant le nouveau mot-clé à la ligne 14. Je peux voir qu'il attend un canevas comme argument. Je passe le canevas à partir de la ligne 25. Si je console cette nouvelle variable de jeu, je peux voir une instance de ma classe de jeu Si je l'ouvre, je peux voir que ces propriétés sont parfaites. Je peux également appeler cette méthode de rendu personnalisée que nous avons écrite à la ligne 19. Et maintenant je peux voir que c'est correctement consolo en largeur de 600 pixels et en hauteur de 800 pixels Notre jeu est prêt à fonctionner. Je veux dessiner et animer Le constructeur de la classe joueur s'attendra une référence à l'objet principal du jeu partir de la ligne 13 comme argument Comme nous avons besoin d'accéder à la largeur et à la hauteur et bien d'autres éléments qui figureront dans la classe de jeu principale, j'ai besoin d'accéder à toutes ces propriétés depuis la classe des joueurs. Gardez à l'esprit qu'en faisant cela, je ne crée pas de copie de l'objet principal du jeu. Je montre simplement l' espace en mémoire où se trouve l'objet du jeu depuis la classe de joueur. J'enregistre cette référence car largeur de cette propriété de jeu de points du joueur sera de 100 pixels. La hauteur sera également de 100 pixels. Pour l'instant, la coordonnée horizontale x sera 200 et la coordonnée Y verticale sera également de 200 pixels. Donnons-lui une méthode de dessin personnalisée. Il s'attendra à une référence au contexte pour spécifier le canevas sur lequel nous voulons dessiner. Je le fais comme ça pour que chaque classe reste aussi autonome que possible . À l'intérieur, nous en retirerons ce contexte. Nous appelons rectangle de remplissage intégré et nous lui donnons x, y, largeur et hauteur. Position et taille actuelles du joueur. Je vais structurer mon code de manière à ce que tout repose sur l'objet principal du jeu afin que je puisse dessiner et tout mettre à jour à partir de là. Dans le constructeur de classe de jeu, je crée une propriété de joueur dist personnalisée et je la définis comme une instance de classe de joueur En utilisant le nouveau mot-clé, joueur s'attend à une référence à l'objet principal du jeu. J'ai passé ce mot clé parce que nous sommes ici dans cette classe de jeu. Maintenant que nous avons créé le joueur, nous pouvons le dessiner en appelant la méthode draw à partir de la ligne neuf. Ce joueur de la ligne 27 fait match nul. Je peux voir que la méthode draw attend le contexte et j' appellerai cette méthode Phil Rectangle à partir du contexte. Je sais aussi que la méthode du rectangle de Phil repose sur ma variable CT X ici. Je passe CTX à render, render attendra cette valeur comme argument et l' enregistrera sous forme de variable appelée context Je vais le transmettre à Player Draw comme si cette méthode s'attendait déjà à un contexte. Et c'est ainsi que l'on peut appeler ce rectangle de remplissage. Ici, à la dixième ligne, c'est sympa, nous dessinons un carré noir représentant le joueur. Je peux changer les coordonnées x et y pour déplacer le joueur. Et si je veux que le joueur soit au milieu, horizontalement ? La largeur des points de ce jeu multipliée par 0,5 Ensuite, nous devons décaler cette valeur de moitié par rapport à la largeur du joueur. Maintenant, il est parfaitement centré verticalement. Je veux que le joueur s'assoit en bas de la zone de jeu. La hauteur du jeu moins la taille du joueur. Parfait. Nous avons un objet de jeu fonctionnel et un objet joueur. Je veux faire bouger le joueur à gauche et à droite. Lorsque nous appuyons sur les touches fléchées du clavier, je donne au joueur cette propriété de vitesse des points. Je veux qu'il se déplace, par exemple, de cinq pixels par image d'animation. Je lui donne une méthode de mise à jour qui actualisera position horizontale du joueur en fonction de sa vitesse. Pour exécuter ce code, je dois l'appeler d'ici. Rien ne se passe vraiment car ce code ne s'exécute qu'une seule fois. Pour créer un mouvement, je dois dessiner le joueur, mettre à jour sa position, le dessiner à nouveau, le mettre à jour à nouveau, etc. Créons une boucle d'animation. Fonction personnalisée. J'appelle Animate. J'ai mis Game Dot Render dedans. Ensuite, nous appelons request animation frame qui se trouve sur l' objet de la fenêtre principale et je lui passe le nom de sa fonction parent pour créer une boucle Si je supprime le point de fenêtre ici, cela fonctionnera toujours. Javascript sait où trouver cette méthode. Nous appelons Animate. Nous dessinons et mettons à jour le jeu, puis nous relançons l'animation. Cela se répétera encore et encore. J'ai juste besoin d'appeler animate pour déclencher la première boucle comme celle-ci Nous voyons de la vieille peinture. Je veux seulement voir le cadre d'animation actuel. Entre chaque boucle, je vais effacer la totalité du canevas à partir de la coordonnée 002. Toile avec hauteur de toile. Bien, le joueur se déplace vers la droite, cinq pixels par image d'animation. 5. Commandes au clavier: Si je règle la vitesse sur moins un, le joueur se déplace vers la gauche un pixel par image d'animation. Si la vitesse est nulle, il n'y a aucun mouvement. Ajoutons les commandes du clavier. Tout le code contenu dans un constructeur de classe est automatiquement exécuté au moment où nous créons une instance de la classe en utilisant le nouveau mot-clé Normalement, nous n' utilisons l'espace que pour donner les propriétés de notre objet, mais nous pouvons y mettre n'importe quel code que nous voulons exécuter à ce stade de la création de cet objet en particulier. Par exemple, si je le fais, les écouteurs d'événements seront automatiquement appliqués Lorsqu'une nouvelle instance d'objet de jeu est créée, je crée un écouteur d'événements pour l'événement key down La fonction de rappel a accès à un objet d'événement généré automatiquement qui contient toutes les différentes propriétés et informations sur l' événement key down qui vient Pour l'utiliser, il suffit de lui donner un nom de variable ici et Javascript saura quoi faire. Je vais l'appeler pour un événement intérieur. Je vais me consoler. J' enregistre mes modifications, je sélectionne l'élément Canvas et j'appuie sur un élément de mon clavier. L'événement Keydown se déclenche et objet d'événement généré automatiquement s' affiche dans la console du navigateur. Si je l'inspecte, je peux voir toutes sortes d'informations. Aujourd'hui, nous ne nous intéressons qu' à cette propriété clé. Ici, vous pouvez voir que j'ai appuyé sur une lettre sur mon clavier, dans ce cas si j'ai appuyé sur la touche console Maintenant, lorsque j'appuie sur des touches aléatoires, le nom de la touche pressée s'affiche. Prenez note de ces valeurs. Remarquez comment les touches fléchées sont orthographiées, car nous aurons besoin de ces valeurs Nous devons maintenant nous assurer que nous utilisons exactement la même orthographe, y compris les minuscules et les majuscules. Sur mon objet de jeu principal, j'aurai un tableau appelé « point keys ». Lorsqu'une touche est enfoncée lors d'un événement, j'ajoute le nom de la touche qui vient d'être enfoncée dans ce tableau. Lorsque la clé est relâchée, nous la retirons. Je prends ces touches à point ici et j'appelle la méthode push. Je vais appuyer sur la touche point pour indiquer le nom de la touche qui a été enfoncée dans le tableau. Je le sauvegarde et je le teste. Lorsque je commence à taper sur mon clavier, je reçois une erreur de console. C'est parce que nous plaçons un écouteur d' événements qui se trouve sur un objet fenêtre à l'intérieur de notre objet de jeu personnalisé Ici, j'essaie d'accéder à cette propriété de touches à points située sur l'objet du jeu. Mais cette fonction de rappel ne se souvient pas réellement où dans le code elle a été initialement déclarée, elle ne se souvient pas de sa portée lexicale Nous devons lier le mot-clé de manière à ce qu'il pointe vers l'objet du jeu depuis cette fonction de rappel Ou bien, nous pouvons utiliser syntaxe de la fonction ES à six flèches. Les fonctions de flèche héritent automatiquement ce mot clé de la portée parent Maintenant, ce point utilisé ici pointe correctement vers l'objet du jeu, et mon code fonctionnera. Les boîtiers Scope sont des sujets de programmation avancés. Si vous êtes débutant, vous n'êtes pas obligé de bien le comprendre à ce stade. Cela finira par avoir plus de sens. Continuez simplement à écrire du code. Je suis contre l'enregistrement de ce dokey et nous pouvons voir qu'il grossit de plus en plus au fur et à mesure que j'appuie sur de plus en plus de touches De plus, je recharge et remarque que si je continue d' appuyer sur la flèche vers le haut, cela l'ajoutera encore et encore. Je souhaite uniquement ajouter une entrée par clé. Si la flèche vers le haut figure déjà dans le tableau, ne l'ajoutez pas à nouveau. En Java Script, la méthode index off peut être appelée sur un tableau. Elle renvoie le premier indice auquel un élément donné peut être trouvé dans le tableau. est important de se rappeler qu'il renvoie moins un si l' élément n'est pas présent. Sachant cela, nous pouvons dire si cet index de touche de dokey est égal à moins un, si la touche pressée n'est pas présente dans ce tableau de touches à points Ensuite seulement, enfoncez la clé dans le tableau. Maintenant, je peux appuyer sur la flèche vers le bas encore et encore, et elle ne sera ajoutée au tableau qu'une fois parfaite. Je souhaite également supprimer la clé du tableau lorsque la clé est relâchée. Lorsque l'événement key up se déclenche, je copie ce bloc de code. Pour le rendre plus propre, je crée une variable constante délimitée par bloc , appelée ici index Et ce sera l'index de la clé qui a été publiée dans ce tableau de touches à points si l'index est supérieur à moins un. Cela signifie que si la clé qui a été relâchée se trouve dans ce tableau de touches à points , elle devrait toujours être le cas. Au fait, nous utiliserons méthode Splice pour supprimer cette entrée, cette clé, de ce tableau de touches à points La méthode d'épissage de script Java intégrée peut être utilisée pour remplacer ou supprimer des éléments existants d'un tableau Si une clé est trouvée dans le tableau que j'appelle splice, je trouve l'index de cet élément dans le tableau et je le supprime L'épissage peut être utilisé pour retirer plusieurs éléments. Nous devons en transmettre un ici parce que nous voulons supprimer uniquement l' élément que nous y avons trouvé. OK, donc j'appuie sur la touche Entrée de mon clavier. Aucune entrée n'est présente dans ce tableau de touches à points. On l'enfonce dedans, je relâche Enter. Nous trouvons l'index de cette entrée dans ce tableau de touches à points et nous le supprimons en utilisant la méthode Splice J'appuie sur la flèche vers le haut, c'est ajouté, je le relâche. Il a été retiré. Je tape un peu plus. Cela fonctionne bien. Génial. C'est une bonne pratique de toujours supprimer les consoles lorsque nous n'en avons plus besoin. maintenant à l'objet principal du jeu, nous avons ce tableau de touches à points qui permet de suivre les touches actuellement enfoncées. Accédez à tout ce qui se trouve sur l'objet du jeu depuis l'intérieur de l'objet du joueur grâce cette propriété de jeu à points située dans la méthode de mise à jour de la classe du joueur. Je peux dire que si index de la flèche gauche de ce jeu est supérieur à moins un, ce qui signifie que vous avez appuyé sur la flèche gauche, continuez à produire la position horizontale du joueur en déformant la vitesse par rapport à la ligne huit, en le faisant se déplacer vers la Une autre flèche d'instruction if vers la droite et nous disons « plus » fait en sorte que la vitesse la fasse se déplacer vers la droite. Maintenant, je dois régler la vitesse de distorsion sur une valeur autre que zéro Ici, par exemple, cinq pixels par image. Maintenant, je peux appuyer sur les flèches gauche et droite, et le joueur se déplace à gauche et à droite. L'avantage de cette structure de code est que nous pouvons facilement augmenter la vitesse des joueurs. Ou nous pouvons ralentir le joueur en modifiant cette propriété de vitesse sur la ligne huit. Le problème est que le joueur peut se déplacer jusqu'en dehors de la zone de jeu. Je vais régler la vitesse à dix pixels par image. Pour l'instant, c'est ici que nous gérons le mouvement horizontal. Je vais introduire ici quelques limites horizontales. Si ce x est la position horizontale du joueur, le coin supérieur gauche du rectangle du joueur est inférieur à zéro, cela créera une limite gauche rigide L. Si le joueur ne peut pas toucher à gauche et droite la zone de jeu dans le même cadre d'animation, nous pouvons utiliser L si ici, si x est supérieur la largeur du jeu moins la largeur du joueur, x est égal à la largeur du jeu moins la largeur du joueur. Cela créera une limite dure sur le côté droit. Je le teste, le joueur ne peut plus sortir de la zone de jeu des deux côtés. Sympa. 6. Pool d'objets: Maintenant que nous avons les commandes du clavier, je veux que le joueur lance des lasers lorsque nous appuyons sur quelque chose. La classe Projectile s'en chargera. Dans un jeu comme celui-ci, nous tirerons un grand nombre de projectiles Nous pourrions créer un nouvel objet projectile chaque fois et le jeter lorsqu' il entre en collision avec quelque chose ou lorsqu'il s' envole Mais comme je l'ai expliqué dans la leçon précédente, création et la suppression de grandes quantités d' objets créent des problèmes de performances liés à la mémoire Dans ce jeu, nous n'aurons que dix projectiles au total Et nous allons réutiliser ces dix mêmes objets encore et encore, pour améliorer considérablement les performances L'avantage en termes de performances sera particulièrement évident dans les parties les plus animées du jeu. Croyez-moi, ce jeu peut devenir très animé lorsque des vagues d'ennemis commencent à arriver. Nous devons nous assurer d'optimiser les performances de nos jeux. Nous y parviendrons en utilisant le modèle de conception du pool d' objets. Chaque projectile aura des propriétés de largeur, de hauteur, de x, de y et de vitesse Parce que nous voulons en faire un membre du pool d'objets réutilisable, membre du pool d'objets réutilisable, nous devons également lui donner cette propriété sans points. Lorsque cette absence de points est vraie, projectile se trouve dans la piscine, prêt à être utilisé Il ne joue actuellement aucun rôle actif dans le jeu. Ce n'est pas visible. Lorsque ce point sans point est faux. Cela signifie que nous l'avons retiré de la piscine et que nous l'utilisons. Ce n'est plus gratuit, il n'est plus disponible. Le modèle de conception du pool d'objets est un modèle de conception créatif. Cela nous permet d'éviter les problèmes de performances liés à l'allocation automatique de mémoire et processus de collecte des déchets qui se déclenchent lorsque nous créons et détruisons de grandes quantités d'objets Javascript. Nous allons plutôt créer un petit pool de dix projectiles Et nous les retirerons de la piscine quand nous en aurons besoin. Lorsque les projectiles entrent en collision avec des ennemis ou lorsqu'ils quittent l'écran, nous les renvoyons simplement Nous réinitialisons leurs propriétés et nous les rendons disponibles pour être retirés à nouveau, ils sont nécessaires. Cela supprimera complètement le ralentissement causé par allocation de mémoire lorsque nous créons des objets un par un. De plus, le processus de collecte des déchets qui efface automatiquement et périodiquement objets qui ne sont plus mémoire les objets qui ne sont plus référencés dans notre jeu ne se déclenchera pas du tout car nous rejetterons pas ces projectiles Le modèle de conception de pool d'objets ne se limite pas à cela, mais ce cours s'adresse aux débutants. Aujourd'hui, je vais vous montrer comment réaliser une implémentation très simple mais puissante dans un véritable projet de travail. Si vous voulez en savoir plus à ce sujet, je vais mettre en lien quelques bons articles dans la description ci-dessous. Nous lui donnons une méthode de dessin, mais nous voulons uniquement dessiner projectiles actifs uniquement si le projectile n'est pas libre actuellement Il en va de même pour la mise à jour. Tout code contenu dans la méthode de mise à jour s'exécutera uniquement pour les membres actifs du pool d' objets. Ce n'est que si free est faux, exclamation signifie faux si les projectiles ne sont pas actifs, s'ils sont juste assis dans la piscine en attente d'être utilisés, nous ne les tirerons pas et nous ne les mettrons pas à nous ne les tirerons pas et nous ne les mettrons pas Si un projectile a été retiré du pool d'objets et qu'il n'est pas libre. le moment, nous allons dessiner un rectangle représentant le projectile, la méthode de mise à jour pour tous les projectiles actifs Nous les ferons se déplacer vers le haut dans le sens négatif sur l'axe vertical y. Je veux qu'ils bougent assez vite. Essayons 20 pixels par image d'animation et voyons à quoi cela ressemble. Chaque membre du pool d'objets doit disposer de deux méthodes d'assistance. Méthode qui s'exécute lorsque l'objet est extrait du pool d'objets. Je vais l'appeler Start. Une autre méthode qui s'exécute lorsque l'objet n'est plus nécessaire et qu'il est renvoyé dans le pool d'objets disponibles. Lorsque nous commençons à utiliser l' objet que nous avons mis libre de faire face, l'objet est utilisé, il n'est plus disponible dans le pool. La méthode de réinitialisation le ramènera dans le pool en définissant sa propriété free sur true. qui signifie qu'en raison de ces deux vérifications, l'objet cessera d'être dessiné et mis à jour après l'exécution de la méthode de réinitialisation. J'espère qu'il est logique de laisser un commentaire si vous le comprenez ou si vous avez besoin d'une explication plus approfondie. Vous pouvez simplement laisser un commentaire avec un simple emoji « pouce levé Si vous l'avez bien compris, je comprendrai ce que vous voulez dire et tout le monde sera déconcerté par ce commentaire. C'est la classe des projectiles. C'est un membre du pool d'objets et il possède tout ce dont il besoin pour créer un modèle de conception de pool d'objets dans notre base de code. Maintenant, nous avons juste besoin d'un moyen de créer ce pool d'objets en utilisant cette classe de projectiles Nous allons le faire dans le cerveau principal de notre base de code. Ici, dans la classe de jeu, je lui donne une propriété appelée pool de projectiles, et je lui attribue un tableau vide. Le nombre de projectiles sera de dix. Je ne veux utiliser qu'un très petit nombre ici. Cela fonctionnera également bien pour le gameplay dans ce cas. Je vais vous montrer pourquoi je ne veux que dix projectiles alors que nous faisons de l'animation Le modèle de conception du pool d'objets nécessite une méthode qui remplira le pool de dix objets projectiles inactifs dans un premier temps De cette façon, nous préallouons la mémoire aux anciens objets en une seule fois, ce qui est bon pour les performances. C'est plus rapide de le faire de cette façon et de créer tous les objets du pool en même temps que de demander à un script Java de rechercher l'espace libre en mémoire pour chaque projectile séparément, un par un au fur et à mesure que nous en avons besoin. Il s'agit d'une méthode très simple pour expliquer comment et pourquoi le modèle de conception du pool d' objets résout problèmes d'allocation de mémoire en réutilisant au lieu de les supprimer Nous évitons également complètement déclencher le processus de collecte des déchets Une autre méthode personnalisée d'amélioration des performances que j'appelle créer des projectiles Il sera exécuté dix fois. Chaque fois qu'il fonctionne, il faut que ce projectile tire et il pousse un nouveau projectile à l' intérieur de nous , créé par nous Dans la classe que nous avons écrite à la ligne 23, nous avons besoin d'une dernière méthode auxiliaire. Une méthode qui nous permettra de retirer un projectile libre de la piscine lorsque nous en aurons besoin J'appelle cette méthode, par exemple, introduire un projectile à l'intérieur. Nous parcourrons le pool de projectiles un par un. Dès que nous trouvons un élément dont les trois propriétés sont définies sur true, nous renvoyons cet élément et nous arrêtons la recherche. Le mot clé return arrêtera l'exécution de ces quatre boucles. Je souhaite créer des projectiles automatiquement. Ici, lorsqu'une instance de la classe de jeu est créée, pool de projectiles est créé et automatiquement rempli dix objets projectiles inactifs et prêts à être utilisés Voyons si cela a fonctionné par console. Dans ce pool de projectiles, je peux voir qu'il s'agit d'un réseau de dix J'en ouvre juste un et je vérifie que je ne vois aucune valeur indéfinie ou non définie qui indiquerait un problème dans ma classe de projectiles. Tout va bien ici. projectile a une méthode de démarrage qui s' exécute lorsque nous sortons le projectile de la piscine Et nous voulons commencer à l'utiliser dans le jeu car le projectile s' envolera hors du joueur La méthode de démarrage attendra les coordonnées X et Y du joueur comme argument, elle placera ce point et ce y du projectile sur les coordonnées x et y actuelles du joueur Enfin, pour compléter cette grande boucle logique, nous donnons au joueur une méthode personnalisée appelée shoot je crée une variable constante délimitée par blocs appelée projectile Et ce sera équivalent à obtenir méthode des projectiles que nous venons d'écrire sur la classe de jeu principale ici à la ligne 92 Il recherchera dans le pool de projectiles si l'un des dix projectiles est gratuit et disponible, il nous le communiquera si les dix projectiles sont actuellement utilisés dans le jeu, il n'en trouvera Nous aurions donc une erreur ici. Ce n'est que si nous avons trouvé le projectile et qu'il n'est pas indéfini nous appellerons la méthode de démarrage sur ce projectile inactif dans le pool pour l'activer Nous savons que la méthode de démarrage attend les positions x et y du joueur. Je le passe point x point y. Nous transmettons les positions x et y actuelles du joueur où qu'il se trouve. Lorsque la méthode de démarrage s'exécute, la méthode de démarrage s'y attend. Il définit les coordonnées x et y du joueur Y sur les coordonnées x et y du projectile Et il l'active en définissant sa propriété free sur falls, ce qui signifie que le code contenu dans les méthodes de dessin et de mise à jour passera cette vérification avec succès. Il commencera à exécuter le dessin et à mettre à jour le projectile Comment déclencher cette méthode de prise de vue personnalisée que nous venons d'écrire ? Je pourrais par exemple venir ici et entrer dans Keydown Event Listener Je dis que si la touche qui a été pressée est Entrée, faites attention à l'orthographe. Les lettres minuscules et majuscules sont ici très importantes. Vous pouvez utiliser la clé de console à partir d'ici pour voir comment une valeur de clé particulière est orthographiée Peut-être que je veux plusieurs attaques différentes. Le tir de base sera déclenché lorsque nous appuierons sur le numéro un du clavier. Dans ce cas, les nombres sont exprimés en nombres dans ce contexte, il s' agit d'un type de données de chaîne. Lorsque le numéro un est enfoncé sur le clavier, méthode de tir du joueur s'exécute. Pour vraiment le voir, je dois parcourir les dix objets projectiles contenus dans les dix objets projectiles contenus réseau de bobines de projectiles, les dessiner et les Je le fais d'ici. Cette bobine de projectile pour chaque objet projectile de la matrice, nous l' appelons mise à jour et nous appelons sa Nous savons que le tirage au sort dépend du contexte. Nous lui transmettons simplement la valeur de contexte de la ligne 84. Cette valeur de contexte est attendue ici. Si le projectile est activé, sa propriété free est définie sur false Le contexte sera utilisé pour appeler la méthode Phil Rectangle qui dessinera le projectile pour nous J'enregistre mes modifications et j' appuie sur l'une des touches du clavier. La méthode de prise de vue fonctionne. Nous obtenons un projectile gratuit dans le pool d'objets et nous déclenchons sa méthode de démarrage projectiles démarrent toujours à partir des positions X et Y actuelles du joueur, même lorsque le joueur se déplace Parce que nous transmettons les coordonnées actuelles du joueur à la méthode de départ. Ici, je ne peux tirer que dix fois. Ensuite, nous avons épuisé tous les objets du pool d'objets et je ne peux plus photographier. Je veux que les projectiles se réinitialisent et redeviennent disponibles dans le pool lorsqu'ils quittent l'écran. Si la coordonnée verticale y du projectile est inférieure à zéro moins la hauteur du projectile, si le projectile entier s'est déplacé derrière le bord supérieur de l'écran, nous appelons méthode de réinitialisation à partir de la nous appelons méthode de réinitialisation à partir de La méthode de réinitialisation définira la propriété libre de ce projectile sur true, le renvoyant dans le pool, le rendant à nouveau disponible. Maintenant je peux tirer sans arrêt. Si je tire très vite, cela me donnera dix projectiles en une courte Lorsqu'ils quittent l'écran, ils se réinitialisent et pourront en ressortir. rectangles parfaits sur toile sont dessinés dans le coin supérieur gauche Les joueurs X et Y sont dans ce coin supérieur gauche. En fait, je veux qu'ils sortent du milieu du joueur horizontalement. Nous lui passons x du joueur plus la moitié de la largeur du joueur. Il n'est toujours pas parfaitement centré, ce qui devient encore plus évident si j'élargis les projectiles Peut-être que mon attaque secondaire ressemblera à ceci. J'ai besoin que cela soit centré sur le joueur, quelle que soit la forme du projectile Je vais le faire à partir d'ici, dans le cadre de la classe de projectiles Parce qu'ici nous avons accès à la largeur du projectile lui-même. Nous pouvons ainsi décaler la position horizontale du joueur de la moitié de la largeur du projectile Maintenant, quelle que soit l'étroitesse ou la largeur des projectiles actuels, ils proviennent toujours exactement du milieu du joueur à l'horizontale Faisons huit pixels pour le moment. Un travail incroyable. Nous avons le joueur qui peut se déplacer et tirer des projectiles Les techniques que nous venons d'apprendre sont extrêmement utiles et puissantes et vous pouvez les utiliser pour créer des centaines de parties différentes si le joueur que nous avons est très large Pour une raison ou une autre, si j'arrête joueur lorsqu'il touche les bords comme ça, nous aurons du mal à tirer sur les ennemis qui se trouvent le plus près des limites de la zone de jeu. Nous ne pourrons pas les atteindre avec notre attaque de base. Cela peut créer toutes sortes de difficultés dans la façon dont nous concevons notre jeu Je vais le corriger ici dans la zone des limites horizontales. En fait, je vais autoriser le joueur à se cacher derrière le bord de l'écran jusqu'à ce que la moitié soit masquée. Ce n'est qu'alors que nous introduirons une limite d'arrêt. Maintenant, je peux atteindre les ennemis sur toute la gauche. Je vais également le faire pour le bord droit de la zone de jeu. Désormais, quelle que soit la largeur du joueur, notre simple attaque laser de base peut atteindre importe où et les ennemis n'ont nulle part où se cacher. Parfait. 7. Vagues ennemies: En parlant d'ennemis, ce sera intéressant. Créons des ennemis qui nous attaqueront en forme de grille. Et chaque fois que nous vaincrons une vague, une plus grande vague d' ennemis arrive. Avant cela, donnons un aperçu de notre jeu. Je vous offre un ensemble complet, raffiné et professionnel d' actifs artistiques de haute qualité pour ce projet. Vous pouvez tout télécharger dans la section des ressources ci-dessous. Prenez l'image PNG d'arrière-plan que vous pouvez y trouver et placez-la dans le dossier de votre projet, puis utilisez-la comme propriété d' arrière-plan. Nous pouvons réellement faire cette partie avec du CSS. Le CSS est accéléré par le GPU. faire de cette façon est plus rapide en termes de performances que de redessiner la même image encore et encore sur Navas au fur et à mesure que notre jeu Maintenant, mes dessins sur toile sont trop sombres par rapport à ce nouveau fond d'ici. Lorsque tout est chargé et que les navas sont configurées, je définis un style de remplissage pour tout ce qui est dessiné sur des navas trop larges. Pour le moment, c'est bon. Je vais créer des ennemis individuels en utilisant notre classe d'ennemis personnalisée. Ils devront avoir accès à certaines méthodes et propriétés que j'ai ajoutées à la classe de jeu principale. Nous aurons également une référence à la classe de jeu à partir d'ici. Comme ça. Il y a quelques défis que nous devons relever ici. Parce que nous voulons que les ennemis se déplacent dans une grille et qu'ils se déplacent dans la même direction. Je veux que toute la vague d' ennemis suive le même schéma de mouvement. Nous devrons nous arrêter et réfléchir à la manière d'organiser notre code. Pour y parvenir, chaque ennemi, en fait, tous les objets de notre jeu doivent avoir des propriétés de largeur, de hauteur, de x et de y, principalement à des fins de détection de collision. La méthode de dessin personnalisée prendra le contexte comme argument et nous traiterons un rectangle représentant chaque ennemi. Pour l'instant, j'allais également transformer les ennemis en un pool d' objets réutilisables. Mais je veux que ce cours reste convivial pour les débutants et combiner un pool d'objets avec la logique de grille que nous sommes sur le point d'écrire pourrait devenir difficile à suivre. Pour l'instant, les ennemis seront des objets de base très simples, aucune fonctionnalité de pool d'objets ici. Pour l'instant, la méthode de mise à jour déplacera l'ennemi. Mais si je veux que tous les ennemis se déplacent dans une formation en grille, selon le même schéma de mouvement, nous ne pouvons pas avoir une vitesse individuelle ici et mettre à jour chaque ennemi séparément. valeur de position de l' ensemble de la vague d'ennemis devra être stockée quelque part au même endroit dans notre code. Et chaque ennemi saura où il se situe par rapport à cette valeur. Au fur et à mesure que la vague se déplace, tous les ennemis se déplacent avec elle. Laissez-moi vous montrer exactement ce que je veux dire. Créez une classe wrapper appelée Wave Constructor. Encore une fois, vous aurez besoin d'accéder aux propriétés et aux méthodes de l'objet principal du jeu. Nous savons que tous les objets de notre jeu doivent avoir une largeur, hauteur, une position x et une position y. Réglons la position sur 00 dans le coin supérieur gauche de la zone de jeu pour le moment. Ici, dans le constructeur de classe de jeu, je supprime cette console Chaque vague comportera un ensemble d' ennemis organisés en grille. La première vague sera une grille de neuf ennemis organisés en trois colonnes et trois rangées. J'ai également besoin de la taille de l'ennemi, la taille de chaque ennemi individuel pour être disponible dans le monde entier, ensemble de ma base de code. Parce que nous devons en être conscients à plusieurs endroits dans le code. Pour l'instant, chaque ennemi sera un carré de 60 fois 60 pixels. Je veux que toute la grille d'ennemis rebondisse entre les bords gauche et droit de la zone de jeu. Chaque fois que la vague d' ennemis touche le bord, elle saute d'un cran, plus près du joueur. La largeur de la vague complète de neuf ennemis organisés en trois rangées et trois colonnes sera celle de ce jeu à points. Colonnes de points à partir de la ligne 95 fois ce jeu, la taille de l'ennemi à partir de la hauteur de la ligne 97 sera ce jeu de points où les roses multiplieront la taille de l'ennemi. Par exemple, cette méthode de rendu attirera et mettra à jour toute cette vague d'ennemis. Il aura besoin du contexte comme d'habitude, puis nous utiliserons ce contexte. Et pour l'instant, nous allons tracer un rectangle représentant l'ensemble de la zone d'onde. Supportez-moi, cela aura plus de sens dans une minute. Chaque vague contiendra un certain nombre d'ennemis en fonction de la valeur des colonnes Didot Rose et Did Nous commençons par trois fois trois. La première vague comptera neuf ennemis. Chaque fois, nous détruisons tous les ennemis en une seule vague. La prochaine vague sera automatiquement déclenchée. Nous conserverons toutes les vagues actives dans le tableau d'ondes Didot de la classe de jeu principale Dès que nous créons une classe de jeu, la première vague composée de trois fois 39 ennemis sera automatiquement créée et repoussée à l'intérieur de cette matrice de vagues de points. J'ai transmis ce mot clé pour représenter l'objet de jeu principal dans lequel nous nous trouvons actuellement. Elle est attendue ici et convertie en cette propriété de classe de jeu à points. De là, nous avons accès aux colonnes, aux lignes et à la taille de l'ennemi. Maintenant, je peux prendre un réseau d'ondes Didot, nous avons poussé une onde à l'intérieur J'appelle déjà chaque objet Wave à l'intérieur de ce réseau d'ondes. Actuellement, il n'y en a qu'un seul à l'intérieur. Nous l'appellerons méthode de reddition. Nous le transmettons dans son contexte. Nous pouvons voir la vague dessinée ici, de style D à large, il est donc plus facile de la voir en style D à large, ligne avec, par exemple, 35 pixels. taille de la vague s'ajustera pour s'adapter à tous les ennemis qu'elle contient. Si nous avons cinq colonnes et huit rangées d'ennemis, 40 ennemis au total, ils seront disposés à l'intérieur de cette zone. Toute la vague d'ennemis se déplacera comme une seule unité. La vitesse sera celle de l'objet ondulatoire. Pour chaque image d'animation, nous augmentons la position horizontale en fonction vitesse si x est inférieur zéro ou si x est supérieur à la largeur du jeu moins la largeur de la vague. Cela signifie que chaque fois que le rectangle d'onde touche le bord gauche ou droit de la zone de jeu, sa vitesse horizontale est ramenée à sa valeur opposée. Cela fera rebondir la vague à l' infini à gauche et à droite. Cela a fonctionné. Faisons-le trois fois trois. La vitesse verticale sera nulle chaque fois qu'elle touche l'un des bords. Je veux qu'il saute en fonction la taille de l'ennemi, verticalement vers le joueur. J'ai coupé cette ligne et je l'ai collée ici. Et j'augmente également la position verticale y par la vitesse y. Lorsque nous touchons le H de cette manière, vitesse y reste élevée et la vague continue de descendre. Je veux juste qu'il saute en fonction de la taille de l'ennemi dans une image d'animation, puis qu'il revienne à une vitesse nulle. Oui, c'est le schéma de mouvement que je recherchais. Nous avons une vague qui se déplace à gauche, à droite et vers le bas au-dessus de la zone de jeu. Il contiendra une grille d'ennemis. Chaque ennemi se déplacera avec la vague en utilisant les positions x et y de cette vague, ainsi que la position horizontale et verticale relative de chaque ennemi dans cette grille. Dans la vague, j'appellerai ces valeurs cette position x et cette position du point Y. position X et la position Y sont la position de l' ennemi dans la vague Chaque ennemi doit savoir exactement où il se trouve à l'intérieur de la grille. largeur de l'ennemi proviendra de cette valeur de la ligne cent et 11, je l'ai réglée sur 60 pixels. Ce jeu marque la taille de l'ennemi. Pour la largeur et la hauteur également. Les ennemis seront de forme carrée. X et y seront égaux à 00. Au départ, lorsque nous créons un ennemi, nous le transmettons comme argument de position relative entre l'ennemi et l'ensemble de la vague. Les valeurs de position x et de position y détermineront la position de la vague par rapport au coin supérieur gauche du rectangle d'onde. Cet ennemi en particulier se trouve en position x et en position Y au-delà, car les arguments seront convertis en propriétés de classe. Ici, la méthode de mise à jour prendra les positions x et y de la vague comme arguments. Et il définira les positions x et y de l'ennemi par rapport à cette valeur actuelle. L'exposition de l'ennemi est la position de la vague plus la position horizontale relative de l'ennemi dans cette vague. position Y de l'ennemi sera verticale, position Y de la vague plus position verticale relative de cet ennemi dans la vague. Il existe peut-être une meilleure façon de structurer ce code. Je viens de trouver ça. Voyons comment cela fonctionne pour nous. Chaque vague aura son propre réseau d'ennemis. Nous lui donnons une méthode de création personnalisée à l'intérieur, nous aurons une boucle à quatre boucles. Nous voulons organiser quelque chose dans une grille, ce qui signifie que nous aurons besoin deux boucles de quatre boucles imbriquées à l'intérieur d'une autre boucle Écrivons-le d'abord, puis expliquons comment cela fonctionne. Les quatre boucles extérieures géreront les lignes au fur et à mesure que nous descendons ligne par ligne. La coordonnée verticale y augmentera. La boucle interne for gérera colonnes au fur et à mesure que nous allons de gauche à droite. À l'intérieur de chaque ligne, la coordonnée horizontale x augmente. Disons que nous sommes ici. Il s'agit du carré ennemi actuel ligne de 60 x 60 pixels est nulle. Dans la boucle extérieure, nous entrons dans la boucle intérieure et nous parcourons toutes les positions horizontales. Dans cette ligne, nous atteignons la dernière colonne. Nous sortons de la boucle intérieure, nous entrons dans la boucle extérieure, nous augmentons la position verticale Y et nous passons à la rangée suivante. Encore une fois, nous entrons dans la boucle, nous parcourons les positions horizontales à travers les colonnes de gauche à droite. Nous sortons de la boucle intérieure, entrons dans la boucle extérieure, nous augmentons y et passons à la ligne suivante. Nous entrons dans le cycle inter-boucles par toutes les positions horizontales. Là, nous répétons cela encore et encore jusqu'à ce que nous ayons créé la grille complète de la vague entière. Je dois tenir compte de la taille de l'ennemi lorsque crée les propriétés de l' ennemi X et de l'ennemi Y. J'aurais aussi pu par la valeur de la taille de l'ennemi ici et ici. Le résultat sera le même. Chaque fois que nous passons à une nouvelle case de la grille. Nous prenons cette vague d'ennemis et nous introduisons un nouvel objet ennemi à l'intérieur. Nous pouvons voir que le constructeur de la classe ennemie attend le jeu et la position relative en X et Y de cet ennemi dans la grille Je passe ce jeu à partir de la ligne 78. Je passe devant l'ennemi X et l'ennemi Y. D'accord, lorsque nous créons une nouvelle vague, nous examinons le constructeur de classes de jeu pour voir la valeur actuelle des lignes et des colonnes Sur cette base, nous créons une grille d'ennemis. Je veux que la méthode create se déclenche automatiquement lorsque nous créons une nouvelle vague. Je l'appelle ici, cela signifie que dès que nous créons une instance de classe wave, tableau de cet ennemi sera automatiquement rempli d'objets ennemis. Et leurs coordonnées X et Y seront organisées dans une grille à l'intérieur du rendu. Je peux maintenant prendre ce tableau et pour chaque objet ennemi à l'intérieur, j'appelle sa méthode de mise à jour et c'est une méthode de dessin. Je passe le contexte de la méthode draw comme d'habitude. Ici, nous pouvons voir que la méthode de mise à jour prévoit la position X et Y de la vague afin que je puisse l'utiliser pour positionner les ennemis dans une formation semblable à une grille. Chaque fois que j'appelle Enemy Update, je dois lui indiquer les positions X et Y de son objet Wrapper Wave pour m' assurer que tous les ennemis se déplacent sur l'écran Avec elle, nous attirons trois fois trois ennemis. Supprimez ce rectangle qui couvre toute la vague. C'était juste pour nous aider à visualiser ce qui se passait. Nous sommes toujours en train de dessiner les ennemis. Nous avons une vague de trois fois trois ennemis qui se déplacent sur l'écran de manière synchronisée Parfait Je veux que les ennemis arrivent vague par vague. Et j'ai besoin que chaque vague démarre hors de l'écran et flotte dans la zone de jeu. J'ai dit que la coordonnée Y initiale de la vague zéro moins la hauteur de la vague, ce qui signifie qu'elle sera initialement cachée derrière le bord supérieur de la zone de jeu. La vague sera créée hors écran, et je veux qu'elle flotte rapidement vers le bas jusqu'à ce qu' elle soit entièrement visible. Ensuite, il commencera son schéma de mouvement gauche-droite. Si ce Y est inférieur à zéro, augmentez Y de cinq pixels par image d'animation. Il flottera ainsi et commencera à rebondir à gauche et à droite lorsque toutes les rangées et colonnes d'ennemis, la vague entière, seront entièrement visibles dans la zone de jeu Je peux le tester en modifiant le nombre de lignes et de colonnes. Vous pouvez voir que cela fonctionne toujours. Elle continue de flotter jusqu'à ce que tous les ennemis de cette vague soient visibles et puissent être ciblés par les lasers des joueurs J'essaie cinq colonnes et sept rangées, ce qui me donnera une vague de 35 ennemis. 8. Ondes ennemies: Ça se passe vraiment bien. Nous avons le joueur, les projectiles et les ennemis. Je veux que les projectiles et les ennemis interagissent. Lorsqu'un ennemi est touché par un projectile, l'ennemi est détruit, le projectile est renvoyé dans le pool d'objets Chaque objet de notre jeu possède des propriétés x, y, de largeur et de hauteur. Créons une méthode de détection des collisions réutilisable, qui comparera deux objets rectangulaires nous lui transmettons en arguments. Et il retournera vrai ou faux selon que ces deux rectangles entrent en collision ou non Aux fins de la détection à deux reprises des collisions, les rectangles doivent être alignés sur les axes S'ils sont pivotés de quelque manière que ce soit, nous devrons les traiter comme des polygones La détection des collisions devrait être une technique plus complexe, telle que la formule du théorème des axes de séparation Aujourd'hui, tous les rectangles seront alignés sur les axes, sans rotation Nous pouvons donc utiliser la formule de détection de collision la plus simple et la plus directe entre deux axes alignés, c'est-à-dire des rectangles non pivotés vérification personnalisée réutilisable des collisions Nous allons prendre deux arguments, rectangle A et le rectangle B. Il existe de nombreux articles en ligne sur cette technique. Je peux y faire référence. Je vais laisser quelques liens dans la section des ressources ci-dessous. La formule vérifie toujours si le rectangle A se trouve dans les limites du rectangle B horizontalement et verticalement. Pour cela, nous devons effectuer quatre vérifications en comparant les quatre arêtes du rectangle. Si ces quatre vérifications sont vraies, il y a une collision, sinon, même si l'une d'entre elles est fausse, il n'y a pas de collision. Laissez-moi vous montrer comment cela fonctionne. D'ailleurs, cette formule est très bon marché en termes de performances car les calculs sont très simples. Si notre game design le permet, nous devrions essayer de l'utiliser. Bien entendu, certains jeux nécessitent des techniques de détection de collision plus complexes. Cela ne convient pas toujours à notre projet. Aujourd'hui c'est parfait. Nous devons vérifier quatre points. abord, nous vérifions si la position horizontale du rectangle que nous passons en argument a ici est inférieure à la position horizontale du rectangle B plus la largeur du rectangle. Nous sommes en train de vérifier si c' est à gauche de celui-ci. Dans le même temps, double pour cent d'opérateur. Nous devons également vérifier si la position horizontale du rectangle a plus la largeur du rectangle a est supérieure à la position horizontale du rectangle. Nous sommes en train de vérifier si c' est à droite. Si ces deux vérifications sont vraies, nous savons que les rectangles entrent en collision horizontalement, mais qu'ils peuvent toujours être éloignés l'un de l'autre Nous devons effectuer les deux mêmes vérifications, mais cette fois pour l'axe vertical y. Je vérifie si la position verticale du rectangle A est inférieure à la position verticale du rectangle B plus sa hauteur. Si c'est au-dessus de cette dernière vérification, nous vérifierons si la position verticale du rectangle A plus sa hauteur est supérieure à la position verticale du rectangle B. Si elle est inférieure à celle-ci. Ce n'est que si ces quatre vérifications sont vraies qu'il y a collision. Si toutes sont fausses ou si au moins l'une d'entre elles est fausse, nous savons qu'il n'y a pas de collision. Nous savons que les deux rectangles sont éloignés l'un de l'autre, au moins dans une direction Je peux en fait simplifier cela et faire en sorte que cette méthode évalue automatiquement cette expression et renvoie directement vrai ou faux. De cette façon, je peux simplement vérifier que la collision a croisé deux objets rectangulaires, par exemple un projectile et un ennemi et elle renverra directement vrai ou faux Pour moi, il s'agit de notre méthode réutilisable de détection des collisions. N'oubliez pas que tous les objets que nous transmettons sous forme de rectangle A ou de rectangle doivent avoir les propriétés x, y, w et hyde. Pour que ce code fonctionne, je souhaite utiliser une méthode de vérification des collisions personnalisée. Nous détenons maintenant les dix objets à projectiles réutilisables. Ici, objets à projectiles réutilisables. Ici dans le pool de projectiles, les ennemis sont rangés séparément dans le réseau ennemi Pour chaque vague ici, ces ennemis sont créés en utilisant la classe, le plan que nous avons écrit ici à la ligne 57 Il est donc logique de mettre ce contrôle de collision ici. Chaque fois que la méthode de mise à jour de chaque objet ennemi est exécutée, nous comparons x, y à la hauteur de cet ennemi en particulier avec les dix projectiles Nous vérifierons uniquement par rapport au pool de projectiles actifs Pour chacun, pour chaque projectile nous appelons notre méthode de vérification personnalisée des collisions Nous savons qu'il attend un objet rectangulaire a et un objet rectangulaire comme arguments. Nous savons que ces deux objets doivent avoir des propriétés x, y, largeur et hauteur pour que la méthode de collision puisse fonctionner avec eux. Je passe devant cet objet ennemi sous forme de rectangle A et je lui fais passer les dix projectiles un par un alors que nous parcourons le pool de projectiles à vélo Pour chaque méthode, nous avons écrit check collision method pour renvoyer directement vrai ou faux. Je peux donc simplement dire si et l' enrouler entre crochets comme ceci. Si cet ennemi et ce projectile entrent en collision, ce bloc de code s'exécutera Nous éliminons l'ennemi. J'ai dit que la propriété de suppression était marquée comme vraie. Je dois également déclarer cette propriété dans le constructeur de classe ennemie Ici, dans la méthode de rendu sur un objet vague, nous filtrerons les ennemis détruits hors du tableau des ennemis Méthode de filtrage de tableau intégrée La méthode de filtrage créera une copie d'un tableau donné et cette copie filtrée contiendra uniquement les éléments qui ont une certaine condition. Ici, je dis essentiellement de créer une copie de ce tableau d'ennemis à points et d'autoriser uniquement éléments internes dont la propriété de suppression est définie sur false. Remplacez ensuite ce tableau d' ennemis à points d'origine par ce nouveau tableau filtré De cette façon, je supprime tous les ennemis qui sont entrés en collision avec des projectiles parce que la propriété de ces ennemis a été marquée pour suppression sur Je reçois une erreur de console. C'est parce que j'ai mal orthographié «   projectile pull » ici. Oui, on dit que les projectiles tirent avec un S. Lorsqu'une nouvelle vague d'ennemis arrive, vous pouvez voir que l'ennemi en bas à gauche est C'est parce que tous mes projectiles inactifs se trouvent initialement dans ce coin à la coordonnée 00 Nous ne les dessinons pas pour les mettre à jour, mais nous sommes toujours en train de calculer la collision entre ces projectiles inactifs et les ennemis Je corrige le problème en vérifiant uniquement collision si l'absence de projectile est fausse Si le projectile est actuellement actif, nous voulons ignorer les projectiles inactifs lorsqu'il s'agit de détecter les collisions Je souhaite également réinitialiser ce projectile et le renvoyer Il entre en collision avec un ennemi, de sorte que chaque projectile ne peut détruire qu'un seul Nous avons ici une méthode de réinitialisation qui définira la propriété libre sur true , renvoyant le projectile dans le pool d'objets disponibles non utilisés En cas de collision entre un ennemi et un projectile, j'appelle la méthode de réinitialisation de ce projectile pour le désactiver Oui, c'est le gameplay que je recherchais. En cas de collision entre un ennemi et un projectile, l'ennemi est supprimé et l'objet projectile est renvoyé dans le pool d'objets 9. Détection de collision: Je veux dessiner des textes de statut, tels que les points de vie des joueurs qui comptent les vagues de points ou la quantité d'énergie dont nous disposons actuellement pour les lasers et les attaques spéciales. Je vais faire tout cela dans la méthode de dessin du texte d'état, que j'appelle la méthode de remplissage de texte intégrée qui prend au moins trois arguments, le texte que nous voulons dessiner et les coordonnées x et y du point d'ancrage par rapport auquel le texte sera positionné. Je l'appelle ici dans Render, et je veux le dessiner derrière les ennemis. Je le dessine donc d'abord. C'est juste mon choix. Vous pouvez le dessiner par dessus si vous le souhaitez. J'ai transmis le contexte, et c'est parti. J'ai réglé la police sur, par exemple, impact de 30 pixels pour des lettres belles, grandes et faciles à lire. Nous conserverons le score actuel sous forme de variable sur l'objet principal du jeu. Il partira de zéro. Dans le texte du champ, j'ajouterai cette valeur de variable dynamique à côté du texte comme ceci. Maintenant, je veux que le score augmente d' un lorsque nous détruisons un ennemi ici. Lorsque le projectile et l'ennemi entrent en collision, nous prenons ce score de jeu et nous l' augmentons d'un point. Comme ça. Super, je tire sur des ennemis et j'augmente mon score. Parfait. La partie sera perdue si un ennemi touche le bas de l'écran. Pour chaque ennemi, je vais vérifier si sa position verticale en Y est associée à sa hauteur. La limite inférieure du rectangle ennemi est supérieure à cette hauteur de point de jeu, la limite inférieure de la zone de jeu visible. Si cela se produit, je redonne à ce jeu la valeur true et je détruis cet ennemi en définissant sa propriété marquée pour suppression sur true. Pour l'instant, je dois m' assurer de déclarer cette propriété game over ici. Dans un premier temps, ce sera faux. Si game over est vrai, je voudrais dessiner du texte. Comme vous pouvez le constater, le texte du canevas est aligné à gauche par défaut. Je veux que ce message de fin de partie soit centré. La police sera de 100 pixels. Le texte d'impact indiquera la fin de la partie en majuscules. Et ce sera exactement au milieu de l'écran. Largeur du jeu fois 0,5 et hauteur du jeu fois 0,5 Super, nous avons un gros texte sur le jeu au milieu de l'écran. Dès que l'ennemi touche le bas de la zone de jeu. Le problème est que cette ligne de texte et les propriétés de police modifient l'état complet du canevas. Désormais, le même style de texte s'applique au texte de remplissage de partition de la ligne 194. Je vais regrouper l' ensemble de ce bloc de code entre les méthodes de sauvegarde et de restauration intégrées au canevas. La méthode sécurisée enregistre l'état du canevas, y compris le style de remplissage, le texte, la police de ligne et toutes les autres propriétés du canevas. Cela crée un point sûr, comme dans un jeu vidéo. Il mémorise les valeurs de toutes les propriétés du canevas. À ce stade, nous pouvons modifier les paramètres du canevas comme nous le souhaitons. Ensuite, lorsque j'appelle restore, toutes les propriétés du canevas seront ramenées à ce qu'elles étaient lorsque la méthode sécurisée a été appelée. Qu'est-ce qui se passe ? Maintenant, nous enregistrons l'état du canevas, nous dessinons le score à 30 pixels et nous l'alignons à gauche, nous définissons le texte aligné au centre de 200 pixels, nous dessinons le jeu terminé et nous réinitialisons ces paramètres. Dans la boucle d'animation suivante, lorsque la partition est redessinée, elle revient à 30 pixels d'alignement à gauche C'est une boucle d'animation sans fin que nous avons ici. J'espère que cela a du sens, que nous pouvons aller encore plus loin Comme nous avons encapsulé tout le texte d'état entre safe et restore, nous l'avons séparé du reste des formes dessinées sur le canevas. Je peux également lui donner qu