Dans la dernière partie de cette série, nous mettons la dernière main à notre jeu de puzzle Unity basé sur une grille et le rendons jouable. À la fin de cette partie, le joueur pourra gagner ou perdre la partie..
Maintenant que vous avez terminé les didacticiels précédents, notre jeu peut créer un champ de tuiles et leur attribuer des mines au hasard. Nous avons également un bel effet lumineux lorsque le joueur survole une tuile avec la souris, et il est possible de placer et d'enlever des drapeaux..
En interne, chaque tuile connaît également les tuiles voisines et peut déjà calculer le nombre de mines à proximité..
Nous avons déjà ajouté la possibilité de placer des drapeaux avec un clic droit. Ajoutons maintenant la possibilité de découvrir des tuiles avec un clic gauche..
dans le OnMouseOver ()
fonction, où nous avons le code de reconnaissance de clic, nous devons reconnaître un clic gauche. Adaptez la fonction pour qu'elle ressemble à ceci:
function OnMouseOver () if (state == "idle") renderer.material = materialLightup; if (Input.GetMouseButtonDown (0)) UncoverTile (); if (Input.GetMouseButtonDown (1)) SetFlag (); else if (state == "flagged") renderer.material = materialLightup; if (Input.GetMouseButtonDown (1)) SetFlag ();
Lorsque le bouton gauche de la souris est enfoncé, le UncoverTile ()
la fonction sera appelée. Assurez-vous de créer cette fonction pour éviter tout bogue.!
function UncoverTile () if (! isMined) state = "découvert"; displayText.renderer.enabled = true; renderer.material = materialUncovered; else Explode ();
Pour que cela fonctionne, nous devons introduire un nouveau matériau.
public var materialUncovered: Matériel;
Créez quelque chose qui a une couleur différente de celle des carreaux de base. Si vos carreaux de base sont bleus, vous pouvez choisir le vert pour le découvert Etat. Mais n'utilisez pas de rouge; nous en aurons besoin plus tard pour montrer que nous avons déclenché une mine.
Lorsque vous appelez cette fonction, les événements suivants se produisent:
découvert
, activez l’affichage de texte qui nous indique le nombre de mines à proximité et réglez le matériel sur découvert Matériel. Avant de pouvoir essayer cela, nous devons nous assurer que le contenu n'est pas modifié lorsque le curseur de la souris sorties la tuile. Pour cela, adaptez le OnMouseExit ()
fonctionne comme ceci:
function OnMouseExit () if (state == "idle" || state == "signalé") renderer.material = materialIdle;
De cette façon, la couleur ne change que si le carreau n'a pas encore été découvert.
Essaye le! Vous devriez pouvoir découvrir des tuiles. Si une tuile est minée, rien ne se passera pour le moment..
Ce sera un peu délicat. Dans Minesweeper, lorsque vous découvrez une tuile avec nonmines adjacentes, il découvrira toutes les tuiles adjacentes dépourvues de mines et les tuiles adjacentes leur qui n'ont pas de mines, etc..
Considérez ce champ:
Nous ne voyons pas les chiffres ou les mines, seulement des tuiles ordinaires.
Quand une tuile avec zéro les mines à proximité sont découvertes, toutes les tuiles à côté doivent être automatiquement découvertes, aussi. La tuile découverte couvre alors tous les voisins.
Ces carreaux récemment découverts vérifieront également leurs voisins et, s’il n’ya pas de mines, les découvriront également..
Cela se répercutera à travers le champ jusqu'à ce que nous atteignions les tuiles sur lesquelles se trouvent des mines adjacentes, où elles s'arrêteront..
Cela crée le zones vides nous pouvons voir dans Démineur.
Pour que cela fonctionne, nous avons besoin de deux fonctions supplémentaires, UncoverAdjacentTiles ()
et UncoverTileExternal ()
:
fonction privée UncoverAdjacentTiles () pour (var currentTile: Tile in adjacentTiles) // découvrir tous les nœuds adjacents avec 0 mines adjacentes if (! currentTile.isMined && currentTile.state == "inactif" && currentTile.adjacentMines == 0) currentTile .UncoverTile (); // découvre tous les nœuds adjacents avec plus d'une mine adjacente, puis cesse de découvrir d'autres si (! currentTile.isMined && currentTile.state == "inactif" && currentTile.adjacentMines> 0) currentTile.UncoverTileExternal (); fonction publique UncoverTileExternal () state = "uncovered"; displayText.renderer.enabled = true; renderer.material = materialUncovered;
Nous devons également apporter cette modification au UncoverTile ()
une fonction:
function UncoverTile () if (! isMined) state = "découvert"; displayText.renderer.enabled = true; renderer.material = materialUncovered; if (adjacentMines == 0) UncoverAdjacentTiles ();
Lorsque nous découvrons une tuile et qu’il n’y a pas de mines à côté, nous appelons le UncoverAdjacentTiles ()
une fonction. Ceci vérifie ensuite chaque tuile voisine pour voir si elle a des mines ou non. aussi. S'il n'y en a pas, il découvre également cette tuile et lance une nouvelle série de vérifications. S'il y a des mines à proximité, seule la tuile sur laquelle elle se trouve actuellement est découverte..
Maintenant, essayez-le. Pour avoir de bonnes chances qu'un champ vide apparaisse, créez un champ assez grand avec quelques mines, disons 81 tuiles, avec neuf tuiles par rangée et 10 mines au total..
Vous pouvez maintenant jouer à cela comme un jeu, sauf que vous ne pouvez pas encore déclencher de mines. Nous allons ajouter cette fonctionnalité à côté.
Lorsque nous découvrons une tuile minée, le jeu s’arrête et le joueur perd. De plus, toutes les autres tuiles minées deviennent visibles. Pour que cela se produise, nous avons besoin d’un matériau supplémentaire, pour les tuiles de mine détonées:
public var materialDetonated: Matériel;
Je suggère d'utiliser quelque chose de rouge pour cette.
En outre, nous devons ajouter deux fonctions supplémentaires pour gérer l'explosion de toutes les mines:
fonction Explode () state = "détonée"; renderer.material = materialDetonated; for (var currentTile: Tile dans Grid.tilesMined) currentTile.ExplodeExternal (); fonction ExplodeExternal () state = "détonée"; renderer.material = materialDetonated;
Nous déclenchons ces méthodes dans le UncoverTile ()
une fonction:
function UncoverTile () if (! isMined) state = "découvert"; displayText.renderer.enabled = true; renderer.material = materialUncovered; if (adjacentMines == 0) UncoverAdjacentTiles (); else Explode ();
Si une tuile est extraite, elle explose. le Exploser()
la fonction envoie ensuite une commande "exploser" à toutes les autres tuiles avec des mines, les révélant toutes.
La partie est gagnée une fois que toutes les tuiles avec les mines ont été correctement marquées. À ce stade, toutes les tuiles non découvertes le sont également. Alors, comment pouvons-nous suivre cela?
Commençons par ajouter un Etat
variable à la la grille
classe, afin que nous puissions savoir quelle partie du jeu nous sommes actuellement (toujours en train de jouer, de perdre ou de gagner).
static var state: String = "inGame";
Pendant que nous y sommes, nous pouvons également commencer à ajouter une interface graphique simple, afin que nous puissions afficher les informations nécessaires à l'écran. Unity est livré avec son propre système graphique que nous utiliserons pour cela.
fonction OnGUI () GUI.Box (Rect (10, 10, 100, 50), état);
Cela nous montrera dans quel état nous sommes actuellement. Nous appellerons ces états En jeu
, jeu terminé
, et partie gagnée
.
Nous pouvons également ajouter des contrôles à la mosaïque pour nous assurer que nous ne pouvons interagir avec les mosaïques que lorsque l'état de jeu actuel est défini. En jeu
.
dans le OnMouseOver ()
et OnMouseExit
fonctions, déplacez tout le code existant dans un si
bloquer qui vérifie si Etat de la grille
est actuellement En jeu
, ainsi:
function OnMouseOver () if (Grid.state == "inGame") if (state == "inactif") renderer.material = materialLightup; if (Input.GetMouseButtonDown (0)) UncoverTile (); if (Input.GetMouseButtonDown (1)) SetFlag (); else if (state == "flagged") renderer.material = materialLightup; if (Input.GetMouseButtonDown (1)) SetFlag (); function OnMouseExit () if (Grid.state == "inGame") if (state == "inactif" || state == "marqué") renderer.material = materialIdle;
Il existe en fait deux façons de vérifier si le jeu a été remporté: nous pouvons compter le nombre de mines marquées correctement ou si toutes les tuiles qui ne sont pas des mines ont été découvertes. Pour cela, nous avons besoin des variables suivantes: ajoutez-les à la la grille
classe:
statique var minesMarkedCorrectly: int = 0; dalles de var statiqueUncovered: int = 0; mines var statiquesRemaining: int = 0;
N'oubliez pas de mettre minesRemaining
dans le Début()
fonction à numberOfMines
, et les autres variables à 0
. le Début()
la fonction devrait maintenant ressembler à ceci:
fonction Start () CreateTiles (); minesRemaining = numberOfMines; minesMarkedCorrectly = 0; tilesUncovered = 0; state = "inGame";
La dernière ligne définit l'état du jeu. (Cela sera important lorsque nous voudrons introduire une fonction de "redémarrage" plus tard.)
Nous vérifions ensuite nos conditions de jeu en fin de partie. Mettre à jour()
une fonction:
function Update () if (state == "inGame") if ((minesRemaining == 0 && minesMarkedCorrectly == numberOfMines) || (tilesUncovered == numberOfTiles - numberOfMines)) FinishGame ();
Nous finissons le jeu en mettant l'état à partie gagnée
, découvrir toutes les tuiles restantes et marquer toutes les mines restantes:
fonction FinishGame () state = "gameWon"; // découvre les champs restants si tous les nœuds ont été placés pour (var currentTile: Tile in tilesAll) if (currentTile.state == "idle" &&! currentTile.isMined) currentTile.UncoverTileExternal (); // marque les mines restantes si tous les nœuds sauf les mines ont été découverts pour (var currentTile: Tile dans Grid.tilesMined) if (currentTile.state! = "marqué") currentTile.SetFlag ();
Pour que tout cela fonctionne réellement, nous devons incrémenter les variables qui suivent nos progrès aux bons endroits. Adapter le UncoverTile ()
fonction pour le faire:
function UncoverTile () if (! isMined) state = "découvert"; displayText.renderer.enabled = true; renderer.material = materialUncovered; Grid.tilesUncovered + = 1; if (adjacentMines == 0) UncoverAdjacentTiles (); else Explode ();
… aussi bien que UncoverTileExternal ()
une fonction:
function UncoverTileExternal () state = "découvert"; displayText.renderer.enabled = true; renderer.material = materialUncovered; Grid.tilesUncovered + = 1;
Nous devons également incrémenter et décrémenter le minesMarkedCorrectement
et minesRemaining
variables selon qu'un indicateur a été défini ou non:
fonction SetFlag () if (state == "inactif") state = "marqué"; displayFlag.renderer.enabled = true; Grid.minesRemaining - = 1; if (isMined) Grid.minesMarkedCorrectly + = 1; else if (state == "marqué") state = "inactif"; displayFlag.renderer.enabled = false; Grid.minesRemaining + = 1; if (isMined) Grid.minesMarkedCorrectly - = 1;
De la même manière, nous devons permettre de perdre une partie. Nous accomplissons cela via le Exploser()
fonction dans la tuile.
Ajoutez simplement cette ligne au Exploser()
une fonction:
Grid.state = "gameOver";
Une fois que cette ligne est exécutée, l’état du jeu passe à jeu terminé
, et les tuiles ne peuvent plus être interagies avec.
Il y a quelques étapes, nous avons utilisé l'interface graphique d'Unity pour indiquer au joueur l'état de jeu actuel. Nous allons maintenant l'étendre pour afficher certains messages réels..
Le cadre pour cela ressemble à ceci:
function OnGUI () if (state == "inGame") sinon if (state == "gameOver") sinon if (state == "gameWon")
Selon l'état, différents messages sont affichés dans l'interface graphique. Si le jeu est perdu ou gagné, par exemple, nous pouvons afficher des messages disant:
function OnGUI () if (state == "inGame") sinon if (state == "gameOver") GUI.Box (Rect (10,10,200,50), "Vous perdez"); else if (state == "gameWon") GUI.Box (Rect (10,10,200,50), "You rock!");
Nous pouvons également afficher le nombre de mines trouvées jusqu'à présent ou ajouter un bouton qui recharge le niveau une fois le jeu terminé:
fonction OnGUI () if (state == "inGame") GUI.Box (Rect (10,10,200,50)), "Mines restantes:" + minesRemaining); else if (state == "gameOver") GUI.Box (Rect (10,10,200,50), "Vous perdez"); if (GUI.Button (Rect (10,70,200,50), "Redémarrer"))) Redémarrer (); else if (state == "gameWon") GUI.Box (Rect (10,10,200,50), "You rock!"); if (GUI.Button (Rect (10,70,200,50), "Redémarrer"))) Redémarrer (); function Restart () state = "loading"; Application.LoadLevel (Application.loadedLevel);
Vous pouvez tout essayer dans cette version finale!
C'est tout! Nous avons créé un jeu de puzzle simple avec Unity, que vous pouvez utiliser pour créer le vôtre. J'espère que vous avez apprécié cette série. veuillez poser toutes les questions que vous avez dans les commentaires!