Работа со спрайтами

Спрайты являются основными стандартными блоками, используемыми для создания большинства содержания сцены, так понимание, что спрайты полезны перед хождением дальше для других классов узла в Наборе Sprite. Спрайты представлены SKSpriteNode объекты. SKSpriteNode объект может быть нарисован или как прямоугольник с текстурой, отображенной на него или как цветной, нетекстурированный прямоугольник. Текстурированные спрайты более распространены, потому что они представляют основной способ, которым Вы приносите пользовательские иллюстрации в сцену. Эти пользовательские иллюстрации могли бы представлять символы в Вашей игре, фоновых элементах или даже элементах пользовательского интерфейса, но основная стратегия является тем же. Художник создает изображения, и Ваша игра загружает их как текстуры. Тогда Вы создаете спрайты с теми текстурами и добавляете их к сцене.

Создание текстурированного Sprite

Самый простой способ создать текстурированный спрайт состоит в том, чтобы иметь Набор Sprite, создают и текстуру и спрайт для Вас. Вы храните иллюстрации в комплекте приложений, и затем загружаете его во время выполнения. Перечисление 2-1 показывает, насколько простой этот код может быть.

Перечисление 2-1  , Создающее текстурированный спрайт из изображения, сохранено в пакете

SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithImageNamed:@"rocket.png"];
spaceship.position = CGPointMake(100,100);
[self addChild: spaceship];

При создании спрайта этим способом Вы получаете большое поведение по умолчанию бесплатно:

Поведение по умолчанию дает Вам полезную основу для создания основанной на спрайте игры. Вы уже знаете достаточно, чтобы добавить иллюстрации к Вашей игре, создать спрайты и выполнить действия с теми спрайтами, чтобы сделать интересные вещи. Поскольку спрайты перемещаются на экране и вне экрана, Набор Sprite прилагает все усилия, чтобы эффективно управлять текстурами и нарисовать кадры анимации. Если это достаточно для Вас, не торопитесь для исследования то, что можно сделать со спрайтами. Или, продолжите читать для более глубокого погружения в SKSpriteNode класс. По пути Вы получите полное понимание его возможностей и как передать те возможности Вашим художникам и разработчикам. И Вы узнаете больше усовершенствованные способы работать с текстурами и как улучшить производительность с основанными на текстуре спрайтами.

Настройка текстурированного Sprite

Можно использовать свойства каждого спрайта для независимого конфигурирования четырех отличных этапов рендеринга:

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

Вот некоторые возможные стратегии, за которыми можно следовать:

Используя точку привязки для перемещения кадра Sprite

По умолчанию кадр спрайта — и таким образом его текстура — центрируются на позиции спрайта. Однако Вы могли бы хотеть, чтобы другая часть текстуры появилась в позиции узла. Когда игровой элемент, изображенный в текстуре, не центрируется в изображении текстуры, Вы обычно делаете это.

Узел спрайта anchorPoint свойство определяет, какая точка в кадре расположена в позицию спрайта. Точки привязки указаны в системе координат модуля, показанной на рисунке 2-1. Система координат модуля помещает источник в левом нижнем углу кадра и (1,1) в главном правом углу кадра. Значения по умолчанию точки привязки спрайта к (0.5,0.5), который соответствует центру кадра.

Рисунок 2-1  система координат модуля

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

Рисунок 2-2  , Изменяющий точку привязки спрайта

Перечисление 2-2 показывает, как поместить точку привязки в носовой обтекатель ракеты. Обычно, Вы устанавливаете точку привязки, когда спрайт инициализируется, потому что это соответствует иллюстрациям. Однако можно установить это свойство в любое время. Кадр сразу обновляется, и спрайт на экране обновляется в следующий раз, когда сцена представляется.

Перечисление 2-2  , Устанавливающее точку привязки спрайта

rocket.anchorPoint = CGPointMake(0.5,1.0);

Изменение размеров Sprite

Размер спрайта frame свойство определяется значениями трех других свойств:

  • Спрайт size свойство содержит основной (немасштабированный) размер спрайта. Когда спрайт инициализируется с помощью кода в Перечислении 2-1, значение этого свойства инициализируется, чтобы быть равным размеру текстуры спрайта.

  • Основной размер тогда масштабируется спрайтом xScale и yScale свойства наследовались от SKNode класс.

Например, если основной размер спрайта 32 x 32 пиксели и это имеют xScale значение 1.0 и a yScale значение 2.0, размер кадра спрайта 32 x 64 пиксели.

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

Рисунок 2-3  текстура расширяется для покрытия кадра спрайта

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

