Bygg et gridbasert puslespill som minesveiper i enhet oppsett

Puslespill finner ofte sted på et rutenett som inneholder fliser som har oppførsel og egenskaper, og reagerer på regler og innganger. I denne serien vil jeg vise deg hvordan du bygger en enkel, grunnleggende versjon av det klassiske spillet Minesweeper, som er det perfekte eksempelet for å starte fra for å lage dine egne puslespill.

Enten du lager et barns minne spill eller en kompleks strategitittel, implementerer de grunnleggende byggeblokkene til Minesweeper et flott sted å starte. I den første delen av denne tredelte opplæringsserien bygger vi et spillfelt som du kan bruke til å lage din egen versjon av spillet. 

Du trenger Unity for dette, og en grunnleggende forståelse for det. (Sjekk ut Bygg Arkanoid With Unity hvis du er ny på det.) Kildekoden kan lastes ned, men er ikke nødvendig for å fullføre denne opplæringen.

Regler for Minesweeper

Minesweeper er et puslespill der du må finne alle gruvene i et felt. Feltstørrelsen varierer med vanskeligheter, og kan variere fra 9x9 fliser (enkelt) til 16x30 fliser (hardt), eller noen tilpassede dimensjoner.

Ved å klikke på en flis du "avdekke" den. Hvis det er en gruve, mister du; Hvis det er tomt og minst en gruve er i en av de tilgrensende fliser, vises et nummer som viser antall gruver i naboblader. Hvis det ikke er gruver i de tilstøtende fliser, blir alle tilstøtende fliser også avdekket.

En flis kan markeres ved å høyreklikke på den og dermed sette et flagg på den. Når alle fliser med gruver er merket riktig, blir spillet vunnet.

Prøv det her:

Elementer vi trenger

Fra reglene ovenfor kan vi ekstrapolere de forskjellige elementene som vår enkle versjon av minesveger vil trenge. Disse er

  • Et flis av fliser
  • Fliser som kan inneholde en gruve
  • Fliser som kan interagere med via museklikk
  • Fliser som tar hensyn til nabobilder når de reagerer på museklikk

Bygg en grunnleggende flis

Opprett et nytt Unity-prosjekt. Lag en kube og navnet på den Tile. Dra den over til prosjektmappen for å gjøre den til en prefab. Vi bruker denne ikke-funksjonelle flisen til å bygge spillefeltet, og deretter legge til funksjonalitet til den.

Bygger gridgeneratoren

Opprett et nytt, tomt objekt og oppgi navnet Nett, og slå den til en prefab også. Dette vil være generatoren av spillfeltet og alle fliser i den.

Opprett en ny JS-fil, navn den Nett også, og legg det til Nett gjenstand. 

Legg til følgende linjer i grid-skriptet, slik at vi kan begynne å lage et felt:

offentlig var tilePrefab: GameObject; offentlig var numberOfTiles: int = 10; offentlig var avstandBetweenTiles: float = 1.0; funksjon Start () CreateTiles ();  funksjon CreateTiles () 

Deretter dra Tile prefab på Tile Prefab slot av Nett gjenstand. Det skal se slik ut:

De numberOfTiles variabel vil tillate deg å angi antall fliser som skal opprettes. DistanceBetweenTiles definerer avstanden mellom dem, slik at vi kan justere avstanden etter vår smak.

Rutenettet gjør ikke noe nå. For å få den til å skape flere fliser, legg til denne koden CreateTiles () funksjon:

var xOffset: float = 0.0; for (var fliserBesatt: int = 0; fliser < numberOfTiles; tilesCreated += 1)  xOffset += distanceBetweenTiles; Instantiate(tilePrefab, Vector3(transform.position.x + xOffset, transform.position.y, transform.position.z), transform.rotation); 

Hvis du kjører den nåværende scenen, bør den lage en linje av fliser, slik:

Funksjonen skaper kopier av flis prefab-så mange som vi spesifiserte - og plasserer dem på rad, en avstand på distanceBetweenTiles fra hverandre. Prøv noen forskjellige verdier for å finne en god avstand.

Men for Minesweeper trenger vi et rutenett, ikke en linje. For å oppnå det, legg til denne variabelen i begynnelsen av Nett kode:

offentlige var fliserPerRow: int = 4;

... og tilpasse CreateTiles () funksjon for å se slik ut:

funksjon CreateTiles () var xOffset: float = 0.0; var zOffset: float = 0.0; for (var fliserBesatt: int = 0; fliser < 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);  

Hvis du kjører det, bør du ende opp med flere fliser:

Hvis du setter inn  tilesPerRow variabel riktig (som 24 fliser i 6 rader), generatoren bør skape en fin rektangulær lekeplass. Hvis programmeringsevnen din er avansert nok, kan du prøve å finne ut hvordan du videre automatiserer prosessen. (Den versjon av Minesweeper vi bygger vil også fungere med uregelmessig formede felt.)

Snu fliser i miner

Nå som vi kan lage et grunnleggende, tilpasset Minesweeper-felt, kan vi jobbe med å legge til faktiske miner på den.

