Вступление
Эта серия статей познакомит вас с двумя новейшими технологиями Apple, Swift и SpriteKit. Swift — это новый язык программирования, продвигаемый как « язык для будущего разработки программного обеспечения Apple ». SpriteKit — это первая платформа Apple для разработки игр, стандартная для SDK. Он поддерживает iOS начиная с версии 7 и Mac OS X.
Мы не будем обсуждать каждую деталь, вместо этого вы изучите основы Swift, создав простую игру. Для подробного обсуждения языка есть официальная книга Apple по этому вопросу. Хотя это и не обязательно для этого курса, настоятельно рекомендуется прочитать, если вы серьезно относитесь к изучению Swift.
Что касается SpriteKit, мы не будем широко использовать его в нашей игре. Нам нужны только самые основные возможности для отображения простых спрайтов на экране. Основное внимание в этом курсе остается на Swift.
Игра, которую вы будете создавать, вдохновлена очень популярной головоломкой 80-х годов. Скорее всего, вы знакомы с этой игрой и, возможно, даже играли в нее один или два раза, или даже больше, если вы фанат игры, как я. Вот краткий обзор того, что вы собираетесь сделать:
Любой, кто заинтересован в изучении Swift, приветствуется. Вы не должны стремиться к карьере в разработке игр, чтобы извлечь выгоду из этой серии. Создание простой игры не является пугающим первым шагом в знакомстве с новой технологией. Обучение становится более эффективным, когда вам весело, и я надеюсь, что вы повеселитесь в этой серии.
Вы не должны быть опытным программистом, чтобы иметь возможность следовать за ним. Фундаментальные знания концепций программирования, таких как переменные, константы, управляющие структуры и другие базовые конструкции, есть, и их цели более чем достаточно, чтобы чувствовать себя комфортно в дискуссиях.
С недавними выпусками iOS 8.1, OS X Yosemite, Xcode 6.1 и множеством новых устройств Apple, сейчас, безусловно, самое подходящее время, чтобы начать изучать их и инвестировать в будущее разработки программного обеспечения Apple.
Создание проекта
Вам потребуется как минимум Xcode 6. Если у вас более старая версия, загрузите последнюю версию Xcode из Mac App Store . Давайте создадим и настроим игровой проект:
-
Запустите Xcode и создайте новый проект.
-
Выберите шаблон Game под платформой iOS и нажмите Next.
-
На экране « Параметры» заполните поле « Имя продукта» названием проекта. Вы можете назвать свой проект «Кирпичи», « Тетромино » или что-то более крутое, что вы имеете в виду. Для краткости я буду называть мои «Кирпичи».
Введите название вашей организации, которое может быть вашей компанией или вашим собственным именем. Для идентификатора организации рекомендуется использовать домен, который вы ввели в обратном DNS-обозначении. Использование собственного домена гарантирует, что сгенерированный идентификатор пакета является уникальным.
Выберите Swift и SpriteKit для используемого языка и технологии. А пока давайте сосредоточимся в первую очередь на iPhone в качестве целевой платформы. Нажмите Далее, чтобы создать и сохранить проект.
-
Выберите подходящее место для проекта. Лично я предпочитаю сохранять текущие проекты на рабочем столе для быстрого доступа. Убедитесь, что управление версиями включено, отметив опцию Source Control как проверенную перед созданием проекта. Если у вас нет опыта работы с Git и у вас есть свободные 15 минут, проверьте try.github.io, чтобы узнать больше об этом.
Теперь у вас есть общий игровой проект с некоторым стандартным кодом. Нажмите ⌘ + R, чтобы запустить проект в симуляторе. Если вы видите негабаритный симулятор, вы можете уменьшить его, нажав ⌘ + 3 . Нажмите ⌘ + 1, чтобы вернуться к исходному размеру.
Поиграйте, чтобы почувствовать симулятор, а затем вернитесь в Xcode. Мы будем изменять некоторые настройки проекта, которые подходят для нашей игры, и удалять ненужные файлы.
-
Наша игра будет работать только в портретной ориентации, поэтому давайте снимем оба параметра Ориентация устройства в разделе « Информация о развертывании ».
Если вы не видите этот экран, убедитесь, что вы находитесь на вкладке Project Navigator ( ⌘ + 1 ) и выбран основной проект.
-
Выберите и удалите GameScene.sks. Убедитесь, что вы переместили файл в корзину.
-
Нам также не понадобится изображение космического корабля, поэтому удалите его. На самом деле, в этом проекте нам не понадобятся изображения. Все будет нарисовано программно с использованием спрайтов и массивов.
Перед сборкой и запуском проекта сначала выполните операцию очистки, нажав ⇧ + ⌘ + K (shift + command + K), чтобы удалить предыдущие сборки проекта, которые могут содержать ресурсы, которые мы уже удалили.
Когда вы запустите проект, вы увидите пустой вид. В следующем разделе мы начнем рисовать что-то на этом пустом экране.
Рисование блока
Взгляните на короткую анимацию геймплея во введении. Вы заметили образец? Быстрый анализ нашей игры скажет нам, что все в ней построено из квадратов или блоков. Буквально, блоки являются строительными блоками игры!
Эти блоки систематически расположены для формирования конечного набора форм, называемых тетромино. Но прежде чем мы попытаемся нарисовать эти более сложные формы тетромино, давайте сначала сосредоточимся на более простой задаче рисования одного блока.
GameViewController
Идите вперед и обновите код по умолчанию в файле GameViewController.swift с помощью приведенного ниже. Не копируйте и не вставляйте. Вместо этого попытайтесь определить, какие строки являются новыми, а какие были удалены или заменены. Ручной ввод и заблаговременный выбор того, какой код добавить, даст вам лучшее представление о языке, а также улучшит ваше обучение.
import SpriteKit class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Configure the view. let skView = view as SKView skView.showsFPS = true skView.showsNodeCount = true /* Sprite Kit applies additional optimizations to improve rendering performance */ skView.ignoresSiblingOrder = true let scene = GameScene(size: skView.bounds.size) /* Set the scale mode to scale to fit the window */ scene.scaleMode = .AspectFill skView.presentScene(scene) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Release any cached data, images, etc that aren't in use. } override func prefersStatusBarHidden() -> Bool { return true } }
Добавлена лишь небольшая часть нового кода, а несколько строк ненужного кода были удалены. Переключите редактор версий, чтобы просмотреть подробные сведения обо всех внесенных вами изменениях. Вы также можете зафиксировать эти изменения в своем репозитории либо через терминал, либо через встроенные команды XCode Source Control . Если вам пока не удобно работать с Git, не беспокойтесь о выполнении каких-либо процедур репозитория в вашем коде. Это не требуется в этой серии, но это хорошая привычка приобретать рано.
Точка с запятой
Первое, что вы особенно заметите, когда исходите из C, C ++ или Java, — это отсутствие точек с запятой. Разработчики Python, с другой стороны, будут приветствовать этот знакомый стиль.
Точки с запятой в Swift не обязательны. Это означает, что вы можете, но вам не нужно помещать их в конце каждого оператора, кроме случаев, когда вы объединяете два или более операторов в одной строке:
let skView = view as SKView; skView.showsFPS = true
Но для удобства чтения кода избегайте объединения нескольких операторов в одной строке.
Импорт модулей
Неудивительно, что import
позволяет импортировать или получать доступ к коду из внешнего источника и использовать его в своих собственных проектах. В нашем случае мы хотим использовать инфраструктуру SpriteKit, поэтому мы объявляем это в начале нашего файла исходного кода.
import SpriteKit
Классы
После импорта GameViewController
нам структуры мы объявляем класс с именем GameViewController
который наследуется от UIViewController
. Класс UIViewController
управляет управлением представлениями для нашей игры. Вы можете узнать больше об этом классе и других каркасных классах, нажав ⌥ + (опция + щелчок) на их названиях.
Класс — это тип объекта со своим поведением и свойствами. В нашем коде GameViewController
объявлен как подкласс UIViewController
который называется суперклассом. Таким образом, GameViewController
наследует поведение и свойства UIViewController
.
class GameViewController: UIViewController {
функции
Как подкласс, GameViewController
может изменить или расширить предопределенное поведение своего суперкласса. В этом случае мы переопределяем функцию viewDidLoad
суперкласса для выполнения наших собственных операций. Для функции класса более точный термин — метод .
Функции в Swift определяются с помощью ключевого слова func
за которым следует имя функции, параметры, тип возвращаемого значения, а затем тело функции, заключенное в фигурные скобки. Что касается viewDidLoad
, мы описываем его как функцию, которая не принимает параметров и ничего не возвращает.
override func viewDidLoad() {}
При переопределении метода родительского класса, подкласс все еще может получить доступ к собственной реализации метода родительского класса через использование super
префикса. Это позволяет вам строить поверх оригинальной реализации, добавляя свои собственные процедуры.
super.viewDidLoad()
Мы узнаем больше о функциях и методах по мере продвижения в этой серии. Ожидайте встречи с примерами, которые содержат больше элементов, таких как возвращаемые типы и параметры.
Константы и переменные
Swift — главный защитник неизменности, который добавляет еще один уровень защиты от ошибок, вызванных непреднамеренным изменением ценностей. Мы используем ключевое слово let
для объявления неизменяемых значений или констант.
let skView = view as SKView
С другой стороны, мы используем ключевое слово var
для изменяемых значений или переменных. Вот предыдущий оператор, написанный как объявление переменной. Однако мы объявляем переменные только в том случае, если уверены, что их значения изменятся в какой-то момент в нашей игре.
var skView = view as SKView
Вывод типа
На первый взгляд вы можете предположить, что Swift является свободно типизированным языком или не требует установки типов для переменных и констант. Но Swift — это строго типизированный язык, или, точнее, типобезопасный язык .
Swift устанавливает тип ваших переменных и констант во время компиляции, используя вывод типа . Этот механизм позволяет компилятору определять соответствующий тип переменной или константы, проверяя присвоенное им значение.
Если вы всегда устанавливаете начальное значение для своих констант и переменных, вам не нужно явно объявлять их тип каждый раз.
Доступ к свойствам
К свойствам skView
можно получить доступ с использованием точечного синтаксиса . Мы ставим точку в конце имени экземпляра, за которым сразу же следует имя свойства.
Здесь мы устанавливаем некоторую полезную диагностическую информацию для отображения в представлении. Однако обратите внимание, что информация FPS ( Frames Per Second ) является точной только тогда, когда игра тестируется на реальном устройстве, а не на симуляторе.
skView.showsFPS = true skView.showsNodeCount = true
Комментарии
Комментарии позволяют вам комментировать ваш код, чтобы помочь читаемости и ясности для всех участников проекта. Комментарии также используются для удобного отключения определенных частей вашего кода без полного их удаления.
Есть два способа написания комментариев: многострочный и однострочный. Код по умолчанию, предоставляемый Xcode, включает однострочный комментарий, выраженный многострочным синтаксисом:
/* Sprite Kit applies additional optimizations to improve rendering performance */ skView.ignoresSiblingOrder = true
Это может быть более удобно выражено как:
// Sprite Kit applies additional optimizations to improve rendering performance skView.ignoresSiblingOrder = true
Если вы не найдете комментарий слишком длинным для одной строки и предпочитаете разделить его на две отдельные строки:
/* Sprite Kit applies additional optimizations to improve rendering performance */ skView.ignoresSiblingOrder = true
Что касается этой строки кода, мы устанавливаем для skView
‘s ignoresSiblingOrder
значение true
поскольку мы не заботимся о порядке рендеринга, и в нашей игре не будет перекрывающихся элементов.
Я намеренно не поместил ни один из моих собственных комментариев в код, чтобы избежать дублирования того, что уже объяснено в руководствах. Тем не менее, вам рекомендуется сделать написание заметных комментариев привычкой и частью вашего рабочего процесса наряду с контролем версий.
Конкретизация
Мы создаем новый экземпляр класса, используя синтаксис инициализатора . Самая простая форма — ничего не передавать имени класса с помощью пустых скобок.
let scene = GameScene()
Но в нашем случае нам нужно передать значение размера на основе ограничивающего прямоугольника представления. Обратите внимание на использование именованного size
параметра, который требуется при инициализации нового экземпляра класса. Это полезная языковая функция, перенесенная из Objective-C для удобства чтения.
let scene = GameScene(size: skView.bounds.size)
Перечисления
Перечисления, как и в классах, также определяют пользовательский тип, но для группы связанных значений. Здесь .AspectFill
является одним из значений, определенных типом перечисления.
scene.scaleMode = .AspectFill
Обратите .AspectFill
Отсутствие префикса .AspectFill
. Это еще одна демонстрация вывода типа . Если заглянуть глубже в свойство scaleMode
scene
нажав + (option + click) на него в редакторе, мы обнаружим, что оно объявлено как переменная типа SKSceneScaleMode
которая является перечислением, содержащим .AspectFill
качестве одного из ее членов.
Это означает, что мы также можем выразить это как:
scene.scaleMode = SKSceneScaleMode.AspectFill
Но такое многословие не требуется в Swift.
Доступ к методам
Метод доступа использует тот же точечный синтаксис, что и доступ к свойству. Вы вызываете метод так же, как вы вызываете функцию, передавая параметры в наборе круглых скобок.
skView.presentScene(scene)
Прибытие в части 2
После того, как мы рассмотрим большую часть базовой структуры Swift в этой статье, далее мы рассмотрим рисование в GameScene и многое другое!