Ahora que ya tienes el núcleo del juego, es importante dar al jugador información visual cuando realice acciones, por ejemplo:
Un marcador de objetivo que indica al jugador dónde ir.
Añadir más tiempo a la cuenta atrás cuando el jugador consigue un objetivo.
Iniciar la partida solo cuando el jugador entra en el vehículo.
Eliminar las pizzas sobrantes del jugador cuando recoge un nuevo objeto para que no las deje caer en el mapa.
Al completar este paso del tutorial Prueba contrarreloj: Reparto de pizzas, tendrás más información sobre cómo pulir un juego.
Cómo mostrar al jugador la siguiente zona de recogida seleccionada
Sigue estos pasos para añadir un marcador de objetivo que muestre al jugador dónde ir. Actualiza el archivo game_coordinator_device.verse:
Añade un
objective_markereditable nombradoPickupMarkerque tenga el especificadorpublica la clasegame_coordinator_device.@editable PickupMarker<public> : objective_marker = objective_marker{}Al principio de la función
PickupDeliveryLoop(), activa el dispositivo Indicador del mapa asociado al objetoPickupMarkery configura undeferpara desactivar y deshabilitar el dispositivo cuando salga 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 desactivación de MapIndicator para que la finalización del bucle PickupDeliveryLoop siempre acabe desactivando el marcador. `defer` también se ejecuta si se cancela el bucle PickupDeliveryLoop. #> defer: if (ValidPlayer := MaybePlayer?): PickupMarker.MapIndicator.DeactivateObjectivePulse(ValidPlayer) PickupMarker.MapIndicator.Disable() PickupMarker.MapIndicator.Enable()Cuando se selecciona la siguiente zona de recogida, mueve el marcador de recogida a la zona de recogida 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 atrás cuando el jugador consigue un objetivo
Puedes animar a un jugador a entregar objetos más a menudo recompensándole con tiempo adicional por cada objeto que entregue.
Sigue estos pasos para añadir más tiempo a la cuenta atrás:
En el archivo score_manager.verse, cambia el tipo de retorno de la función
AddPendingScoreToTotalScore()ainty añadereturn PendingScorepara que puedas utilizar los puntos añadidos a la puntuación total para actualizar la cuenta atrás.AddPendingScoreToTotalScore<public>() : int = set TotalGameScore += PendingScore defer: set PendingScore = 0 UpdateUI() return PendingScoreEn el archivo `game_coordinator_device.verse`, añade un
floateditable nombradoDeliveryBonusSecondsque tenga el especificadorpublica la definición de la clasegame_coordinator_devicepara representar cuántos segundos añadir al cronómetro de cuenta atrás por cada punto logrado en la entrega.# Cuántos segundos añadir al cronómetro de cuenta atrás cuando se entrega una recogida. @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 atrás.block: FirstPickupZoneCompletedEvent.Await() if (DeliveryZone := DeliveryZoneSelector.SelectNext[]): DeliveryZone.ActivateZone() # Diferimos la desactivación de la zona para que la cancelación de PickupDeliveryLoop también acabe desactivando cualquier zona de entrega activa. defer: Logger.Print("Desactivando zona de entrega.", ?Level := log_level.Normal) DeliveryZone.DeactivateZone() DeliveryZone.ZoneCompletedEvent.Await() Logger.Print("Entregado", ?Level := log_level.Normal) PointsCommitted := ScoreManager.AddPendingScoreToTotalScore() BonusTime : float = DeliveryBonusSeconds * PointsCommitted CountdownTimer.AddRemainingTime(BonusTime) else: Logger.Print("No se encuentra la siguiente zona de entrega para seleccionar.", ?Level := log_level.Error) return # Error de PickupDeliveryLoopEn las pruebas de juego, ir a la zona de entrega después de recoger una pizza añade más tiempo a la cuenta atrás.
Cómo iniciar la partida cuando el jugador entra en el vehículo
Sigue estos pasos para iniciar la partida cuando el jugador entre en el vehículo y controlar cuándo sale de él:
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 nombrada
StartGameOnPlayerEntersVehicle()que tenga los especificadoresprivateysuspends. Esta función debe esperar a que el jugador entre en el vehículo antes de llamar aStartGame(), y actualizar la variableMaybePlayercon las referencias del jugador a la entrada en el vehículo. ActualizaOnBegin()para llamar a esta función en lugar deStartGame().OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Solo queremos que se notifique la primera vez que el jugador entre en el vehículo para iniciar la partida. # StartGameOnPlayerEntersVehicle esperará ese evento e iniciará el bucle de juego. StartGameOnPlayerEntersVehicle() StartGameOnPlayerEntersVehicle<private>()<suspends> : void = VehiclePlayer := VehicleSpawner.AgentEntersVehicleEvent.Await() Logger.Print("El jugador ha entrado en el 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 nombrada
HandlePlayerExitsVehicle()que tenga el especificadorprivate.OnBegin<override>()<suspends> : void = FindPlayer() SetupZones() # Tras entrar en el vehículo, el jugador puede salir en cualquier momento; # queremos detectar esto cada vez que ocurra para volver a introducirlos en el vehículo. VehicleSpawner.AgentExitsVehicleEvent.Subscribe(HandlePlayerExitsVehicle) # Solo queremos que se notifique la primera vez que el jugador entre en el vehículo para iniciar la partida. # StartGameOnPlayerEntersVehicle esperará ese evento e iniciará el bucle de juego. StartGameOnPlayerEntersVehicle() HandlePlayerExitsVehicle<private>(VehiclePlayer : agent) : void = Logger.Print("El jugador ha salido del vehículo. Reasignando jugador al vehículo") VehicleSpawner.AssignDriver(VehiclePlayer)
Cómo eliminar pizzas extra
Sigue estos pasos para eliminar las pizzas extra del jugador cuando recoja un nuevo objeto, de modo que no las deje caer en el mapa:
Añade una referencia editable al dispositivo Eliminador de objetos, responsable de eliminar las pizzas del inventario del jugador.
@editable PizzaRemover<public> : item_remover_device = item_remover_device{}En la función
PickupDeliveryLoop(), elimina las pizzas del jugador justo después de que recoja un objeto.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. #>