Лучший способ изучить Sprite Kit это увидеть его в действии — Часть 2

Этот пример создает пару сцен и оживляет содержание в каждой из них.

Разбирая этот пример, вы узнаете некоторые из основных методов для работы со Sprite Kit, в том числе:
— Использование сцен в Sprite Kit играх.
— Организация дерева узлов.
— Использование SKAction для анимации содержимого сцены.
— Добавление интерактивности в сцену.
— Переход между сценами.
— Имитация физики внутри сцены.

После завершения этого проекта, вы сможете использовать его, чтобы попробовать другие возможности Kit Sprite. Вам необходим Xcode не ниже версии 5.0.

Начинаем
Создайте новый Xcode проект для IOS, используйте шаблон Single View Application. Добавьте в проект SpriteKit Framework.

Создаем первую сцену
Sprite Kit контент размещается в окне, так же как и любой другой визуальный контент. В окне размещается SKView который показывает сцены SKScene. Т.к. SKView расположен как и любой другой view в окне, то SKView можно комбинировать с традиционными элементами управления, например с кнопками UIButton. В этом случае, достаточно традиционные элементы управления просто расположить сверху SKView. Это очень удобно, об этом я расскажу немного позже в этом примере. Вернемся к нашему проекту.
1. В Main сториборд выделите UIView в UIViewController и установите его класс SKView вместо UIView.
2. Добавьте в ViewController.h импорт Sprite Kit:

#import <SpriteKit/SpriteKit.h>

3. Добавьте следующий код в метод viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];
    SKView *spriteView = (SKView *) self.view;
    spriteView.showsNodeCount = YES;
    spriteView.showsFPS = YES;
}

Этот код включает показ диагностической информации. Наиболее важный показатель это FPS (частота кадров), наблюдайте за ним, чтобы ваша игра работала на постоянной частоте кадров. Это обеспечит нужную плавность игры. nodeCount показывает число узлов которые отображаются в данный момент.

Дальше добавим сцену:
1. Создайте новый класс с названием HelloScene и установите subclass как SKScene.

#import <SpriteKit/SpriteKit.h>
@interface HelloScene : SKScene
@end

2. Добавьте HelloScene в заголовок ViewController.h

#import "HelloScene.h"

3. Добавьте во ViewController.m метод viewWillAppear, который создаст сцену HelloScene
— (void)viewWillAppear:(BOOL)animated
{
HelloScene* hello = [[HelloScene alloc] initWithSize:self.view.frame.size];
SKView *spriteView = (SKView *) self.view;
[spriteView presentScene: hello];
}
4. Запустите проект.
На экране вы должны увидеть пустой экран и диагностическую информацию.

Добавим контент на сцену
Это первая сцена отображает традиционную «Hello World» надпись. Чаще всего, настройка контента сцены происходит во время первого показа. В этом примере код находится внутри метода didMoveToView:, который вызывается когда сцена становится видимой.

1. Добавьте новое свойство в HelloScene.h

#import <SpriteKit/SpriteKit.h>

@interface HelloScene : SKScene

@property BOOL contentCreated;

@end


2. Добавьте в HelloScene.m реализацию метода didMoveToView:

- (void)didMoveToView: (SKView *) view
{
    if (!self.contentCreated)
    {
        [self createSceneContents];
        self.contentCreated = YES;
    }
}

В этом методе создается надпись на сцене. Как я уже написал, этот метод выполняется при показе сцены на экране. Но так как наша сцена может показываться и скрываться с экрана несколько раз, а создавать надпись каждый раз нам не надо, мы ввели свойство contentCreated, которое говорит, создана ли уже надпись или нет.

3. Добавьте в HelloScene.m реализацию метода createSceneContents

- (void)createSceneContents
{
    self.backgroundColor = [SKColor redColor];
    self.scaleMode = SKSceneScaleModeAspectFit;
    [self addChild: [self newHelloNode]];
}

Здесь устанавливается цвет фона сцены, режим масштабирования сцены (примерно также как и у UIImageView например) и добавляем на сцену SKLabelNode который возвращает newHelloNode. Обратите внимание на установку цвета — используется не UIColor, а SKColor. Это просто макрос UIColor, который призван сделать цвет более кроссплатформенным.

4. Добавим метод newHelloNode

- (SKLabelNode *)newHelloNode
{
    SKLabelNode *helloNode = [SKLabelNode
labelNodeWithFontNamed:@"Chalkduster"];
    helloNode.text = @"Hello, World!";
    helloNode.fontSize = 22;
    helloNode.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
    return helloNode;
}

5. Запустите проект. Должно получится так:
img2

Добавляем SKAction для анимации
1. Добавьте в newHelloNode

helloNode.name = @"helloNode";

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

2. Добавьте в самое начало файла HelloScene.m макрос для перевода градусов в радианы

#define DEGREES_RADIANS(angle) ((angle) / 180.0 * M_PI)

3. Переопределим метод touchesBegan:withEvent: он выполняется по тапу на экране, ищет узел с именем helloNode и добавляет для него небольшую анимацию:

- (void)touchesBegan:(NSSet *) touches withEvent:(UIEvent *)event
        {
            SKNode *helloNode = [self childNodeWithName:@"helloNode"];
            if (helloNode != nil)
            {
                helloNode.name = nil;
                SKAction *moveUp = [SKAction moveByX: 0 y: 100.0 duration: 0.5];
                SKAction *zoom = [SKAction scaleTo: 2.0 duration: 0.55];
                SKAction *rotation = [SKAction rotateByAngle: DEGREES_RADIANS(360) duration:0.5];
                SKAction *fadeAway = [SKAction fadeOutWithDuration: 1.0];
                SKAction *remove = [SKAction removeFromParent];

                SKAction *moveSequence = [SKAction sequence:@[moveUp, zoom, rotation, fadeAway, remove]];
                [helloNode runAction: moveSequence];
            }
}

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

4. Запустите проект. Тапните по экрану и вы должны увидеть небольшую анимацию.

В следующей части обсудим физику и переходы между сценами.

  • Konstantin

    Помогите пожалуйста! При тесте не показывает количество узлов и не показывает анимацию. helloNode.name = @»helloNode»;(пишет по поводу этой строчки code will never be executed) больше ошибок не пишет. Версия xCode-7