Создание команд
В этом разделе вы научитесь настраивать команды охотников и прячущихся игроков в начале игры и телепортировать их к месту, откуда они начнут игру.
На данной странице приведены фрагменты кода на Verse, показывающие, как реализовать механику для этого режима. Выполните следующие действия и скопируйте весь код из этой инструкции на шаге 6.
Для настройки команд выполните следующие шаги:
-
Создайте новую функцию SetupTeams(). Здесь вы зададите несколько подписок на функции, которые мы определим чуть позже, в частности, функции, используемые при устранении игрока прячущейся команды или отвечающие за действия в момент присоединения игрока к игре.
# При запуске раунда подписываемся на устройства команд, случайным образом выбираем агентов охотников, включаем таймер охотников, задаём агентов прячущейся команды и телепортируем их в игровую область. SetUpTeams()<suspends>:void = Logger.Print("Создание команд.")
-
Сначала подпишитесь на таймер счёта команды SuccessEvent, событие устранения TeamManager команды, а также задайте количество присуждаемых очков в диспетчере счёта.
# При запуске раунда подписываемся на устройства команд, случайным образом выбираем агентов охотников, включаем таймер охотников, задаём агентов прячущейся команды и телепортируем их в игровую область. SetUpTeams()<suspends>:void = Logger.Print("Создание команд.") # Выполняем подписку на таймер счёта прячущейся команды, задаём количество присуждаемых очков и подписываемся на событие устранения прячущейся команды. PropTeam.ScoreTimer.SuccessEvent.Subscribe(PropTeam.OnPropsScore) PropTeam.ScoreManager.SetScoreAward(PropTeam.ScorePerSecond) PropTeam.TeamManager.TeamMemberEliminatedEvent.Subscribe(OnPropEliminated) # Происходит при устранении агента прячущейся команды.
-
Далее проделайте то же самое для команды охотников. Затем установите для команды охотников таймер ожидания, чтобы происходила задержка перед появлением охотников.
# При запуске раунда подписываемся на устройства команд, случайным образом выбираем агентов охотников, включаем таймер охотников, задаём агентов прячущейся команды и телепортируем их в игровую область. SetUpTeams()<suspends>:void = Logger.Print("Создание команд.") # Выполняем подписку на таймер счёта прячущейся команды, задаём количество присуждаемых очков и подписываемся на событие устранения прячущейся команды. PropTeam.ScoreTimer.SuccessEvent.Subscribe(PropTeam.OnPropsScore) PropTeam.ScoreManager.SetScoreAward(PropTeam.ScorePerSecond) PropTeam.TeamManager.TeamMemberEliminatedEvent.Subscribe(OnPropEliminated) # Происходит при устранении агента прячущейся команды. # Подписываемся на таймер ожидания команды охотников и устанавливаем длительность. Также выполняем подписку на событие устранения команды охотников. HunterTeam.WaitTimer.SuccessEvent.Subscribe(HuntersGo) HunterTeam.WaitTimer.SetMaxDuration(HunterTeam.SpawnDelay) HunterTeam.TeamManager.EnemyEliminatedEvent.Subscribe(OnHunterEliminated) # Происходит при устранении агентом охотника агента прячущейся команды.
-
В
SetupTeams()
также инициализируйте начальные массивы агентов охотников и прячущейся команды, затем включите HUD-интерфейс ожидания на время проверки того, достаточно ли игроков для запуска игры. Если их достаточно, отключите HUD-интерфейс ожидания.# Инициализируем начальные массивы агентов охотников и прячущейся команды. Получаем игроков и определяем количество игроков на сервере var StartingHunterAgents:[]agent = array{} var StartingPropAgents:[]agent = array{} var Players:[]player = GetPlayspace().GetPlayers() # Включаем HUD-интерфейс для ожидания игроков. HUDControllerWaiting.Enable() # Проверяем, достаточно ли игроков для запуска раунда. set Players = WaitingForMorePlayers.WaitForMinimumNumberOfPlayers(Players) Logger.Print("Раунд начался.") # Отключаем HUD-интерфейс ожидания, чтобы далее использовать HUD-интерфейс со следующим приоритетом важности. HUDControllerWaiting.Disable()
-
Теперь, когда раунд начался, необходимо обеспечить обработку событий присоединения нового игрока и удаления игрока из матча. Подписки мы настроим здесь, а функции определим позже.
# Раунд начался, поэтому необходимо обрабатывать события присоединения новых игроков и их удаления из матча. Выполняем подписку на эти события. GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded) GetPlayspace().PlayerRemovedEvent().Subscribe(OnPlayerRemoved)
-
Начальное количество охотников зависит от количества игроков в игре. Один охотник не должен играть против десятерых игроков, поэтому нужно создать такую функцию, которая будет регулировать количество охотников по формуле. Преобразуйте количество игроков в значение с плавающей запятой: оно и будет использоваться в формуле.
# Определяем начальное количество агентов охотников для игры с учётом количества игроков, а также количество агентов охотников на определённое количество игроков. NumberOfPlayers:float = 1.0 * Players.Length # Преобразует Players.Length в значение с плавающей запятой для использования в следующей функции Ceil.
-
Теперь установите предельное начальное количество охотников для следующей формулы. Затем перемешайте элементы массива всех игроков, поскольку охотников из списка игроков в начале нужно выбрать случайным образом.
# Определяем начальное количество агентов охотников для игры с учётом количества игроков, а также количество агентов охотников на определённое количество игроков. NumberOfPlayers:float = 1.0 * Players.Length # Преобразует Players.Length в значение с плавающей запятой для использования в следующей функции Ceil. if (NumberOfStartingHunters:int = Ceil[NumberOfPlayers / Max(1.1, HunterTeam.HunterAgentPerNumberOfPlayers)]): # Перемешиваем игроков и создаём срез массива для получения первых агентов охотников. Оставшиеся игроки на этом этапе будут выступать агентами прячущейся команды. var RandomizedPlayers:[]agent = Shuffle(Players)
-
Выполните срез перемешанного массива, размер которого будет от 0 до желаемого начального количества охотников. Это будет начальная команда охотников, которую мы задаём в StartingHunterAgents. Остальные игроки станут начальной командой предметов окружения, которую мы задаём в StartingPropAgents.
# Определяем начальное количество агентов охотников для игры с учётом количества игроков, а также количество агентов охотников на определённое количество игроков. NumberOfPlayers:float = 1.0 * Players.Length # Преобразует Players.Length в значение с плавающей запятой для использования в следующей функции Ceil. if (NumberOfStartingHunters:int = Ceil[NumberOfPlayers / Max(1.1, HunterTeam.HunterAgentPerNumberOfPlayers)]): # Перемешиваем игроков и создаём срез массива для получения первых агентов охотников. Оставшиеся игроки на этом этапе будут выступать агентами прячущейся команды. var RandomizedPlayers:[]agent = Shuffle(Players) if (set StartingHunterAgents = RandomizedPlayers.Slice[0,NumberOfStartingHunters]) {} if (set StartingPropAgents = RandomizedPlayers.Slice[NumberOfStartingHunters,RandomizedPlayers.Length]) {} # Перебираем начальных агентов охотников и назначаем их в команду охотников. Далее запускаем таймер ожидания охотников. Logger.Print("Setting {StartingHunterAgents.Length} hunter agent(s).") for (StartingHunterAgent : StartingHunterAgents): HunterTeam.InitializeAgent(StartingHunterAgent) HunterTeam.WaitTimer.Start() # Перебираем начальных агентов прячущейся команды и назначаем их в прячущуюся команду. Телепортируем их в игровую зону. Logger.Print("Setting {StartingPropAgents.Length} prop agent(s).")
-
Как только команды будут настроены, включите устройство «Телепорт в лобби» для телепортации игроков прячущейся команды из стартовой комнаты и активируйте для них эффект сердцебиения. Затем отключите устройство «Телепорт в лобби», которое больше не понадобится. Наконец, задайте количество остающихся предметов в PropsRemainingTracker, которое будет представлять собой количество членов прячущейся команды.
LobbyTeleporter.Enable() for (StartingPropAgent : StartingPropAgents): PropTeam.InitializeAgent(StartingPropAgent) PropTeam.HeartBeat.SetUpUI(StartingPropAgent) LobbyTeleporter.Activate(StartingPropAgent) LobbyTeleporter.Disable() # Задаём для целевого показателя и значения остающихся прячущихся игроков в устройстве управления заданиями текущее количество прячущихся игроков. # В дальнейшем мы будем обновлять значение только при устранении прячущихся игроков. PropTeam.PropsRemainingTracker.SetTarget(PropTeam.Count()) PropTeam.UpdatePropsRemainingTracker()
Управление устранениями игроков
Охотники побеждают, когда устранят всех прячущихся игроков и превратят их в охотников. Выполните следующие действия, чтобы настроить начисление охотникам очков при устранении прячущегося игрока и его переносе в команду охотников.
-
Создайте функцию под названием OnHunterEliminated(). Вы уже выполнили подписку устройства «Диспетчер команды охотников» на событие EnemyEliminatedEvent, поэтому оно активируется при любом устранении охотником предмета окружения.
# Начисляем очки при устранении агентом охотника агента прячущейся команды. Очки делятся на количество оставшихся агентов прячущейся команды. OnHunterEliminated(HunterAgent:agent):void = Logger.Print("Агент охотника устранил агента прячущейся команды.")
-
Сначала необходимо присвоить очки охотникам пропорционально количеству остающихся агентов предметов. Создайте переменную
EliminationAward
, которая будет равна значениюMaxEliminationScore
, разделённому наPropTeamSize
. Задайте такой счёт в диспетчере счёта команды охотников, затем начислите очки охотнику, который произвёл устранение.# Начисляем очки при устранении агентом охотника агента прячущейся команды. Очки делятся на количество оставшихся агентов прячущейся команды. OnHunterEliminated(HunterAgent:agent):void = Logger.Print("Агент охотника устранил агента прячущейся команды.") PropTeamSize := PropTeam.Count() if (EliminationAward := Floor(HunterTeam.MaxEliminationScore / PropTeamSize)): Logger.Print("Присуждается очков: {EliminationAward}.") HunterTeam.ScoreManager.SetScoreAward(EliminationAward HunterTeam.ScoreManager.Activate(HunterAgent)
-
Кроме того, нужно обрабатывать события, происходящие с прячущейся командой при устранении её игроков. Создайте функцию под названием OnPropEliminated(). Как и в случае с OnHunterEliminated(), вы уже подписались на эту функцию. Прячущегося игрока, которого устранили, нужно удалить из его команды при помощи функции EliminateAgent() в PropTeam, а затем инициализировать его в качестве охотника с помощью функции InitializeAgent() в HunterTeam.
# При устранении агента прячущейся команды мы удаляем его из его команды, выполняем проверку условия окончания раунда и назначаем его охотником. OnPropEliminated(PropAgent:agent):void = Logger.Print("Агент прячущейся команды устранён.") spawn{ PropTeam.EliminateAgent(PropAgent) } HunterTeam.InitializeAgent(PropAgent)
Как игроки присоединяются к игре и покидают её
Игроки, присоединяющиеся по ходу игры, будут становиться охотниками.
-
Для этого создайте функцию OnPlayerAdded(). Она будет просто инициализировать игрока, присоединяющегося в качестве охотника.
# Игрока, присоединяющегося по ходу матча, делаем охотником. OnPlayerAdded(Player:player):void = Logger.Print("К игре присоединился новый игрок.") HunterTeam.InitializeAgent(Player)
-
При выходе игрока из матча ситуация немного сложнее. Если игрок покидает матч, нужно не только удалить его из команды, но и проверить, не станет ли это завершением игры. Игрок, покинувший матч, мог быть последним из прячущихся или единственным охотником. Эта логика обрабатывается функциями EliminateAgent() в каждой команде: вы создаёте соответствующий экземпляр в зависимости от команды, из которой удаляется игрок.
# Когда игрок покидает матч, необходимо проверить, какую команду он покинул, а затем проверить, не приведёт ли это к завершению раунда. OnPlayerRemoved(Player:player):void= Logger.Print("Игрок выбыл из игры.") if (PropTeam.FindOnTeam[Player]): Logger.Print("Игрок был из прячущейся команды.") spawn{ PropTeam.EliminateAgent(Player) } if (HunterTeam.FindOnTeam[Player]): Logger.Print("Игрок был охотником.") spawn{ HunterTeam.EliminateAgent(Player) }
Завершение раунда
Когда все команды настроены, необходимо отслеживать количество игроков в каждой из них для определения конца раунда. Игра завершается, как только любая из команд останется без игроков, либо когда истечёт время раунда: для этого мы будем использовать выражение race, чтобы узнать, какое событие произойдёт первым.
-
В конце функции OnBegin(), в выражении race, требуется ожидание — Await() — события TeamEmptyEvent и команды охотников, и прячущейся команды, а также функции AwaitEnd() в RoundTimer. Как только конкурентное выполнение завершится, необходимо вызвать функцию EndRound(), которую мы определим в следующем шаге.
# Когда больше не окажется агентов прячущейся команды или охотников (в зависимости от того, что произойдёт первым), либо когда завершится таймер раунда или сам раунд. race: PropTeam.TeamEmptyEvent.Await() HunterTeam.TeamEmptyEvent.Await() RoundTimer.AwaitEnd() Logger.Print("Раунд завершается.") EndRound()
-
В функции EndRound() необходимо отключить датчик сердцебиения для каждого игрока прячущейся команды и вызвать EndRound() в устройстве RoundSettings. Поскольку в функцию EndRound() в устройстве RoundSettings необходимо передать игрока, то возьмите первого игрока из массива игроков и передайте его в качестве инициатора.
# Убирает визуальный эффект сердцебиения и завершает раунд. EndRound():void= PropTeam.HeartBeat.DisableAll() # Получаем игрока и передаём в EndRound Players:[]player = GetPlayspace().GetPlayers() if (RoundEndInstigator := Players[0]): Logger.Print("Раунд завершён.") RoundSettings.EndRound(RoundEndInstigator)