Ora che hai creato la base del gameplay, è importante dare al giocatore un feedback visivo quando compie delle azioni, ad esempio:
- Un indicatore di obiettivo che segnala al giocatore dove andare.
- Aggiungere più tempo al conto alla rovescia quando il giocatore segna punti.
- Avviare il gioco solo quando il giocatore entra nel veicolo.
- Rimuovere le pizze extra dal giocatore quando raccoglie un nuovo oggetto, in modo che il giocatore non lasci cadere le pizze sulla mappa.
Completando questo passaggio nel tutorial Prova a tempo: A caccia di pizza, imparerai a perfezionare il gioco.
Mostrare al giocatore la prossima zona di raccolta selezionata
Per aggiungere un indicatore di obiettivo che mostri al giocatore dove andare, attieniti ai passaggi seguenti. Aggiorna il file game_coordinator_device.verse:
- Aggiungi un
objective_marker
modificabile di nomePickupMarker
con lo specificatorepublic
alla classegame_coordinator_device
.@editable PickupMarker<public> : objective_marker = objective_marker{}
- All'inizio della funzione
PickupDeliveryLoop()
, attiva il dispositivo Indicatore mappa associato all'oggettoPickupMarker
e imposta undefer
per disattivare e disabilitare il dispositivo all'uscita della funzione.PickupDeliveryLoop<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(){} <# Esegui il rinvio della disabilitazione del MapIndicator, in modo che la chiusura del PickupDeliveryLoop comporti sempre la disabilitazione dell'indicatore. Defer viene eseguito anche se PickupDeliveryLoop viene annullato. #> defer: if (ValidPlayer := MaybePlayer?): PickupMarker.MapIndicator.DeactivateObjectivePulse(ValidPlayer) PickupMarker.MapIndicator.Disable() PickupMarker.MapIndicator.Enable()
- Quando viene selezionata la zona di raccolta successiva, sposta l'indicatore di raccolta nella zona di raccolta selezionata e chiama
PickupMarker.MapIndicator.ActivateObjectivePulse()
per guidare il giocatore verso di essa.race: loop: if (PickupZone : base_zone = PickupZoneSelectors[PickupLevel].SelectNext[]): PickupZone.ActivateZone() Sleep(0.0) PickupMarker.MoveMarker(PickupZone.GetTransform(), ?OverTime := 0.0) if (ValidPlayer := MaybePlayer?): PickupMarker.MapIndicator.ActivateObjectivePulse(ValidPlayer) <# Questo è l'unico rinvio necessario per ogni PickupZone attivata. Disattiverà la prima PickupZone alla fine di ogni loop esterno, oppure disattiverà qualsiasi PickupZone successiva. Questo avviene perché l'espressione viene valutata alla fine, quando la variabile PickupZone è stata legata a una zona più recente. #> defer: PickupZone.DeactivateZone() PickupZone.ZoneCompletedEvent.Await() Logger.Print("Raccolto", ?Level := log_level.Normal)
Aggiungere più tempo al conto alla rovescia quando il giocatore segna punti
Puoi incoraggiare un giocatore a consegnare più spesso gli oggetti premiandolo con un tempo aggiuntivo per ogni oggetto consegnato.
Per aggiungere più tempo al conto alla rovescia, attieniti ai passaggi seguenti:
- Nel file score_manager.verse, cambia il tipo restituito della funzione
AddPendingScoreToTotalScore()
inint
e aggiungireturn PendingScore
, in modo da poter usare i punti aggiunti al punteggio totale per aggiornare il conto alla rovescia.AddPendingScoreToTotalScore<public>() : int = set TotalGameScore += PendingScore defer: set PendingScore = 0 UpdateUI() return PendingScore
- Nel file game_coordinator_device.verse, aggiungi alla definizione della classe
game_coordinator_device
unfloat
modificabile chiamatoDeliveryBonusSeconds
con lo specificatorepublic
, per rappresentare quanti secondi devono essere aggiunti al timer del conto alla rovescia per ogni punto di cui è stato eseguito il commit alla consegna.# Quanti secondi aggiungere al timer del conto alla rovescia quando viene consegnato un oggetto raccoglibile. @editable DeliveryBonusSeconds<public> : float = 20.0
- Aggiorna l'espressione
block
di consegna per calcolare il tempo di bonus e aggiorna il tempo rimanente sul timer del conto alla rovescia.block: FirstPickupZoneCompletedEvent.Await() if (DeliveryZone := DeliveryZoneSelector.SelectNext[]): DeliveryZone.ActivateZone() # Rinviamo la disattivazione delle zone in modo che l'annullamento di PickupDeliveryLoop finisca per disattivare anche le zone di consegna attive. defer: Logger.Print("Disattivazione della zona di consegna.", ?Level := log_level.Normal) DeliveryZone.DeactivateZone() DeliveryZone.ZoneCompletedEvent.Await() Logger.Print("Consegnato", ?Level := log_level.Normal) PointsCommitted := ScoreManager.AddPendingScoreToTotalScore() BonusTime : float = DeliveryBonusSeconds * PointsCommitted CountdownTimer.AddRemainingTime(BonusTime) else: Logger.Print("DeliveryZone successiva da selezionare non trovata.", ?Level := log_level.Error) return # Errore in uscita dal PickupDeliveryLoop
- Durante il playtest, andare nella zona di consegna dopo aver raccolto una pizza aggiunge più tempo al conto alla rovescia.