Спрайт centerRect свойство, указанное в координатах модуля текстуры, управляет масштабирующимся поведением. Значение по умолчанию является прямоугольником, покрывающим всю текстуру, которая является, почему вся текстура расширяется через кадр. Если Вы указываете прямоугольник, только покрывающий часть текстуры, Вы создаете a 3 x 3 сетка. Каждый окружает сетку, имеет ее собственное поведение масштабирования:

  • Части текстуры в четырех углах сетки нарисованы без любого масштабирования.

  • Центр сетки масштабируется в обеих размерностях.

  • Верхние - и более низко-средние части только масштабируются горизонтально.

  • Лево-и правильно-средние части только масштабируются вертикально.

Рисунок 2-4 показывает представление крупным планом текстуры, которую Вы могли бы использовать для рисования кнопки пользовательского интерфейса. Полная текстура 28 x 28 пиксели. Угловые части - каждый 12 x 12 пиксели и центр 4 X 4 пиксели.

Рисунок 2-4  поддающаяся растягиванию текстура кнопки

Перечисление 2-3 показывает, как был бы инициализирован этот спрайт кнопки. centerRect свойство вычислено на основе проекта текстуры.

Перечисление 2-3  , Устанавливающее центр спрайта rect для корректировки простирающееся поведение

SKSpriteNode *button = [SKSpriteNode spriteNodeWithImageNamed:@"stretchable_button.png"];
button.centerRect = CGRectMake(12.0/28.0,12.0/28.0,4.0/28.0,4.0/28.0);

Рисунок 2-5 показывает, что углы остаются тем же, даже когда кнопка нарисована в различных размерах.

Рисунок 2-5  , Применяющий кнопку, текстурирует к кнопкам различных размеров

Colorizing Sprite

Можно использовать color и colorBlendFactor свойства к colorize текстура прежде, чем применить его к спрайту. Цветные значения по умолчанию фактора смешения к 0.0, который указывает, что текстура должна использоваться неизмененная. Поскольку Вы увеличиваете это число, больше цвета текстуры заменяется смешанным цветом. Например, когда монстр в Вашей игре наносит ущерб, Вы могли бы хотеть добавить красный оттенок к символу. Перечисление 2-4 показывает, как Вы применили бы оттенок к спрайту.

Перечисление 2-4  , Окрашивающее цвет спрайта

monsterSprite.color = [SKColor redColor];
monsterSprite.colorBlendFactor = 0.5;
Рисунок 2-6  Colorizing корректирует цвет текстуры

Можно также анимировать цветные и цветные факторы смешения с помощью действий. Перечисление 2-5 показывает, как кратко окрасить спрайт и затем возвратить его нормальному.

Перечисление 2-5  , Анимирующее цветное изменение

SKAction *pulseRed = [SKAction sequence:@[
                        [SKAction colorizeWithColor:[SKColor redColor] colorBlendFactor:1.0 duration:0.15],
                        [SKAction waitForDuration:0.1],
                        [SKAction colorizeWithColorBlendFactor:0.0 duration:0.15]]];     [monsterSprite runAction: pulseRed];

Смешивание Sprite в кадровый буфер

Заключительный этап рендеринга должен смешать текстуру спрайта в свой целевой кадровый буфер. Поведение по умолчанию использует альфа-значения текстуры для смешивания текстуры с целевыми пикселями. Когда Вы хотите добавить другие специальные эффекты к сцене, Однако можно использовать другие режимы смешивания.

Вы управляете поведением смешивания спрайта с помощью blendMode свойство. Например, аддитивный режим смешивания полезен для объединения многократных спрайтов вместе, такой что касается огня или освещения. Перечисление 2-6 показывает, как изменить режим смешивания для использования аддитивного смешения.

Перечисление 2-6  Используя аддитивный режим смешивания для моделирования света

lightFlareSprite.blendMode = SKBlendModeAdd;

Работа с объектами текстуры

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

Вы делаете все эти вещи путем работы непосредственно с SKTexture объекты. Вы создаете SKTexture возразите и затем используйте его, чтобы создать новые спрайты или изменить текстуру существующего спрайта.

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

Перечисление 2-7 показывает пример, подобный Перечислению 2-1, но теперь код явно создает объект текстуры. Тогдашний код создает многократные ракеты из той же текстуры.

Перечисление 2-7  , Загружающее текстуру из пакета

SKTexture *rocketTexture = [SKTexture textureWithImageNamed:@"rocket.png"];
for (int i= 0; i< 10; i++)
{
    SKSpriteNode *rocket = [SKSpriteNode spriteNodeWithTexture:rocketTexture];
    rocket.position = [self randomRocketLocation];
    [self addChild: rocket];
}

Сам объект текстуры является просто заполнителем для фактических данных текстуры. Данные текстуры являются более интенсивно использующими ресурсы, таким образом, Набор Sprite загружает их в память только при необходимости.

Используя атласы текстуры для сбора связанных активов Искусства

