Faire un match-3 dans Construct 2 Éliminer les correspondances prédéfinies

Dans le tutoriel précédent, nous avons finalement fait bouger notre jeu et ajouté du mouvement à nos blocs. En plus de cela, nous avons créé un système de difficulté rudimentaire pour rendre le jeu plus difficile à mesure que le joueur joue plus longtemps..

Avec ces deux fonctionnalités dans le jeu, nous sommes prêts à mettre en œuvre le système qui éliminera les correspondances prédéfinies du tableau. Bien que ce ne soit pas le dernier article de la série, il s’agit du dernier système majeur que nous devons mettre en œuvre - alors soyez à l’aise, car nous avons du travail à faire.


Démo finale du jeu

Voici une démonstration du jeu sur lequel nous travaillons tout au long de cette série:




Réparations rapides

Avant de commencer avec la partie principale de ce didacticiel, je souhaite prendre quelques instants pour résoudre deux problèmes que j'ai découverts en écrivant le didacticiel précédent..

Correspondant à

Le premier problème auquel je fais allusion se situe dans le scénario que vous pouvez voir ci-dessous:

Dans cette situation, si vous faites glisser Bloc B sur le point vert, il devrait tomber à cause des espaces vides sous le point, et finalement atterrir à l'endroit marqué C. Dans la plupart des scénarios, cela se produira et le jeu fonctionnera normalement, mais dans certains scénarios, le jeu détectera plutôt une correspondance dans le bref moment où Bloc B est à côté du groupe UNE et il finira par détruire les trois blocs.

Ce problème n'est pas exclusif au scénario ci-dessus et peut également se présenter lorsque vous faites la même chose dans le scénario que j'ai souligné ci-dessous..

Si nous ne résolvons pas cela, le joueur recevra un crédit et des points pour un nombre de matchs qu'il n'a jamais voulu faire et pourrait également ne pas comprendre pourquoi tant de blocs disparaissent de manière inattendue..

Heureusement, il s'agit d'un problème simple à résoudre. Pour résoudre ce problème, nous allons créer un nouveau Variable globale appelé MatchsPossible qui dictera si des correspondances peuvent être faites, et un nouvel événement qui détectera quand un bloc est "en train de" tomber et qui modifiera MatchsPossible faire en sorte qu'aucune correspondance ne puisse être faite tant que cela se produit.

Nous allons d'abord créer la variable globale:

Variable globale: MatchesPossible Type = Nombre Valeur initiale = 1

Votre nouvelle variable devrait ressembler à ceci:

Nous allons maintenant créer l’événement à écouter lorsqu'un bloc tombe:

Evénement: Condition: Inverser: Bloc> chevauche le décalage. Objet = Bloc Décalage X = 0 Décalage Y = 8 Condition: Bloc> Comparaison Y Comparaison = Coordonnée Y inférieure ou égale = SPAWNY Action: Système> Valeur définie Variable = CorrespondancePossible Valeur = 1

Cet événement fait en sorte que lorsqu'un bloc se trouve avoir un espace vide en dessous MatchsPossible est réglé sur 1, les correspondances de sens ne sont pas possibles. Vous remarquerez également qu'il vérifie la position Y du bloc. Cela permet de s'assurer que le bloc ne se trouve pas sur la rangée de blocs la plus basse, qui aura toujours un espace vide en dessous..

Ensuite, nous avons besoin d’un événement qui définisse MKatchesPossible retour à 0 quand aucun bloc n'a d'espace vide en dessous d'eux. Ce deuxième événement sera basé sur une condition Else:

Evénement: Condition: Système> Autre Action: Système> Valeur définie Variable = MatchesPossible Value = 0

Assurez-vous que cet événement suit immédiatement le premier événement afin que l'instruction Else soit utilisée correctement.

Vos deux nouveaux événements devraient ressembler à ceci:

Enfin, nous allons ajouter une nouvelle condition à CheckMatches pour qu'il regarde MatchsPossible pour déterminer si une correspondance peut être faite. Ajoutez cette condition à l'appel de fonction initial du CheckMatches un événement.

