Je vais vous présenter la création d'un jeu de tir / plateforme inspiré par Megaman. Nous nous concentrerons davantage sur les aspects de tir du gameplay que sur la plate-forme. Dans ce tutoriel, je vais utiliser Construct 2 comme outil pour créer le jeu, mais je vais expliquer la logique en utilisant le pseudocode afin que vous puissiez suivre ce tutoriel dans la langue ou le moteur de votre choix..
Articles SimilairesAfin de me concentrer sur l'implémentation du gameplay, je n'expliquerai pas chaque fonctionnalité de Construct 2; Je suppose que vous connaissez les bases telles que le chargement d'un sprite, une collision de base ou la lecture de sons. Cela dit, commençons à faire le jeu.
Tout d’abord, nous devons avoir des sprites pour notre jeu. Heureusement, opengameart nous a couverts de leur merveilleuse collection d'art de jeu juridique. Nous avons besoin de quatre ensembles de sprites; un héros, un ennemi et des tuiles pour plates-formes.
Pour les utiliser dans Construct 2, je recadre les sprites du héros dans des images individuelles à l'aide de GIMP..
J'utiliserai le comportement de la plate-forme de Construct 2 pour le reste du didacticiel afin de pouvoir me concentrer sur la partie prise de vue et l'intelligence artificielle du jeu, qui était l'objectif principal de ce didacticiel..
Si vous travaillez dans une autre langue ou souhaitez implémenter votre propre mouvement de plateforme de base au lieu d'utiliser le comportement intégré. Vous ne devez utiliser le code de cette section que si vous n'utilisez pas le comportement intégré de Construct 2.
Pour commencer, nous devons considérer trois façons dont notre héros peut se déplacer. marcher à droite, marcher à gauche ou sauter. Chaque image, nous mettons à jour la simulation du jeu.
nombre moveSpeed = 50; fonction update () moveHero ();
Pour mettre à jour le personnage du joueur, nous implémentons un mouvement de base comme ceci:
function moveHero () // le joueur appuie sur cette touche vers le bas si (keyDown (KEY_LEFT)) hero.x - = moveSpeed * deltaTime; hero.animate ("walkLeft"); if (keyDown (KEY_RIGHT)) hero.x + = moveSpeed * deltaTime; hero.animate ("walkRight"); if (keyDown (KEY_UP)) hero.jump (); hero.animate ("jump"); // une clé qui n'était pas pressée si (keyReleased (KEY_LEFT)) hero.animate ("standLeft"); if (keyReleased (KEY_RIGHT)) hero.animate ("standRight");
J'utilise une autre fonction pour sauter car le saut ne consiste pas seulement à modifier la valeur y, mais également à calculer la gravité. Nous aurons également une fonction qui écoute si une clé vient juste d'être relâchée, pour que l'animation de notre héros redevienne une animation permanente..
Parlons de la manière de faire sauter le joueur. Le héros devra savoir s'il saute actuellement ou non, et s'il est en train de tomber ou non. Nous allons donc déclarer deux nouvelles variables: isJumping et isFalling. Par défaut, les deux sont faux, ce qui signifie que le héros se tient sur une plate-forme..
Pour effectuer un saut, nous devons d’abord vérifier si les deux valeurs sont fausses ou non, puis faire en sorte que isJump soit vrai.
Fonction jump () if (! IsJumping &&! IsFalling) isJumping = True
Pour que le héros puisse sauter, nous avons besoin d’une variable appelée jumpPower et gravity. La valeur par défaut de jumpPower est -20 et la gravité est de 1. La logique est d'ajouter la valeur de la puissance de saut à la position Y du héros et d'ajouter la gravité à la valeur de la puissance de saut.
Nous faisons cela à chaque tick. Peut-être que la physique de la gravité n’est pas la plus réaliste qui soit, mais les jeux n’ont pas besoin d’être réalistes, ils doivent simplement être crédibles, c’est pourquoi certains jeux proposent des sauts super humains et des sauts doubles. Le code ci-dessous appartient à la fonction de mise à jour.
Si (isJumping || isFalling) hero.y + = hero.jumpPower; hero.jumpPower + = hero.gravity; // la puissance de saut sera éventuellement supérieure à zéro, ce qui signifie que le héros est en train de tomber si (hero.jumpPower> = 0) isJumping = False; isFalling = True; // pour arrêter la chute, faites quelque chose lorsque le héros chevauche la plateforme si (hero.isOverlapping (platform1)) // plateforme1 est la plateforme sur laquelle notre héros peut marcher // réinitialise la variable à sa valeur par défaut isJumping = False; isFalling = False; hero.jumpPower = -20; // et puis il y a la chute libre, quand le joueur tombe par-dessus le bord d'une plate-forme si (! hero.isOverlapping (platform1) && hero.jumpPower < 0 && !isJumping) // !hero.isOverlapping(platform1) checks whether or not our hero is standing on a platform // and if jumpPower is less than zero and the player is not currently jumping, then that means // he's falling // setting these two values like this will make the player fall. hero.jumpPower = 0; isFalling = true;
Le comportement de plate-forme intégré de Construct 2 reproduit l'exemple de code ci-dessus, auquel seules les personnes travaillant dans une autre langue ont accès..
Vient maintenant la partie tir du jeu. Dans la série Megaman, il existe trois types de tirs: les tirs normaux, les tirs chargés et les tirs énergiques de boss.
Les coups normaux vont de soi. Les coups chargés sont des coups qui sont chargés en premier avant d'être libérés. Ces coups chargés sont de deux types: à moitié chargés et complètement chargés. Ces attaques chargées sont plus fortes que les tirs normaux, avec le complètement chargé devenir le plus fort.
Les tirs d'énergie de boss sont des coups de puissance acquis par le joueur après avoir vaincu chaque boss. Les dégâts sont les mêmes que la normale mais ils ont des propriétés spéciales que les tirs normaux n'ont pas.
Maintenant que nous connaissons le type de chaque plan, commençons par les réaliser. Voyons d'abord la logique derrière la façon dont nous utilisons chaque tir. Ici, nous supposons que le bouton Z du clavier est utilisé pour tirer un coup de feu. Nous allons implémenter deux comportements différents:
Maintenant, commençons à coder. Parce que notre héros peut tirer à gauche et à droite, nous devons savoir dans quelle direction il se trouve actuellement. Déclarons une nouvelle variable appelée face qui stocke une valeur de chaîne indiquant si le héros fait face à gauche ou à droite.
Face à la chaîne = "right"; // dans quelle direction le héros se trouve actuellement dans la fonction moveHero () // le joueur appuie sur cette touche vers le bas si (keyDown (KEY_LEFT)) hero.x - = moveSpeed * deltaTime; hero.animate ("walkLeft"); en face = "à gauche"; if (keyDown (KEY_RIGHT)) hero.x + = moveSpeed * deltaTime; hero.animate ("walkRight"); face = "à droite"; //… la suite de la fonction moveHero () va ici function update () //… le code de mise à jour que nous avons précédemment écrit va ici… // le joueur appuie une fois sur cette touche si (keyPressed (KEY_Z)) if == "droit") hero.animate ("Shoot"); // nous ajouterons la fonction de prise de vue ici plus tard else if (en face de == "à gauche") hero.animate ("Shoot"); hero.mirrorSprite (); // cette fonction retourne le sprite horizontalement if (keyReleased (KEY_Z)) if (en face de == "right") hero.animate ("standRight"); else if (face == "left") hero.animate ("standLeft"); hero.mirrorSprite (); // nous devons appeler à nouveau parce que l'image-objet a été mise en miroir // si nous ne reflétons pas l'image-objet à nouveau, standLeft ressemblera à standRight
Avant de tirer une balle, nous devons examiner les propriétés de la balle:
Ces propriétés seront différentes pour chaque puce. En particulier, la propriété power sera différente. La propriété angle n'est normalement qu'une des deux valeurs; si la balle est tirée à droite ou à gauche, à moins qu'il s'agisse d'une balle d'énergie du chef pouvant tirer à un angle unique.
Les variations de prise de vue seront discutées plus tard, je ne traiterai donc que des prises de vue de base. Ce qui suit est le morceau de code qui tire une balle.
// commence par créer une fonction créant une nouvelle puce Fonction shoot (chaîne pathToSprite, numéro bulletPower, nombre bulletSpeed, nombre bulletAngle) myBullet = new Bullet (pathToSprite); myBullet.power = bulletPower; // la classe ou l'objet bullet a deux variables privées qui le déplacent en fonction de son angle // plus d'explications sur ces deux lignes nécessitent plus de maths, j'ai donc choisi de ne pas l'expliquer // je suppose que votre moteur de choix a le moyen de déplacer un objet en fonction de son angle ySpeed = Math.sin (bulletAngle) * bulletSpeed; xSpeed = Math.cos (bulletAngle) * bulletSpeed; // c'est la fonction de la classe Bullet qui s'appelle chaque image, cela déplace la puce en fonction de sa fonction d'angle moveBullet () x + = xSpeed * deltaTime; y + = ySpeed * deltaTime; // et voici la modification de notre précédente fonction update () function function update () //… le code de mise à jour que nous avons précédemment écrit va ici… // le joueur appuie une fois sur cette touche if (keyPressed (KEY_Z)) if ( face à == "à droite") hero.animate ("Shoot"); hero.shoot ("path / to / sprite.png", 10, 400, 0); else if (en face == "à gauche") hero.animate ("Shoot"); hero.mirrorSprite (); // cette fonction retourne le sprite horizontalement hero.shoot ("path / to / sprite.png", 10, 400, 180); // l'angle est égal à 180 pour que la puce aille à gauche //… la suite du code de mise à jour va ici…
Certaines balles peuvent être plus puissantes que d’autres. Pour créer un coup chargé, nous avons besoin d'une variable appelée facturée, qui incrémentera chaque seconde où le joueur maintient Z enfoncé et reviendra à zéro lorsque la balle sera tirée. Les modifications apportées au code de mise à jour sont les suivantes:
// le joueur vient de relâcher la touche z si (keyReleased (KEY_Z)) if (chargéTime> 0 && chargéTime <= 5) if (facing == "right") hero.animate("Shoot"); hero.shoot("path/to/halfChargedBullet.png", 20, 400, 0); chargedTime = 0; else if (facing == "left") hero.animate("Shoot"); hero.mirrorSprite(); // this function flips the sprite horizontally hero.shoot("path/to/halfChargedBullet.png", 20, 400, 180); chargedTime = 0; else if (chargedTime > 5) if (= = "" right ") hero.animate (" Shoot "); hero.shoot ("path / to / fullChargedBullet.png", 40, 400, 0); chargéTime = 0; else if (en face == "à gauche") hero.animate ("Shoot"); hero.mirrorSprite (); // cette fonction retourne le sprite horizontalement hero.shoot ("path / to / fullChargedBullet.png", 40, 400, 180); chargéTime = 0; if (== "right") hero.animate ("standRight"); else if (face == "left") hero.animate ("standLeft"); hero.mirrorSprite (); // nous devons rappeler ceci car le sprite a été mis en miroir // si nous ne reproduisons pas le sprite à nouveau, standLeft ressemblera à standRight // le joueur appuie sur cette touche si (keyDown (KEY_Z)) // c'est la fonction qui ajoute la valeur chargéeTime toutes les secondes // ce bloc de code keyDown sera exécuté à chaque image, ce qui est inférieur à une seconde // votre moteur de choix devrait avoir un moyen de savoir si une seconde s'est écoulée ou non. addChargedTime ();
Notre personnage héros se déplace de nouveau à gauche, à droite et saute en fonction de nos informations. Il tire également des balles, qu'elles soient normales, à moitié chargées ou complètement chargées..
Nous avons maintenant un héros contrôlable. Appelons cela Xeon pour des raisons de simplicité. Il peut effectuer certains mouvements de base comme la marche, le saut et le tir. C'est génial! Mais à quoi sert-il de pouvoir tirer sans quelque chose à tirer, non? Voilà pourquoi cette fois nous allons faire notre premier ennemi.
Concevons les attributs de notre ennemi avant de commencer à le coder.
Santé: Le nombre de soins dont notre ennemi dispose détermine le nombre de tirs (et de quel type) nécessaires pour le détruire..
Puissance: puissance d'attaque de l'ennemi, combien de dégâts cela inflige-t-il à notre joueur.
ShotAngle: dans quelle direction l'ennemi tire la balle, elle peut être à gauche ou à droite ou n'importe où.
C'est à peu près ce dont nous avons besoin pour notre ennemi, faisons en sorte que la classe / objet de l'ennemi.
La classe / objet Enemy est à peu près la même chose que la classe / objet du joueur, sauf que l'ennemi n'écoute pas les informations du joueur. Pour cette raison, nous devons remplacer les parties où le héros écoute les entrées des joueurs, l’intelligence artificielle ennemie / la logique..
Pour commencer, prenons l'IA de base de l'ennemi en matière de tir. L'ennemi va tirer sur le joueur quand il voit le joueur.
Pour déterminer si l'ennemi "voit" le joueur, nous devrons définir une variable pour l'objet ennemi appelé en face qui est une chaîne qui stocke l'une des deux valeurs, "gauche" ou "droite"..
L'ennemi a également besoin d'une sorte de portée visuelle, c'est pourquoi nous allons créer une autre variable appelée portée. Si le joueur se trouve dans cette plage, cela signifie que l'ennemi "voit" le joueur. Le pseudocode est le suivant:
function boolean checkSees () if (en face de == "gauche" && hero.x> = ennemi.x - plage) retour vrai; if (en face de == "right" && hero.x <= enemy.x + range) return true; return false;
Fonction checkSees ()
Peut-être avez-vous remarqué quelque chose dans ce pseudo-code: il ne tient pas compte de la position y du héros, de sorte que l'ennemi tirera toujours sur le héros même s'il se trouve sur des plates-formes de hauteurs différentes.
Pour l'instant, cela suffira, car la création d'un algorithme de ligne de mire sort du cadre de ce tutoriel. Dans votre propre jeu, vous voudrez peut-être ajouter une tolérance Y à la fonction ci-dessus, qui vérifiera si la position du héros est entre deux points qui définissent les hauteurs de l'ennemi..
Le pseudocode pour le tir ennemi est le suivant:
// peut être dans update () ou ailleurs, chaque fonction du cadre étant exécutée update () if (checkSees ()) shoot ("path / to / bulletSprite.png", ennemiPower, 400, shotAngle);
Comme vous pouvez le constater, la fonction de tir ennemi () est similaire à celle du joueur. Il prend comme paramètres le trajet de l’image-objet, sa puissance d’attaque, sa vitesse de balle et son angle de tir..
Quand l'ennemi passe-t-il de la gauche vers la droite? Pour notre héros, nous utilisons les informations des joueurs pour changer la direction de notre héros. Pour notre ennemi, nous avons deux options: utiliser une sorte de minuterie pour changer de direction toutes les quelques secondes tout en gardant l’ennemi immobile, ou demander à l’ennemi de se déplacer à un certain endroit, puis de changer de direction et de marcher vers un autre point. pour changer sa direction de face.
Cette seconde méthode peut être utilisée comme une IA en patrouille. Bien sûr, nous pouvons simplement faire marcher l’ennemi dans une direction et ne jamais revenir en arrière..
Le pseudocode de la première méthode est le suivant:
function switchingAI () // elapsedTime () est une fonction qui compte le nombre de secondes écoulées depuis la réinitialisation de sa valeur. // Je suppose que votre moteur de choix possède ce type de fonctionnalité si (elapsedTime ()> 4.0) if == "gauche") en face = "droite"; shotAngle = 0; if (en face == "droite") en face = "gauche"; shotAngle = 180; ennemi.mirrorSprite (); // retourne également le sprite horizontalement resetTime (); // réinitialise le temps qui compte dans elapsedTime ()
Pour rendre l'IA en patrouille, nous devons créer deux objets invisibles qui se trouvent au bout des deux voies de la route de patrouille de l'ennemi, et faire en sorte que l'ennemi se déplace d'une autre manière s'il entre en collision avec eux..
Écrivons maintenant notre pseudocode pour l'IA de patrouille de l'ennemi:
fonction patrollingAI () if (en face de == "droite") walkRight (); // identique à celui de player player / class if (collidesWith (rightPatrolBorder)) faces = "left"; ennemi.mirrorSprite (); if (en face == "gauche") walkLeft (); if (collidesWith (leftPatrolBorder)) face = "right"; ennemi.mirrorSprite ();
Après cela, l’ennemi patrouille entre deux points comme nous le souhaitons..
Pour définir l'IA utilisée par l'ennemi, nous allons ajouter une autre variable avec un type de chaîne pour notre ennemi: l'IA ennemie. Cela déterminera quelle IA utiliser chaque image, comme ceci:
if (ennemiAI == "commutation") commutationAI (); else if (ennemiAI == "patrouillant") patrollingAI ();
Bien sûr, vous pouvez ajouter plus de type d'IA ennemi si vous voulez.
Continuons sur la manière dont nous pouvons faire des variations de tir pour le joueur et pour l'ennemi. Nous faisons des variations de tir en changeant deux choses: l'angle de tir et le nombre de balles.
De cette façon, nous pouvons faire un simple coup d'une balle, ou un coup de balle dans trois directions. Avant de faire cela, nous allons créer une autre variable pour l'objet / la classe ennemie appelée shotAI, qui est une chaîne. Nous l'utiliserons dans notre checkSees () pour vérifier si nous bloquons, là où l'ennemi tire. Les modifications apportées à ce bloc de code seront les suivantes:
// peut être dans update () ou ailleurs, toutes les fonctions du cadre sont exécutées update () if (checkSees ()) if (shotAI == "simple") shoot ("path / to / bulletSprite.png", ennemisPower , 400, shotAngle); if (shotAI == "threeBullets") shootThreeBullets ();
Bien sûr, le nom de l'IA et le type de tir que l'ennemi tirerait sont à vous, ce n'est qu'un exemple..
Maintenant, approfondissons ce qui se trouve à l'intérieur de la fonction shootThreeBullets ().
Fonction shootThreeBullets () if (face == "droite") shoot ("chemin / vers / bulletSprite.png", ennemisPower, 400, 0); // cette balle va droit au tir droit ("path / to / bulletSprite.png", ennemisPower, 400, 330); // cela monte de 30 degrés ("path / to / bulletSprite.png", ennemisPower, 400, 30); // cela descend de 30 degrés if (face == "left") shoot ("path / to / bulletSprite.png", ennemisPower, 400, 180); // cette balle va tout droit au tir gauche ("path / to / bulletSprite.png", ennemisPower, 400, 210); // cela monte de 30 degrés ("path / to / bulletSprite.png", ennemisPower, 400, 150); // cela diminue de 30 degrés
Si vous ne savez pas pourquoi 0 va à droite et 180 à gauche, c'est parce que la direction de 0 degrés va tout droit vers le côté droit de l'écran, que 90 degrés vont vers le bas de l'écran, et ainsi de suite jusqu'à ce que vous atteigniez 360 degrés. Une fois que vous savez quelle valeur va où, vous pouvez créer votre propre variation de tir.
Nous pouvons également créer une variable shotAI pour le joueur, mais je préfère que nous l'appelions selectedShot, car notre joueur choisira la balle au lieu de la programmer depuis le début. T
La logique de mégaman est que chaque mégaman défait un patron, il obtient le pouvoir de ce patron comme un nouveau coup. Je vais essayer de recréer cette logique. Pour ce faire, nous avons besoin d’un tableau contenant les coups du joueur, y compris les coups normaux. Le pseudocode est comme ça:
var shotArr = ["normalShot", "boss1", "boss2"]; var shotIndex = 0; var selectedShot = "normalShot"; function update () // Il s'agit du bloc de code de la fonction de mise à jour du lecteur dans lequel le joueur tire une balle // Cette fonction modifie la puce pour laquelle le joueur tire changeBullet (); // joueur appuie une fois sur cette touche if (keyPressed (KEY_Z)) if (face == "right") hero.animate ("Shoot"); if (selectedShot == "normalShot") hero.shoot ("path / to / sprite.png", 10, 400, 0); else if (selectedShot == "boss1") // ajoute des codes pour tirer le type de tir que le joueur a reçu après avoir vaincu le boss 1 function changeBullet () // modifie shotIndex en fonction du bouton enfoncé si (touche enfoncée (KEY_E)) shotIndex + = 1; if (keyPressed (KEY_Q)) shotIndex - = 1; // corrige shotIndex s'il dépasse la longueur du tableau if (shotIndex == shotArr.length) shotIndex = 0; if (shotIndex < 0) shotIndex = shotArr.length -- 1; selectedShot = shotArr[shotIndex];
Nous devons suivre deux nouvelles variables:
Nous allons pousser de nouveaux éléments à shotArr lorsque le joueur bat un boss.
Tout comme le shootThreeBullet () de l'ennemi, vous pouvez être créatif et créer vos propres variations de tir. Puisque c'est la balle du héros, donnons-lui quelque chose de spécial.
Faisons en sorte qu'un type de tir soit efficace contre un boss spécifique, afin qu'il inflige plus de dégâts. Pour ce faire, nous allons créer une variable pour l'objet puce appelé strongAgainst, qui est une autre variable de type chaîne contenant le nom du responsable contre lequel cette puce est efficace. Nous allons ajouter cette fonctionnalité qui inflige plus de dégâts lorsque nous discutons de la partie boss du jeu..
C’est là que toutes les variations de tir que nous faisons ont vraiment commencé à compter. C’est là que notre héros endommage et tue l’ennemi, et l’inverse.
Pour commencer, créons une variable pour le héros et l'objet ennemi, nommée santé, qui est un int, et une autre variable pour le héros, nommée vies. Jetons un coup d'oeil au pseudocode:
if (bullet.collidesWith (hero)) hero.health - = bullet.power; createExplosion (); // pour l'instant, nous n'avons pas d'image-objet d'explosion, donc ceci servira de rappel // vérifie si le héros est mort si (hero.health <= 0) hero.lives -= 1; // decreases hero's total number of lives. destroyHero();
Nous ferons le même pseudo-code pour nuire aux ennemis, comme ceci:
si (bullet.collidesWith (ennemi)) ennemi.health - = bullet.power; createExplosion (); si (ennemi.health <= 0) destroyEnemy();
Maintenant, si je m'en tenais là, ce ne serait pas intéressant. Je vais donc faire un sprite rectangle dans le coin supérieur gauche de l'écran qui sert de barre de santé de notre héros.
La longueur de cette barre de santé va changer en fonction de la santé actuelle de notre héros. La formule pour changer la longueur de la barre de santé est la suivante:
// cela se trouve dans la fonction de mise à jour healthBar.width = (hero.health / hero.maxHealth) * 100;
Nous avons besoin d'une autre variable pour notre héros appelée maxHealth; la valeur de santé de notre héros. Pour le moment, cette valeur ne peut pas être modifiée, mais nous pourrions peut-être créer un élément augmentant la quantité de maxHealth du héros..
Maintenant que nous avons créé nos variations de héros, d’ennemis et de tir, nous devons créer plusieurs niveaux et patrons..
Avoir plusieurs niveaux signifie qu’à un moment du jeu, le joueur va atteindre un ou plusieurs points de contrôle qui bascule le jeu du niveau 1-1 au niveau 1-2 au niveau 1-3 et ainsi de suite jusqu’à atteindre le boss..
Lorsque le joueur meurt quelque part au niveau 1-2, il n'a pas besoin de rejouer depuis le début du niveau 1-1. Comment je fais ça? Premièrement, nous allons faire le niveau, je ne vais pas expliquer beaucoup sur la conception de niveau, mais voici l'exemple de niveau dans Construct 2.
L'image dans le coin supérieur gauche est la couche HUD. Il fera défiler, en suivant le héros lorsque le jeu est joué.
Un sprite auquel vous devriez faire attention est le sprite vert dans la partie supérieure droite du niveau. C'est le point de contrôle de ce niveau lorsque le héros entre en collision, nous allons transférer le jeu au niveau 1-2..
Pour gérer plusieurs niveaux, nous avons besoin de trois variables: currentLevel, levelName et nextLevel..
La variable currentLevel est créée dans l'objet / la classe héros. Le levelName est créé dans l'objet de scène de jeu (niveau) pour chaque niveau. La variable nextLevel est créée dans l'objet sprite vert..
La logique est la suivante: lorsque le héros entre en collision avec le sprite vert (je l'appelle greenDoor), nous allons changer notre niveau en scène de jeu dans laquelle levelName est identique à la variable nextLevel. Une fois le niveau modifié, la valeur de la variable currentLevel de hero sera identique à la valeur levelName de la scène du jeu. Voici le pseudocode:
// cela fait partie de la fonction de mise à jour du jeu if (hero.collidesWith (greenDoor)) changeLevelTo (greenDoor.nextLevel);
Voici le pseudocode à utiliser lorsque le prochain niveau est chargé et prêt à être joué.
// c'est la fonction qui est déclenchée quand le nouveau niveau est chargé function onStart () hero.currentLevel = scene.LevelName; hero.x = startPos.x; hero.y = startPos.y;
Maintenant que nous avons changé de niveau, je vais expliquer le sprite orange derrière notre héros dans l'image ci-dessus. Ce sprite orange est un objet que j'appelle startPos. Il est utilisé pour marquer la position de départ de chaque niveau.
Nous nous référons à cet objet lorsque le héros vient de changer de niveau ou meurt, afin que nous sachions où le reproduire.
Voici le pseudocode pour le traitement lorsque le héros meurt:
// la fonction qui est déclenchée lorsque le héros est détruit Function onDestroyed () // ravive le héros si le héros a encore des vies. Si (hero.lives> 0) var newHero = new Hero (); newHero.x = startPos.x; newHero.y = startPos.y;
Maintenant, nous pouvons avoir plusieurs niveaux et nous pouvons également réapparaître le héros après sa mort.
Vous pouvez créer autant de niveaux que vous le souhaitez, ou peut-être même créer deux objets greenDoor dans un niveau dont l'un retourne au niveau 1-1 si le joueur résout un puzzle de manière incorrecte..
Il est enfin temps de mettre en œuvre le patron lui-même. Faire un niveau de boss est aussi simple que de créer un autre niveau qui engendrera un boss au lieu d’ennemis normaux.
La partie difficile est de créer une IA pour le patron, car chaque patron aura une IA unique. Donc, pour que ce soit facile à comprendre et à dupliquer pour beaucoup de patrons, je vais faire en sorte que l'IA des patrons soit dépendante du temps après leur apparition. Ce qui signifie qu'ils vont faire A pendant x secondes, puis passer à B pendant y secondes, puis à C pendant z secondes avant de revenir à A. Le pseudocode ressemblera à ceci:
// ce code est dans la fonction de mise à jour du boss, il est donc exécuté à chaque image if (elapsedTime ()> 2.0) // this si block est exécuté pendant 3 secondes, car la différence de temps entre celle-ci et celle ci-dessous est de trois secondes. BossShot1 (); // tourné la variante à exécuter cette fois else if (elapsedTime ()> 5.0) bossShot2 (); else if (elapsedTime ()> 6.0) bossShot3 (); if (elapsedTime ()> 7.0) // réinitialiser le temps afin que le boss exécute à nouveau la première action resetsTime ();
La définition de la fonction Boss Shot est ci-dessous. N'hésitez pas à le changer pour l'adapter à ce que vous voulez pour un combat contre un boss:
function bossShot1 () // un simple tir droit bossEnemy.shoot ("pa