Si completas este paso del tutorial Puzle de luces marcadas, aprenderás a detectar cuándo el jugador resuelve el puzle para poder generar un objeto y evitar que se siga interactuando con el puzle
Cómo detectar un puzle resuelto
Esta sección muestra cómo detectar cuándo el jugador resuelve el puzle encontrando la combinación correcta de luces. Cuando se resuelva el puzle, debe activarse el dispositivo Generador de objetos para que pueda generar su objeto.
Sigue estos pasos para detectar cuándo el jugador resuelve el puzle:
- Añade un campo editable
item_spawner_devicellamadoItemSpawnera la clasetagged_lights_puzzlepara representar el dispositivo generador de elementos.@editable ItemSpawner : item_spawner_device = item_spawner_device{} - A continuación, define en qué estado deben estar las luces para resolver el puzle. Dado que la representación del estado de las luces es una matriz
lógica, el estado resuelto de las luces debe ser también una matrizlógicapara compararlos fácilmente. Crea un campo de matrizlógicaeditable llamadoSolvedLightsStatepara la clasetagged_lights_puzzle. En este ejemplo, el jugador debe encender todas las luces para resolver el puzle, 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 actualizar tu dispositivo de Verse en el nivel.
- En el esquematizador, selecciona tagged_lights_puzzle para abrir su panel Detalles.
- En el panel Detalles, establece la propiedad ItemSpawner en el dispositivo Generador de objetos que hay en el nivel.
- A continuación, desarrolla el código que comprueba si
LightsStateactual coincide conSolvedLightsState. Añade un nuevo método nombradoIsPuzzleSolved()a la clasetagged_lights_puzzle. Este método debe tener éxito si el puzle está resuelto y puede fallar si no lo está, para que su invocador sepa el resultado de la comprobación. Esto significa que el método debe marcarse como falible con el especificadordecides. Como el método tiene el especificadordecides, también debe tener el especificadortransacts, lo que significa que las acciones realizadas por este método pueden revertirse (como si nunca se hubieran realizado) si se produce un fallo en cualquier parte del método.IsPuzzleSolved()<decides><transacts> : void = Logger.Print(“Checking if puzzle is solved”)Verse utiliza el mecanismo de éxito/fracaso para la toma de decisiones. Para obtener más información sobre cómo utiliza Verse el fallo, consulta Error.
- ¿Cuándo debe comprobar el dispositivo si se ha resuelto el puzle? El mejor momento es cuando se acaba de actualizar la matriz
LightsState, lo que ocurre dentro del métodoToggleLights(). Una vez que la expresiónfortermina de actualizar la matrizLightsState, llama al métodoIsPuzzleSolved[]para determinar si el puzle está resuelto y así generar un objeto (llamando 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 en función de si se resuelve el puzle.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Encendiendo luz en el índice {LightIndex} {if (IsLightOn?) then "Apagado" else "Encendido"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): Logger.Print("Se ha actualizado el estado de la luz en {LightIndex}") if (IsPuzzleSolved[]): Logger.Print("¡Puzle resuelto!") ItemSpawner.Enable() - A continuación, haz que el método
IsPuzzleSolved()detecte si el puzle está resuelto. ComoIsPuzzleSolved()es un contexto de fallo, puedes utilizar expresiones falibles en el cuerpo del método sin necesidad de utilizar otro contexto de fallo, como una expresiónif. En este caso, tendrás que comprobar si el estado de cada luz es el mismo que el del puzle resuelto. Para comprobar si dos valoreslogicson iguales, puedes utilizar el operador igual=, que es una expresión falible. La primera vez que dos valores que estás comprobando no sean iguales, la expresión fallará, por lo que el método fallará también y volverá al contexto de lo que lo llama (en este caso, la expresiónifdel métodoToggleLights()).IsPuzzleSolved()<decides><transacts> : void = Logger.Print(“Checking if puzzle is solved”) 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 secuencias de comandos de Verse para compilar tu código.
- Haz clic en Jugar en la barra de herramientas de UEFN para poner a prueba el nivel.
Cuando pruebes tu nivel con los ajustes que se muestran en este ejemplo, interactuar con todos los botones una vez debería resolver el puzle y hacer aparecer el objeto.

Cómo eliminar la interacción de los botones cuando el puzle está resuelto
Después de que el jugador haya completado el puzle, no debería poder interactuar con los botones ni encender o apagar las luces. Esta sección muestra cómo anular la suscripción a un evento para que el controlador de eventos deje de ser llamado cuando un jugador interactúa con el botón.
Cuando llamas a Subscribe() en un evento de dispositivo, la llamada a la función tiene un resultado cancellable. Llamar a Cancel() en una variable cancelable anula la suscripción a la función que controla el evento, de modo que ya no se llamará a la función cuando se envíe el evento.
Sigue estos pasos para eliminar las interacciones de los botones una vez resuelto el puzle:
- Añade un campo variable de matriz
cancelablenombradoButtonSubscriptionsa la clasetagged_lights_puzzlepara almacenar el resultado de suscribirse al evento de cada botón, e inicializa el campo con una matriz vacía.var ButtonSubscriptions : []cancelable = array{} - Como esta es la última sentencia de la expresión
for, sus valores devueltos de todas las iteraciones correctas se recopilan en una matriz del tipo de retorno de la expresión. Como ya se ha explicado, el tipo de retorno de una llamada aSubscribea un evento escancelable; esto se refiere a ToggleLights los resultados deforen una matriz de elementoscancelable([]cancelable). Eso coincide con el tipoButtonsSubscription, por lo que puedes asignar el resultado de la expresiónfora la matrizButtonsSubscription. Añade este código en la funciónOnBegin, despué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 estar desactivados para que el jugador ya no pueda cambiar
LightsState. Eso se consigue anulando la suscripción de los controladoresInteractedWithEventde cada botón con una llamada a su suscripcióncancelable. EstosButtonSubscriptionsse guardaron cuando se crearon los controladores de eventos enOnBegin. Lo único que queda por hacer es recorrer esta matriz y llamar a cancelar en cadaButtonSubcription:ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Encendiendo luz en el índice {LightIndex} {if (IsLightOn?) then "Apagado" else "Encendido"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): Logger.Print("Se ha actualizado el estado de la luz en {LightIndex}") if (IsPuzzleSolved[]): Logger.Print("¡Puzle resuelto!") ItemSpawner.Enable() para (ButtonSubscription : ButtonSubscriptions): ButtonSubscription.Cancel() - Guarda los cambios en Visual Studio Code.
- En la barra de herramientas de UEFN, haz clic en Compilar secuencias de comandos de Verse para compilar tu código.
- Haz clic en Jugar en la barra de herramientas de UEFN para poner a prueba el nivel.
Con las propiedades predeterminadas, interactuar con todos los botones una vez debería resolver el puzle, hacer aparecer el objeto y desactivar otras interacciones con los botones.
Siguiente paso
En el último paso de este tutorial, podrás ver la secuencia de comandos completa de este tutorial e ideas para seguir modificando el ejemplo.