Cómo descifrar el algoritmo
Cuando empiece la partida, queremos equilibrar cada equipo para que tenga una cantidad adecuada de jugadores.
A diferencia de los juegos en los que el equilibrio de jugadores es simétrico y los jugadores se distribuyen uniformemente entre los equipos, equilibrar los equipos asimétricamente significa que cada equipo debe tener un número relativo de jugadores. Es decir, el tamaño de los equipos debe seguir una proporción relativa.
Por ejemplo, puede que siempre quieras que un equipo tenga el doble de jugadores que otro. A medida que se incorporan jugadores, tienes que equilibrarlos de forma que se preserve este número relativo. En los modos de juego en los que un equipo es más poderoso o tiene habilidades diferentes a las del otro equipo, el equilibrio asimétrico crea experiencias de juego más fluidas al distribuir cuidadosamente el número de jugadores de cada equipo.
En este ejemplo, debes asegurarte de que los equipos con un número máximo de jugadores mayor (en este caso, los defensores) siempre tendrán más que los equipos con un máximo menor (como los infiltrados).
Para distribuir correctamente a los jugadores, tendrás que colocar a cada jugador en el equipo con la mayor diferencia respecto a su número máximo de jugadores.
Para ello, para cada nuevo jugador tendrás que comprobar cada equipo y almacenar una referencia al número máximo y actual de jugadores, así como el equipo al que asignar este jugador. Puedes restar el número máximo de jugadores del número actual para obtener la diferencia respecto al máximo. Cuando encuentres un equipo con una diferencia mayor respecto al máximo, establecerás que el jugador sea asignado a ese equipo.
Al iterar a través de cada equipo, te aseguras de encontrar el equipo con la mayor diferencia.
Cómo definir el algoritmo
Este paso muestra cómo equilibrar equipos de jugadores de forma asimétrica al inicio de una partida.
- Añade un nuevo método llamado
BalanceTeams()a la clasetriad_infiltration_game. Este método asigna un jugador al equipo con la mayor diferencia respecto a su número máximo de jugadores.# Equilibra a todos los jugadores de todos los equipos del juego. BalanceTeams():void= Logger.Print("Empezando a equilibrar los equipos") - Obtén todos los jugadores de la partida y almacénalos en una matriz variable
AllPlayers. A continuación, mezclaAllPlayers. Esto garantizará que los jugadores sean asignados a los equipos aleatoriamente, y no en función del orden en que se unieron inicialmente al juego.# Equilibra a todos los jugadores de todos los equipos del juego. BalanceTeams():void= Logger.Print("Empezando a equilibrar los equipos") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) - Ahora itera todos los jugadores y asígnalos al equipo con la mayor diferencia respecto a su número máximo de jugadores. Lo harás a través de una función auxiliar que crearás en el siguiente paso llamada
FindTeamWithLargestDifference(), pero antes, inicializa una variable de opción llamadaTeamToAssignpara asignar un jugador, y establécela con el valor devuelto porFindTeamWithLargestDifference().for (TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() - Crea la función
FindTeamWithLargestDifference()en la definición de la clasetriad_infiltration_game. Esta función se encargará de encontrar el equipo con la mayor diferencia en el número de jugadores respecto a su máximo, y devuelve unteamopcional. Te aconsejamos que elteamdevuelto sea una opción para evitar reasignar a un jugador cuando ya está en el equipo con mayor diferencia.# Encuentra el equipo con la mayor diferencia en el número de jugadores de su # número máximo de jugadores FindTeamWithLargestDifference():?team = Logger.Print("Intentando encontrar el equipo más pequeño") - Inicializa una variable opcional de equipo llamada
TeamToAssignque almacenará una referencia al equipo con la mayor diferencia de jugadores, y un enteroLargestDifferencepara registrar esa diferencia de jugadores.# Encuentra el equipo con la mayor diferencia en el número de jugadores de su # número máximo de jugadores. FindTeamWithLargestDifference():?team = Logger.Print("Intentando encontrar el equipo más pequeño") var TeamToAssign:?team = false var LargestDifference:int = 0 - Ahora itera por la lista de equipos, obteniendo tanto el tamaño actual como el máximo de ese equipo.
var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] - Para cada equipo, calcula la
DifferenceFromMaximum, que es la diferencia entre el tamaño máximo de este equipo y el número de jugadores que tiene actualmente. Si el equipo tiene una diferencia mayor queLargestDifference, estableceLargestDifferenceenDifferenceFromMaximumy envuelveTeamToAssignen unoption.for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Comprobando un equipo...") Logger.Print("El tamaño máximo del equipo es {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("La diferencia con el máximo es {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Se ha encontrado un equipo por debajo del máximo de jugadores: {DifferenceFromMaximum}") - Por último, devuelve
TeamToAssign. Tu código deFindTeamWithLargestDifference()debería tener ahora este aspecto:# Encuentra el equipo con la mayor diferencia en el número de jugadores de su # número máximo de jugadores. FindTeamWithLargestDifference():?team = Logger.Print("Intentando encontrar el equipo más pequeño") var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Comprobando un equipo...") Logger.Print("El tamaño máximo del equipo {CandidateTeamIndex + 1} es {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("La diferencia con el mínimo es {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Se ha encontrado un equipo por debajo del mínimo de jugadores: {DifferenceFromMaximum}") return TeamToAssign - De vuelta en
BalanceTeams(), asigna al jugador a un nuevo equipo mediante la funciónFortTeamCollection.AddToTeam[]. Si esta asignación falla, el jugador ya estaba en el equipo más pequeño.var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Intentando asignar un jugador a un nuevo equipo") - Tu función
BalanceTeams()debería tener el siguiente aspecto:# Equilibra a todos los jugadores de todos los equipos del juego. BalanceTeams():void= Logger.Print("Empezando a equilibrar los equipos") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) Logger.Print("La longitud de AllPlayers es {AllPlayers.Length}") for (TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Jugador asignado a un nuevo equipo")
Teletransportar jugadores a sus zonas de aparición
Aunque los jugadores acabarán en el equipo con mayor diferencia, puede que no aparezcan en la zona correcta. Esto se debe a que los jugadores aparecen antes de ser asignados a un nuevo equipo. Para solucionarlo, crearás una nueva función para teletransportar a los jugadores a su lugar de origen una vez que los equipos estén equilibrados.
- Crea la función
TeleportPlayersToStartLocations()en la definición de la clasetriad_infiltration_game. Esta función teletransportará a los jugadores al punto de aparición de su equipo una vez finalizado el equilibrio.# Teletransporta a los jugadores al punto de aparición de su equipo tras equilibrar los equipos. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando a los jugadores a las ubicaciones iniciales") - En un bucle
for, recorre cada matrizTeams, obteniendo el índice de ese equipo y almacenándolo en una variableTeamIndex.# Teletransporta a los jugadores al punto de aparición de su equipo tras equilibrar los equipos. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando a los jugadores a las ubicaciones iniciales") for: TeamIndex -> PlayerTeam:Teams - Obtén los jutadores de
PlayerTeamllamando aGetAgents[]conPlayerTeam. A continuación, obtén el teletransportador asociado a ese equipo indexando en la matrizTeleportersmedianteTeamIndexy almacenándolo en una variableTeamTeleporter. Guarda la transformación de ese teletransportador en una variableTransform.# Teletransporta a los jugadores al punto de aparición de su equipo tras equilibrar los equipos. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando a los jugadores a las ubicaciones iniciales") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform()Asegúrate de que el orden de tus equipos en
Teamscoincide con el orden de tus repartidores de objetos enTeleporters. Si los infiltrados son el Equipo 1, entonces el primer telepuerto enTeleportersdebe ser para los infiltrados. Comprueba en el editor que estos valores son correctos. - Ahora, en un segundo bucle
for, recorre cada jugador delTeamPlayersy haz que aparezcan en la transformación del teletransportador utilizandoRespawn()y la traslación y rotación de laTransform. Tu funciónTeleportPlayersToStartLocations()debería tener el siguiente aspecto:# Teletransporta a los jugadores al punto de aparición de su equipo tras equilibrar los equipos. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando a los jugadores a las ubicaciones iniciales") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform() do: for(TeamPlayer:TeamPlayers): TeamPlayer.Respawn(Transform.Translation, Transform.Rotation) Logger.Print("Se ha teletransportado a este jugador a su ubicación inicial") - En
OnBegin(), añade una llamada aBalanceTeams()después de mezclarAllPlayers. Esto garantizará que los jugadores estén equilibrados en un orden aleatorio en lugar de acabar siempre en el mismo equipo. A continuación, teletransporta a los jugadores a sus ubicaciones iniciales llamando aTeleportPlayersToStartLocations().OnBegin<override>()<suspends> : void = # Obtiene todos los equipos set Teams = GetPlayspace().GetTeamCollection().GetTeams() # Guarda los equipos para hacer referencia a ellos más tarde set MaybeInfiltrators = option{Teams[0]} set MaybeAttackers = option{Teams[1]} set MaybeDefenders = option{Teams[2]} if: Infiltrators := MaybeInfiltrators? Attackers := MaybeAttackers? Defenders := MaybeDefenders? Logger.Print("Encontrados los tres equipos") set TeamsAndTotals[Infiltrators] = MaximumInfiltrators set TeamsAndTotals[Attackers] = MaximumAttackers set TeamsAndTotals[Defenders] = MaximumDefenders Logger.Print("Configura los tres equipos en TeamsAndTotals") then: BalanceTeams() TeleportPlayersToStartLocations() else: Logger.Print("No se han encontrado todos los equipos, asegúrate de asignar los equipos correctos en la configuración de tu isla.") -
Guarda la secuencia de comandos, compílala y haz clic en Abrir sesión en la barra de herramientas de UEFN para probar el nivel. Cuando pruebes tu nivel, cada jugador debe acabar en el equipo con mayor diferencia y aparecer en la zona de aparición de ese equipo. Comprueba este comportamiento utilizando el registro. Puedes ajustar el número máximo de jugadores por equipo en tu
triad_infiltration_gamepara probar esta funcionalidad cuando tengas menos del número máximo de jugadores. Por ejemplo, cuando pruebes en solitario, intenta establecer el número máximo de jugadores del equipo en el que quieres acabar más alto que el de los otros dos equipos. Si quieres acabar entre los atacantes, configuraMaximumAttackersen un valor más alto. Si quieres acabar entre los infiltrados, configuraMaximumInfiltratorsen un valor más alto.
Siguiente paso
En el siguiente paso de este tutorial, aprenderás a conceder armas a los jugadores al inicio de la partida y cuando aparezcan.