Активы Искусства, сохраненные в Вашем комплекте приложений, являются не всегда несвязанными изображениями. Иногда они - наборы изображений, использующихся вместе для того же спрайта. Например, вот несколько общих наборов художественных активов:

  • Кадры анимации для символа

  • Мозаики ландшафта раньше создавали игровой уровень или проблему

  • Изображения, используемые для средств управления пользовательским интерфейсом, таких как кнопки, переключатели и ползунки

Если каждая текстура обрабатывается как отдельный объект, то Набор Sprite и аппаратное обеспечение машинной графики должны работать тяжелее для рендеринга сцен — и производительность игры могла бы пострадать. В частности Набор Sprite должен сделать по крайней мере одну передачу получения на текстуру. Чтобы избежать делать многократные передачи получения, Набор Sprite использует атласы текстуры для сбора связанных изображений вместе. Вы указываете, какие активы должны быть собраны вместе, и XCode создает атлас текстуры автоматически. Затем когда Ваша игра загружает атлас текстуры, Набор Sprite управляет всеми изображениями в атласе, как будто они были единственной текстурой. Вы продолжаете использовать SKTexture объекты получить доступ к элементам, содержавшимся в атласе.

Создание атласа текстуры

XCode может автоматически создать атласы текстуры для Вас от набора изображений. Процесс описан подробно в Справке Атласа Текстуры.

При создании атласа текстуры Вы хотите установить равновесие между сбором слишком многих текстур или лишь немногих. При использовании очень небольшого числа изображений Набор Sprite, возможно, все еще нуждается во многих передачах получения для рендеринга кадра. Если Вы включаете слишком много изображений, то большие суммы данных текстуры, возможно, должны быть загружены в память сразу. Поскольку XCode создает атласы для Вас, можно переключиться между различными конфигурациями атласа с относительной простотой. Так экспериментируют с различными конфигурациями Ваших атласов текстуры и выбирают комбинацию, дающую Вам лучшую производительность.

Загрузка текстур из атласа текстуры

Код в Перечислении 2-7 также используется для загрузки текстур из атласа текстуры. Набор Sprite ищет сначала файл образа с указанным именем файла. Если это не находит один, это ищет в любых атласах текстуры, встроенных в комплект приложений. Это означает, что Вы не должны вносить изменения кодирования для поддержки этого в игре. Этот проект также предлагает Вашим художникам возможность экспериментировать с новыми текстурами, не требуя что Ваша игра быть восстановленным. Художники бросают текстуры в комплект приложений. Когда приложение повторно запускается, Набор Sprite автоматически обнаруживает текстуры (переопределяющий любые предыдущие версии, встроенные в атласы текстуры). Когда художники удовлетворены текстурами, Вы тогда добавляете те текстуры к проекту и печете их в Ваши атласы текстуры.

Если Вы хотите явно работать с атласами текстуры, используйте SKTextureAtlas класс. Во-первых, создайте объект атласа текстуры использование имени атласа. Затем, используйте имена файлов образа, сохраненных в атласе для поиска отдельных текстур. Перечисление 2-8 показывает пример этого. Это использует атлас текстуры, содержащий многократные кадры анимации для монстра. Код загружает те кадры и хранит их в массиве. В фактическом проекте Вы добавили бы a monster.atlas папка с этими четырьмя файлами образа.

Перечисление 2-8  , Загружающее текстуры на прогулке анимация

SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:@"monster"];
SKTexture *f1 = [atlas textureNamed:@"monster-walk1.png"];
SKTexture *f2 = [atlas textureNamed:@"monster-walk2.png"];
SKTexture *f3 = [atlas textureNamed:@"monster-walk3.png"];
SKTexture *f4 = [atlas textureNamed:@"monster-walk4.png"];
NSArray *monsterWalkTextures = @[f1,f2,f3,f4];

Создание Текстуры от Подраздела Текстуры

Если Вы уже имеете SKTexture объект, можно создать новые текстуры, ссылающиеся на часть его. Этот подход эффективен, потому что новые объекты текстуры ссылаются на те же данные текстуры в памяти. (Это поведение подобно тому из атласа текстуры.) Если Ваша игра уже имеет свой собственный формат атласа текстуры, Как правило, Вы используете этот подход. В этом случае Вы ответственны за хранение координат для отдельных изображений, сохраненных в пользовательском атласе текстуры.

Перечисление 2-9 показывает, как извлечь часть текстуры. Координаты для прямоугольника находятся в координатном пространстве модуля.

Перечисление 2-9  Используя часть текстуры

SKTexture *bottomLeftTexture = [SKTexture textureWithRect:CGRectMake(0.0,0.0,0.5,0.5) inTexture:cornerTextures];

Другие способы создать текстуры

