Główna rozgrywka jest już gotowa. Teraz ważne, aby udostępnić graczowi wizualne informacje zwrotne, gdy wykonuje określone akcje, na przykład:
Znacznik celu wskazujący graczowi, gdzie się udać.
Zwiększenie wartości na liczniku czasu odliczania, gdy gracz wykona zadanie.
Rozpoczęcie gry dopiero wówczas, gdy gracz wejdzie do pojazdu.
Odebranie graczowi dodatkowej pizzy, gdy podniesie nowy przedmiot, aby gracz nie upuszczał pizzy na mapie.
Wykonując ten krok w samouczku Próba czasu: Pogoń za pizzą (Time Trial: Pizza Pursuit), dowiesz się, jak dopracować grę.
Pokazywanie graczowi następnej wybranej strefy odbioru
Aby dodać znacznik celu, który będzie wskazywał graczowi, gdzie ma się udać, wykonaj następujące instrukcje. Zaktualizuj plik game_coordinator_device.verse:
Dodaj edytowalny element
objective_markero nazwiePickupMarkerzawierający specyfikatorpublicdo klasygame_coordinator_device.@editable PickupMarker<public> : objective_marker = objective_marker{}Na początku funkcji
PickupDeliveryLoop()włącz urządzenie wskaźnika na mapie powiązane z obiektemPickupMarkeri skonfiguruj wyrażeniedefer, aby dezaktywować i wyłączyć urządzenie po zakończeniu funkcji.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(){} <# Opóźnij wyłączenie urządzenia MapIndicator tak, aby zakończenie pętli PickupDeliveryLoop zawsze kończyło się wyłączeniem znacznika. Wyrażenie defer wykonywane jest także w przypadku anulowania pętli PickupDeliveryLoop. #> defer: if (ValidPlayer := MaybePlayer?): PickupMarker.MapIndicator.DeactivateObjectivePulse(ValidPlayer) PickupMarker.MapIndicator.Disable() PickupMarker.MapIndicator.Enable()Po wybraniu kolejnej strefy odbioru przenieś znacznik odbioru do wybranej strefy odbioru i wywołaj funkcję
PickupMarker.MapIndicator.ActivateObjectivePulse(), aby poprowadzić do niej gracza.Verserace: 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) <# This is the only defer we need for any PickupZone we activate. It will either deactivate the first PickupZone at the end of each outer loop,
Zwiększanie wartości na liczniku czasu odliczania, gdy gracz wykona zadanie
Można zachęcić gracza, aby dostarczał przedmioty częściej, nagradzając go przydzieleniem dodatkowego czasu za każdy dostarczony przedmiot.
Postępuj zgodnie z poniższą instrukcją, aby dodać więcej czasu do licznika czasu odliczania:
W pliku score_manager.verse zmień typ wartości zwracanej przez funkcję
AddPendingScoreToTotalScore()nainti dodaj członreturn PendingScore, aby wykorzystać punkty dodane do całkowitego wyniku w celu zaktualizowania licznika czasu odliczania.AddPendingScoreToTotalScore<public>() : int = set TotalGameScore += PendingScore defer: set PendingScore = 0 UpdateUI() return PendingScoreW pliku game_coordinator_device.verse dodaj edytowalną wartość
zmiennopozycyjnąo nazwieDeliveryBonusSecondszawierającą specyfikatorpublicdo definicji klasygame_coordinator_device. Będzie ona odpowiadała liczbie sekund, jaka ma być dodana do licznika czasu odliczania za każdy punkt uzyskany podczas dostarczenia.# Ile sekund dodać do licznika czasu odliczania, gdy odebrany przedmiot zostanie dostarczony. @editable DeliveryBonusSeconds<public> : float = 20.0Zaktualizuj wyrażenie
block, aby obliczyć premię w postaci czasu i zaktualizować czas pozostały na liczniku czasu odliczania.block: FirstPickupZoneCompletedEvent.Await() if (DeliveryZone := DeliveryZoneSelector.SelectNext[]): DeliveryZone.ActivateZone() # Opóźniamy dezaktywację strefy, aby anulowanie pętli PickupDeliveryLoop kończyło się także dezaktywacją każdej aktywnej strefy dostarczania. defer: Logger.Print("Dezaktywacja strefy dostarczania.", ?Level := log_level.Normal) DeliveryZone.DeactivateZone() DeliveryZone.ZoneCompletedEvent.Await() Logger.Print("Dostarczono", ?Level := log_level.Normal) PointsCommitted := ScoreManager.AddPendingScoreToTotalScore() BonusTime : float = DeliveryBonusSeconds * PointsCommitted CountdownTimer.AddRemainingTime(BonusTime) else: Logger.Print("Nie znaleziono następnej strefy DeliveryZone do wybrania.", ?Level := log_level.Error) return # Błąd pętli PickupDeliveryLoopW trakcie testu gry widać, że przejście do strefy dostarczania po odebraniu pizzy zwiększa wartość czasu na liczniku czasu odliczania.
Rozpoczynanie gry, gdy gracz wejdzie do pojazdu
Aby rozpocząć grę dopiero, gdy gracz wejdzie do pojazdu, a także skonfigurować zachowanie, gdy gracz opuści pojazd, wykonaj następujące instrukcje:
Utwórz edytowalne odwołanie do urządzenia generatora pojazdów zawierające specyfikator
public.@editable VehicleSpawner<public> : vehicle_spawner_atk_device = vehicle_spawner_atk_device{}Utwórz funkcję o nazwie
StartGameOnPlayerEntersVehicle()zawierającą specyfikatoryprivateisuspend. Funkcja ta powinna odczekać, aż gracz wejdzie do pojazdu, zanim wywoła funkcjęStartGame(), a także zaktualizować zmiennąMaybePlayero odwołanie do gracza z wejścia do pojazdu. Zaktualizuj metodęOnBegin()tak, aby wywoływała tę funkcję zamiast funkcjiStartGame().OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Chcemy jedynie otrzymać powiadomienie, gdy gracz wejdzie do pojazdu po raz pierwszy, aby rozpocząć grę. # Funkcja StartGameOnPlayerEntersVehicle będzie oczekiwać na to zdarzenie, a następnie uruchomi pętlę rozgrywki. StartGameOnPlayerEntersVehicle() StartGameOnPlayerEntersVehicle<private>()<suspends> : void = VehiclePlayer := VehicleSpawner.AgentEntersVehicleEvent.Await() Logger.Print("Gracz wszedł do pojazdu") set MaybePlayer = option{player[VehiclePlayer]} StartGame()Skonfiguruj procedurę obsługi zdarzeń dla sytuacji, w której gracz opuszcza pojazd. Utwórz funkcję o nazwie
HandlePlayerExitsVehicle()zawierającą specyfikatorprivate.OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Po wejściu do pojazdu gracz może go w dowolnej chwili opuścić. # Chcemy wykrywać każde takie zdarzenie i umieszczać gracza z powrotem w pojeździe. VehicleSpawner.AgentExitsVehicleEvent.Subscribe(HandlePlayerExitsVehicle) # Chcemy jedynie otrzymać powiadomienie, gdy gracz wejdzie do pojazdu po raz pierwszy, aby rozpocząć grę. # Funkcja StartGameOnPlayerEntersVehicle będzie oczekiwać na to zdarzenie, a następnie uruchomi pętlę rozgrywki. StartGameOnPlayerEntersVehicle() HandlePlayerExitsVehicle<private>(VehiclePlayer : agent) : void = Logger.Print("Gracz opuścił pojazd. Ponowne przypisywanie gracza do pojazdu") VehicleSpawner.AssignDriver(VehiclePlayer)
Odbieranie dodatkowej pizzy
Aby odebrać graczowi dodatkowe pizze, gdy podniesie nowy przedmiot, tak aby gracz nie upuszczał pizzy na mapę, wykonaj następujące instrukcje:
Dodaj edytowalne odwołanie do urządzenia usuwacza przedmiotów, które odpowiada za usuwanie pizzy z ekwipunku gracza.
@editable PizzaRemover<public> : item_remover_device = item_remover_device{}W funkcji
PickupDeliveryLoop()usuń pizze z ekwipunku gracza, gdy tylko podniesie przedmiot.Verseloop: 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) <# This is the only defer we need for any PickupZone we activate. It will either deactivate the first PickupZone at the end of each outer loop, or it'll deactivate any later PickupZone. That's because the expression is evaluated at the end, when the PickupZone variable has been bound to a newer zone. #>