Haga un juego de Match 3 en Construct 2 Points, Matching, and Gravity

En el tutorial anterior, integramos un sistema básico de detección de coincidencias en nuestro juego Match-3. Si bien estamos en el buen camino para tener un juego jugable, todavía hay algunos elementos importantes del juego que necesitamos antes de que podamos realmente llamar a lo que tenemos un "juego". Este artículo se centrará en completar algunos de los detalles que faltan y nos acercará mucho más a nuestro producto final..


Demostración final del juego

Aquí está una demostración del juego en el que estamos trabajando a lo largo de esta serie:




1. Puntos de adjudicación

Vamos a cubrir los puntos antes de comenzar a mejorar el sistema de coincidencia, ya que será mucho más fácil ver el primer problema en nuestro sistema de coincidencia actual si tenemos un sistema de puntos implementado.

El sistema de puntos en nuestro juego será muy simple, por cada Bloque utilizado para formar un grupo determinado, el jugador recibirá 10 puntos. En un tutorial posterior también agregaremos un sistema que le permita al jugador ganar más puntos al encadenar varios grupos, pero por ahora nos enfocaremos en solo introducir un sistema de puntos simple para el jugador..

Antes de comenzar a editar los eventos, debemos agregar una pantalla de Puntos, así que primero vaya a Diseño 1 y haz lo siguiente:

  1. Insertar un nuevo Duende objeto.
    1. Abre la imagen Imágenes del campo de juego / ScoreArea.png del paquete gráfico.
    2. Cerrar el editor de animacion.
    3. Establezca la posición en 491, 383.
  2. Insertar un nuevo Texto objeto.
    1. Selecciona el Fuente a Calibri, Negrita, 22 usando el desplegable.
    2. Selecciona el Nombre a ScoreText
    3. Selecciona el Color a Blanco o 255, 255, 255
    4. Selecciona el Posición a 419, 398.
    5. Selecciona el tamaño a 200, 50.
    6. Selecciona el Texto a 0.

Diseño 1 Ahora debería verse así:

Ahora que tenemos algo para decirle al jugador lo que significa el texto de los puntos, y un objeto de texto para mostrar la puntuación del jugador, podemos pasar a darle puntos al jugador. Ir Hoja de evento 1 y crea un nuevo Variable global.

Nombre de variable global: Tipo de "puntaje" = Valor de número = 0

La variable debería verse así:

Esta es la variable que modificaremos cuando le demos puntos al jugador. A continuación, crearemos una nueva función que, cuando sea llamada, detectará cuántos Bloques ha combinado el jugador en grupos y les dará el número de puntos adecuado..

Evento: Condición: Función> En Nombre de la función = "GivePoints" Condición: Sistema> Para cada objeto = Condición del bloque: Bloque> Es el conjunto de variables de la instancia booleana Instancia Variable = IsMatched Acción: Sistema> Agregar a la variable = Valor de puntuación = 10 Acción: ScoreText > Set text Text = Score

Tu código debería verse así:

Entonces, para reiterar, este evento analiza cada Bloque. Cada vez que encuentra un Bloque que tiene Ismatched ajustado a cierto - lo que significa que se ha confirmado que forma parte de un grupo: le otorga al jugador 10 puntos por ese Bloque y actualiza el texto de la puntuación.

Si prueba su juego en este punto, parecerá que la función no está funcionando. La razón de esto es que en realidad no hemos llamado a la función en ninguna parte del código, por lo que los puntos nunca se incrementan y el texto nunca se actualiza. Ir a tu FindMatches función y agregar una nueva acción al comienzo del sub-evento final para esta función.

Acción: Función> Nombre de la función de llamada = "GivePoints"

Tu FindMatches La función ahora debería verse así:

Nota: asegúrese de haber agregado esta nueva Acción al comienzo del Sub-evento. Si agrega esta Acción al final, no funcionará ya que todos los Bloques emparejados se habrán destruido antes de la GivePoints se llama funcion Esto significa que, cuando busque los Bloques coincidentes, no encontrará ninguno y, por lo tanto, el jugador no recibirá ningún punto..

En este punto, puedes probar tu juego de nuevo y deberías ver la actualización del texto de los puntos, y que el jugador está recibiendo la cantidad correcta de puntos por cada partida que realice..