Condition: Système> Variable de comparaison Variable = MatchesPossible Comparaison = Égal à Vale = 0

Avec la condition ajoutée, votre CheckMatches L'événement devrait maintenant ressembler à ceci:

Contrairement à la plupart des problèmes que nous avons rencontrés jusqu'à présent, ce problème apparaît de manière relativement incohérente. Cela signifie que nous ne pouvons pas vraiment tester pour voir si nous avons résolu le problème, mais uniquement pour voir si nous avons causé d'autres problèmes. Si vous jouez au jeu maintenant, vous devriez voir qu’aucun nouveau problème n’a été causé par cette condition..

Points

Le deuxième problème que je voulais résoudre avant d'ajouter quoi que ce soit concerne le système de points.

Pendant que je travaillais sur le projet de ce tutoriel, j’ai remarqué que quelque chose que j’avais fait avait pour effet que le système de points se comportait de manière étrange et donnait au joueur quatre ou cinq fois plus de points qu’il devrait obtenir pour chaque match. Bien que je n’ai pas été en mesure de déterminer le changement que j’ai apporté qui a provoqué l’apparition de cette situation, j’ai trouvé que le problème était Give Points fonction a été appelée plusieurs fois puisque les blocs n’étaient pas détruits immédiatement. Heureusement, comme notre dernier numéro, cela peut être résolu facilement.

Pour résoudre ce problème, nous allons créer une nouvelle variable qui indiquera au système s'il peut ou non attribuer des points. Ensuite, chaque fois que nous allons utiliser le Give Points fonction, nous allons également modifier la variable pour que l'événement ne soit déclenché qu'une seule fois. Enfin, une fois que les points ont été attribués, nous allons modifier la variable une fois de plus afin d'éviter tout problème lors de la prochaine tentative d'attribution de points..

Tout d’abord, créez une variable globale appelée PointsGiven:

Variable globale: PointsGiven Type = Nombre Valeur initiale = 0

Votre variable devrait ressembler à ceci:

Ensuite, nous allons modifier la partie de la FindMatches fonction qui donne réellement les points en ajoutant une nouvelle condition et deux nouvelles actions.

Condition: Système> Variable de comparaison Variable = PointsGiven Comparaison = Égal à Valeur = 0

Ajoutez maintenant cette action au début de la liste d’actions:

Action: Système> Valeur définie Variable = PointsGiven Value = 1

Enfin, ajoutez cette action à la fin de la liste d’actions:

Action: Système> Valeur définie Variable = PointsGiven Value = 0

L'événement devrait maintenant ressembler à ceci:

Avec ces changements, nous avons fait en sorte que l'événement qui appelle Give Points ne fonctionnera que lorsque le PointsGiven variable est 0. Puisque nous définissons immédiatement la valeur sur 1 lorsque nous commençons l'événement, cela empêche l'événement de se déclencher plus d'une fois et garantit que le joueur recevra le nombre correct de points.

Si vous lancez le jeu à ce stade, vous devriez recevoir le nombre correct de points pour chaque match que vous faites, même si vous n'aviez pas ce problème pour commencer..


Éliminer les correspondances prédéfinies

Maintenant que ces correctifs ont été résolus, nous pouvons créer le système qui éliminera les correspondances générées par le système lorsqu'il attribue des couleurs de manière aléatoire aux blocs qu'il crée..

Le problème que nous avons maintenant est que, comme les couleurs du bloc sont entièrement aléatoires, il n’est pas rare que vous commenciez le jeu et que vous constatiez que de nombreux matchs étaient faits immédiatement. Ceci est un problème car cela pourrait rendre les premières secondes du jeu très déroutant pour quelqu'un qui n'a jamais joué auparavant, et parce qu'il donne des points au joueur qu'il n'a pas gagné..

Pour résoudre le problème, nous allons créer une fonction qui examinera chaque bloc, puis verra si ce bloc a la même couleur que l'un de ses voisins. Si c'est la même couleur que ses voisins, il continuera à changer la couleur de ce bloc jusqu'à ce qu'il ne corresponde plus à aucun des blocs qui l'entourent.

