Construye un juego de rompecabezas basado en cuadrícula como el buscaminas en Unity Configuración

Los juegos de rompecabezas a menudo tienen lugar en una cuadrícula que contiene mosaicos que tienen comportamientos y propiedades, y reaccionan a las reglas y entradas. En esta serie te mostraré cómo construir una versión simple y básica del clásico juego Buscaminas, que es el ejemplo perfecto para comenzar a crear tus propios juegos de rompecabezas..

Ya sea que esté creando un juego de memoria para niños o un título de estrategia compleja, la implementación de los componentes básicos de Buscaminas es un excelente lugar para comenzar. En la primera parte de esta serie de tutoriales de tres partes, construiremos un campo de juego que luego podrás usar para crear tu propia versión del juego.. 

Necesitarás Unity para esto, y una comprensión básica de ello. (Echa un vistazo a Build Arkanoid With Unity si eres nuevo.) El código fuente se puede descargar, pero no es necesario para completar este tutorial..

Las Reglas del Buscaminas

Buscaminas es un juego de rompecabezas en el que tienes que localizar todas las minas en un campo. El tamaño del campo varía según la dificultad, y puede ir desde 9x9 mosaicos (fácil) a 16x30 azulejos (duro), o cualquier dimensión personalizada..

Al hacer clic en una ficha, se "destapa". Si es una mina, pierdes; si está vacío y al menos una mina está en una de las baldosas limítrofes, aparece un número que muestra el número de minas en las baldosas vecinas. Si no hay minas en las baldosas adyacentes, todas las baldosas adyacentes también están descubiertas.

Una ficha puede marcarse haciendo clic con el botón derecho en ella, colocando una bandera en ella. Una vez que todas las fichas con minas se han marcado correctamente, se gana el juego..

Pruébalo aquí:

Elementos que necesitaremos

A partir de las reglas anteriores, podemos extrapolar los diferentes elementos que necesitará nuestra versión simple de minesweeper. Estos son

  • Una cuadrícula de azulejos.
  • Azulejos que pueden contener una mina.
  • Azulejos con los que se puede interactuar mediante clics del mouse
  • Azulejos que toman en cuenta los azulejos vecinos al reaccionar a los clics del mouse

Construyendo un Azulejo Básico

Crea un nuevo proyecto de Unity. Crear un cubo y nombrarlo Azulejo. Arrástrelo a la carpeta del proyecto para convertirlo en un prefab. Usaremos este mosaico no funcional para construir el campo de juego y luego le agregaremos funcionalidad.

Construyendo el generador de red

Crear un nuevo objeto vacío y nombrarlo Cuadrícula, y convertirlo también en una casa prefabricada. Este será el generador del campo de juego y todas las fichas dentro de él..

Crea un nuevo archivo JS, llámalo Cuadrícula también, y añadirlo a la Cuadrícula objeto. 

Agregue las siguientes líneas al script Grid, para que podamos comenzar a crear un campo:

public var tilePrefab: GameObject; public var numberOfTiles: int = 10; public var distanceBetweenTiles: float = 1.0; función Start () CreateTiles ();  function CreateTiles () 

A continuación, arrastre el prefab Azulejo prefabricado ranura de la Cuadrícula objeto. Debe tener un aspecto como este:

los numberOfTiles La variable le permitirá establecer el número de mosaicos que se crearán. Distancia entre las baldosas Define la distancia entre ellos, para que podamos ajustar el espaciado a nuestro gusto..

En este momento, el generador de red no hace nada. Para hacer que cree varios mosaicos, agregue este código al CreateTiles () función:

var xOffset: float = 0.0; para (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); 

Si ejecuta la escena actual, debería crear una línea de nuestros mosaicos, como este:

La función crea copias del prefab de baldosas (tantas como especificamos) y las coloca en una fila, una distancia de distancia entre los azulejos aparte. Probar algunos valores diferentes para encontrar un buen espaciado.

Pero para el Buscaminas necesitaremos una cuadrícula, no una línea. Para lograr esto, agregue esta variable al comienzo de la Cuadrícula código:

public var tilesPerRow: int = 4;

... y adaptar el CreateTiles () funciona para parecerse a esto:

function CreateTiles () var xOffset: float = 0.0; var zOffset: float = 0.0; para (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);  

Si lo ejecutas, deberías terminar con varias líneas de fichas:

Si configura el  tilesPerRow variable correctamente (como 24 azulejos en 6 filas), el generador debe crear un campo de juego rectangular agradable. Si sus habilidades de programación son lo suficientemente avanzadas, puede intentar averiguar cómo automatizar aún más el proceso. (La versión de Buscaminas que estamos construyendo también funcionará con campos de forma irregular).

Convertir los azulejos en minas

Ahora que podemos crear un campo básico y personalizado de Buscaminas, podemos trabajar en agregarle minas reales..

Crea un nuevo archivo JS, llámalo Azulejo, y añádelo al prefab. Luego, agregue la siguiente variable a ella:

public var isMined: boolean = false;

Esto nos dirá si la baldosa tiene una mina.. 

A continuación, tenemos que poner las minas reales en la red. Para eso, cambia el GameObject Tipo de prefabricado de la baldosa a la nueva Azulejo clase que acabamos de crear.
Cambiar el tilePrefab variable por lo que se ve así:

public var tilePrefab: Tile;

Y luego vuelva a asignar el objeto Tile a esa variable. Ahora puede acceder automáticamente a las variables que colocamos allí desde el principio..

Asignar minas es un poco más complicado. Lo haremos desde el generador de Grid.. 

Primero, tres matrices para sujetar nuestros azulejos al código de cuadrícula:

static var tilesAll: Tile []; estática var tilesMined: Array; static var tilesUnmined: Array;

También necesitamos inicializarlos. Coloca las siguientes líneas al comienzo de la CreateTiles () función:

tilesAll = new Tile [numberOfTiles]; tilesMined = new Array (); tilesUnmined = new Array ();

Luego, cambie el comando de instanciar en el CreateTiles () funciona para parecerse a esto:

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

Ahora agregue este comando al final de la CreateTiles () función para iniciar el AssignMines () proceso:

AssignMines ();

los CreateTiles () La función debería verse así:

function CreateTiles () tilesAll = new Tile [numberOfTiles]; tilesMined = new Array (); tilesUnmined = new Array (); var xOffset: float = 0.0; var zOffset: float = 0.0; para (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(); 

También agrega la función AssignMines (), para que podamos usarlo:

function AssignMines () tilesUnmined = tilesAll; para (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;  

Esto es lo que sucede: cuando se crea un nuevo mosaico en el CreateTiles-función, se añade a la azulejos todo-formación. Todas las fichas allí se copian en el azulejos sin mina-formación. De esta matriz elegimos aleatoriamente una ficha para agregar una mina a. Añadimos una mina a la configuración de la isMined-variable a verdadero, elimínelo de la azulejos sin mina-matriz y agregarlo a la tilesMined-array (que usaremos más adelante). Al final, hemos colocado al azar la cantidad especificada de minas en el campo de juego.

En este momento, una loseta minada no es visiblemente diferente de una baldosa sin minar. El objetivo del juego es resolver eso, después de todo!

En esta versión puedes probar cómo se supone que funciona. Para propósitos de demostración, los azulejos minados aparecen como rojos.

Y voilá: ahora tienes un campo Buscaminas con un tamaño personalizado!

Haciendo los azulejos más interesantes visualmente

En este momento, los azulejos son cubos estándar de Unity. Vamos a convertirlos en reales azulejos.

En los archivos de origen, encontrarás un archivo 3D llamado puzzleObjects.fbx. Cópialo en tu carpeta de activos, para que podamos usarlo en nuestro juego. Asegúrese de que el archivo se importe con su tamaño establecido en 1, para que se ajuste a la configuración que hemos estado usando hasta ahora. 

La configuración de importación del archivo debería verse así:

Luego, vaya a la configuración de la prefab, e intercambie la malla del cubo por la Azulejo Mejorado malla.

Mientras estamos aquí, presione Reiniciar sobre el Box Collider Componente de la baldosa. Esto hará que el colisionador se ajuste de nuevo alrededor de la baldosa.

Finalmente, dale un nuevo material a la baldosa para que no tenga el aspecto blanco estándar.

Recuerda aplicar todos los cambios al prefab de baldosas también, para que los nuevos se creen cuando comenzamos un nuevo juego. Si lo intentas, el juego debería crear la cuadrícula utilizando estos nuevos mosaicos en lugar de los cubos antiguos..

Agregar una pantalla de número a los azulejos

Necesitamos una forma de mostrar un número para que una ficha nos muestre cuántas minas están adyacentes a ella. Una forma sencilla de lograr esto es utilizando un Texto 3D, que viene con la unidad.

Crea uno haciendo clic GameObject> Crear otro> Texto 3D, y añadirlo a la baldosa. Debe tener un aspecto como este:

Vamos a mejorar eso. Gire el texto para que quede hacia arriba. Establece la cadena que muestra actualmente 0, para que sepamos de qué tamaño será el texto. También adaptar el Tamaño de fuente y Tamano del texto, para que no se vea borroso.

¡Genial! Ahora necesitamos poder acceder al texto 3D en código. Agregue la siguiente variable a la Azulejo código:

public var displayText: TextMesh;

Arrastre el texto 3D a la ranura abierta, para que podamos acceder a él a través del código más adelante.

Recuerda aplicar todo en el prefab, y pruébalo. Las nuevas e importadas baldosas ahora deben ser creadas..

Conclusión

Hemos creado una base funcional para nuestro juego de rompecabezas, pero aún no podemos jugarlo. Agregaremos esa funcionalidad en la segunda parte de esta serie..