2. Mejorar la detección de partidos.

Ahora que tenemos el sistema de puntos, quiero que ejecute el juego y cree el escenario que se muestra a continuación..


Ahora intercambia los Bloques que he resaltado aquí, y observa tu puntuación para ver cuántos puntos ganas.


Cuando formaste este partido, deberías haber visto que ganaste 50 puntos. Esto se debe a que, actualmente, el sistema de puntos le da al jugador 10 puntos por cada Bloque que está marcado como Ismatched, En lugar de darle al jugador 10 puntos por cada Bloque. usado En cada partido, como el sistema que describí anteriormente..

Si el sistema de puntos funcionara correctamente, le daría al jugador 60 puntos: 30 para el grupo vertical de tres Bloques y 30 para el grupo horizontal de tres Bloques. Este problema se debe al hecho de que el sistema de emparejamiento no tiene ninguna forma de marcar cuando un Bloque se empareja tanto horizontalmente y verticalmente Solo se sabe si el Bloque está emparejado..

Para resolver este problema primero vamos a agregar dos nuevos Variables de instancia a nuestro objeto Bloque, MatchedX y Emparejado.

Variable de instancia: Nombre = Tipo MatchedX = Valor inicial booleano = falso Variable de instancia: Nombre = Tipo coincidenteY = Valor inicial booleano = falso

Sus variables deben verse así:


Estas variables se van a utilizar junto con Ismatched para indicar al sistema cuando el Bloque es parte de grupos horizontales, o X, y cuando el Bloque es parte de grupos verticales, o Y, Ahora que tenemos las variables, vamos a modificar la CheckMatches función para que cuando se etiqueta un bloque Ismatched porque encontró un grupo lo suficientemente grande, también etiquetará ese Bloque como parte de un grupo X o Y dependiendo de si el Parámetro 3 o el Parámetro 4 es 1.

Ve a la CheckMatches funciona y reemplaza el original NumMatchesFound Consulta con estos dos nuevos sub-eventos:

Subevento: Condición: Sistema> Comparar dos valores Primer valor = Función.Param (3) Comparación = Igual al segundo valor = 1 Condición: Sistema> Comparar variable Variable = NumMatchesFound Comparación = Mayor o igual Valor = 3 Acción: Bloque> Establecer Variable de instancia booleana = Valor de IsMatched = Acción verdadera: Bloque> Establecer variable de instancia booleana = Valor de MatchedX = Sub-evento verdadero: Condición: Sistema> Comparar dos valores Primer valor = Función.Param (4) Comparación = Igual a Segundo valor = 1 Condición : Sistema> Comparar variable Variable = NumMatchesFound Comparison = Mayor o igual Valor = 3 Acción: Bloque> Establecer variable de instancia booleana = IsMatched Valor = Verdadera acción: Bloquear> Establecer variable de instancia booleana = Valor coincidenteY = Verdadero

Tu CheckMatches La función ahora debería verse así:


Así que la nueva versión de CheckMatches funciona de la misma manera que la anterior, excepto que ahora también verifica si se encontró que el Bloque es una coincidencia en un grupo vertical o en un grupo horizontal, y etiqueta el Bloque en consecuencia con las nuevas variables MatchedX y Emparejado.

Otorgar puntos extra a los bloques que coinciden dos veces

Ahora que tenemos una manera de determinar cuándo un Bloque se empareja verticalmente, se empareja horizontalmente y se empareja en ambas direcciones, en lugar de saber que se ha emparejado en un grupo, debemos agregar un sub-evento a la GivePoints función que distribuirá 10 puntos extra para un Bloque que tenga ambos MatchedX y Emparejado establecer en verdadero.

Ve a la GivePoints Funciona y agrega este sub-evento:

Subevento: Condición: Bloque> Es el conjunto de variables de la instancia booleana Instancia variable = MatchedX Condición: Bloque> Es el conjunto de variables de la instancia booleana Variable de la instancia = EmparejadoY Acción: Sistema> Agregar a la variable = Valor de la puntuación = 10 Acción: Texto> Establecer el valor del texto = Puntuación

Tu GivePoints La función ahora debería verse así:


Si ejecutas tu juego y nuevamente creas el escenario que ilustré arriba, tu puntaje ahora debería aumentar correctamente en 60 puntos.


