Для отслеживания количества устранений, совершенных игроком, мы будем использовать ассоциативный массив. Ассоциативные массивы являются удобным представлением пар ключ-значение, и на разбираемом примере мы будем использовать игрока в качестве ключа, а связанный с ним уровень оружия (целочисленное значение int) — в качестве значения. Таким образом, мы сможем получать текущий уровень игрока, имея только ссылку на него. Ниже приведён пример того, как может выглядеть ассоциативный массив для игроков и уровней оружия.
| Ключ | игрок 1 | игрок 2 | игрок 3 |
| Значение | 1 | 2 | 2 |
| Оружие в игре | Боевой пистолет L1 | Пистолет «Бретёр» L1 | Пистолет «Бретёр» L1 |
Для заполнения ассоциативных массивов игроков выполните следующие шаги:
-
Добавьте ассоциативный массив типа
[player]intс названиемPlayerMapв классteam_elimination_game. В нём будут храниться ссылки на каждого игрока и соответствующие уровни оружия.team_elimination_game := class(creative_device): var PlayerMap : [player]int = map{} -
Добавьте новый метод
PopulateTeamsAndPlayers()в классteam_elimination_game. Данный метод будет заполнять массивPlayerMapи будет вызываться из блокаOnBegin().PopulateTeamsAndPlayers() : void= Print("Начинаю заполнение игроков") -
В класс
team_elimination_gameдобавьте новый методOnPlayerEliminated. Он будет вызываться при каждом устранении игрока и будет определять, кто именно его устранил, путём обращения к структуреelimination_result, переданной в качестве аргумента.OnPlayerEliminated(Result : elimination_result) : void= Print("Игрок устранён!") -
В начале игры необходимо выполнить итерацию по списку игроков и выдать для всех оружие первого уровня. Внутри
PopulateTeamsAndPlayersполучите всех игроков с помощью методаGetPlaySpace().GetPlayers()и сохраните их в массивAllPlayers. Для каждого игрока получите значениеFortCharacterи сохраните его в переменнойFortCharacter. ВPlayerMapприсвойте счёту игрока значение 0, чтобы выдать ему первое оружие из массиваWeaponGranters, а затем подпишите методFortCharacter.EliminatedEvent()наOnPlayerEliminated.AllPlayers := GetPlayspace().GetPlayers() for (Agent : AllPlayers, TeamPlayer := player[Agent], FortCharacter := TeamPlayer.GetFortCharacter[]): if(set PlayerMap[TeamPlayer] = 0, WeaponTier := PlayerMap[TeamPlayer]): Print("В PlayerMap добавлен игрок с уровнем оружия {WeaponTier}") FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated) -
С помощью ссылки на счёт игрока в массиве
PlayerMapможно предоставить ему первое оружие. Внесём изменения в блокOnPlayerSpawn, чтобы выдать игрокам первое оружие. При появлении игрока получите его уровень оружия изPlayerMapи сохраните его в переменнойWeaponTier, затем вызовитеGrantWeapon, передав значениеWeaponTierи ссылку на игрока.OnPlayerSpawn(InPlayer : agent) : void = Print("Игрок появился!") if(WeaponTier := PlayerMap[InPlayer]): GrantWeapon(option{InPlayer}, WeaponTier) Print("Появившемуся игроку выдано оружие уровня {WeaponTier}") -
Сохраните сценарий в Visual Studio Code, скомпилируйте его и нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня. При тестировании уровня игрок должен появиться с первым оружием из массива
WeaponGranters. Проверьте верность поведения с помощью журнала.
Распределение команд
Мы успешно создали ассоциативный массив для игроков, теперь подумаем о том, как проверять счёт игрока. Поскольку наш сценарий автоматически повышает уровень игрока в команде с наименьшим количеством устранений, нет смысла проверять уровень оружия игроков вражеской команды. В связи с этим вы уже наверняка заметили одну проблему: в массиве PlayerMap нет различий между игроками из разных команд.
Чтобы решить эту проблему, можно использовать ещё один ассоциативный массив. Для этого немного изменим массив PlayerMap, добавив в него систему вложенных ассоциативных массивов. Поскольку пары «ключ-значение» в таком массиве могут относиться к любому из типов, будет логичным сделать так, чтобы ключ команды имел другой ассоциативный массив в качестве своего значения. Первый ассоциативный массив будет связывать команды (ключ) с другим ассоциативным массивом игроков этой команды (значение). Вложенный массив, в свою очередь, будет использоваться для связывания игроков (ключ) с их счётом (значение).
Теперь, получив игрока, вы сможете проверить, в какой команде он находится, при помощи GetTeam(). Вы также сможете получить список товарищей по команде, чтобы сравнить количество устранений.
Синтаксис вложенного массива [team][player]int некоторым может показаться непонятным. В этой ситуации для упрощения понимания вы можете создать для него собственный псевдоним типа. В этом примере мы создадим для [player]int псевдоним player_map. Таким образом, для обращения к [player]int вы сможете использовать псевдоним player_map, а вложенный массив можно записать как [team]player_map: то есть как ассоциативный массив, связывающий команды с ассоциативными массивами игроков.
Выполните следующие действия, чтобы адаптировать ассоциативный массив к вложенной системе массивов:
-
Перед определением класса
team_elimination_gameдобавьте псевдоним для[player]intс названиемplayer_map.player_map := [player]int # Это псевдоним типа! team_elimination_game := class(creative_device): -
Замените созданную ранее переменную
PlayerMapизteam_elimination_gameна новую переменнуюTeamMapтипа[team]player_map.# Ассоциативный массив Team Map, где ключ — это команда, а значение — ассоциативный массив # из пар «игрок» (ключ) -> «целое число» (значение) var TeamMap : [team]player_map = map{} -
Поскольку значение
TeamMapимеет типplayer_map, для каждой команды необходимо инициализировать ассоциативный массив игроков, заполнить его, установить для каждого игрока значение0, а затем присвоить этот массив игроков кTeamMap. Измените блокPopulateTeamsAndPlayers(), добавив в него обновлённый код.- Для каждой команды найдите игроков этой команды и сохраните их в переменной
TeamPlayers. Инициализируйте новую переменнуюPlayerMapтипаplayer_mapдля сопоставления игроков с их счётом.
PopulateTeamsAndPlayers() : void= Print("Начинаю заполнение игроков") for (Team : Teams, TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[Team]): var PlayerMap : player_map = map {}- Для каждого игрока в
TeamPlayersполучите значениеFortCharacterи сохраните его в переменнойFortCharacter. ВPlayerMapприсвойте счёту игрока значение0, чтобы выдать ему первое оружие из массиваWeaponGranters, а затем подпишите методFortCharacter.EliminatedEvent()наOnPlayerEliminated.
PopulateTeamsAndPlayers() : void = Print("Начинаю заполнение игроков") for (Team : Teams, TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[Team]): var PlayerMap : player_map = map {} for (Agent : TeamPlayers, TeamPlayer := player[Agent], FortCharacter := Agent.GetFortCharacter[]): if(set PlayerMap[TeamPlayer] = 0, WeaponTier := PlayerMap[TeamPlayer]): Print("В PlayerMap добавлен игрок с уровнем оружия {WeaponTier}") FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated)- Наконец, установите
PlayerMapв качестве значения текущего ключаTeamвTeamMap. КодPopulateTeamsAndPlayersтеперь должен выглядеть следующим образом.
PopulateTeamsAndPlayers() : void = Print("Начинаю заполнение игроков") for (Team : Teams, TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[Team]): var PlayerMap : player_map = map {} for (Agent : TeamPlayers, TeamPlayer := player[Agent], FortCharacter := Agent.GetFortCharacter[]): if(set PlayerMap[TeamPlayer] = 0, WeaponTier := PlayerMap[TeamPlayer]): Print("В PlayerMap добавлен игрок с уровнем оружия {WeaponTier}") FortCharacter.EliminatedEvent().Subscribe(OnPlayerEliminated) if(set TeamMap[Team] = PlayerMap): Print("Команда успешно добавлена в TeamMap") - Для каждой команды найдите игроков этой команды и сохраните их в переменной
-
После создания
TeamMapобновитеOnPlayerSpawnтаким образом, чтобы получить доступ к команде игрока с помощью методаGetTeam[]и сохранить её в локальной переменнойPlayerTeam. Установите значениеWeaponTierпутём получения текущего счёта игрока изTeamMap, используяPlayerTeamи ссылку на игрока. Обновлённый блокOnPlayerSpawn()сейчас должен выглядеть следующим образом.OnPlayerSpawn(InPlayer : agent) : void = Print("Игрок появился!") if: PlayerTeam := GetPlayspace().GetTeamCollection().GetTeam[InPlayer] WeaponTier:int := TeamMap[PlayerTeam][InPlayer] then: GrantWeapon(option{InPlayer}, WeaponTier) Print("Появившемуся игроку выдано оружие уровня {WeaponTier}")
Сохраните сценарий в Visual Studio Code, скомпилируйте его и нажмите Запустить сеанс на панели инструментов UEFN, чтобы выполнить игровой тест уровня. При тестировании уровня игрок снова должен появиться с первым оружием из массива WeaponGranters. Убедитесь, что этот так, проверив журнал.
Что дальше
Дальше мы разберём, как выдавать игрокам оружие, когда они зарабатывают очки за устранение.