Al completar este paso del tutorial Puzzle de luces etiquetadas, aprenderás cómo detectar cuando el jugador resuelve el puzzle para generar un elemento e impedir más interacciones con el puzzle.
Detectar el puzzle resuelto
Esta sección muestra cómo detectar cuando el jugador resuelve el puzzle al encontrar la combinación correcta de luces. Al resolver el puzzle, el dispositivo generador de elementos debería habilitarse para que genere su elemento.
Realiza lo siguiente para detectar cuando el jugador resuelve el puzzle:
- Añade un campo
item_spawner_deviceeditable denominadoItemSpawnera la clasetagged_lights_puzzlepara representar el dispositivo generador de objetos.@editable ItemSpawner : item_spawner_device = item_spawner_device{} - A continuación, define en qué estado deben estar las luces para resolver el puzzle. Dado que la representación del estado de las luces es una matriz
logic(lógica), el estado resuelto de las luces también debe ser una matrizlogicpara compararlas fácilmente. Crea un campo de matrizlogiceditable denominadoSolvedLightsStateen la clasetagged_lights_puzzle. En este ejemplo, el jugador debe encender todas las luces para resolver el puzzle, así que inicializa cada elemento con el valortruepara representar que la luz está encendida.@editable SolvedLightsState : []logic = array{true, true, true, true} - Guarda el archivo en Visual Studio Code.
- En la barra de herramientas de UEFN, haz clic en Compilar scripts de Verse para actalizar el dispositivo de Verse en el nivel.
- En el esquematizador, selecciona tagged_lights_puzzle para abrir su panel Detalles.
- En el panel Detalles, define la propiedad Generador de elemento al dispositivo generador de elementos que está en el nivel.
- A continuación, desarrolla el código que comprueba si el estado
LightsStateactual coincide conSolvedLightsState. Añade un nuevo método denominadoIsPuzzleSolved()a la clasetagged_lights_puzzle. Este método debería ejecutarse correctamente si el puzzle se resolvió y generar error si no se resolvió, para notificar el resultado de la comprobación a su llamador. Esto significa que debe marcarse el método como falible con el especificadordecides. Como el método tiene el especificadordecides, también debe tener el especificadortransacts; es decir, las acciones que realice el método pueden revertirse (como si nunca se hubieran realizado) si existe un fracaso en algún punto del método.IsPuzzleSolved()<decides><transacts> : void = Logger.Print(“Verificando si se resolvió el puzzle”)Verse usa éxito / fracaso para tomar decisiones. Si deseas obtener más información acerca de cómo Verse usa el fracaso, consulta Fracaso.
- ¿Cuándo debería el dispositivo comprobar si se ha resuelto el puzzle? El mejor momento es siempre que el array
LightsStatese haya actualizado; esto ocurre dentro del métodoToggleLights(). Una vez que la expresiónforfinaliza la actualización del arrayLightsState, llama al métodoIsPuzzleSolved[]para determinar si se ha resuelto el puzzle para generar un elemento (mediante un llamado aItemSpawner.Enable()). ComoIsPuzzleSolved[]es una expresión falible (por eso el método tiene[]en lugar de()cuando lo llamas) debe llamarse en un contexto de fallo. En este ejemplo, el contexto de fallo es una expresiónifpara que puedas ejecutar condicionalmente expresiones basadas en si se resolvió el puzzle o no.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Cambiando estado de luz en {LightIndex} {if (IsLightOn?) entonces "Apagar" else "Encender"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): Logger.Print("Se actualizó el estado de la luz en {LightIndex}") if (IsPuzzleSolved[]): Logger.Print("¡Puzzle resuelto!") ItemSpawner.Enable() - A continuación, haz que el método
IsPuzzleSolved()detecte si se resolvió el puzzle. ComoIsPuzzleSolved()es un contexto de fracaso, puedes usar expresiones falibles en el cuerpo del método sin necesidad de usar otro contexto de fracaso, como una expresiónif. En este caso, necesitarás comprobar si el estado de cada una de las luces es el mismo que el estado de puzzle resuelto. Para probar si dos valoreslogic(lógicos) son iguales, puedes usar el operador de igualdad=, que es una expresión falible. La primera vez que los dos valores que estás comprobando no sean iguales, la expresión generará error, por lo tanto, el método no se ejecutará correctamente y volverá al contexto de su llamador (en este caso, la expresiónifen el métodoToggleLights()).IsPuzzleSolved()<decides><transacts> : void = Logger.Print(“Verificando si se resolvió el puzzle”) for: LightIndex -> IsLightOn : LightsState IsLightOnInSolution := SolvedLightsState[LightIndex] do: IsLightOn = IsLightOnInSolution - Guarda los cambios en Visual Studio Code.
- En la barra de herramientas de UEFN, haz clic en Compilar scripts de Verse para compilar tu código.
- Haz clic en Jugar en la barra de herramientas de UEFN para realizar una prueba de juego del nivel.
Cuando pruebas el set de juego con la configuración que se muestra en este ejemplo, interactuar con todos los botones una vez debería resolver el puzzle y generar el elemento.

