Nous continuons à construire notre jeu de réflexion basé sur une grille en connectant les tuiles les unes aux autres, en les allumant avec le curseur de la souris et en ajoutant la possibilité de placer des drapeaux..
Dans la dernière partie de ce didacticiel, nous avons créé un champ de carreaux qui constitue la base de notre jeu de puzzle. Dans cette partie, nous allons le rendre jouable. Ce tutoriel fait suite à la dernière partie, donc lisez ceci avant de commencer.
Lorsque la souris survole une tuile, nous voulons qu’elle s’allume. C'est une fonctionnalité intéressante qui donne même des actions simples (telles que le déplacement du pointeur de la souris) un retour instantané.
Nous utilisons le OnMouseOver ()
fonction pour accomplir cela. Il est appelé automatiquement chaque fois que le curseur de la souris passe sur l'objet auquel le code est attaché. Ajoutez ces variables au Tuile
scénario:
public var materialIdle: Material; public var materialLightup: Matériel;
Puis assignez votre matériau de base à la materialIdle
fente. Nous avons aussi besoin d'un allumer matériau, qui devrait avoir la même couleur, mais utilise un shader différent. Bien que le matériel de base puisse avoir une diffuser shader…
… Le matériel lumineux pourrait avoir un spéculaire shader. De nombreux jeux utilisent également un shader de bord supplémentaire pour cet effet. Ceux-ci ne viennent pas avec Unity, mais si vous pouvez trouver un moyen d’en obtenir un, vous pouvez l’utiliser à la place.!
N'oubliez pas d'attribuer réellement les matériaux à la Matériel fentes sur le préfabriqué, pour pouvoir les utiliser.
Puis ajoutez ceci OnMouseOver ()
fonction à la Tuile
scénario
function OnMouseOver () renderer.material = materialLightup;
Essaye le! Lorsque vous déplacez le curseur de la souris sur les carreaux, ils doivent changer d’apparence..
Ce que vous avez peut-être remarqué, c'est que les carreaux changent d'apparence une fois que la souris est sur eux, mais ne changent pas réellement retour. Pour cela, nous devons utiliser le OnMouseExit ()
une fonction:
function OnMouseExit () renderer.material = materialIdle;
Et voila; nous avons maintenant des tuiles qui s'allument et rendent le jeu beaucoup plus intéressant.
Pour que les tuiles communiquent les unes avec les autres (pour savoir combien de mines sont à proximité), chaque tuile doit connaître les tuiles voisines. Une façon d’y parvenir consiste à utiliser des identifiants, qui seront attribués à chaque tuile..
Commencez par adapter le code de tuile pour inclure un ID
variable. Ajoutez également une variable pour contenir le nombre de carreaux par ligne, que nous utiliserons dans ce calcul:
public var ID: int; public var tilesPerRow: int;
Puis modifiez la commande instancier dans le code de la grille pour qu’elle ressemble à l’extrait suivant. (La nouvelle ligne attribue des identifiants aux tuiles au fur et à mesure de leur création.)
var newTile = Instantiate (tilePrefab, Vector3 (transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); newTile.ID = tilesCreated; newTile.tilesPerRow = tilesPerRow;
La première tuile recevra l'ID 0, le prochain sera attribué l'ID 1, etc. Vous pouvez les vérifier en cliquant sur les carreaux pendant l'exécution et voir le numéro qui leur a été attribué..
Nous voulons maintenant que chaque tuile connaisse ses tuiles voisines. Lorsque nous exécutons une action sur une tuile (en la découvrant, par exemple), nous devons prendre en compte les tuiles voisines..
Dans notre cas, cela implique de compter les mines adjacentes à la tuile que nous venons de découvrir et éventuellement de découvrir d'autres tuiles également, mais nous y reviendrons plus tard..
Cela peut également être utilisé, par exemple, pour vérifier si trois tuiles ou plus sont côte à côte dans un match 3..
Commencez par ajouter ces variables au script de mosaïque:
public var tileUpper: Tile; public var tileLower: Tile; public var tileLeft: Tile; public var tileRight: Tile; public var tileUpperRight: Tile; public var tileUpperLeft: Tile; public var tileLowerRight: Tile; public var tileLowerLeft: Tile;
Ceux-ci contiendront toutes les tuiles voisines. Elles sont publiques afin que nous puissions vérifier pendant l'exécution qu'elles ont été affectées correctement..
Depuis lors, chaque mosaïque a un ID, le nombre de mosaïques qui apparaissent dans une colonne et un accès au tableau statique dans lequel toutes les mosaïques sont enregistrées. la grille
classe, nous pouvons calculer les positions des tuiles voisines après leur création.
Cette partie ressemble à ceci:
tileUpper = Grid.tilesAll [ID + tilesPerRow]; tileLower = Grid.tilesAll [ID - tilesPerRow]; tileLeft = Grid.tilesAll [ID - 1]; tileRight = Grid.tilesAll [ID + 1]; tileUpperRight = Grid.tilesAll [ID + tilesPerRow + 1]; tileUpperLeft = Grid.tilesAll [ID + tilesPerRow - 1]; tileLowerRight = Grid.tilesAll [ID - tilesPerRow + 1]; tileLowerLeft = Grid.tilesAll [ID - tilesPerRow - 1];
Avec les ID et le nombre de tuiles par ligne, nous pouvons calculer quelles sont les tuiles les plus proches. Supposons que la tuile effectuant les calculs ait l'ID 3
, et qu'il y a cinq tuiles par rangée. La tuile au-dessus aura l'ID 8
(l'identifiant de la tuile sélectionnée plus le nombre de tuiles par ligne); la tuile à droite aura l'identifiant 6
(ID de la tuile sélectionnée plus un), etc..
Malheureusement, cela ne suffit pas. Le code vérifie correctement les chiffres, mais quand il demande à la allTiles
tableau pour renvoyer les tuiles, il peut demander des numéros d’index hors limites, produisant une longue liste d’erreurs.
Afin de résoudre ce problème, nous devons vérifier que l'index que nous demandons au tableau est réellement valide. Le moyen le plus efficace de le faire est avec un nouveau inBounds ()
une fonction. Ajoutez-le à la tuile:
fonction privée inBounds (inputArray: Array, targetID: int): boolean if (targetID < 0 || targetID >= inputArray.length) renvoie false; sinon, retourne vrai;
Maintenant, nous devons vérifier que chaque tuile voisine possible est dans les limites du tableau qui contient toutes les tuiles, avant d'essayer de l'obtenir à partir du tableau:
if (inBounds (Grid.tilesAll, ID + tilesPerRow)) tileUpper = Grid.tilesAll [ID + tilesPerRow]; if (inBounds (Grid.tilesAll, ID - tilesPerRow)) tileLower = Grid.tilesAll [ID - tilesPerRow]; if (inBounds (Grid.tilesAll, ID - 1) && ID% tilesPerRow! = 0) tileLeft = Grid.tilesAll [ID - 1]; if (inBounds (Grid.tilesAll, ID + 1) && (ID + 1)% tilesPerRow! = 0) tileRight = Grid.tilesAll [ID + 1]; if (inBounds (Grid.tilesAll, ID + tilesPerRow + 1) && (ID + 1)% tilesPerRow! = 0) tileUpperRight = Grid.tilesAll [ID + tilesPerRow + 1]; if (inBounds (Grid.tilesAll, ID + tilesPerRow - 1) && ID% tilesPerRow! = 0) tileUpperLeft = Grid.tilesAll [ID + tilesPerRow - 1]; if (inBounds (Grid.tilesAll, ID - tilesPerRow + 1) && (ID + 1)% tilesPerRow! = 0) tileLowerRight = Grid.tilesAll [ID - tilesPerRow + 1]; if (inBounds (Grid.tilesAll, ID - tilesPerRow - 1) && ID% tilesPerRow! = 0) tileLowerLeft = Grid.tilesAll [ID - tilesPerRow - 1];
Ce bloc de code vérifie toutes les possibilités. Il vérifie également si une tuile est au bord du champ. Une tuile sur le bord droit de la grille, après tout, n’a pas de tuile à sa place. droite.
Essaye le! Vérifiez quelques tuiles et voyez si vous avez récupéré correctement toutes les tuiles voisines. Ça devrait ressembler à ça:
La mosaïque de cette capture d'écran étant une mosaïque située sur le bord droit du champ, elle n'a pas de voisins à droite, en haut à droite ou en bas à droite. Les variables sans mosaïques affectées sont correctement vides et un test révèle que les variables restantes ont également été affectées correctement..
Enfin, une fois que nous nous sommes assurés que cela fonctionne, nous ajoutons toutes les mosaïques voisines dans un tableau, afin de pouvoir y accéder toutes en même temps plus tard. Nous devons déclarer ce tableau au début:
public var adjacentTiles: Array = new Array ();
Vous pouvez ensuite adapter chaque ligne de l'algorithme que nous avons créé ci-dessus pour entrer chaque tuile voisine de ce tableau, ou ajouter ce bloc par la suite:
if (tileUpper) adjacentTiles.Push (tileUpper); if (tileLower) adjacentTiles.Push (tileLower); if (tileLeft) adjacentTiles.Push (tileLeft); if (tileRight) adjacentTiles.Push (tileRight); if (tileUpperRight) adjacentTiles.Push (tileUpperRight); if (tileUpperLeft) adjacentTiles.Push (tileUpperLeft); if (tileLowerRight) adjacentTiles.Push (tileLowerRight); if (tileLowerLeft) adjacentTiles.Push (tileLowerLeft);
Une fois que toutes les tuiles ont été créées, toutes les mines ont été attribuées et que chaque tuile a récupéré ses voisins, nous devons ensuite vérifier si chacune de ces tuiles voisines est exploitée ou non..
Le code de grille attribue déjà le nombre spécifié de mines à des tuiles choisies au hasard. Maintenant, nous avons seulement besoin de chaque tuile pour vérifier ses voisins. Ajoutez ce code au début de la Tuile
script, de sorte que nous avons un endroit pour stocker la quantité de mines:
public var adjacentMines: int = 0;
Pour les compter, nous parcourons le tableau dans lequel nous avons précédemment ajouté toutes les tuiles voisines, et vérifions chaque entrée à tour de rôle pour voir si elle est minée. Si oui, nous augmentons la valeur de mines adjacentes
par 1.
fonction CountMines () adjacentMines = 0; pour chaque (var currentTile: Tile in adjacentTiles) if (currentTile.isMined) adjacentMines + = 1; displayText.text = adjacentMines.ToString (); si (adjacentMines <= 0) displayText.text = "";
Cette fonction définit également l’élément texte de la vignette pour afficher le nombre de mines à proximité. S'il n'y a pas de mines, rien ne s'affiche (plutôt que 0).
Ajoutons un Etat
à chaque tuile. De cette façon, nous pouvons savoir dans quel état il se trouve actuellement.-tourner au ralenti
, découvert
, ou signalé
. Selon l'état dans lequel se trouve la tuile, celle-ci réagira différemment. Ajoutez-le maintenant, car nous allons l'utiliser dans un instant.
public var state: String = "idle";
Nous voulons pouvoir marquer les carreaux comme signalé. Une tuile à drapeau est surmontée d'un tout petit drapeau. Si on clique avec le bouton droit sur le drapeau, il disparaîtra à nouveau. Si toutes les tuiles minées ont été marquées et qu'il ne reste aucune tuile mal signalée, la partie est gagnée..
Commencez par créer un objet indicateur et ajoutez-le à la tuile (vous trouverez un filet d'indicateur dans les fichiers source)..
Nous avons également besoin d'une variable pour accéder au drapeau. Ajoutez ce code:
public var displayFlag: GameObject;
N'oubliez pas de faire glisser le drapeau qui fait partie de la tuile sur le displayFlag fente.
Ajoutez aussi ceci à la début()
fonction de la tuile:
displayFlag.renderer.enabled = false; displayText.renderer.enabled = false;
Cela désactivera le drapeau et le texte au début. Plus tard, nous pouvons alors Activer un drapeau, le rendant à nouveau visible, le plaçant effectivement là. Sinon, si nous devoiler une tuile, nous rendons le texte visible à nouveau.
Nous allons écrire une fonction qui gère à la fois le placement et la suppression des drapeaux:
fonction SetFlag () if (state == "inactif") state = "marqué"; displayFlag.renderer.enabled = true; else if (state == "marqué") state = "inactif"; displayFlag.renderer.enabled = false;
Une fois que vous avez ajouté cela, ajoutez également le code permettant de gérer un événement de clic. Pour ce faire, adaptez le OnMouseOver ()
fonction nous devons déjà vérifier pour un clic de souris:
function OnMouseOver () if (state == "idle") renderer.material = materialLightup; if (Input.GetMouseButtonDown (1)) SetFlag (); else if (state == "flagged") renderer.material = materialLightup; if (Input.GetMouseButtonDown (1)) SetFlag ();
Ceci reconnaîtra un clic droit (bouton 1
) et activez le SetFlag ()
une fonction. Il activera ou désactivera alors le drapeau sur la tuile actuelle. Essaye le!
Nous avons étendu notre jeu de puzzle avec plusieurs fonctionnalités vitales, l'avons rendu visuellement plus intéressant et avons donné au joueur la possibilité d'influencer le terrain.
La prochaine fois, nous ajouterons des découvertes de tuiles, créerons une interface simple et en ferons un bon jeu..