3. Agregando gravedad

Ahora que hemos implementado un sistema de Puntos, y hemos actualizado el sistema de emparejamiento, comenzaremos a mejorar otro aspecto importante del juego. Si has pasado algún tiempo jugando con el juego hasta este punto, sabrás que uno de los mayores problemas es que cuando se destruyen los Bloques, no pasa nada sobre los Bloques que están sobre ellos. Específicamente, los bloques sobre los espacios vacíos no caen para llenar esos espacios.

Esto está bien en las pruebas, pero en la versión final sería perjudicial para el juego dejar las cosas como están, por lo que lo siguiente que vamos a agregar es la "gravedad" que hará que los Bloques se caigan y se llenen. espacios vacíos cuando otros bloques son destruidos.

La forma en que implementaremos este sistema es bastante simple. Realizaremos un control utilizando el Bloque> Se superpone en el desplazamiento evento para ver si hay un Bloque debajo del Bloque que estamos viendo. Si encontramos que no hay Bloque, moveremos el Bloque que estamos viendo hacia abajo para llenar el espacio vacío; de lo contrario, no haremos nada.

Para hacer este trabajo crearemos un nuevo evento:

Evento: Condición: INVERTIDO> Bloque> Se superpone en el desplazamiento Objeto = Bloque Desplazamiento X = 0 Desplazamiento Y = 8 Acción: Bloque> Mover en ángulo Ángulo = 90 Distancia = (Bloque.Ancho + 2) / 2

Tu código debería verse así:


Si ejecutas el juego en este momento, verás que en el momento en que comienza el juego, ¡todos los bloques se caen de la pantalla! La razón de esto es porque no pusimos nada en el código para decirle dónde estaría el "piso" del campo de juego.

Esencialmente, los Bloques en la fila inferior se dan cuenta de que no hay Bloques debajo de ellos y caen en consecuencia. Luego, una vez que la fila más baja de Bloques ha caído, la siguiente fila más baja ve que ahora no hay Bloques debajo de ellos, y también caen. Este proceso continúa, hasta que todos los Bloques se han caído, y deja la pantalla completamente vacía..

Puede ver una versión ligeramente más lenta de esto en acción en el GIF a continuación:


Para solucionar esto, agregaremos una segunda condición al Evento..

Evento: Condición: Bloque> Comparar Comparación de Y = menor o igual Y = SPAWNY - 1

Tu código ahora debería verse así:


Al agregar esta nueva condición, nos aseguramos de que solo los Bloques que están por encima de la posición Y de la fila más baja se vean afectados por nuestra "gravedad". A pesar de esta solución, todavía tenemos algunos problemas..

Tratar con el arrastre

El problema principal es que el evento que se ve para ver si hay un espacio vacío debajo de un Bloque no tiene nada que le indique que esté inactivo cuando el jugador está arrastrando un Bloque. Esto significa que, si arrastra un Bloque demasiado lejos sin soltarlo, los Bloques en la posición por encima de donde lo arrastró caerán en el espacio dejado por el Bloque que arrastró. Además de eso, el Bloque que estás arrastrando también tendrá un problema si lo sacas del campo de juego, y comenzará a alejarse del cursor del mouse ya que no hay Bloques debajo de él..

Para solucionar este problema, debemos agregar una nueva variable global para indicar al sistema cuando estamos moviendo un Bloque, una nueva acción para los eventos de arrastrar y soltar del Bloque para establecer esta variable global y una tercera condición para el evento de gravedad, por lo que es necesario esta variable en cuenta antes de activar.

Primero, hagamos la variable global:

Variable global: Nombre = BlockBeingMoved Tipo = Número Valor inicial = 0

Tu variable debería verse así:


Ahora, ve a la En DragDrop arrastrar inicio evento y añadir una nueva acción:

Acción: Sistema> Establecer valor Variable = BlockBeingMoved Value = 1

También, ve a la En la gota DragDrop evento y agregar una nueva acción al evento principal:

Acción: Sistema> Establecer valor Variable = BlockBeingMoved Value = 0

Con las líneas agregadas, sus eventos DragDrop ahora deberían verse así:


Finalmente, vaya al evento de gravedad y agregue una nueva condición:

Condición: Sistema> Comparar Variable Variable = BlockBeingMoved Comparación = Igual a Valor = 0