Avviare il gioco quando il giocatore entra nel veicolo
Per avviare il gioco quando il giocatore entra nel veicolo e gestirlo quando ne esce, attieniti ai passaggi seguenti:
- Crea un riferimento modificabile al dispositivo Generatore veicoli con lo specificatore
public
.@editable VehicleSpawner<public> : vehicle_spawner_atk_device = vehicle_spawner_atk_device{}
- Crea una funzione denominata
StartGameOnPlayerEntersVehicle()
con gli specificatoriprivate
esuspends
. Questa funzione deve attendere che il giocatore entri nel veicolo prima di chiamareStartGame()
e aggiornare la variabileMaybePlayer
con il riferimento al giocatore entrato nel veicolo. AggiornaOnBegin()
per chiamare questa funzione invece diStartGame()
.OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Vogliamo ricevere una notifica solo la prima volta che il giocatore entra nel veicolo per iniziare la partita. # StartGameOnPlayerEntersVehicle attende l'evento e avvia il loop di gameplay. StartGameOnPlayerEntersVehicle() StartGameOnPlayerEntersVehicle<private>()<suspends> : void = VehiclePlayer := VehicleSpawner.AgentEntersVehicleEvent.Await() Logger.Print("Il giocatore è entrato nel veicolo") set MaybePlayer = option{player[VehiclePlayer]} StartGame()
- Imposta un gestore eventi per il momento in cui il giocatore esce dal veicolo. Crea una funzione denominata
HandlePlayerExitsVehicle()
con lo specificatoreprivate
.OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Dopo essere entrato nel veicolo, il giocatore potrebbe uscirne in qualsiasi momento # vogliamo rilevarlo ogni volta che accade per farlo rientrare nel veicolo. VehicleSpawner.AgentExitsVehicleEvent.Subscribe(HandlePlayerExitsVehicle) # Vogliamo ricevere una notifica solo la prima volta che il giocatore entra nel veicolo per iniziare la partita. # StartGameOnPlayerEntersVehicle attende l'evento e avvia il loop di gameplay. StartGameOnPlayerEntersVehicle() HandlePlayerExitsVehicle<private>(VehiclePlayer : agent) : void = Logger.Print("Il giocatore è uscito dal veicolo. Riassegnazione del giocatore al veicolo") VehicleSpawner.AssignDriver(VehiclePlayer)
Rimozione delle pizze extra
Per rimuovere le pizze extra dal giocatore quando raccoglie un nuovo oggetto, in modo che il giocatore non lasci cadere le pizze sulla mappa, attieniti ai passaggi seguenti:
- Aggiungi un riferimento modificabile al dispositivo Scarta oggetti, responsabile della rimozione delle pizze dall'inventario del giocatore.
@editable PizzaRemover<public> : item_remover_device = item_remover_device{}
- Nella funzione
PickupDeliveryLoop()
, rimuovi le pizze dal giocatore subito dopo che ha raccolto un oggetto.loop: if (PickupZone : base_zone = PickupZones[PickupLevel].SelectNext[]): PickupZone.ActivateZone() Sleep(0.0) PickupMarker.MoveMarker(PickupZone.GetTransform(), ?OverTime := 0.0) if (ValidPlayer := MaybePlayer?): PickupMarker.MapIndicator.ActivateObjectivePulse(ValidPlayer) <# Questo è l'unico rinvio necessario per ogni PickupZone attivata. Disattiverà la prima PickupZone alla fine di ogni loop esterno, oppure disattiverà qualsiasi PickupZone successiva. Questo avviene perché l'espressione viene valutata alla fine, quando la variabile PickupZone è stata legata a una zona più recente. #> defer: PickupZone.DeactivateZone() PickupZone.ZoneCompletedEvent.Await() Logger.Print("Raccolto", ?Level := log_level.Normal) <# Rimuoviamo gli oggetti raccoglibili pizza dall'inventario del giocatore per evitare di impilarli e farli cadere a terra, una volta che la pila è al completo. #> if (RemovingPlayer := MaybePlayer?): PizzaRemover.Remove(RemovingPlayer) # Dopo la prima raccolta, possiamo attivare la zona di consegna. # Aggiorna il livello di raccolta e ScoreManager. if (PickupLevel < MaxPickupLevel): set PickupLevel += 1 else: Logger.Print("PickupZone successiva da selezionare non trovata.", ?Level := log_level.Error) return # Errore in uscita dal PickupDeliveryLoop