I giochi di puzzle spesso si svolgono su una griglia contenente tessere che hanno comportamenti e proprietà e reagiscono a regole e input. In questa serie ti mostrerò come costruire una versione semplice e basilare del classico gioco Minesweeper, che è l'esempio perfetto da cui partire per creare i tuoi puzzle game.
Sia che tu stia realizzando un gioco di memoria per bambini o un titolo strategico complesso, l'implementazione degli elementi base del Campo minato è un ottimo punto di partenza. Nella prima parte di questa serie di tutorial in tre parti, costruiremo un campo di gioco che potrai utilizzare per creare la tua versione del gioco.
Avrai bisogno di Unity per questo, e una comprensione di base di esso. (Dai un'occhiata a Build Arkanoid With Unity se sei nuovo.) Il codice sorgente può essere scaricato, ma non è necessario per completare questo tutorial.
Minesweeper è un puzzle game in cui devi localizzare tutte le mine in un campo. Le dimensioni del campo variano a seconda della difficoltà e possono variare da 9x9 caselle (facile) a 16x30 caselle (disco rigido) o qualsiasi dimensione personalizzata.
Cliccando su una tessera lo "scopri". Se è una miniera, perdi; se è vuoto e almeno una mina è in una delle tessere confinanti, appare un numero che mostra il numero di mine nelle tessere vicine. Se non ci sono mine nelle tessere adiacenti, anche tutte le tessere adiacenti sono scoperte.
Un riquadro può essere contrassegnato facendo clic con il pulsante destro del mouse su di esso, inserendo quindi una bandiera su di esso. Una volta che tutte le tessere con mine sono state segnate correttamente, il gioco è vinto.
Provalo qui:
Dalle regole di cui sopra, possiamo estrapolare i diversi elementi di cui avrà bisogno la nostra versione semplice di dragamine. Questi sono
Crea un nuovo progetto Unity. Crea un cubo e chiamalo Piastrella
. Trascinalo nella cartella del progetto per trasformarlo in un prefabbricato. Useremo questa tessera non funzionale per costruire il campo di gioco, e successivamente aggiungeremo funzionalità.
Crea un nuovo oggetto vuoto e nominalo Griglia
, e trasformarlo in un prefabbricato pure. Questo sarà il generatore del campo di gioco e tutte le tessere al suo interno.
Crea un nuovo file JS, chiamalo Griglia
pure, e aggiungilo al Griglia
oggetto.
Aggiungi le seguenti righe allo script Grid, in modo che possiamo iniziare a creare un campo:
public var tilePrefab: GameObject; public var numberOfTiles: int = 10; public var distanceBetweenTiles: float = 1.0; function Start () CreateTiles (); function CreateTiles ()
Quindi, trascina il prefabbricato Tile sul Piastrella prefabbricata slot del Griglia
oggetto. Dovrebbe sembrare come questo:
Il numberOfTiles
variabile ti permetterà di impostare il numero di tessere da creare. DistanceBetweenTiles
definisce la distanza tra loro, in modo che possiamo regolare la spaziatura a nostro piacimento.
In questo momento, il generatore di rete non fa nulla. Per fare in modo che crei diverse tessere, aggiungi questo codice CreateTiles ()
funzione:
var xOffset: float = 0.0; per (var tilesCreated: int = 0; tilesCreated < numberOfTiles; tilesCreated += 1) xOffset += distanceBetweenTiles; Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z), transform.rotation);
Se si esegue la scena corrente, dovrebbe creare una linea delle nostre tessere, in questo modo:
La funzione crea copie del prefabbricato delle piastrelle, tante quante ne abbiamo specificato, e le colloca in fila, a una distanza di distanceBetweenTiles
a parte. Prova alcuni valori diversi per trovare una buona spaziatura.
Ma per Minesweeper avremo bisogno di una griglia, non di una linea. Per ottenere ciò, aggiungi questa variabile all'inizio del Griglia
codice:
public var tilesPerRow: int = 4;
... e adattare il CreateTiles ()
funzione per assomigliare a questo:
function CreateTiles () var xOffset: float = 0.0; var zOffset: float = 0.0; per (var tilesCreated: int = 0; tilesCreated < numberOfTiles; tilesCreated += 1) xOffset += distanceBetweenTiles; if(tilesCreated % tilesPerRow == 0) zOffset += distanceBetweenTiles; xOffset = 0; Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation);
Se lo esegui, dovresti finire con diverse linee di tessere:
Se imposti il tilesPerRow
variabile correttamente (come 24
piastrelle in 6
righe), il generatore dovrebbe creare un bel campo rettangolare. Se le tue capacità di programmazione sono abbastanza avanzate, puoi provare a capire come automatizzare ulteriormente il processo. (La versione di Minesweeper che stiamo costruendo funzionerà anche con campi di forma irregolare.)
Ora che possiamo creare un campo minuscolo e personalizzato, possiamo lavorare ad aggiungere miniere effettive su di esso.
Crea un nuovo file JS, chiamalo Piastrella
, e aggiungilo al prefabbricato Tile. Quindi, aggiungi la seguente variabile ad esso:
public var isMined: boolean = false;
Questo ci dirà se la tessera ha una miniera in essa.
Quindi, dobbiamo mettere le miniere effettive nella griglia. Per questo, cambia il GameObject
tipo di prefabbricato delle mattonelle al nuovo Piastrella
classe che abbiamo appena creato.
Cambiare il tilePrefab
variabile in modo che assomigli a questo:
public var tilePrefab: Tile;
E quindi assegnare nuovamente l'oggetto Tile a quella variabile. Ora può accedere automaticamente alle variabili che abbiamo inserito fin dall'inizio.
Assegnare le mine è un po 'più complicato. Lo faremo dal generatore di griglia.
Innanzitutto, tre matrici per mantenere le nostre tessere al codice Grid:
static var tilesAll: Tile []; static var tilesMined: Array; static var tilesUnmined: Array;
Abbiamo anche bisogno di inizializzarli. Metti le seguenti righe all'inizio del CreateTiles ()
funzione:
tilesAll = new Tile [numberOfTiles]; tilesMined = new Array (); tilesUnmined = new Array ();
Quindi, modificare il comando di istanza nel file CreateTiles ()
funzione per assomigliare a questo:
var newTile = Instantiate (tilePrefab, Vector3 (transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); tilesTutto [tilesCreated] = newTile;
Ora aggiungi questo comando alla fine del CreateTiles ()
funzione per avviare il AssignMines ()
processi:
AssignMines ();
Il CreateTiles ()
la funzione dovrebbe assomigliare a questa:
function CreateTiles () tilesAll = new Tile [numberOfTiles]; tilesMined = new Array (); tilesUnmined = new Array (); var xOffset: float = 0.0; var zOffset: float = 0.0; per (var tilesCreated: int = 0; tilesCreated < numberOfTiles; tilesCreated += 1) xOffset += distanceBetweenTiles; if(tilesCreated % tilesPerRow == 0) zOffset += distanceBetweenTiles; xOffset = 0; var newTile = Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); tilesAll[tilesCreated] = newTile; AssignMines();
Aggiungi anche la funzione AssignMines ()
, in modo che possiamo effettivamente usarlo:
function AssignMines () tilesUnmined = tilesAll; for (var minesAssigned: int = 0; minesAssigned < numberOfMines; minesAssigned += 1) var currentTile: Tile = tilesUnmined[Random.Range(0, tilesUnmined.length)]; tilesMined.Push(currentTile); tilesUnmined.Remove(currentTile); currentTile.GetComponent(Tile).isMined = true;
Ecco cosa succede: quando viene creata una nuova tessera nel CreateTiles
-funzione, è aggiunto al tilesAll
-array. Tutte le tessere in là sono poi copiate nel tilesUnmined
-array. Da questo array abbiamo scelto casualmente una tessera per aggiungere una miniera. Aggiungiamo una miniera impostando il isMined
-variabile a true, rimuoverlo dal tilesUnmined
-array e aggiungilo al tilesMined
-array (che useremo in seguito). Alla fine abbiamo posizionato casualmente la quantità specificata di mine sul campo di gioco.
In questo momento, una tessera estratta non è visibilmente diversa da una tessera non terminata. L'obiettivo del gioco è quello di capirlo, dopo tutto!
In questa build puoi testare come dovrebbe funzionare. A scopo dimostrativo, i riquadri estratti appaiono in rosso.
E voilá: ora hai un campo minato con una dimensione personalizzata!
In questo momento, le tessere sono cubi di unità standard. Trasformiamoli in effettivi piastrelle.
Nei file sorgente, troverai un file 3D chiamato puzzleObjects.fbx. Copialo nella tua cartella delle risorse, in modo che possiamo usarlo nel nostro gioco. Assicurati che il file sia importato con le dimensioni impostate su 1
, in modo che si adatti alle impostazioni che abbiamo utilizzato finora.
Le impostazioni di importazione del file dovrebbero assomigliare a questo:
Quindi, vai alle impostazioni del pannello prefabbricato e sostituisci la mesh del cubo per il tileImproved maglia.
Mentre siamo qui, stampa Reset sul Box Collider componente della piastrella. Questo renderà il collisore più vicino alla tessera.
Infine, dai alla piastrella un nuovo materiale, quindi non ha l'aspetto bianco standard.
Ricorda di applicare anche tutte le modifiche al prefabbricato delle piastrelle, in modo che vengano create nuove quando si inizia una nuova partita. Se lo provi, il gioco dovrebbe creare la griglia usando queste nuove tessere invece dei vecchi cubi.
Abbiamo bisogno di un modo per visualizzare un numero in modo che una tessera ci mostri quante mine sono adiacenti ad essa. Un modo semplice per farlo è usando a Testo 3D, che viene fornito con Unity.
Creane uno facendo clic GameObject> Crea altro> Testo 3D, e aggiungilo alla tessera. Dovrebbe sembrare come questo:
Miglioriamolo. Ruota il testo in modo che sia rivolto verso l'alto. Imposta la stringa a cui viene attualmente visualizzata 0
, in modo che sappiamo quale dimensione sarà il testo. Anche adattare il Dimensione del font e Dimensione del testo, in modo che non sembri sfocato.
Grande! Ora dobbiamo essere in grado di accedere al testo 3D nel codice. Aggiungi la seguente variabile al Piastrella
codice:
public var displayText: TextMesh;
Trascina il testo 3D nello slot aperto, in modo che possiamo accedervi tramite codice in seguito.
Ricorda di applicare tutto al prefabbricato delle piastrelle e provalo. Le nuove tessere impiantate dovrebbero ora essere create.
Abbiamo creato una base funzionale per il gioco puzzle, ma non possiamo ancora giocarci. Aggiungeremo quella funzionalità nella seconda parte di questa serie.