Разработка игр с помощью SpriteKit и SwiftUI

Недавно я опубликовал статью об использовании SpriteKit вместе со SwiftUI. Я рад сказать, что он был хорошо принят:



В нем я создал простую игру, используя матрицу игровых сцен SpriteKit вместе с некоторым кодом SwiftUI для их упорядочивания. Акцент в приложении был сделан на управлении вашим интерфейсом SwiftUI с помощью SpriteKit.

В этой статье я хочу сделать обратное. Я собираюсь использовать одну игровую сцену, на этот раз в интерфейсе SwiftUI, но с акцентом на SwiftUI, управляющий SpriteKit - во всяком случае, до некоторой степени.

Путешествие

Давайте создадим одну из тех игр, в которых игроку нужно ловить объекты, когда они встречаются. Я собираюсь разделить устройство iOS на два экрана. Верхний экран - это дисплей, а нижний - панель управления (мне нужно было изменить ориентацию для этой статьи).

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

Код SwiftUI в ContentView, очевидно, также сильно отличается: эта статья подробно описывает код шаблона, который мне нужен для жеста drag. Я использую этот жест для непосредственного обновления позиции спрайта.

Вы можете увидеть конечный результат в анимированном GIF-изображении ниже. Создание такого простого интерфейса - свидетельство того, насколько мощны фреймворки Apple.

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

Первое, что мне нужно исправить, - это исчезновение. Я добавил пару строк в GameScene, чтобы исправить это:

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

Я должен упомянуть здесь, что я также рассмотрел SKActions, нашел эту статью Джереми Джейкобсона и попытался использовать кнопки вместо жестов drag, но это показалось мне неправильным, и я вернулся к drag.

Затем мне нужно изменить способ запуска и хода игры. Мне тоже нужно добавить несколько кнопок в интерфейс. Я также хочу добавить еще несколько спрайтов. Я также хотел, чтобы все это выглядело более округлым. Цель на этом этапе - добраться до этого этапа:

Как я это сделал? Во-первых, я добавил две кнопки в ContentView (мое стандартное приложение SwiftUI). Затем я добавил логическую переменную, чтобы начать создание маленьких зеленых камней, и связал ее с действием кнопки. Я также изменил свою теперь зеленую контрольную поверхность на прямоугольник с закругленными углами и добавил маску прямоугольника с закругленными углами к SpriteView.

Затем я перешел к своему GameScene.swift и добавил код для создания зеленых прямоугольников (камней) и случайного размещения их в верхней части экрана (слева в анимированном GIF). Я добавил физику в GameScene и, наконец, настроил блоки так, чтобы они исчезали при попадании в колоду.

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

PhysicsWorld.gravity = CGVector(dy:0, dx:0.1)

Теперь цель моей игры - переместить красный квадрат так, чтобы я ловил зеленые камни. Следующая задача - добавить в микс обнаружение столкновений. Я начинаю с того, что задаю своему красному квадрату физическое тело, хотя я обязательно выключаю гравитационную силу на указанном узле. Я делаю это с помощью этих двух строк:

box.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 40, height: 40))
box.physicsBody?.affectedByGravity = false

Теперь я могу ловить маленькие зеленые камешки - по крайней мере, два квадрата взаимодействуют друг с другом.

Следующий этап - что-то делать при столкновении блоков. Для этого мне нужно использовать протокол делегата, добавив расширение к нашему GameScene, в котором я добавляю код для удаления зеленого камня, если он попадает в красный квадрат. Наш игровой процесс будет выглядеть так:

Я почти закончил. Теперь мне нужна какая-то динамика, которая будет показывать прогресс, когда вы ловите зеленые прямоугольники. Я наткнулся на отличное предложение / расширение для текстурирования спрайтов от Artturi Jalli в этой статье и применил эту идею к игре.

Я отредактировал GameScene так, чтобы и ящик, и камень стирались при столкновении. Последний просто снова появляется как еще один падающий зеленый камень. Первый вариант тоже, но с текстурой, использующей метод, описанный в только что упомянутой мною предыдущей статье.

Я добавил переменную gameOver, чтобы подсчитать, сколько раз происходит столкновение, и массив текстур, которые я буду применять по мере увеличения указанного числа. Текстуры в основном меняют цвет блока с красного на зеленый. Если в вас попадает зеленый камень, а красного у вас не остается, игра окончена. Вот финальная игра в действии:

В сценарии окончания игры ни красный ящик, ни зеленые камни не возвращаются.

В этой статье мы рассмотрели создание GameScene в SwiftUI, управление указанным GameScene с помощью элементов управления в SwiftUI и несколько полезных методов кодирования SpriteKit. Вот окончательный код для GameScene:

И ContentView:

Дополнительный кредит

Что ж, можно было изменить динамику игры. Возможно, тебе удастся заставить зеленый камень падать быстрее. Возможно, вы могли бы добавить несколько зеленых камней. Возможно, тебе удастся сделать зеленые камни больше. Может, красную коробку сделай больше. Может быть, вы сможете изменить задействованные формы. Вы можете добавить таймер. Вы можете изменить поверхность управления с drag на кнопки или даже на ползунок. Вы можете изменить направление, откуда исходят зеленые прямоугольники, и заставить их падать в разных направлениях. Вы даже могли добавить звук, следуя этой статье Дэвида Пайпера. Если вы чувствуете себя очень уверенно, вы можете разделить вид управления и вид дисплея между разными устройствами. Эта статья, которую я написал не так давно, описывает, как это сделать. Когда вы поиграете с этой простой идеей, у вас будет большой потенциал.

На этом я закончу эту статью. Я надеюсь, что вы вставили в него проиллюстрированный код и попытались создать свою собственную версию игры.