Статьи

Основы SpriteKit: спрайты

В этой серии мы узнаем, как использовать SpriteKit для создания 2D-игр для iOS. В этом посте мы продолжим наше исследование узлов SpriteKit и узнаем об особом виде узлов, называемых «спрайтами» — SKSpriteNode .

Чтобы следовать этому уроку, просто загрузите прилагаемое репозиторий GitHub . В нем есть папка с именем ExampleProject Starter . Откройте проект в этой папке в Xcode, и вы готовы к работе!

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

Добавьте следующее в метод didMove(to:) в GameScene.swift .

1
2
3
4
5
6
7
8
9
override func didMove(to view: SKView) {
    let startGameLabel = SKLabelNode(text: «Start Game»)
    startGameLabel.name = «startgame»
    startGameLabel.position = CGPoint(x: size.width/2, y: size.height/2)
    addChild(startGameLabel)
         
    let redSprite = SKSpriteNode(color: .red, size: CGSize(width: 200, height: 200))
    addChild(redSprite)
}

Здесь мы используем удобный инициализатор init(color:size:) который нарисует прямоугольный спрайт с цветом и размером, которые вы передаете в качестве параметров. Если вы протестируете проект сейчас, вы увидите половину красного квадрата.

красный спрайт

Вы можете задаться вопросом, почему показывается только половина спрайта, поскольку мы уже определили, что SKNode находится в ( 0,0 ). Это потому, что SKSpriteNode и, следовательно, его текстура центрированы на его позиции. Чтобы изменить это поведение, вы можете изменить свойство anchorPoint спрайта, которое определяет точку, в которой расположен кадр. Диаграмма ниже показывает, как работает anchorPoint .

Диаграмма, показывающая свойство anchorPoint в системе координат

anchorPoint указывается в системе координат единицы, которая размещает ( 0,0 ) в левом нижнем углу и ( 1,1 ) в верхнем правом углу кадра. Значение по умолчанию для SKSpriteNode s: ( 0,5,0,5 ).

Идем дальше и изменим свойство anchorPoint на ( 0,0 ) и заметим разницу.

01
02
03
04
05
06
07
08
09
10
11
override func didMove(to view: SKView) {
    let startGameLabel = SKLabelNode(text: «Start Game»)
    startGameLabel.name = «startgame»
    startGameLabel.position = CGPoint(x: size.width/2, y: size.height/2)
    addChild(startGameLabel)
         
         
    let redSprite = SKSpriteNode(color: .red, size: CGSize(width: 200, height: 200))
    redSprite.anchorPoint = CGPoint(x: 0, y:0)
    addChild(redSprite)
}

Теперь, если вы протестируете, вы увидите, что спрайт идеально выровнен по левому нижнему краю сцены.

красный спрайт выровнен внизу слева

Теперь давайте переместим его в верхний центр сцены, изменив его свойство position. Замените didMove(to:) на следующую:

01
02
03
04
05
06
07
08
09
10
11
12
override func didMove(to view: SKView) {
    let startGameLabel = SKLabelNode(text: «Start Game»)
    startGameLabel.name = «startgame»
    startGameLabel.position = CGPoint(x: size.width/2, y: size.height/2)
    addChild(startGameLabel)
         
         
    let redSprite = SKSpriteNode(color: .red, size: CGSize(width: 200, height: 200))
    redSprite.anchorPoint = CGPoint(x: 0, y:0)
    redSprite.position = CGPoint(x: size.width/2 — 100, y: size.height — 210)
    addChild(redSprite)
}

Обратите внимание, как мы должны были вычесть значения x и y чтобы центрировать спрайт. Если бы мы оставили anchorPoint по умолчанию, тогда он уже был бы центрирован по оси x . Важно помнить, что когда вы меняете опорную точку, вам, возможно, придется внести некоторые коррективы в ваше положение.

красный спрайт по центру

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

Давайте создадим текстурированный SKSpriteNode . Добавьте следующий код внизу метода didMove(to:) .

1
2
3
4
5
6
7
8
override func didMove(to view: SKView) {
 
    …
         
    let player = SKSpriteNode(imageNamed: «player»)
    player.position = CGPoint(x: size.width/2 , y: 300)
    addChild(player)
}

Здесь мы используем удобный инициализатор init(imageNamed:) , который принимает в качестве параметра имя изображения без расширения. Это самый простой способ создать текстурированный спрайт, поскольку он создает текстуру для вас из изображения, которое вы передаете.

Другой способ создания текстурированного SKSpriteNode — это заранее создать SKTexture и использовать один из инициализаторов, которые принимают текстуру в качестве параметра.

текстурированный спрайт

