Completando questo passaggio del tutorial Prova a tempo: A caccia di pizza, imparerai a gestire il punteggio quando un giocatore raccoglie e consegna gli oggetti e ad aggiornare la UI per visualizzare i punteggi. Per saperne di più sulla creazione di una UI di gioco in Verse, vedi Creare una UI in gioco.
Gestione punteggio terrà traccia e visualizzerà:
Punti totali: rappresenta i punti totali che il giocatore ha totalizzato nel gioco.
Punti in sospeso: rappresenta i punti accumulati dal giocatore per la serie attuale di oggetti raccoglibili.
Livello di raccolta: rappresenta il livello di raccolta attuale.
Creazione della UI
Per creare l'interfaccia utente di gestione punteggio in Verse, attieniti ai passaggi seguenti:
Crea un nuovo file vuoto di Verse e nominalo score_manager.verse.
Crea una nuova classe denominata
score_managere aggiungi i seguenti campi alla classe:Un
agenteopzionale denominatoMaybePlayerper memorizzare un riferimento al giocatore.MaybePlayer<internal> : ?agent = falseUn
player_uiopzionale denominatoMaybePlayerUIper memorizzare un riferimento alla UI del giocatore.MaybePlayerUI<internal> : ?player_ui = falseScore_manager_deviceper memorizzare un riferimento per il dispositivo Gestione punteggio attorno al quale è costruita questa classe. (Nota: non si tratta di un riferimento modificabile, perché deve essere collegato al dispositivo creato da Versegame_coordinator_device.ScoreManagerDevice<internal> : score_manager_device = score_manager_device{}Variabile intera denominata
TotalGameScoreche rappresenta tutti i punti che il giocatore ha totalizzato complessivamente nella partita.var TotalGameScore<private> : int = 0Variabile intera denominata
PendingScoreche rappresenta i punti che il giocatore ha attualmente accumulato per questa serie di oggetti raccoglibili.var PendingScore<private> : int = 0Una variabile intera denominata
PickupLevelche rappresenta il livello di raccolta attuale.var PickupLevel<private> : int = 0
La definizione della tua classe score_manager dovrebbe ora essere simile a:
score_manager := class: MaybePlayer<internal> : ?agent = false MaybePlayerUI<internal> : ?player_ui = false ScoreManagerDevice<internal> : score_manager_device = score_manager_device{} var TotalGameScore<private> : int = 0 var PendingScore<private> : int = 0 var PickupLevel<private> : int = 0Crea l'interfaccia utente quando la classe viene creata per la prima volta. Puoi farlo aggiungendo un'espressione
blockalla definizione della classe, che verrà eseguita ogni volta che crei un'istanza della classe. Per generare l'interfaccia utente, aggiungi le seguenti variabili:Variabile
canvasdenominataCanvasche ha lo specificatoreinternalper memorizzare il widget canvas personalizzato.var Canvas<internal> : canvas = canvas{}Un
text_blockdenominatoTotalGameScoreWidgetche ha lo specificatoreinternal, per memorizzare il widget di testo per la visualizzazione di tutti i punti che il giocatore ha totalizzato complessivamente nella partita, come rappresentato dalla variabileTotalGameScore. Imposta su bianco il colore predefinito del testo del blocco di testo.TotalGameScoreWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White}Un
text_blockdenominatoPendingScoreWidgetche ha lo specificatoreinternal, per memorizzare il widget di testo per la visualizzazione dei punti che il giocatore ha attualmente accumulato per questa serie di oggetti raccoglibili, come rappresentato dalla variabilePendingScore. Imposta su bianco il colore predefinito del testo del blocco di testo.PendingScoreWidget<internal> : text_block = text_block{}Un
text_blockdenominatoPickupLevelWidgetche ha lo specificatoreinternal, per memorizzare il widget di testo per la visualizzazione del livello di raccolta corrente, come rappresentato dalla variabilePickupLevel. Imposta su bianco il colore predefinito del testo del blocco di testo.PickupLevelWidget<internal> : text_block = text_block{}Funzione che restituisce un
messagedenominatoTotalGameScoreTextche crea un testo localizzabile che può essere visualizzato nella UI per i punti complessivi che il giocatore ha totalizzato nel gioco.TotalGameScoreText<localizes>(CurrentTotalGameScore : int) : message = "Punti totali: {CurrentTotalGameScore}"Funzione che restituisce un
messagedenominatoPendingScoreTextche crea un testo localizzabile che può essere visualizzato nella UI per i punti che il giocatore ha attualmente accumulato per questa serie di oggetti raccoglibili.PendingScoreText<localizes>(CurrentPendingScore : int) : message = "Punti in sospeso: {CurrentPendingScore}"Funzione che restituisce un
messagedenominatoPickupLevelTextche crea un testo localizzabile che può essere visualizzato nella UI per il livello di raccolta corrente.PickupLevelText<localizes>(CurrentPickupLevel : int) : message = "Livello di raccolta: {CurrentPickupLevel}"Aggiungi un'espressione
blockche crei il widget canvas e posizioni il testo impilato verticalmente sulla sinistra dello schermo.<# Poiché non ricreeremo il canvas nella durata della gestione punteggio, esegui questa operazione una volta, ogni momento che viene creato un oggetto di questo tipo. #> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.25}, Maximum := vector2{X := 0.0, Y := 0.25} } Offsets := margin{Top := 0.0, Left := 25.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.0, Y := 0.0} SizeToContent := true Widget := stack_box: Orientation := orientation.Vertical Slots := array: stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := TotalGameScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PendingScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PickupLevelWidget
Il codice per
score_managerdovrebbe ora essere simile al seguente:using { /UnrealEngine.com/Temporary/UI } using { /Fortnite.com/UI } using { /Verse.org/Colors } score_manager := class: var Canvas<internal> : canvas = canvas{} TotalGameScoreWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White} PendingScoreWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White} PickupLevelWidget<internal> : text_block = text_block{DefaultTextColor := NamedColors.White} MaybePlayer<internal> : ?agent = false MaybePlayerUI<internal> : ?player_ui = false ScoreManagerDevice<internal> : score_manager_device = score_manager_device{} PickupLevelText<private><localizes>(InLevel : int) : message = "Livello di raccolta: {InLevel}" PendingScoreText<private><localizes>(InPoints : int) : message = "Punti in sospeso: {InPoints}" TotalGameScoreText<private><localizes>(InPoints : int) : message = "Punti totali: {InPoints}" var TotalGameScore<private> : int = 0 var PendingScore<private> : int = 0 var PickupLevel<private> : int = 0 <# Poiché non ricreeremo il canvas nella durata della gestione punteggio, esegui questa operazione una volta, ogni momento che viene creato un oggetto di questo tipo. #> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.25}, Maximum := vector2{X := 0.0, Y := 0.25} } Offsets := margin{Top := 0.0, Left := 25.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.0, Y := 0.0} SizeToContent := true Widget := stack_box: Orientation := orientation.Vertical Slots := array: stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := TotalGameScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PendingScoreWidget stack_box_slot: HorizontalAlignment := horizontal_alignment.Left Widget := PickupLevelWidgetCrea una funzione denominata
UpdateUI()che abbia lo specificatoreprivateche aggiorna il testo della UI con i valori di punteggio più recenti e il livello di raccolta attuale.UpdateUI()<private>: void = if (PlayerUI := MaybePlayerUI?): PickupLevelWidget.SetText(PickupLevelText(PickupLevel)) PendingScoreWidget.SetText(PendingScoreText(PendingScore)) PendingScoreWidget.SetText(TotalGameScoreText(TotalGameScore))Crea una funzione denominata
AddScoreManagerToUI()che aggiorni la UI del giocatore con quella della gestione punteggio personalizzata.AddScoreManagerToUI<public>() : void = if (PlayerUI := MaybePlayerUI?): PlayerUI.AddWidget(Canvas) UpdateUI()Crea una funzione per ogni valore visualizzato nell'interfaccia utente, in modo che il loop di gioco possa aggiornare i valori seguenti:
Funzione denominata
AddPendingScoreToTotalScore()che ha lo specificatorepublic. Questa funzione deve aggiungere il punteggio in sospeso al punteggio totale della partita e reimpostare il valore del punteggio in sospeso a0. Puoi eseguire ildeferdella reimpostazione diPendingScoree dell'aggiornamento della UI una volta aggiornatoTotalGameScore. In questo modo si evita di utilizzare una variabile temporanea per mantenere il valore diPendingScoreprima che si reimposti.Verse<# Adds PendingScore to TotalGameScore and resets PendingScore to 0.#> AddPendingScoreToTotalScore<public>() : void = defer: set PendingScore = 0 UpdateUI() set TotalGameScore += PendingScoreFunzione denominata
UpdatePendingScore()che ha lo specificatorepublice un parametro intero denominatoPoints, che la funzione aggiungerà al punteggio in sospeso corrente.Verse<# Adds the given amount of points to the pending points. #> UpdatePendingScore<public>(Points : int) : void = set PendingScore += Points UpdateUI()Funzione denominata
UpdatePickupLevelche ha lo specificatorepublice un parametro intero denominatoLevel, corrispondente al nuovo valore per il livello di raccolta attuale.VerseUpdatePickupLevel<public>(Level : int) : void = set PickupLevel = Level UpdateUI()Crea una funzione denominata
AwardScore()che abbia lo specificatorepublic. Questa funzione assegna il punteggio al giocatore che utilizza il dispositivo Gestione punteggio, eseguendone l'attivazione.Verse<# Awards the score to the player with the Score Manager device, by activating it. #> AwardScore<public>() : void = ScoreManagerDevice.SetScoreAward(TotalGameScore) if (AwardedPlayer := MaybePlayer?): ScoreManagerDevice.Activate(AwardedPlayer)
La classe
score_managerdovrebbe ora essere simile alla seguente:Versescore_manager := class: <# Since we won't recreate the canvas during the score manager lifetime, do it once anytime an object of this type is created.> block: set Canvas = canvas: Slots := array: canvas_slot: Anchors := anchors{Minimum := vector2{X := 0.0, Y := 0.25}, Maximum := vector2{X := 0.0, Y := 0.25} } Offsets := margin{Top := 0.0, Left := 25.0, Right := 0.0, Bottom := 0.0} Alignment := vector2{X := 0.0, Y := 0.0} SizeToContent := trueOra che hai creato la classe
score_manager, crea un costruttore della classe per inizializzare le variabili del giocatore dal gioco. Tieni presente che devi eseguire il type cast del riferimento al giocatore daagentaplayer, per ottenere un riferimento alla UI del giocatore.VerseMakeScoreManager<constructor><public>(InPlayer : agent, InScoreManagerDevice : score_manager_device) := score_manager: MaybePlayer := option{InPlayer} MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}Il file score_manager.verse dovrebbe ora essere simile al seguente:
Verseusing { /UnrealEngine.com/Temporary/SpatialMath} using { /UnrealEngine.com/Temporary/UI } using { /Fortnite.com/Devices } using { /Fortnite.com/UI } using { /Verse.org/Colors } using { /Verse.org/Simulation } MakeScoreManager<constructor><public>(InPlayer : agent, InScoreManagerDevice : score_manager_device) := score_manager: MaybePlayer := option{InPlayer} MaybePlayerUI := option{GetPlayerUI[player[InPlayer]]}
Aggiornamento del punteggio e della UI nel loop di gioco
Per creare e aggiornare la UI durante la partita nel file game_coordinator_device.verse, segui questi passaggi:
Aggiungi le seguenti proprietà alla classe
game_coordinator_device:Variabile
score_managerdenominataScoreManagerche ha lo specificatoreprivate. Questa istanza gestisce il punteggio e l'interfaccia utente del giocatore.var ScoreManager<private> : score_manager = score_manager{}Score_manager_devicemodificabile che puoi impostare sul dispositivo Gestione punteggio nel livello. È il dispositivo che utilizzerà la classescore_manager.@editable ScoreManagerDevice<public> : score_manager_device = score_manager_device{}Array di interi modificabili denominato
PointsForPickupLevelche ha lo specificatorepublicper definire i punti che il giocatore può totalizzare per ciascun livello di raccolta.@editable # Esegue la mappatura di quanti punti vale un oggetto raccoglibile, in base al suo livello di raccolta. PointsForPickupLevel<public> : []int = array{1, 2, 3}
Nella funzione
StartGame, inizializza la variabile di gestione punteggio chiamando il costruttoreMakeScoreManager()con un riferimento al giocatore e al dispositivo Gestione punteggio e genera la UI visibile al giocatore.VerseStartGame<private>()<suspends> : void = Logger.Print("Trying to start the game...") # We construct a new countdown_timer that'll countdown from InitialCountdownTime once started. # Also construct a new score_manager that'll keep track of the player's score and pickup level. # The countdown_timer and score_manager require a player to show their UI to. # We should have a valid player by now: the one that entered the vehicle, triggering the game start. if (ValidPlayer := MaybePlayer?): Logger.Print("Valid player, starting game...")Nella funzione
PickupDeliveryLoop()del loop di gioco, aggiorna la UI ogni volta che il livello di raccolta cambia e il giocatore termina una raccolta o una consegna:VersePickupDeliveryLoop<private>()<suspends> : void = PickupZonesTags : []pickup_zone_tag = array{pickup_zone_level_1_tag{}, pickup_zone_level_2_tag{}, pickup_zone_level_3_tag{}} MaxPickupLevel := PickupZonesTags.Length - 1 FirstPickupZoneCompletedEvent := event(){} loop: var PickupLevel : int = 0 var IsFirstPickup : logic = true # Every time the loop restarts, we should reset the pickup level UI through the ScoreManager.A questo punto, al termine del conto alla rovescia, assegna al giocatore il suo punteggio. In
HandleCountdownEnd(), chiamaScoreManager.AwardScore().HandleCountdownEnd<private>(InPlayer : player)<suspends>:void= TotalTime := CountdownTimer.CountdownEndedEvent.Await() ScoreManager.AwardScore() EndGame.Activate(InPlayer)Il file game_coordinator_device.verse dovrebbe ora essere simile al seguente:
Verseusing { /Verse.org/Simulation } using { /Fortnite.com/Devices } using { /Fortnite.com/Vehicles } using { /Fortnite.com/Characters } using { /Fortnite.com/Playspaces } using { /Verse.org/Random } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath } using { /EpicGames.com/Temporary/Curves } using { /Verse.org/Simulation/Tags }