Ahora que tienes la jugabilidad central, es importante ofrecer al jugador comentarios visuales cuando realice acciones como la siguiente:
Un marcador de objetivo que muestra al jugador a dónde ir.
Añadir más tiempo a la cuenta regresiva cuando el jugador anota puntos.
Solo se inicia el juego cuando el jugador entra en el vehículo.
Quitar las pizzas adicionales del jugador cuando recoge un nuevo elemento para que las pizzas no se caigan en el mapa.
Al completar este paso del tutorial Prueba contrarreloj: Persecución de pizza, aprenderás a pulir un juego.
Cómo mostrar al jugador la siguiente zona de recolección seleccionada
Sigue estos pasos para añadir un marcador de objetivo que muestre al jugador a dónde ir. Actualiza el archivo game_coordinator_device.verse:
Añade un
objective_markereditable que se llamePickupMarkery tenga el especificadorpublica la clasegame_coordinator_device.@editable PickupMarker<public> : objective_marker = objective_marker{}Al comienzo de la función
PickupDeliveryLoop(), habilita el dispositivo indicador de mapa asociado con el objetoPickupMarkery configura una expresióndeferpara desactivar e inhabilitar el dispositivo cuando se salga de la función.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(){} <# Aplaza la deshabilitación de MapIndicator para que la terminación de PickupDeliveryLoop siempre termine deshabilitando el marcador. El aplazamiento también se ejecuta si se cancela PickupDeliveryLoop. #> defer: if (ValidPlayer := MaybePlayer?): PickupMarker.MapIndicator.DeactivateObjectivePulse(ValidPlayer) PickupMarker.MapIndicator.Disable() PickupMarker.MapIndicator.Enable()Cuando se seleccione la siguiente zona de recolección, mueve el marcador de recolección a la zona de recolección seleccionada y llama a
PickupMarker.MapIndicator.ActivateObjectivePulse()para guiar al jugador hacia ella.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,
Cómo añadir más tiempo a la cuenta regresiva cuando el jugador anota puntos
Puedes alentar a un jugador a que entregue objetos con más frecuencia si lo recompensas con tiempo adicional por cada objeto entregado.
Sigue estos pasos para añadir más tiempo a la cuenta regresiva:
En el archivo score_manager.verse, cambia el tipo de devolución de la función
AddPendingScoreToTotalScore()ainty añadereturn PendingScorepara que puedas usar los puntos añadidos a la puntuación total para actualizar la cuenta regresiva.AddPendingScoreToTotalScore<public>() : int = set TotalGameScore += PendingScore defer: set PendingScore = 0 UpdateUI() return PendingScoreEn el archivo game_coordinator_device.verse, añade un
floateditable denominadoDeliveryBonusSecondsque tenga el especificadorpublica la definición de clasegame_coordinator_devicepara representar cuántos segundos añadir al cronómetro de cuenta regresiva por cada punto confirmado en la entrega.# Cuántos segundos añadir al cronómetro de cuenta regresiva cuando se entrega una recolección. @editable DeliveryBonusSeconds<public> : float = 20.0Actualiza la expresión
blockde entrega para calcular el tiempo de bonificación y actualizar el tiempo restante en el cronómetro de cuenta regresiva.block: FirstPickupZoneCompletedEvent.Await() if (DeliveryZone := DeliveryZoneSelector.SelectNext[]): DeliveryZone.ActivateZone() # Diferimos la desactivación de la zona de manera que al cancelar PickupDeliveryLoop también se desactive cualquier zona de entrega activa. defer: Logger.Print("Desactivando zona de entrega.", ?Level := log_level.Normal) DeliveryZone.DeactivateZone() DeliveryZone.ZoneCompletedEvent.Await() Logger.Print("Entegado", ?Level:=log_level.Normal) PointsCommitted := ScoreManager.AddPendingScoreToTotalScore() BonusTime : float = DeliveryBonusSeconds * PointsCommitted CountdownTimer.AddRemainingTime(BonusTime) else: Logger.Print("No se pudo encontrar la siguiente DeliveryZone para seleccionar.", ?Level := log_level.Error) return # Error out of the PickupDeliveryLoopCuando realices una prueba del juego, ir a la zona de entrega después de recoger una pizza le añade más tiempo a la cuenta regresiva.
Cómo iniciar el juego cuando el jugador entra en el vehículo
Realiza estos pasos para iniciar el juego cuando el jugador entre al vehículo y controlar cuando salga del vehículo:
Crea una referencia editable al dispositivo generador de vehículos que tenga el especificador
public.@editable VehicleSpawner<public> : vehicle_spawner_atk_device = vehicle_spawner_atk_device{}Crea una función denominada
StartGameOnPlayerEntersVehicle()que tenga los especificadoresprivateysuspends. Esta función debe esperar a que el jugador ingrese al vehículo antes de llamar aStartGame(), y actualizar la variableMaybePlayercon la referencia del jugador desde la entrada al vehículo. ActualizaOnBegin()para llamar a esta función en lugar deStartGame().OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Solo queremos que se nos notifique la primera vez que el jugador entra en el vehículo para iniciar la partida. # StartGameOnPlayerEntersVehicle esperará ese evento y luego iniciará el bucle de juego. StartGameOnPlayerEntersVehicle() StartGameOnPlayerEntersVehicle<private>()<suspends> : void = VehiclePlayer := VehicleSpawner.AgentEntersVehicleEvent.Await() Logger.Print("El jugador entró al vehículo") set MaybePlayer = option{player[VehiclePlayer]} StartGame()Configura un controlador de eventos para cuando el jugador salga del vehículo. Crea una función denominada
HandlePlayerExitsVehicle()que tenga el especificadorprivate.OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Después de entrar al vehículo, el jugador podría salir en cualquier momento; nosotros # queremos detectar esto cada vez que sucede para volver a colocarlo en el vehículo. VehicleSpawner.AgentExitsVehicleEvent.Subscribe(HandlePlayerExitsVehicle) # Solo queremos que se nos notifique la primera vez que el jugador entra en el vehículo para iniciar la partida. # StartGameOnPlayerEntersVehicle esperará ese evento y luego iniciará el bucle de juego. StartGameOnPlayerEntersVehicle() HandlePlayerExitsVehicle<private>(VehiclePlayer : agent) : void = Logger.Print("El jugador salió del vehículo. Reasignando jugador al vehículo") VehicleSpawner.AssignDriver(VehiclePlayer)
Cómo eliminar las pizzas adicionales
Realiza estos pasos para quitar las pizzas adicionales del jugador cuando recoge un nuevo elemento, para que no deje caer pizzas en el mapa:
Añade una referencia editable al dispositivo de eliminación de elementos responsable de eliminar las pizzas del inventario del jugador.
@editable PizzaRemover<public> : item_remover_device = item_remover_device{}En la función
PickupDeliveryLoop(),, quita las pizzas al jugador justo después de que recoja un elemento.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. #>