Nesta última etapa do tutorial Enigma de Luzes Marcadas, você encontrará o script completo para o enigma e ideias para mudar ainda mais o exemplo.
O script completo
O código a seguir é o script completo para um enigma reutilizável que exige que o jogador encontre a combinação certa de luzes alternando seu estado com botões.
~~~(verse) using { /Fortnite.com/Devices } using { /Verse.org/Native } using { /UnrealEngine.com/Temporary/Diagnostics } using { /Verse.org/Simulation/Tags } using { /Verse.org/Simulation }
Derive da classe tag no módulo Verse.org/Simulation/Tags para criar uma nova tag de jogabilidade.
puzzle_light := class(tag){}
log_tagged_lights_puzzle := class(log_channel){}
<#
Você pode usar uma instância dessa classe para assinar o
InteractedWithEvent de um button_device e ter acesso às propriedades por evento (nesse caso, Indices e PuzzleDevice) no seu manipulador de eventos.
Imagine isso como se cada botão tivesse seu estado pessoal e manipulador de eventos.
Como a classe não tem o especificador
>
button_event_handler := class(): # Posições usadas para acessar as luzes que este botão controla. Indices : []int
# tagged_lights_puzzle que criou este button_event_handler para que possamos chamar funções nele. PuzzleDevice : tagged_lights_puzzle
OnButtonPressed(InPlayer : agent) : void = # Diga a PuzzleDevice para alternar as luzes nas posições que este botão controla. PuzzleDevice.ToggleLights(Indices)
tagged_lights_puzzle := class
# Botões que o jogador usa para interagir com o enigma. @editable Buttons : []button_device = array{}
<# O número de elementos em ButtonsToLights deve corresponder ao número de elementos em Buttons. Cada matriz de índices com índice zero descreve quais luzes o botão em Buttons[x] alterna (em que 'x' é o índice do botão). Por exemplo, Buttons[2] alterna a primeira e a segunda luz, conforme especificado pela matriz{0,1}. #> ButtonsToLights : [][]int = array{array{0, 3}, array{0, 1, 2}, array{0, 1}, array{1}}
<# A matriz lógica LightsState é usada para acompanhar o estado aceso/apagado de todas as luzes. Também é usada para definir o estado inicial das luzes, portanto, seu número de elementos deve corresponder ao número de luzes marcadas com a tag puzzle_light. #> @editable var LightsState : []logic = array{false, false, false, false}
<# O enigma é resolvido quando LightsState corresponde a SolvedLightsState. Isso significa que SolvedLightsState deve ter o mesmo número de elementos que LightsState. #> @editable SolvedLightsState : []logic = array{true, true, true, true}
@editable # Este ItemSpawner é habilitado quando o enigma é resolvido. ItemSpawner : item_spawner_device = item_spawner_device{}
# Mantém as luzes encontradas nas etiquetas de jogo. var Lights : []customizable_light_device = array{}
# Mantém os manipuladores para InteractedWithEvent de cada botão para permitir o cancelamento da assinatura do evento assim que o enigma for resolvido. var ButtonSubscriptions : []cancelable = array{}
OnBegin
<# Para cada botão e seu índice, se tiver valores LightsIndices válidos, criar um novo button_event_handler com os índices que ele usa e uma referência a esse tagged_light_puzzle (Self). Use a função OnButtonPressed do manipulador para assinar o InteractedWithEvent do botão. Salve essas assinaturas na matriz ButtonSubscriptions para cancelar a assinatura mais tarde, para que o jogador não possa interagir com o enigma depois de solucionado. #> set ButtonSubscriptions = for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: Button.InteractedWithEvent.Subscribe(button_event_handler{Indices := LightIndices, PuzzleDevice := Self}.OnButtonPressed)
SetupPuzzleLights() : void = # Lembre-se de que os dispositivos não têm nenhuma ordem específica garantida quando recuperados por meio de etiquetas de jogo. TaggedActors := GetCreativeObjectsWithTag(puzzle_light{}) <# Para cada ator com a tag puzzle_light, verifique se é um customize_light_device tentando lançá-lo para esse tipo. Se for, obtenha seu LightState inicial para TurnOn() ou TurnOff() LightDevice. Salve todos os customize_light_device marcados na matriz Lights. #> set Lights = for: ActorIndex -> TaggedActor : TaggedActors LightDevice := customizable_light_device[TaggedActor] ShouldLightBeOn := LightsState[ActorIndex] do: Logger.Print("Adicionando luz no índice {ActorIndex} com State:{if (ShouldLightBeOn?) then "On" else "Off"}")
if (ShouldLightBeOn?) then LightDevice.TurnOn() else LightDevice.TurnOff()
LightDevice # A última instrução de uma expressão é seu valor de resultado. As expressões for retornam todos os valores em uma matriz.
ToggleLights(LightIndices : []int) : void = <# Para cada índice, obtenha o LightState correspondente e a referência ao dispositivo Light. Se ambos forem válidos, determine IsLightOn a partir do LightState atual (se on->off ; se off->on) e defina o LighsState[Index] correspondente como IsLightOn. #> for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: <# Para negar um valor booleano no Verse: if (MyLogic?) {false} else {true} Aqui, também apaga - TurnOff() - ou acende - TurnOn() - a luz antes de retornar o valor negado. #> Logger.Print("Acendendo a luz no índice {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): # A indexação da matriz pode falhar e, portanto, ela deve ser agrupada em um contexto de falha. Logger.Print("Estado da luz atualizado em {LightIndex}")
# LightsState pode ter mudado, então verifique se o enigma foi resolvido. if (IsPuzzleSolved[]): Logger.Print("Quebra-cabeça resolvido!")
ItemSpawner.Enable()
# Retirar a assinatura/Cancelar todos os manipuladores de eventos para que o jogador não possa mais alternar as luzes. for (ButtonSubscription : ButtonSubscriptions): ButtonSubscription.Cancel()
<#
Uma função com o efeito if (IsPuzzleSolved[]).
Observe a chamada de função com [] em vez de () para chamadas de função com falhas.
#>
IsPuzzleSolved()for falhar, a função falhará, e
a falha chegará ao chamador.
Caso contrário, a função será bem-sucedida.
#>
for:
LightIndex -> IsLightOn : LightsState
IsLightOnInSolution := SolvedLightsState[LightIndex]
do:
IsLightOn = IsLightOnInSolution
~~~
Por conta própria
Ao concluir este tutorial, você aprendeu como criar um enigma reutilizável usando o Verse que exige que o jogador encontre a combinação certa de luzes alternando seu estado com botões.
Usando o que você aprendeu, tente o seguinte:
- Crie mais tags e use-as para controlar as luzes com uma ordem visual determinística.
- Use diferentes condições e soluções iniciais e adicione mais botões e luzes para criar mais enigmas com a mesma configuração.
- Controle vários tipos de dispositivos com vários tipos de dispositivos interativos do usuário.