Dans cette étape du tutoriel Créer un jeu de casse-tête avec séquences de lumières balisées, vous allez apprendre à activer/désactiver un groupe de lumières en fonction du bouton avec lequel le joueur interagit.
Activer/désactiver des lumières
Vous devez créer un mappage entre un bouton et le groupe de lumières qu'il doit activer ou désactiver lorsque le joueur interagit avec le bouton. Pour ce faire, vous pouvez mapper chaque bouton sur les index des lumières dans la matrice Lights.
Dans cet exemple, nous utilisons le mappage suivant entre les boutons et les lumières :
- Le bouton 1 est mappé sur la lumière à l'index 0 et sur la lumière à l'index 3.
- Le bouton 2 est mappé sur la lumière à l'index 0, sur la lumière à l'index 1 et sur la lumière à l'index 2.
- Le bouton 3 est mappé sur la lumière à l'index 0 et sur la lumière à l'index 1.
- Le bouton 4 est mappé sur la lumière à l'index 1.
Vous pouvez représenter ce mappage avec une matrice nommée ButtonsToLights, où chaque élément de ButtonsToLights est une autre matrice contenant les index des lumières. Le type de ButtonsToLights est alors [][]int, pour spécifier que ButtonsToLights est une matrice de matrice de nombres entiers.
| Index | 0 | 1 | 2 | 3 |
| Élément | array{0, 3} | array{0, 1, 2} | array{0, 1} | array{1} |
Procédez comme suit pour activer/désactiver les lumières :
- Créez une matrice de matrices de nombres entiers nommée
ButtonsToLightset initialisez-la avec le mappage des index bouton/lumière décrit dans le tableau ci-dessus.ButtonsToLights : [][]int = array{array{0, 3}, array{0, 1, 2}, array{0, 1}, array{1}}Les index d'une matrice sont compris entre 0 et le nombre d'éléments, moins 1. Ainsi, le premier élément de
ButtonsToLightscommence à l'index 0 et le dernier élément à l'index 3. - Ajoutez une méthode appelée
ToggleLights()à la classetagged_lights_puzzle. Cette méthode bascule les lumières de la matriceLightsen fonction des index fournis à la fonction sous forme de matrice de nombres entiers (pour les mettre en correspondance avec les éléments de la matriceButtonsToLights) et met à jour les éléments aux mêmes index dansLightsState.- Ajoutez le paramètre
LightIndices : []intà la méthodeToggleLights(), et affichez chaque index dans le journal de sortie en utilisant l'expressionfor.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices do: Logger.Print("Toggling light at {LightIndex}") - Appelez
ToggleLights()dansOnBegin()pour tester la méthode à mesure que vous la créez. Utilisez le premier élément deButtonsToLightscomme test. L'indexation dans une matrice étant une expression faillible, vous devrez accéder à la matrice à partir d'un contexte d'échec. Dans cet exemple, nous utilisons l'expressionifpour le contexte d'échec.
OnBegin<override>()<suspends> : void = SetupPuzzleLights() # Utilisez le premier élément de ButtonsToLights pour tester la méthode ToggleLights if (LightIndices : []int = ButtonsToLights[0]): ToggleLights(LightIndices) - Ajoutez le paramètre
- Maintenant que vous disposez du
LightIndex, accédez aux matricesLightsetLightsStateà cet index pour obtenir la référence de l'appareil Lumière personnalisable et son état actuel. "Basculer une lumière" signifie que si la lumière est allumée, vous l'éteignez, et inversement. Mettez à jour l'instruction d'affichage pour indiquer quel sera le nouvel état de la lumière.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices Light := Lights[LightIndex] IsLightOn := LightsState[LightIndex] do: Logger.Print("Turning light at {LightIndex} {if (IsLightOn?) then "Off" else "On"}") - Maintenant, actualisez l'état de l'appareil Lumière personnalisable à la fois dans le jeu et dans la matrice
LightsState.- Appelez
TurnOn()sur la lumière siIsLightOnestfalseetTurnOff()siIsLightOnesttrue. La dernière expression d'un bloc de code correspond au résultat ; par conséquent, définirfalseoutruecomme dernière expression signifie que cette valeur est stockée dansNewLightState.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices Light := Lights[LightIndex] IsLightOn := LightsState[LightIndex] do: Logger.Print("Turning light at {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true - Mettez à jour l'élément
LighsStatede l'indexLightIndexselon la valeur deNewLightState. Dans la mesure où l'indexation de la matrice est une expression faillible, la configuration deLightsStatedoit être englobée dans un contexte d'échec. Dans cet exemple, le contexte d'échec est l'expressionif. Indiquez dans le journal de sortie que l'état a été modifié.ToggleLights(LightIndices : []int) : void = for: LightIndex : LightIndices IsLightOn := LightsState[LightIndex] Light := Lights[LightIndex] do: Logger.Print("Turning light at {LightIndex} {if (IsLightOn?) then "Off" else "On"}") NewLightState := if (IsLightOn?): Light.TurnOff() false else: Light.TurnOn() true if (set LightsState[LightIndex] = NewLightState): Logger.Print("Updated the state for light at {LightIndex}")
Il est conseillé de mettre à jour le journal de sortie lorsque vous utilisez des contextes d'échec. Si une expression échoue dans un contexte d'échec, toutes les modifications apportées dans le contexte d'échec sont annulées, comme si elles n'avaient jamais eu lieu. Si vous mettez à jour le journal de sortie, vous pouvez vérifier que la modification a été effectuée si le texte apparaît dans le journal de sortie, sans compter uniquement sur l'état du jeu pour vérifier si la modification a réussi.
- Appelez
Relier l'appui sur des boutons à l'activation/la désactivation des lumières
Maintenant que vous avez défini comment activer/désactiver les lumières, l'étape suivante consiste à relier l'appui sur les boutons à l'activation/désactivation des lumières.
Pour cela, vous pouvez vous abonner à l'événement InteractedWithEvent du bouton. Consultez la rubrique Interactions des appareils de codage, pour plus d'informations sur la souscription à l'événement.
L'événement InteractedWithEvent attend un gestionnaire d'événements avec un paramètre InPlayer : agent et un type de retour void, mais le gestionnaire d'événements doit également savoir à quelles lumières est connecté le bouton ayant envoyé l'événement et contenir une référence à votre appareil Verse tagged_lights_puzzle pour pouvoir appeler sa méthode ToggleLights().
Vous pouvez regrouper toutes ces informations dans un objet personnalisé en créant une nouvelle classe qui contient les index et la fonction à laquelle s'abonner. De cette façon, chaque bouton a son propre état et son propre gestionnaire d'événements, représentés par cette nouvelle classe.
Procédez comme suit pour créer un objet personnalisé pour la gestion des événements :
- Créez une nouvelle classe nommée
button_event_handler. La définition de classe doit contenir les éléments suivants :- Une matrice de nombres entiers nommée
Indices. - Un champ
tagged_lights_puzzlenomméPuzzleDevice, qui référence votre appareil Verse, afin que vous puissiez appeler la méthodeToggleLights(). - Une méthode appelée
OnButtonPressed()avec le paramètreInPlayer : agentet un type de retourvoid, qui appelle la méthodeToggleLights()surPuzzleDevice.button_event_handler := class(): # Positions utilisées pour accéder aux lumières que ce bouton contrôle. Indices : []int # tagged_lights_puzzle ayant créé ce button_event_handler afin de pouvoir appeler des fonctions dessus. PuzzleDevice : tagged_lights_puzzle OnButtonPressed(InPlayer : agent) : void = # Demandez à PuzzleDevice d'activer/de désactiver les lumières aux positions que ce bouton contrôle. PuzzleDevice.ToggleLights(Indices)
- Une matrice de nombres entiers nommée
- Créez un champ de matrice
button_devicemodifiable dans la classetagged_lights_puzzlepour référencer les boutons avec lesquels le joueur peut interagir :@editable Buttons : []button_device = array{} - Maintenant, mettez à jour
OnBegin()dans la classetagged_lights_puzzlepour créer une instancebutton_event_handlerpour chaque bouton. L'instance button_event_handler doit disposer des informations suivantes :- Les index des lumières associées au bouton, que vous pouvez obtenir auprès de la matrice
ButtonsToLightsen utilisant l'index de bouton fourni par l'expressionfor. Vous pouvez l'obtenir comme condition de filtre de l'expressionforutilisée pour itérer tous les boutons. Il fait également office de garde-fou pour empêcher le code d'indexer des données non valides ; si l'indexation échoue, le programme reste valide, car cette itération défaillante est ignorée (cet échec peut se produire si vous avez oublié de mettre en correspondance le nombre deButtonsToLightsavec le nombre deButtons). - Une référence à votre appareil Verse, l'instance de
tagged_lights_puzzle. Pour obtenir une référence à l'objet actuel depuis l'intérieur d'une définition de classe, vous pouvez utiliserSelf. - La création d'un objet
button_event_handleravec ces données ressemble à ce qui suit :OnBegin<override>()<suspends> : void = SetupPuzzleLights() for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: button_event_handler{Indices := LightIndices, PuzzleDevice := Self}
- Les index des lumières associées au bouton, que vous pouvez obtenir auprès de la matrice
- Vous pouvez à présent utiliser la fonction
OnButtonPressed()du gestionnaire nouvellement créé pour vous abonner à l'événementInteractedWithEventde l'appareil Bouton. Lorsque la fonctionOnButtonPressed()est appelée, vous avez accès aux index des lumières et à une référence à l'appareiltagged_lights_puzzleassocié au bouton avec lequel le joueur a interagi.OnBegin<override>()<suspends> : void = SetupPuzzleLights() for: ButtonIndex -> Button : Buttons LightIndices := ButtonsToLights[ButtonIndex] do: Button.InteractedWithEvent.Subscribe(button_event_handler{Indices := LightIndices, PuzzleDevice := Self}.OnButtonPressed) - Enregistrez le script dans Visual Studio Code.
- Dans la barre d'outils de l'UEFN, cliquez sur Générer les scripts Verse pour mettre à jour votre appareil Verse dans le niveau avec votre nouveau code.
- Dans l'Organiseur, sélectionnez l'appareil tagged_lights_puzzle pour ouvrir le panneau Détails correspondant.
- Dans le panneau Détails, ajoutez quatre éléments à la matrice
Buttonset attribuez un bouton différent à chacun d'eux. Vous n'avez pas besoin de modifier les autres propriétés, car le script les renseigne automatiquement. - Cliquez sur Jouer dans la barre d'outils de l'UEFN pour tester le niveau.
Lorsque vous testez votre niveau, vous devez être en mesure d'interagir avec les boutons, et chaque bouton doit activer/désactiver un ensemble différent de lumières en fonction de la configuration de ButtonsLightsIndices. Remarque : dans la mesure où GetCreativeObjectsWithTag() ne garantit pas un ordre spécifique, il est possible que les lumières activées/désactivées en fonction de l'ordre dans le script ne correspondent pas à l'ordre que vous voyez dans le niveau.

Étape suivante
Dans l'étape suivante de ce tutoriel, vous apprendrez à détecter le moment où le joueur résout le casse-tête afin de faire apparaître un objet et d'empêcher toute autre interaction avec le jeu.