Знакомимся с языком Swift на примере игры Snake
Всем привет! В преддверии запуска курса «iOS-разработчик. Базовый курс» мы организовали очередной открытый урок. Этот вебинар рассчитан на людей, которые имеют опыт разработки на любых языках и платформах, однако желают ещё изучить язык Swift и освоить разработку под iOS. На уроке мы подробно разобрали синтаксис и ключевые конструкции языка Swift, познакомились с основными инструментами разработки.
Участники вебинара узнали:
Делаем Snake своими руками
Для работы мы использовали интегрированную среду разработки Xcode. Это удобная, бесплатная и функциональная среда, созданная компанией Apple.
В самом начале создали новый проект и выбрали базовый набор файлов «Game»:
Не мудрствуя лукаво, назвали проект «Snake». Все настройки оставили по умолчанию, убедившись лишь в том, что в строке Game Technology стоит SpriteKit.
После выполнения вышеперечисленных действий в левой части окна отобразится список файлов, автоматически созданных для нашего проекта. Одним из наиболее важных файлов является AppDelegate.swift, который помогает системе связываться с нашим кодом, когда возникают какие-нибудь значимые события для приложения (запуск, пуш, переход по ссылке и т. п.). Код этого файла:
Не менее важными файлами являются GameScene.swift и GameViewController.swift. Класс GameScene создаёт сцену, а GameViewController отвечает за один экран приложения, который мы видим (один экран — один GameViewController). Конечно, это правило поддерживается не всегда, но в целом оно работает. Так как наше приложение довольно простое, у нас будет всего один GameViewController. С него и начнём.
Пишем GameViewController
Код по умолчанию мы удалим. У вью-контроллера есть несколько методов, которые срабатывают в зависимости от состояния экрана. Например, viewDidLoad() срабатывает, когда все элементы экрана уже загрузились, и экран вот-вот отобразится на смартфоне. Так как у нас игра, мы должны в наш вью-контроллер поместить игровую сцену (именно здесь будет бегать змейка и будут происходить все остальные события игры).
let — константа и ключевое слово. В языке Swift используется также и ключевое слово var, необходимое для определения переменной. Используя var, мы можем изменять значение переменных многократно во время работы программы. Используя let, мы не можем изменить значение переменных после инициализации.
Убедившись, что элемент экрана соответствует нужному типу, добавляем к нему нашу сцену:
Также нужно, чтобы показывалось количество кадров в секунду (FPS):
Потом отобразим количество элементов всех типов на сцене:
И сделаем так, чтобы элементы отображались на экране вне зависимости от их порядка в иерархии элементов:
А ещё не забываем о том, что наша сцена должна растягиваться на всю ширину экрана:
Вот итоговый код файла GameViewController.swift:
Итак, мы создали сцену, но она пустая, поэтому если запустим эмулятор сейчас, увидим лишь чёрный экран.
Пишем GameScene
Как и в прошлый раз, большую часть кода удаляем, а потом выполняем необходимые настройки сцены. Здесь также есть свои методы. Например, так как мы добавили нашу сцену во ViewController, нам нужен метод didMove() :
Далее, когда запускается игра, на каждый кадр происходит вызов метода Update() :
И ещё нам понадобится несколько обработчиков нажатия на экран:
Как известно, Swift славится наличием синтаксического сахара. Синтаксический сахар — это такие технические моменты, которые упрощают жизнь разработчику, ускоряют написание кода. Всё это очень помогает при настройке сцены, которой мы сейчас и займёмся. В первую очередь, зададим цвет:
Так как змейка работает в плоскости, физика нам не нужна, и её можно отключить, чтобы змейка не падала вниз из-за гравитации. Также нам не нужно, чтобы игра вращалась и т. п.:
Теперь создадим кнопки:
Когда вы написали какой-то участок кода, следует подумать о том, можно ли код улучшить или отрефакторить так, чтобы его можно было в дальнейшем переиспользовать. Смотрите, у нас на экране по сути две кнопки, для создания которых используется один и тот же код. А значит, этот код можно вынести в отдельную функцию. Для этого создадим новый класс и, соответственно, файл ControlsFactory.swift со следующим кодом:
Чтобы нарисовать рандомное яблоко, которое будет «кушать» наша змейка, создаём класс Apple и файл Apple.swift:
И описываем наше яблоко функцией createApple() в GameScene.swift:
Что же, пришла очередь и для змеи. Она будет состоять из двух частей: тела (SnakeBodyPart.swift) и головы (SnakeHead.swift).
Однако не будем вас утомлять описанием каждой строчки, т. к. подробности создания файла GameScene.swift и других классов хорошо отображены в видео. Предлагаем лишь посмотреть итоговый код GameScene.swift:
Результатом работы стала простейшая игра Snake:
На написание игры у нас ушло около полутора часов. Если хотите получить навыки программирования на Swift, повторите все этапы самостоятельно. Кстати здесь вы получите полный доступ ко всем файлам кода, которые использовались в данном проекте.
Пишем игру «Карточки памяти» на Swift
В этой статье описывается процесс создания простой игры для тренировки памяти, которая мне очень нравится. Кроме того, что она сама по себе хороша, во время работы вы немного больше узнаете о классах и протоколах Swift. Но прежде чем начать, давайте разберемся в самой игре.
Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Как играть в Memory Card
Игра начинается с демонстрации набора карточек. Они лежат «рубашкой» вверх (соответственно, изображением вниз). Когда вы кликаете по любой, на несколько секунд открывается изображение.
Задача игрока — найти все карточки с одинаковыми картинками. Если после открытия первой карты вы переворачиваете вторую и картинки совпадают, обе карточки остаются открытыми. Если не совпадают, карточки снова закрываются. Задача — открыть все.
Структура проекта
Для того, чтобы создать простую версию этой игры нужны следующие компоненты:
У модели карточки будет три свойства: id для идентификации каждой, логическая переменная shown для уточнения статуса карты (скрыта или открыта) и artworkURL для картинок на карточках.
Также будут нужны эти методы для управления взаимодействием пользователя с картами:
Метод для вывода изображения на карту. Здесь мы сбрасываем все свойства на дефолтные. Для id генерируем случайный id путем вызова NSUUIS().uuidString.
Метод для сравнения id карт.
Метод для создания копии каждой карточки — для того, чтобы получить большее число одинаковых. Этот метод будет возвращать card с аналогичными значениями.
И еще один метод нужен для перемешивания карточек на старте. Мы сделаем его расширением класса Array.
А вот реализация кода для модели Card со всеми свойствами и методами.
Вторая модель — MemoryGame, здесь задаем сетку 4*4. У модели будут такие свойства, как cards (массив карточек на сетке), массив cardsShown с уже открытыми карточками и логическая переменная isPlaying для отслеживания статуса игры.
Нам также нужно разработать методы для управления взаимодействия пользователя с сеткой.
Метод, который перемешивает карточки в сетке.
Метод для создания новой игры. Здесь мы вызываем первый метод для старта начальной раскладки и инициализируем переменную isPlaying как true.
Если мы хотим перезапустить игру, то устанавливаем переменную isPlaying как false и убираем первоначальную раскладку карточек.
Метод для верификации нажатых карточек. Подробнее о нем позже.
Метод, возвращающий позицию определенной карточки.
Проверка соответствия выбранной карточке эталону.
Этот метод читает последний элемент в массиве **cardsShown** и возвращает несоответствующую карточку.
Main.storyboard и GameController.swift
Main.storyboard выглядит примерно так:
Изначально в контроллере нужно установить новую игру как viewDidLoad, включая изображения для сетки. В игре все это будет представлено 4*4 collectionView. Если вы еще не знакомы с collectionView, вот здесь можно получить нужную информацию.
Мы настроим GameController в качестве корневого контроллера приложения. В GameController будет collectionView, на который мы будем ссылаться в качестве IBOutlet. Еще одна ссылка — на кнопку IBAction onStartGame (), это UIButton, ее вы можете увидеть в раскадровке под названием PLAY.
Немного о реализации контроллеров:
Теперь давайте немного остановимся на важных протоколах.
Протоколы
Работа с протоколами — основа основ программирования на Swift. Протоколы дают возможность задать правила для класса, структуры или перечисления. Этот принцип позволяет писать модульный и расширяемый код. Фактически это шаблон, который мы уже реализуем для collectionView в GameController. Теперь сделаем собственный вариант. Синтаксис будет выглядеть так:
Мы знаем, что протокол позволяет определить правила или инструкции для реализации класса, поэтому давайте подумаем, какими они должны быть. Всего нужно четыре.
memoryGameDidStart
Когда этот метод запущен, игра должна начаться (пользователь нажимает PLAY). Здесь просто перезагрузим контент, вызвав collectionView.reloadData (), что приведет к перемешиванию карт.
memoryGameShowCards
Вызываем этот метод из collectionSDViewSelectItemAt. Сначала он показывает выбранную карту. Затем проверяет, есть ли в массиве cardsShown несопоставленная карта (если число cardsShown нечетное). Если такая есть, выбранная карта сравнивается с ней. Если картинки одинаковые, обе карты добавляются к cardsShown и остаются открытыми. Если разные, карта уходит из cardsShown, и обе переворачиваются рубашкой вверх.
memoryGameHideCards
Если карты не соответствуют друг другу, вызывается этот метод, и картинки карточек скрываются.
memoryGameDidEnd
Когда вызывается этот метод, означает, что все карты уже открыты и находятся в списке cardsShown: cardsShown.count = cards.count, так что игра окончена. Метод вызывается специально после того, как мы вызвали endGame (), чтобы установить isPlaying var в false, после чего показывается сообщение о завершении игры. Также alertController используется в качестве индикатора для контроллера. Вызывается viewDidDisappear и игра сбрасывается.
Вот как все это выглядит в GameController:
Собственно, вот и все. Вы можете использовать этот проект для создания собственного варианта игры.
Пишем игру «Карточки памяти» на Swift
В этой статье описывается процесс создания простой игры для тренировки памяти, которая мне очень нравится. Кроме того, что она сама по себе хороша, во время работы вы немного больше узнаете о классах и протоколах Swift. Но прежде чем начать, давайте разберемся в самой игре.
Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Skillbox рекомендует: Образовательный онлайн-курс «Профессия Java-разработчик».
Как играть в Memory Card
Игра начинается с демонстрации набора карточек. Они лежат «рубашкой» вверх (соответственно, изображением вниз). Когда вы кликаете по любой, на несколько секунд открывается изображение.
Задача игрока — найти все карточки с одинаковыми картинками. Если после открытия первой карты вы переворачиваете вторую и картинки совпадают, обе карточки остаются открытыми. Если не совпадают, карточки снова закрываются. Задача — открыть все.
Структура проекта
Для того, чтобы создать простую версию этой игры нужны следующие компоненты:
У модели карточки будет три свойства: id для идентификации каждой, логическая переменная shown для уточнения статуса карты (скрыта или открыта) и artworkURL для картинок на карточках.
Также будут нужны эти методы для управления взаимодействием пользователя с картами:
Метод для вывода изображения на карту. Здесь мы сбрасываем все свойства на дефолтные. Для id генерируем случайный id путем вызова NSUUIS().uuidString.
Метод для сравнения id карт.
Метод для создания копии каждой карточки — для того, чтобы получить большее число одинаковых. Этот метод будет возвращать card с аналогичными значениями.
И еще один метод нужен для перемешивания карточек на старте. Мы сделаем его расширением класса Array.
А вот реализация кода для модели Card со всеми свойствами и методами.
Вторая модель — MemoryGame, здесь задаем сетку 4*4. У модели будут такие свойства, как cards (массив карточек на сетке), массив cardsShown с уже открытыми карточками и логическая переменная isPlaying для отслеживания статуса игры.
Нам также нужно разработать методы для управления взаимодействия пользователя с сеткой.
Метод, который перемешивает карточки в сетке.
Метод для создания новой игры. Здесь мы вызываем первый метод для старта начальной раскладки и инициализируем переменную isPlaying как true.
Если мы хотим перезапустить игру, то устанавливаем переменную isPlaying как false и убираем первоначальную раскладку карточек.
Метод для верификации нажатых карточек. Подробнее о нем позже.
Метод, возвращающий позицию определенной карточки.
Проверка соответствия выбранной карточке эталону.
Этот метод читает последний элемент в массиве **cardsShown** и возвращает несоответствующую карточку.
Main.storyboard и GameController.swift
Main.storyboard выглядит примерно так:
Изначально в контроллере нужно установить новую игру как viewDidLoad, включая изображения для сетки. В игре все это будет представлено 4*4 collectionView. Если вы еще не знакомы с collectionView, вот здесь можно получить нужную информацию.
Мы настроим GameController в качестве корневого контроллера приложения. В GameController будет collectionView, на который мы будем ссылаться в качестве IBOutlet. Еще одна ссылка — на кнопку IBAction onStartGame (), это UIButton, ее вы можете увидеть в раскадровке под названием PLAY.
Немного о реализации контроллеров:
Теперь давайте немного остановимся на важных протоколах.
Протоколы
Работа с протоколами — основа основ программирования на Swift. Протоколы дают возможность задать правила для класса, структуры или перечисления. Этот принцип позволяет писать модульный и расширяемый код. Фактически это шаблон, который мы уже реализуем для collectionView в GameController. Теперь сделаем собственный вариант. Синтаксис будет выглядеть так:
Мы знаем, что протокол позволяет определить правила или инструкции для реализации класса, поэтому давайте подумаем, какими они должны быть. Всего нужно четыре.
memoryGameDidStart
Когда этот метод запущен, игра должна начаться (пользователь нажимает PLAY). Здесь просто перезагрузим контент, вызвав collectionView.reloadData (), что приведет к перемешиванию карт.
memoryGameShowCards
Вызываем этот метод из collectionSDViewSelectItemAt. Сначала он показывает выбранную карту. Затем проверяет, есть ли в массиве cardsShown несопоставленная карта (если число cardsShown нечетное). Если такая есть, выбранная карта сравнивается с ней. Если картинки одинаковые, обе карты добавляются к cardsShown и остаются открытыми. Если разные, карта уходит из cardsShown, и обе переворачиваются рубашкой вверх.
memoryGameHideCards
Если карты не соответствуют друг другу, вызывается этот метод, и картинки карточек скрываются.
memoryGameDidEnd
Когда вызывается этот метод, означает, что все карты уже открыты и находятся в списке cardsShown: cardsShown.count = cards.count, так что игра окончена. Метод вызывается специально после того, как мы вызвали endGame (), чтобы установить isPlaying var в false, после чего показывается сообщение о завершении игры. Также alertController используется в качестве индикатора для контроллера. Вызывается viewDidDisappear и игра сбрасывается.
Вот как все это выглядит в GameController:
Собственно, вот и все. Вы можете использовать этот проект для создания собственного варианта игры.
Создаем игру Блекджек в Swift 3 и SpriteKit
Russian (Pусский) translation by Ellen Nelson (you can also view the original English article)
В этом уроке мы будем создавать игру Блэкджек в SpriteKit используя Swift 3. Вы узнаете о взаимодействии с «касанием» (тач), создании визуальной анимации и многих других аспектах, которые будут полезны при создании игр в SpriteKit.
1. Создаём проект и импортируем ресурсы
Откройте Xcode и выберите Create a new Xcode project или выберите New > Project. в меню File. Убедитесь, что выбрано iOS и выберите шаблон Game.
Затем, укажите что угодно в Product Name, Organization Name, и Organization Identifier. Убедитесь, что Language установлен на Swift, Game Technology установлен на SpriteKit, и в Devices выбран iPad.
Выберите куда сохранить файлы проекта и нажмите Создать.
Импорт вспомогательных классов
Загрузите GitHub репозиторий для этого проекта. Там вы найдете папку с классами classes. Откройте эту папку и перетащите все файлы в папку вашего проекта, которую вы могли бы назвать blackjack. Убедитесь, что отмечена галочка «Скопировать при необходимости» — Copy items if needed, а так же указана целевая папка назначения (targets blackjack).
Импортируем изображения
Также, как в этом уроке в репозитории GitHub вы найдёте папку под названием tutorial images. Внутри вашего проекта найдите и откройте Assets.xcassets, а затем переместите туда все изображения из папки. Xcode автоматически создаст атласы текстур из этих изображений.
2. Настраиваем наш проект
В навигаторе проекта есть два файла, которые вы можете удалить (Gamescene.sks и Actions.sks). Удалите эти два файла и выберите Move To Trash. Эти файлы используются встроенным редактором сцен Xcode, который можно использовать для визуальной компоновки ваших проектов. Тем не менее, мы будем создавать все с помощью кода, поэтому эти файлы не нужны.
Откройте GameViewController.swift, удалите его содержимое и замените его следующим.
Теперь, удалите все в файле GameScene.swift и вставьте туда следующее.
Теперь вы можете протестировать проект, вы должны увидеть чёрный-чёрный экран. На следующем этапе мы добавим содержимое в наши сцены.
3. Переменные и константы
4. Реализация setupTable
Так же добавим в сцену moneyContainer (контейнер для денег) и instructionText (текст со справкой). Установим цвет шрифта fontColor для instructionText как черный (по умолчанию он белый).
Обновите didMove(to:) до следующего состояния.
5. Реализация setupMoney
Добавьте следующее после метода setupTable
6. Реализация setupButtons
Если вы запустите приложение сейчас, вы увидите, что экземпляры денег и кнопок были добавлены в сцену.
7. Реализация touchesBegan
8. Реализация ставки bet
9. Реализация раздачи deal
Добавьте следующее к остальным вашим константами и переменным.
Мы прошли через логическую цепочку. Если что-то неясно, то просто почитайте ещё раз не торопясь, чтобы лучше понять.
10. Реализация окончания игры doGameOver
11. Реализация moveMoneyContainer
12. Реализация сброса кона resetMoneyContainer
13. Реализация newGame
Теперь, мы сбрасываем все необходимые переменные и убираем все карты из сцены, пройдя через массив allCards и вызвав removeFromParent() для каждого элемента.
14. Реализация hitBtn и standBtn
Теперь вы можете попробовать завершенную игру.
Заключение
Это был длинный урок с хорошо продуманной логикой, спрятанной в работе методов. Мы не применили Pot (горшок, банка), добавление и вычитание денег из банка игрока. Почему бы вам не попробовать сделать это как упражнение, чтобы закончить приложение?
Теперь вы можете гордиться своей игрой в блэкджек. Спасибо за чтение и я надеюсь, вы нашли этот урок полезным. Пока вы ещё здесь, посмотрите наши другие курсы и уроки о разработке приложений со Swift и SpriteKit!
Курс: Фреймворк для создания игр SpriteKit
Содержание
Над этим курсом мы усердно работали, чтобы вы смогли не просто написать игру, но и познакомиться с важными аспектами программирования, которые используются не только при создании игр, но и в программировании на Swift в целом.
При написании игры мы с вами познакомимся:
Мы с вами напишем полноценную игру, которую вы сможете выложить в AppStore!
Пусть вас не смущает меню на английском языке. Мы хотим, чтобы вы, проходя наши курсы, постоянно слышали новые термины на английском языке и осваивали их, ну а меню нам в этом немного помогает.
Содержание курса
1 Intro (0:57)
2 Demo project (23:57)
3 Cleaning project (6:15)
4 Adding background (10:23)
5 Adding islands (16:36)
6 Adding clouds (13:56)
7 Player plane class (8:04)
8 Movement by CoreMotion (15:20)
9 Islands movement (14:16)
10 Moving background (7:00)
11 Remove from scene 8:54)
12 Cleaning our project (7:41)
13 Turning plane animation (12:56)
14 Turning plane animation. Part 2 (23:31)
15 Power Up (11:59)
16 Little code refactoring (13:35)
17 Creating class Enemy (9:06)
18 Enemy movement (15:15)
19 Enemy final movement (19:20)
20 PowerUp classes (14:15)
21 PowerUp movement logic (11:27)
22 Player fire ability (11:11)
23 Preload atlases (10:13)
24 Menu scene (9:08)
25 Physics body (18:47)
26 Collisions (7:37)
27 Physics body with CGPath (6:41)
28 Bit masks advanced (14:33)
29 User Interface (21:48)
30 Make it nice (6:40)
31 Menu interface (19:18)
32 Pause scene (5:47)
33 Scene manager (10:54)
34 Pause logic (12:33)
35 Scene logic (18:51)
36 Best scene (10:39)
37 Collision explosion (11:07)
38 Update lives (7:52)
39 Game over scene (9:27)
40 Home Task Wrap Up (7:32)
41 Music and sound (6:14)
42 UserDefaults (14:53)
43 Scores (8:20)
44 Publish your awesome app (11:21)
Общая продолжительность курса 8 часов 46 минут 54 секунды!