Pour que ce système fonctionne, nous devrons également créer plusieurs fonctions de support et des événements, et ajouter une nouvelle variable d'instance à Bloc objet.

Le faire fonctionner

Tout d'abord, créez une nouvelle variable d'instance pour le Bloc objet:

Variable d'instance: BlockID Type = Number Valeur initiale = 0

Cette variable est ce que nous allons utiliser pour identifier facilement un bloc afin de pouvoir indiquer certaines des fonctions que nous allons créer, quel bloc nous voulons examiner, quelle que soit sa position..

Avant de poursuivre, nous devons également commencer à utiliser cette variable. Aller au Au début de la mise en page Evénement qui crée les blocs et ajoute une nouvelle action avant l'action qui augmente Verrouillage numérique:

Action: Bloquer> Définir une valeur Instance variable = BlockID Valeur = NumBlocks

Votre événement générateur de bloc devrait maintenant ressembler à ceci:

Ensuite, nous devons créer une fonction qui prendra les positions X et Y d’un bloc et nous dira quelle est la couleur de ce bloc:

Événement: Condition: Fonction> Fonction On Name = "GetBlockColor" Sous-événement: Condition: Bloc> Comparer X Comparaison = Egale à la coordonnée X = Fonction.Param (0) Condition: Bloc> Comparer Y Comparaison = Egale à Y co -ordinate = Function.Param (0) Action: Fonction> Définir la valeur renvoyée. Valeur = Block.Color Sous-événement: Système> Else. Action: Fonction> Définir la valeur renvoyée. Valeur = -1

La fonction devrait ressembler à ceci quand elle est finie:

Maintenant que nous avons une fonction qui peut nous indiquer la couleur de n'importe quel bloc, nous allons créer la fonction qui examinera un bloc et déterminera s'il a des blocs voisins de même couleur..

Le fonctionnement de cette fonction est assez simple.

  • Tout d'abord, nous allons passer un BlockID dans la fonction.
  • S'il y a actuellement un bloc avec cela BlockID, la fonction examinera les quatre blocs voisins et déterminera si le bloc examiné est de la même couleur que l'un de ses voisins.
  • S'il trouve qu'il y a un voisin de la même couleur, il commencera à changer la couleur du bloc qu'il regarde et continuera à changer de couleur jusqu'à ce que le bloc soit d'une couleur différente de celle de tous ses voisins..

Avant de pouvoir réaliser cet événement, nous devons créer une nouvelle variable globale. Dans la fonction, nous utiliserons une boucle While pour déterminer si la couleur du bloc doit être modifiée. La variable que nous sommes sur le point de créer est la variable que la boucle While utilisera pour déterminer si elle doit continuer à s'exécuter:

Variable globale: HasMatchingNeighbor Type = Nombre Valeur initiale = 0

Pointe:L'événement que nous allons créer contient un événement basé sur Or. Si vous n'avez jamais créé de bloc d'événement ayant un attribut Ou, il vous suffit de le transformer comme vous le feriez normalement, puis de cliquer avec le bouton droit de la souris sur tout le bloc et de choisir Faire un bloc «ou». Contrairement à un bloc d’événements standard qui exige que toutes les conditions soient remplies avant son déclenchement, un bloc Ou se déclenche si tout la condition est remplie.

Alors, faisons de l'événement:

Evénement: Condition: Fonction> Fonction activée Name = "RemoveSpawnedMatches" Sous-événement: Condition: Bloquer> Variable d'instance variable Variable d'instance = Identifiant de bloc = Valeur égale à Function.param (0) Action: Système> Valeur définie Variable = Valeur HasMatchingNeighbor = 1 Sous-événement: Condition: Système> While Condition: Système> Variable de comparaison Variable = HasMatchingNeighbor Comparison = Égal à la valeur = 1 Sous-événement: Condition: Bloc> Comparaison de la variable d'instance Variable d'instance = Comparaison des couleurs = Égal à la valeur = Fonction. Appel ("GetBlockColor", Block.X - (Block.Width + 2), Block.Y) Action: Bloc> Valeur définie Variable d'instance = Couleur Valeur = étage (Aléatoire (1,7)) Action: Système> Valeur définie Variable = HasMatchingNeighbor Value = 1 Sous-événement: Condition: System> Else Condition: Block> Comparaison de la variable d'instance Variable d'instance = Comparaison des couleurs = Egale à Valeur = Function.Call ("GetBlockColor", Block.X + (Block.Width + 2) , Block.Y) Action: Bloquer> Définir une valeur Variable d'instance = Couleur Valeur = Sol (Random (1,7)) Action: Système> Valeur définie Variable = HasMatchingNeighbor Valeur = 1 Sous-événement: Condition: Système> Autre Condition: Bloc> Variable d'instance variable Variable d'instance = Comparaison de couleurs = Egale à Valeur = Function.Call ("GetBlockColor", Block.X, Block.Y - (Block.Width + 2)) Action: Block> Valeur définie Variable d'instance = Couleur Valeur = floor (Aléatoire (1,7)) Action: Système> Valeur définie Variable = HasMatchingNeighbor Valeur = 1 Sous-événement: Condition : System> Else Condition: Block> Comparaison de la variable d'instance Variable d'instance = Comparaison des couleurs = Egale à la valeur = Function.Call ("GetBlockColor", Block.X, Block.Y + (Block.Width + 2)) Action: Bloquer> Définir valeur Instance variable = Couleur Valeur = sol (Aléatoire (1,7)) Action: Système> Valeur définie Variable = HasMatchingNeighbor Valeur = 1 Sous-événement: Condition: Système> Autre Action: Système> Valeur définie Variable = HasMatchingNeighbor Valeur = 0

Votre événement devrait ressembler à ceci:


Alors, comment fonctionne cette fonction exactement?

La première chose qu’il fait est de rechercher un Bloc avec le BlockID que le système est passé po Quand il localise que Bloc il définit la valeur de HasMatchingNeothers à 1 puis exécute la boucle While.

Depuis la boucle While ne fonctionnera que lorsque HasMatchingNeothers est 1, c'est la valeur qu'il définit. Pendant la boucle While, il teste pour voir s’il existe un voisin Bloc à gauche, à droite, au-dessus ou au-dessous, la même couleur que le Bloc nous regardons. S'il trouve une correspondance Bloc dans tout de ces positions, il attribue une nouvelle couleur au hasard Bloc puis relance le test en veillant à ce que HasMatchingNeothers est réglé sur 1. Quand il trouve enfin une couleur pour le Bloc qui ne correspond à aucun de ses voisins, il change la valeur de HasMatchingNeothers à 0 de sorte que la boucle While se termine et que le programme puisse continuer.

Maintenant, nous devons implémenter cette fonction dans le jeu; Pour ce faire, nous allons devoir créer deux nouvelles variables et deux nouvelles fonctions. Commençons par les variables.

Variable globale: CheckStartingMatches Type = Nombre Valeur = 0
Variable globale: CheckNewestRow Type = Nombre Valeur = 0

Vos variables devraient ressembler à ceci:

Les deux variables que nous venons de créer seront utilisées pour déclencher les deux événements que nous sommes sur le point de créer. Les événements eux-mêmes seront utilisés pour parcourir les blocs immédiatement après leur création et envoyer chaque bloc dans le SupprimerSpawnedMatches une fonction.

La raison pour laquelle nous n'appelons pas simplement le SupprimerSpawnedMatches immédiatement après la création du bloc parce que la grille de blocs doit être complète pour que la fonction fonctionne correctement. Donc, au lieu d'appeler directement la fonction lorsque des blocs sont créés, nous allons plutôt déclencher un événement qui peut parcourir les blocs et appeler la fonction seule après la génération de la grille..

Le premier événement sera spécifiquement conçu pour parcourir le groupe de blocs initial:

