Узнайте, как использовать протокол Preferences

Хотя я достаточно уверен, что Конфуций, живший примерно в 450 г. до н.э., не был программистом, некоторые советы, которые он давал об обучении, как нельзя более верны, когда дело доходит до программирования.

Скажи мне, и я забуду;
Покажи мне, и я запомню;
Вовлеки меня, и я пойму.

Так что присоединяйтесь ко мне в этой статье, чтобы понять, как создать простую игру, похожую на змею. Код, в котором я коснусь протокола настроек в SwiftUI, GeometryReader и т. д.

Игра

Как вы могли догадаться, я не разрабатывал игру для запуска слева направо, но мне нужно было откатиться в сторону, чтобы показать вам. Поэтому поверните экран вправо, чтобы увидеть его правильно.

Вы смотрите на каждую петлю фигур, связанную с каждой петлей линий через протокол настроек. Я использую задержку для перемещения различных сегментов, когда я перетаскиваю голову, потому что это выглядит лучше. Формы, проходящие слева направо, начинаются как круги, которые вам нужно поймать. Не успеете сделать это к тому времени, когда они доберутся до середины экрана и превратятся в звезды. Звезды, которых вы не хотите ловить. Когда вы ловите круг, змейка увеличивается на один сегмент. Случайно поймаете звезду или полностью пропустите круг [который становится звездой], и змея сожмется на отрезок. Конечная игра наступает, когда змее больше нечего терять.

Дизайн

На прошлой неделе я опубликовал статью о другой игре, которую я только что создал, которую вы можете найти здесь. Он тоже опирался на круги и линии; Но я сделал это совсем по-другому. Чтобы построить внутри него графоподобную структуру, я предопределил все координаты. Но в данном случае мне нужно было иметь возможность построить его динамически, поэтому я обратился к протоколу настроек SwiftUI.

Доказательство концепции

Анимированный GIF-файл показывает POC со всеми основными элементами на месте — у меня есть змея, передача вещей, чтобы поймать или нет, и происходит подсчет очков, куда идти дальше. В первую очередь, на мой взгляд, фраза меньше значит больше.

  • В большинстве игр есть какие-то этапы или задачи — нужно их выполнить.
  • В большинстве игр есть несколько уровней, к которым вы можете присоединиться — нужно сделать.
  • В большинстве игр есть своего рода рейтинговая таблица — это необходимо.

Больше вызовов

Бон, на данный момент у меня есть «ягодки», если хотите, которые падают с постоянной скоростью. Если змея промахивается по ним посреди экрана, то ей нужно их избегать. Какие легкие победы? Вот некоторые мысли о том, как я мог бы сделать игру более сложной без большого количества кода.

  • Я мог бы представить «ягоды», которых ему вообще нужно избегать?
  • Я мог бы ввести «ягоды», которые падают с разной скоростью, какие-то быстрее, какие-то медленнее?
  • Я мог бы представить «ягоды», которые меняют свою кожуру в какой-то случайный момент на своем пути?
  • Я мог бы сделать некоторые «ягоды» более ценными, чем другие, и иметь некоторый механизм подсчета очков.
  • Я мог заставить «ягодки» падать с разной скоростью?
  • Что касается змеи, то изменение формы сегментов было бы отличным способом контролировать уровень сложности; чем крупнее змееголов, тем легче ему ловить «ягодки»?
  • Я мог бы замедлить скольжение змеи, когда она станет больше.
  • Сейчас я могу сделать его тело уязвимой точкой. Дальше головы ничего не происходит.
  • Возвращаясь к ценности ягод, я мог заставить змею расти быстрее или медленнее.

Доказательство концепции, часть 2

Хорошо, как это выглядит — . Формат змеи немного изменился, но более или менее остался прежним, за исключением анимации хвоста, которая становится медленнее по мере увеличения длины. Ягоды теперь бывают четырех вкусов; чем темнее вы хотите поймать, тем светлее вы не поймаете. И все они теперь движутся с разной скоростью.

Применяются те же правила: поймай ягоду, хвост удлинится, брось ягоду и она станет короче. Поймать не ту ягоду хвост становится короче. Это гораздо более быстрая игра, чем POCI.

Покажи мне код

Бон — хватит текста и картинок — как я это сделал. Как я уже сказал, ключ заключается в реализации протокола настроек SwiftUI, который выглядит следующим образом.

Я создал структуру, в которой я храню значение индекса и CGRect. Я назвал эту структуру для сохранения в шаблоне протокола настроек, а затем создал третью структуру для ее использования.
Кроме того, я создал структуру PreferenceViewSetter в качестве фона сегментов змеи. Так и с этим фрагментом кода.

RoundedRectangle(cornerRadius: 8)
  .stroke(Color.black, lineWidth: 2)
  .frame(width: 24, height: 24)
  .background(PreferenceViewSetter(idx: idx))

Код, который я вызываю в цикле, говорит, сколько сегментов мне нужно. Это цикл, размер которого я меняю по ходу игры. Я получил этот код вне цикла, рисуя сегменты.

.onPreferenceChange(TextPreferenceKey.self) { preferences in
  for p in preferences {
    self.rects[p.viewIdx] = p.rect
  }

Он сохраняет CGRects, поскольку каждый сегмент рисуется во внешнем массиве, на который я впоследствии снова ссылаюсь с этой структурой в том же прогоне, что и рисование сегментов.

Снова вызываемая внутри цикла, эта процедура рисует линию между каждым сегментом змеи. Собрав все это вместе, это выглядит так. SnakeView здесь отрисовываются настройки обновлений сегментов, которые обновляют массив reacts — массив, прошедший обратно к отрисовке линий.

Реализация ягодных капель намного проще и просто использует таймер для запуска массива ягодных данных, на которые нужно воздействовать.

Все это подводит меня к концу этого короткого отрывка. Загрузите всю кодовую базу с битбакета по этой ссылке, чтобы принять более активное участие, как советовал Конфуций. Используйте его как основу для создания собственной игры про змей!