Opprett en ny JS-fil, navn den Tile, og legg det til flisens prefab. Deretter legger du til følgende variabel for den:

offentlig var isMined: boolean = false;

Dette vil fortelle oss om flisen har en gruve i den. 

Deretter må vi legge de faktiske gruvene i rutenettet. For det, endre GameObject type flis prefab til den nye Tile klasse vi nettopp opprettet.
Endre tilePrefab variabel slik at den ser slik ut:

offentlig var tilePrefab: Tile;

Og deretter tilordne Tile-objektet igjen til den variabelen. Nå kan den automatisk få tilgang til variablene vi legger inn der fra starten.

Tildeling av gruver er litt vanskeligere. Vi gjør dette fra gridgeneratoren. 

For det første tre arrays å holde fliser til Grid-koden:

statiske varfliserAll: Tile []; statiske var fliserMined: Array; statiske var fliser Utryddet: Array;

Vi må også initialisere dem. Sett følgende linjer i begynnelsen av CreateTiles () funksjon:

fliseneAll = ny flis [numberOfTiles]; fliserMined = new Array (); tilesUnmined = new Array ();

Endre deretter kommandoen instantiate i CreateTiles () funksjon for å se slik ut:

var newTile = Instantiate (tilePrefab, Vector3 (transform.position.x + xOffset, transform.position.y, transform.position.z + zOffset), transform.rotation); fliserAlle [fliser tilberedt] = newTile;

Legg nå denne kommandoen på slutten av CreateTiles () funksjon for å starte AssignMines () prosess:

AssignMines ();

De CreateTiles () funksjonen skal se slik ut:

funksjon CreateTiles () tilesAll = new Tile [numberOfTiles]; fliserMined = new Array (); tilesUnmined = new Array (); var xOffset: float = 0.0; var zOffset: float = 0.0; for (var fliserBesatt: int = 0; fliser < 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(); 

Legg også til funksjonen AssignMines (), slik at vi faktisk kan bruke den:

funksjon 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;  

Her er hva som skjer: Når en ny flis er opprettet i CreateTiles-funksjon, er det lagt til tilesAll-array. Alle fliser der inne kopieres deretter inn i tilesUnmined-array. Fra denne gruppen valgte vi tilfeldig en flis til å legge til en gruve til. Vi legger til en gruve ved å sette inn isMined-variabel til sann, fjern den fra tilesUnmined-array og legg det til tilesMined-array (som vi vil bruke senere). Til slutt har vi tilfeldig plassert den angitte mengden gruver på spillefeltet.

Akkurat nå er en gruvtegning ikke synlig forskjellig fra en unmined flis. Målet med spillet er å finne ut det, tross alt!

I denne bygningen kan du teste ut hvordan det skal fungere. For demonstrasjonsformål vises gruvefliser som røde.

Og voilá: Du har nå et Minesweeper-felt med en egendefinert størrelse!

Gjør flisene mer visuelt interessante

Akkurat nå er fliser standard Unity-kuber. La oss gjøre dem til virkelige fliser.

I kildefilene finner du en 3D-fil som heter puzzleObjects.fbx. Kopier det inn i aktivmappen din, slik at vi kan bruke den i vårt spill. Kontroller at filen er importert med sin størrelse satt til 1, slik at den passer med innstillingene vi har brukt hittil. 

Importinnstillingene for filen skal se slik ut:

Deretter går innstillingene til flisen prefab, og bytt ut kubenettet for tileImproved maske.

Mens vi er her, trykker du på tilbakestilleBox Collider komponent av flisen. Dette vil gjøre at collideren passer tett rundt flisene igjen.

Til slutt, gi flisen et nytt materiale, så det har ikke den vanlige hvite utseendet.

Husk å bruke alle endringene i flis-prefab også, slik at nye blir opprettet når vi starter et nytt spill. Hvis du prøver det, bør spillet lage rutenettet ved å bruke disse nye fliser i stedet for de gamle kubene.

Legge til en tallvisning til flisene

Vi trenger en måte å vise et nummer på for at en flis skal vise oss hvor mange gruver som er tilstøtende med det. En enkel måte å oppnå dette på er å bruke en 3D-tekst, som følger med enhet.

Opprett en ved å klikke GameObject> Opprett annet> 3D-tekst, og legg det til flisen. Det skal se slik ut:

La oss forbedre det. Roter teksten slik at den vender oppover. Angi strengen som den for øyeblikket viser til 0, slik at vi vet hvilken størrelse teksten vil være. Tilpass også Skriftstørrelse og Tekststørrelse, slik at det ikke ser uklart ut.

Flott! Nå må vi kunne få tilgang til 3D-teksten i koden. Legg til følgende variabel i Tile kode:

offentlig var displayText: TextMesh;

Dra 3D-teksten på den åpne sporet, slik at vi får tilgang til den via kode senere.

Husk å bruke alt til flis prefab, og prøv det ut. De nye og imporvede fliser bør nå opprettes.

Konklusjon

Vi har skapt et funksjonelt grunnlag for ut puslespill, men kan faktisk ikke spille det enda. Vi legger til den funksjonaliteten i den andre delen av denne serien.