Давайте создадим еще пару SKSpriteNode и изменим некоторые их свойства. Опять же, добавьте их в didMove(to:) функции didMove(to:) .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
override func didMove(to view: SKView) {
     
    …
     
    let enemy1 = SKSpriteNode(imageNamed: «enemy1»)
    enemy1.position = CGPoint(x: 100 , y: 300)
    enemy1.xScale = 2
    addChild(enemy1)
         
         
    let enemy2 = SKSpriteNode(imageNamed: «enemy2»)
    enemy2.position = CGPoint(x: size.width — 100 , y: 300)
    enemy2.zRotation = 3.14 * 90 / 180
    addChild(enemy2)
}

Здесь мы создаем два SKSpriteNode s, enemy1 и enemy2 . Мы устанавливаем xScale на enemy1 на 2 и изменяем zRotation на enemy2 чтобы повернуть его на 90 градусов. (Свойство zRotation принимает значения в радианах, а положительное значение указывает на вращение против часовой стрелки.)

Мы экспериментировали с изменением нескольких свойств спрайта. Посмотрите документацию для SKNodes и SKSpriteNodes и попробуйте изменить некоторые другие свойства, чтобы увидеть их эффекты.

свойства текстурированного спрайта изменены

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

Другим полезным узлом является SKShapeNode . Этот узел отображает форму, определенную путем Core Graphics. SKShapeNode полезны для контента, который не может быть легко реализован с помощью SKSpriteNode . Этот класс SKSpriteNode больше памяти и имеет более низкую производительность, чем при использовании SKSpriteNode , поэтому вы должны стараться использовать его экономно.

Чтобы назначить фигуру SKShapeNode , вы можете установить CGPath для свойства path узла. Однако есть несколько инициализаторов, которые предлагают предопределенные формы, такие как прямоугольники, круги и эллипсы. Давайте создадим круг, используя удобный инициализатор init(circleOfRadius:) .

Затем добавьте следующее в didMove(to:) метода didMove(to:) .

01
02
03
04
05
06
07
08
09
10
11
override func didMove(to view: SKView) {
         
    …
         
    let circle = SKShapeNode(circleOfRadius: 50)
    circle.strokeColor = SKColor.green
    circle.fillColor = SKColor.blue
    circle.lineWidth = 8
    circle.position = CGPoint(x: size.width/2, y: 400)
    addChild(circle)
}

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

К счастью, есть инструмент, который позволяет визуально рисовать фигуры и экспортировать их CGPath виде кода Swift. Проверьте PaintCode, если вы хотите узнать больше.

узел формы

Узлы Sprite и Shape Nodes будут охватывать большинство случаев, но иногда вы можете отображать видео в своих приложениях. SKVideoNode , который мы рассмотрим далее, охватил вас.

Последний узел, который мы рассмотрим, это SKVideoNode . Как видно из названия, этот узел позволяет воспроизводить видео в ваших играх.

Есть несколько разных способов создания SKVideoNode . Один использует экземпляр AVPlayer , другой просто использует имя видеофайла, который хранится в комплекте приложений, а третий — использовать URL .

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

Следует также помнить, что SKVideoNode предлагает только методы play() и pause() . Если вы хотите больше контролировать свои видео, вы должны инициализировать SKVideoNode с существующим AVPlayer и использовать его для управления своими видео.

Давайте используем самый простой метод для создания SKVideoNode . Добавьте следующее в didMove(to:) метода didMove(to:) .

1
2
3
4
5
6
7
8
9
override func didMove(to view: SKView) {
         
    …
 
    let video = SKVideoNode(fileNamed: «video.mov»)
    video.position = CGPoint(x: size.width/2,y: 600)
    addChild(video)
    video.play()
}

Здесь мы использовали intiailizer init(fileNamed:) для создания видео. Вы передаете имя видео вместе с расширением. Я не включил видео вместе с исходным кодом проекта, но если вы хотите посмотреть эту работу, вы можете добавить видео с именем » video.mov » в свой проект.

Это завершает наше исследование узлов. Прочитав этот пост и предыдущий, вы должны хорошо понимать SKNode и их подклассы. В следующей части этой серии мы рассмотрим SKActions и использование физики в наших играх. Спасибо за чтение, и я увижу вас там!

А пока ознакомьтесь с другими нашими замечательными курсами и учебными пособиями по созданию приложений для iOS с использованием Swift и SpriteKit.

  • SpriteKit
    Создание космических захватчиков с набором Swift и Sprite: Представляем набор Sprite
  • iOS SDK
    Создайте игру в блэкджек в Swift 3 и SpriteKit
  • IOS
    SpriteKit с нуля: основы
    Дэвис Элли

Кроме того, ознакомьтесь с нашими курсами SpriteKit! Они проведут вас через все этапы создания вашей первой игры SpriteKit для iOS, даже если вы никогда не программировали SpriteKit раньше.

  • стриж
    Запрограммируйте игру с боковой прокруткой с помощью Swift и SpriteKit
    Дерек Дженсен
  • Разработка игр
    Разработка игр со Swift и SpriteKit
    Дерек Дженсен