Eliminar la interacción con los botones cuando se resuelve el puzzle
Cuando el jugador completa el puzzle, no debería poder interactuar con los botones ni encender y apagar las luces. Esta sección muestra cómo desuscribir de un evento para que ya no se llame a su controlador cuando el jugador interactúa con el botón.
Cuando llamas a Subscribe() en un evento de dispositivo, la llamada a función tiene un resultado cancelable. Cuando se llama a Cancel()en una variable cancelable, desuscribe la función que controla el evento, de manera que ya no se llamará a la función cuando se despache el evento.
Realiza lo siguiente para eliminar las interacciones con los botones después de que se ha resuelto el puzzle:
- Añade un campo de variable de matriz
cancelabledenominadoButtonSubscriptionsa la clasetagged_lights_puzzlepara almacenar el resultado de la suscripción al evento de cada botón y, a continuación, inicializa el campo con una matriz vacía.var ButtonSubscriptions : []cancelable = array{} - Como esta es la última declaración de la expresión
for, sus valores de devolución para todas las iteraciones exitosas se recopilan en una matriz del tipo devolución de expresión. Como se explicó anteriormente, el tipo de devolución de una llamadaSuscribea un evento escancelable; esto refiere ToggleLights a los resultadosforde una matriz decancelable([]cancelable). Esto coincide con el tipoButtonsSubscriptionpor lo que puedes asignar el resultado de la expresiónfora la matrizButtonsSubscription. Añade este código a la funciónOnBegindespués deSetupPuzzleLights:OnBegin<override>()<suspends> : void = SetupPuzzleLights() set ButtonSubscriptions = for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: Button.InteractedWithEvent.Subscribe(button_event_handler{Indices := LightIndices, PuzzleDevice := Self}.OnButtonPressed) - Por último, recuerda que los botones deben deshabilitarse para que el jugador no pueda cambiar más
LightsState. Para lograr esto, hay que cancelar la suscripción a los controladoresInteractedWithEventde cada botón con una llamada a su suscripcióncancelable. EstasButtonSubscriptionsse guardaron cuando se crearon los controladores de evento enOnBegin. Todo lo que queda por hacer es iterar a través de esta matriz y llamar a la función de cancelar en cadaButtonSubcription:ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Cambiando estado de luz en {LightIndex} {if (IsLightOn?) entonces "Apagar" else "Encender"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): Logger.Print("Se actualizó el estado de la luz en {LightIndex}") if (IsPuzzleSolved[]): Logger.Print("¡Puzzle resuelto!") ItemSpawner.Enable() for (ButtonSubscription : ButtonSubscriptions): ButtonSubscription.Cancel() - Guarda los cambios en Visual Studio Code.
- En la barra de herramientas de UEFN, haz clic en Compilar scripts de Verse para compilar tu código.
- Haz clic en Jugar en la barra de herramientas de UEFN para realizar una prueba de juego del nivel.
Con las propiedades predeterminadas, interactuar con todos los botones una vez debería resolver el puzzle, generar el elemento y deshabilitar interacciones futuras.
Próximo paso
En el último paso de este tutorial, podrás ver la secuencia de comandos completa e ideas para cambiar el ejemplo.