Tu código de gravedad ahora debería verse así:


La nueva variable que creamos., BlockBeingMoved, se utiliza para indicar al sistema cuando el Jugador mueve un Bloque. Si la variable es igual a 0 significa que no se está moviendo ningún Bloque y puede ejecutar los scripts de gravedad de forma normal. Si la variable es igual a 1, significa un bloque es ser movido, y los scripts de gravedad no deben ser ejecutados.

Si ejecuta el juego en este punto, verá que no importa dónde mueva el Bloque mientras lo arrastra, no se producen problemas..

Comprobando nuevos partidos

Ahora solo tenemos un último problema con el sistema de gravedad. Ejecuta el juego y crea un escenario similar a este:


Ahora, haz el intercambio que he resaltado en la siguiente imagen..


Debes notar que cuando el grupo de Green / Star Blocks se destruye, un Orange / Hexagon Block cae y forma un grupo de tres Bloques, pero no se destruye..

La razón por la que estos Bloques no se destruyen es porque nunca llamamos al FindMatches funciona una segunda vez para ver si se formaron nuevas coincidencias cuando los Bloques cayeron para llenar los espacios vacíos. Para solucionarlo, vaya al Evento que verifica los espacios vacíos debajo de Bloques y agregue este Evento Else:

Evento: Condición: Sistema> Otra acción: Función> Nombre de la función de llamada = "FindMatches"

Tu código debería verse así:


Esta declaración de lo contrario significa que, siempre que encuentre que no hay espacios vacíos, realizará una verificación para ver si hay grupos para destruir. Este evento se ejecutará automáticamente cada vez que los Bloques caen en nuevas posiciones, ya que se activa mediante una instrucción Else que está vinculada a esa comprobación, y solo se activará una vez que esté seguro de que todos los Bloques han encajado..

Si ejecutas el juego en este punto, verás que ahora puedes crear cadenas de Bloques destruyendo Bloques de forma que se formen grupos cuando caigan los Bloques restantes. Además de eso, también encontrarás que cuando comiences el juego por primera vez, cualquier grupo que se genere inicialmente también será destruido. Como dije en el tutorial anterior, eventualmente eliminaremos las coincidencias prefabricadas, por lo que este problema no importará al final.

Eliminar bloques de la disposición inicial

Finalmente, tenemos que hacer otra cosa antes de que podamos considerar que nuestro sistema de gravedad está completo. Dependiendo de dónde colocó el sprite de Bloque inicial cuando completó el primer tutorial, puede notar que cuando comienza el juego cae y se hace visible..

Si no sabes lo que quiero decir, ve a Diseño 1, establece la posición de tu sprite Block en 521, -32, y ejecuta el juego. Cuando juegues, deberías ver el Bloqueo original en la posición que he resaltado en la siguiente imagen:


Como puede ver en la imagen de arriba, el Bloque inicial cae de su posición fuera de la pantalla y se hace visible. No queremos esto porque solo nos causará problemas más adelante. Para resolver este pequeño problema vamos a agregar una acción a la Al inicio del diseño. Evento que destruirá cualquier bloque que esté en el diseño cuando se cargue inicialmente..

Acción: Bloquear> Destruir.

Tu evento ahora debería verse así:


Ahora cuando ejecutas el juego, ya no deberías ver el Bloque. Es posible que se esté preguntando por qué no eliminamos el bloqueo del diseño para que no tengamos que preocuparnos por este problema. La razón por la que no hicimos esto es porque Construct 2 no puede crear copias de ningún tipo de objeto con Eventos, a menos que ya haya una instancia de ese tipo de Objeto en el juego cuando se carga por primera vez. Al eliminarlo dentro de un evento, lo eliminamos para que no se convierta en un problema más adelante, y hacemos posible generar tantos Bloques como sea necesario a través del código.


Conclusión

Cubrimos muchos temas en este tutorial, y aunque hay más que podríamos hacer, creo que es importante tomar un descanso y dejar que esta información se hunda. En la próxima entrega, arreglaremos un par de pequeños problemas. El elegante texto de puntos flotantes que podría haber notado está en la demostración final y configura el sistema de encadenamiento.

Espero que hayas sacado mucho partido a esta parte de la serie, y te veré aquí la próxima semana..