В этом уроке для реализации некоторых функций используется язык Verse. Воспользовавшись кодом Verse из этого урока, вы сможете:
Периодически запускать и воспроизводить анимации для создания игровой механики.
Обновляет информацию об очках игрока для всех игроков в мини-игре.
Настраивайте задержки появления игроков и время периодического появления предметов.
Вы можете использовать этот код повторно, чтобы:
Включать и отключать устройства, когда игра переходит из режима ЦЕНТРА в режим игрового процесса и обратно в режим ЦЕНТРА.
Проверять счёт игроков, чтобы определить лучший результат и отобразить его в ЦЕНТРЕ.
Завершить игру и телепортировать игроков обратно в ЦЕНТР по окончании мини-игры.
Настройка устройства Verse и редактируемых объектов
Выполните следующие действия, чтобы настроить устройство Verse и редактируемые объекты:
Создайте новое устройство Verse с именем
tiltnboomи добавьте его на уровень. Порядок действий см. в разделе «Создание собственного устройства с помощью Verse».Добавьте следующие модули в начале файла:
Verseusing { /Fortnite.com/Characters } using { /Fortnite.com/Devices } using { /Fortnite.com/Game } using { /UnrealEngine.com/Temporary/Diagnostics } using { /Verse.org/Random } using { /Verse.org/Simulation }Добавьте следующие поля в определение класса
tiltnboom:Два редактируемых устройства
trigger: ActivateGameTrigger и EndGameTrigger.ActivateGameTriggerиспользуется для активации этой игры. Триггер может быть активирован чем угодно, например телепортом в игру или завершением вступительного видеоролика.EndGameTriggerиспользуется для завершения мини-игры и последующего удаления всех камер и устройств управления у игроков.
Verse@editable ActivateGameTrigger:trigger_device = trigger_device{} @editable EndGameTrigger:trigger_device = trigger_device{}Редактируемое устройство «Таймер» с именем GameTimer. Через определённое время завершает игру.
Массив
arrayустройств «Последовательность внутриигрового видео» с именемCannonballSequences. Каждое устройство в этом массиве воспроизводит попадание пушечного ядра в определённое место.Массив зон поражения с именем DamageVolumes, которые включаются и отключаются в зависимости от состояния игры.
Массив генераторов предметов с именем ItemSpawners, которые случайным образом создают случайное количество предметов во время игры.
Устройство «Область захвата» с именем CaptureArea. Начисляет игрокам очки за нахождение на плоту и включается/отключается в зависимости от состояния игры.
Устройство «Панель управления счётом» с именем
ScoreManager, которое сбрасывает счёт игроков в начале игры и определяет победителя в конце игры.Телепорт с именем
HUBTeleporter, который возвращает всех игроков в ЦЕНТР по окончании игры.Устройство «Упоминание игрока» с именем PlayerReference, которое отображает победителя в ЦЕНТРЕ между играми.
Verse@editable GameTimer:timer_device = timer_device{} @editable CannonballSequences:[]cinematic_sequence_device = array{} @editable DamageVolumes:[]damage_volume_device = array{} @editable
Два редактируемых массива точек появления игроков с именами
PlayerSpawnersиHUBSpawners. Отключают появление и возвращают игроков в ЦЕНТР после завершения мини-игры.Verse@editable PlayerSpawners:[]player_spawner_device = array{} @editable HUBSpawners:[]player_spawner_device = array{}Две редактируемые переменные типа
floatс именамиMinimumItemSpawnTimeиMaximumItemSpawnTime. Это минимальное и максимальное время ожидания между появлением предметов на плоту.Verse@editable MinimumItemSpawnTime:float = 5.0 @editable MaximumItemSpawnTime:float = 10.0Редактируемая переменная типа
floatс именемDelayAfterGame. Это задержка телепортации игроков обратно в ЦЕНТР после завершения игры.Verse@editable DelayAfterGame:float = 5.0Переменная
floatс именемDelayBetweenCannonballSequences. Задержка появления пушечных ядер между последовательностями на протяжении всей мини-игры.VerseDelayBetweenCannonballSequences:float = 8.0Логическая переменная с именем
GameActive, которая определяет активное или неактивное состояние игры.Versevar GameActive:logic = false
Начало игры
Когда начинается мини-игра, включается несколько устройств и счёт игрока сбрасывается на 0.
Перед определением класса
tiltnboomдобавьте канал записи в журнал сообщений, относящихся к мини-игре. Затем добавьте средство ведения журнала в определение класса для использования с каналом ведения журнала.Versetiltnboom_log_channel := class(log_channel){} # A Verse-authored creative device that can be placed in a level tiltnboom := class(creative_device): Logger:log = log{Channel := tiltnboom_log_channel}Добавьте новый метод
OnTriggeredв определение классаtitnboom, который принимает значениеInitiatingAgentи запускает игру. Добавьте выражение if в метод, чтобы он возвращал управление, если игра уже активна, поскольку нам не нужно запускать игру, если она уже запущена.VerseOnTriggered(InitiatingAgent:?agent):void= if (GameActive?): return spawn{StartGame()}В
OnBegin()подпишите событиеTriggeredEventв ActivateGameTrigger на функциюOnTriggered, чтобы запускать игру. Любое устройство, которое необходимо включить в начале мини-игры, будет подписано на это событие и включится при возникновении события OnTrigger.VerseOnBegin<override>()<suspends>:void= ActivateGameTrigger.TriggeredEvent.Subscribe(OnTriggered)Добавьте новый метод
StartGame(), управляющий логикой запуска игры. Добавьте модификатор<suspends>к этой функции, чтобы она могла запускаться асинхронно.Сначала задайте для
GameActiveзначениеtrue, чтобы сигнализировать о том, что игра активна, а затем включитеCaptureAreaи каждую зонуDamageVolumeв массивеDamageVolumes.Сбросьте на ноль счёт каждого игрока, у которого он больше 0. Для этого начислите такому игроку количество очков, противоположное текущему; в результате счёт станет равен 0.
Затем в выражении race задайте конкурентное выполнение завершения отсчёта таймера, последовательностей запуска пушечных ядер и появления случайных предметов. Последовательность запуска пушечных ядер и появление случайных предметов выполняются в бесконечных циклах, но они прерываются, как только таймер завершает отсчёт.
По завершении игры вызовите функцию
OnGameFinished(), чтобы выполнить очистку.VerseStartGame()<suspends>:void= Logger.Print("Starting game.") set GameActive = true CaptureArea.Enable() for (DamageVolume : DamageVolumes): DamageVolume.Enable() for:
Создание цикла пушечного ядра
В этом разделе мы создадим функцию, которая воспроизводит последовательности внутриигрового видео для пушечных ядер.
Добавьте в определение класса
tiltnboomновый методStartCannonSequence(), который воспроизводит видеоряды для пушечных ядер и использует цикл для выполнения выражения задержки между анимациями пушечных ядер. Добавьте модификатор<suspends>к этой функции, чтобы она могла запускаться асинхронно.В цикле выберите случайную последовательность из массива
CannonballSequences, определив индекс элемента с помощьюGetRandomInt(). Воспроизведите последовательность, а затем вставьте задержку (Sleep) длительностьюDelayBetweenCannonballSequences, прежде чем воспроизводить другую последовательность.VerseStartCannonSequence()<suspends>:void= loop: RandomCannonballSequence:int = GetRandomInt(0, CannonballSequences.Length - 1) if (CannonballSequence := CannonballSequences[RandomCannonballSequence]): Logger.Print("Set CannonballSequence to {RandomCannonballSequence}") CannonballSequence.Play()
Создание циклов случайного появления предметов
Этот раздел посвящён созданию функции, которая обеспечивает повторное появление случайных предметов в случайных местах на плоту, что может повышать или понижать шансы игроков на победу в мини–игре.
В определении класса
titlnboomдобавьте новый методSpawnRandomItems. Этот метод управляет появлением предметов на плоту.Получите количество элементов в массиве
ItemSpawners, а затем переберите элементы массива в цикле. Используйте случайное числоint, чтобы получить случайный генератор предметов из массива, а затем активируйте его. Вставьте случайную задержку (Sleep) между появлением предметов.В цикле случайным образом определяется, сколько предметов нужно создать, и случайным образом выбирается предмет для создания
NumberOfItemsToSpawnраз.DelayBetweenItemSpawnsзадаёт неопределённое время ожидания между появлением предметов.VerseSpawnRandomItems()<suspends>:void= ItemSpawnerCount:int = ItemSpawners.Length - 1 loop: NumberOfItemsToSpawn:int = GetRandomInt(0, ItemSpawnerCount) # Spawn a randomly selected item, as many times as NumberOfItemsToSpawn. for: CurrentItemSpawnNumber := 0..NumberOfItemsToSpawn
Завершение игры
В конце мини-игры нужно отправить результат победителя в ЦЕНТР, отключить устройства и телепортировать игроков обратно в ЦЕНТР.
В определении класса
tiltnboomдобавьте новый методOnGameFinished. Когда игра закончится, эта функция переведёт её в неактивный режим и отключит соответствующие устройства.~~~(verse) OnGameFinished()<suspends>:void= Logger.Print("Конец игры.") set GameActive = false
CaptureArea.Disable()
for (PlayerSpawner : PlayerSpawners): PlayerSpawner.Disable()
for (DamageVolume : DamageVolumes): DamageVolume.Disable() ~~~
Добавьте переменную
HighestScoreтипаintдля отслеживания игрока с лучшим счётом и переменную-ссылкуWinningPlayerтипа option на этого игрока.Versevar HighestScore:int = -1 var WinningPlayer:?agent = falseВ выражении for/do получите всех игроков в игровом пространстве, а затем получите
FortCharacterдля каждого из них. Запретите игроку перемещаться с помощьюPutInStasis(), передав новый наборstasis_args, позволяющий проявлять эмоции и поворачиваться, чтобы игроки могли повеселиться в игре.Versefor: Player : GetPlayspace().GetPlayers() FortCharacter := Player.GetFortCharacter[] do: FortCharacter.PutInStasis(stasis_args{AllowTurning := true, AllowEmotes := true})С помощью выражения
ifпроверьте счёт каждого игрока, чтобы найти и сохранить лучший счёт в устройстве «Упоминание игрока» в ЦЕНТРЕ.Verseif (ScoreManager.GetCurrentScore(Player) > HighestScore): set HighestScore = ScoreManager.GetCurrentScore(Player) set WinningPlayer = option{Player}Наконец, в другом выражении if вызовите
TeleportPlayersToHUB(), чтобы телепортировать всех игроков обратно в ЦЕНТР, когда лучший счёт будет определён.Verseif(Winner := WinningPlayer?): PlayerReference.Register(Winner) TeleportPlayersToHUB()
Телепортация игроков обратно в ЦЕНТР
Когда будет определён счёт всех игроков и объявлен победитель, все игроки должны телепортироваться обратно в ЦЕНТР.
Добавьте новый метод
TeleportPlayersToHUB()в определении класса tiltnboom. Этот метод включает все генераторы игроков в ЦЕНТРЕ, а затем ждёт несколько секунд, прежде чем телепортировать всех обратно в ЦЕНТР. Также этот метод должен активироватьEndGameTrigger, чтобы удалить камеру и устройства управления у игроков.VerseTeleportPlayersToHUB()<suspends>:void= for (HUBSpawner : HUBSpawners): HUBSpawner.Enable() Sleep(DelayAfterGame) EndGameTrigger.Trigger()В выражении
forтелепортируйте каждого игрока обратно вHUBTeleporterи освободите его из стазиса.Versefor: Player : GetPlayspace().GetPlayers() FortCharacter := Player.GetFortCharacter[] do: HUBTeleporter.Teleport(Player) Sleep(1.0) FortCharacter.ReleaseFromStasis()
Самостоятельная работа
Измените этот код, чтобы использовать устройство «Таймер» для решения других задач. Вместо того чтобы определять продолжительность мини-игры, можно использовать устройство «Таймер» для задания времени конкурентного выполнения.
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
tiltnboom_log_channel := class(log_channel){}
# A Verse-authored creative device that can be placed in a level