В дополнение к загрузке текстур от комплекта приложений можно создать текстуры из других источников:

  • Используйте SKTexture методы инициализатора для создания текстур из должным образом отформатированных пиксельных данных в памяти, из базовых графических изображений, или путем применения Базового Изображения фильтруют к существующей текстуре.

  • SKView класс textureFromNode: метод может представить содержание дерева узла в текстуре. Текстура измерена так, чтобы она содержала содержание узла и всех его видимых потомков.

Изменение текстуры Sprite

Спрайт texture свойство указывает на его текущую текстуру. Можно изменить это свойство для указания на новую текстуру. В следующий раз, когда сцена представляет новый кадр, она представляет с новой текстурой. Каждый раз, когда Вы изменяете текстуру, Вы, возможно, также должны изменить другие свойства спрайта — такой как size, anchorPoint, и centerRect— быть соответствующим новой текстуре. Обычно, лучше гарантировать, что все иллюстрации являются непротиворечивыми так, чтобы те же значения могли использоваться для всех текстур. Т.е. текстуры должны иметь непротиворечивый размер и размещение точки привязки так, чтобы Ваша игра ничего не должна была обновлять кроме текстуры.

Поскольку анимация является общей задачей, можно использовать действия для анимации серии текстур на спрайте. Код в Перечислении 2-10 показывает, как использовать массив кадров анимации, создаваемых в Перечислении 2-8 для анимации текстуры спрайта.

  Анимация перечисления 2-10 через серию текстур

SKAction *walkAnimation = [SKAction animateWithTextures:monsterWalkTextures timePerFrame:0.1]
[monster runAction:walkAnimation];
// insert other code here to move the monster.

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

Предварительно загружение текстур в память

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

Перечисление 2-11 показывает, как предварительно загрузить массив SKTexture объекты. preloadTextures:withCompletionHandler: вызовы метода обработчик завершения после всех текстур загружаются в память. В этом примере все текстуры для определенного уровня игры предварительно загружены в единственной работе. Когда текстуры - все в памяти, обработчик завершения вызывают. Это создает сцену и представляет его. (Необходимо добавить код для обеспечения этих, текстура возражает против сцены; тот код не показан здесь).

Перечисление 2-11  , Предварительно загружающее текстуру

[SKTexture preloadTextures:textureArrayForLevel1 withCompletionHandler:^
    {
        // The textures are loaded into memory. Start the level.
        GamePlayScene* gameScene = [[GamePlayScene alloc] initWithSize:CGSizeMake(768,1024)];
        SKView *spriteView = (SKView *) self.view;
        [spriteView presentScene: gameScene];
    }];

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

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

  • Для большей игры Вы, возможно, должны разделить текстуры на уровни или темы. Каждый уровень или текстуры темы разработаны для помещений в определенный объем памяти. Когда проигрыватель запускает новый уровень, Вы предварительно загружаете, все из которых текстура уровня возражает. Когда проигрыватель заканчивает играть уровень, текстуры, не необходимые для следующего уровня, отбрасываются. Путем предварительно загружения уровней время загрузки является все передней стороной, прежде чем запустится геймплей.

  • Если для игры нужно больше текстур, чем может вписаться в память, необходимо предварительно загрузить текстуры динамично, поскольку играют в игру. Как правило, Вы предварительно загружаете некоторые текстуры в начале уровня, и затем загружаете другие текстуры, когда Вы будете думать, что они скоро будут необходимы. Например, в мчащейся игре, проигрыватель всегда перемещается в то же направление, таким образом, для каждого кадра Вы могли бы выбрать новую текстуру для содержания, проигрыватель собирается видеть. Текстуры загружаются в фоновом режиме, перемещая самые старые текстуры для дорожки. В игре приключения, допускающей управляемое проигрывателем перемещение, Вам, возможно, придется временно загрузить текстуры, когда проигрыватель перемещается в определенное направление.

Удаление текстуры из памяти

После того, как текстура загружается в память аппаратного обеспечения машинной графики, это остается в памяти до ссылки SKTexture объект удален. Это означает, что между уровнями (или в динамической игре), Вы, возможно, должны удостовериться, что удален объект текстуры. Удалите a SKTexture возразите объекту путем удаления любых сильных ссылок к нему, включая:

  • Все ссылки текстуры от SKSpriteNode и SKEffectNode объекты в Вашей игре

  • Любые сильные ссылки к текстуре в Вашем собственном коде

  • SKTextureAtlas объект, использовавшийся для создания объекта текстуры

Создание нетекстурированных спрайтов

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

Другие свойства (size, anchorPoint, и blendMode) работайте то же.

Попробуйте это!

Теперь, когда Вы знаете больше о спрайтах, попробуйте некоторые следующие действия:

Можно найти полезный код в Туристической выборке Sprite.