Événement: Condition: Système> Variable de comparaison Instance variable = CheckStartingMatches Comparison = Égal à Valeur = 1 Condition: Système> Pour Nom = "Blocs" Index initial = 0 Index final = NumBlocks-1 Action: Fonction> Appel fonction Name = "RemoveSpawnedMatches" Paramètre 0 = loopindex ("Blocks") SubEvent: Condition: Système> Comparer deux valeurs Première valeur = loopindex ("Blocks") Comparaison = Egale à Seconde valeur = NumBlocks-1 Action: Système> Variable Variable d'instance = CheckStartingMatches Valeur = 0

Voici à quoi votre événement devrait ressembler:

Le second événement servira spécifiquement à vérifier les nouvelles rangées de blocs lors de leur création:

Evénement: Condition: Système> Variable de comparaison Instance variable = CheckNewestRow Comparison = Égal à Valeur = 1 Condition: Système> Pour Nom = "Blocs" Début index = NumBlocks-9 End index = NumBlocks-1 Action: Fonction> Appelez la fonction Nom = ". RemoveSpawnedMatches "Parameter 0 = loopindex (" Blocks ") Sous-événement: Condition: Système> Comparer deux valeurs Première valeur = loopindex (" Blocks ") Comparaison = Egale à la deuxième valeur = NumBlocks-1 Action: Système> Définir la variable Variable d'instance = CheckNewestRow Valeur = 0

Voici à quoi devrait ressembler le deuxième événement:

la mise en oeuvre

Avec ces deux fonctions en place, il ne nous reste plus qu'à les mettre en œuvre. Aller à l'événement initial qui crée les blocs, le Au début de la mise en page Un événement. Nous allons ajouter un sous-événement à cela qui dira au CheckStartingMatches Evénement à activer.

Sous-événement: Condition: Système> Comparer deux valeurs Première valeur = loopindex ("X") Comparaison deuxième valeur: 7 Condition: Système> Comparer deux valeurs Première valeur = loopindex ("Y") Comparaison deuxième valeur: 3 Action: Système> Définir la valeur Instance variable = CheckStartingMatches Value = 1

Votre événement devrait maintenant ressembler à ceci:

Ce sous-événement écoute la fin de la boucle For imbriquée, puis modifie la valeur de la CheckStartingMatches variable pour activer l'événement approprié.

Nous allons maintenant faire presque le même sous-événement et l’attacher au SpawnNewBlocks une fonction.

Sous-événement: Condition: Système> Comparer deux valeurs Première valeur = loopindex ("X") Comparaison Deuxième valeur: 7 Action: Système> Définir une valeur Variable d'instance = CheckNewestRow Valeur = 1

SpawnNewBlocks devrait maintenant ressembler à ceci:

Ce sous-événement fait la même chose que le précédent, sauf qu'il active l'autre événement que nous avons créé. Si vous lancez le jeu à ce stade, vous devriez voir que lorsque vous démarrez le jeu, il n'y a plus de correspondance automatique..


Conclusion

Dans ce tutoriel, nous n’avons pas apporté beaucoup de modifications au jeu, mais celles que nous avons apportées étaient très importantes..

À ce stade, je pense qu'il est préférable que nous arrêtions pour l'instant et sauvegardions les deux derniers éléments du jeu pour le prochain tutoriel, où nous couvrirons les chaînes / combos et l'écran Game Over. Comme ce sera la dernière partie de la série, je vais aussi parler de mécanismes de jeu que nous ne couvrirons pas dans ces tutoriels et vous donner des conseils sur la façon de créer ces systèmes vous-même..

Si vous souhaitez prendre une longueur d'avance sur le contenu de la semaine prochaine, commencez à regarder comment vous pouvez détecter le moment où l'écran Game Over devrait apparaître, en fonction de la position ou de la hauteur de certains des blocs. Sinon, commencez à réfléchir à la manière dont vous pourriez détecter le moment où le joueur fait une réaction en chaîne qui entraîne la formation de plusieurs groupes..

Quoi que vous fassiez, j'espère vous revoir ici la semaine prochaine pour le dernier versement de la série..