Cocos2d-x — Работа со спрайтами

  • Tutorial

Предисловие


Эта статья является второй, из серии переводов документации к игровому движку Cocos2d-x. Если вы не видели первую часть перевода, то советую сначала ознакомится с ней:
Cocos2d-x — Основные понятия

А теперь продолжим!

Что такое спрайт


Спрайт — это 2D изображение, которое может быть анимировано или трансформировано, путем изменения свойств, таких как: rotation, scale, color, и так далее.

Создание спрайтов


Существуют различные способы создания спрайтов, зависящие от того что вам необходимо выполнить. Вы можете создать спрайт, используя изображения различных графических форматов, включая: PNG, JPEG, TIFF и другие. Давайте рассмотрим некоторые методы создания и поговорим о каждом из них.

Создание простого спрайта


Спрайт может быть создан путем указания файла изображения.

auto mySprite = Sprite::create("mysprite.png");

image

Код выше создает спрайт, используя изображение mysprite.png. В результате, созданный спрайт использует целое изображение. Он имеет те же размеры, что и mysprite.png. Если файл изображения 200 x 200 то результирующий спрайт тоже будет 200 x 200.

Создание спрайта с использованием Rect (прямоугольника)


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

Rect имеет 4 значения: origin x, origin y, width и height.

auto mySprite = Sprite::create("mysprite.png", Rect(0,0,40,40));

image

Rect берет левый верхний угол за начало координат. Это противоположно тому принципу, что мы использовали, когда устанавливали позицию на экране, отчитывая координаты от левого нижнего угла. Таким образом, результирующий спрайт – только часть исходного файла изображения. В этом случае, размер спрайта 40 x 40 начиная от левого верхнего угла.

Если вы не зададите Rect, Cocos2d-x автоматически будет использовать полную высоту и ширину заданного изображения. Взгляните на код ниже. Если вы используете изображение с размерами 200 x 200, то следующие два выражения будут иметь одинаковые результаты.

auto mySprite = Sprite::create("mysprite.png");
auto mySprite = Sprite::create("mysprite.png", Rect(0,0,200,200));

Создание спрайта из текстурного атласа (Sprite Sheet)


Sprite sheet – это способ объединения спрайтов в один файл. Использование sprite sheet помогает добиться лучшей производительности, путем пакетной обработки вызовов рисования. Они могут также сохранить дисковую- и видео-память, если упаковать спрайты более эффективно (обычно требуются специальные инструменты). Вы прочитаете больше об этом в продвинутой главе, но это только один из многих стандартных методов повышения производительности игр.

При использовании sprite sheet, он сначала загружается в SpriteFrameCache. SpriteFrameCache – это класс кеширования, который сохраняет объекты SpriteFrame, для быстрого доступа к ним. SpriteFrame загружается один раз и сохраняется в SpriteFrameCache.

Вот пример sprite sheet:

image

Давайте рассмотрим подробнее, что происходит:

image

Как вы можете видеть, sprite sheet объединяет все спрайты в один файл и минимизирует лишнее пространство.

Загрузка Sprite Sheet


Вероятнее всего, вы будете осуществлять загрузку в AppDelegate:

// загрузка Sprite Sheet
auto spritecache = SpriteFrameCache::getInstance();
// файлы .plist могут быть сгенерированы при помощи любого из перечисленных в последнем пункте инструментов
spritecache->addSpriteFramesWithFile("sprites.plist");

Теперь, когда мы имеем текстурный атлас загруженный в SpriteFrameCache, мы можем создать спрайт.

Создание спрайта из SpriteFrameCache


Это создание спрайта, путем вытягивания его из SpriteFrameCache.

// Наш .plist содержит имена всех спрайтов, находящихся в нем.
// "mysprite" – имя спрайта из sprite sheet:
auto mysprite = Sprite::createWithSpriteFrameName("mysprite.png");

image

Создание спрайта из SpriteFrame


Еще один способ создать такой же спрайт – получить SpriteFrame из SpriteFrameCache, и затем создать спрайт при помощи SpriteFrame. Пример:

// это равнозначно с предыдущим примером,
// но он создается, путем извлечения SpriteFrame из кэша.
auto newspriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("Blue_Front1.png");
auto newSprite = Sprite::createWithSpriteFrame(newspriteFrame);

image

Инструменты для создания Sprite Sheets


Создание sprite sheet вручную – утомительный процесс. К счастью, есть инструменты, которые могут генерировать их автоматически. Эти инструменты предлагают множество возможностей для максимальной оптимизации ваших спрайтов!

Здесь представлено несколько инструментов:


Манипуляции со спрайтами


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

Дано:

auto mySprite = Sprite::create("mysprite.png");

image

Опорная точка и позиция


Опорная точка (Anchor Point) – это точка, которую вы задаете, чтобы указать, какая часть спрайта будет использоваться, при установке его координат. Опорная точка влияет только на свойства связанные с трансформацией. Они включают: scale, rotation, skew. И не включают: color и opacity. Опорная точка использует систему координат от нижнего левого угла. Учитывайте это, при выполнении своих расчетов. По умолчанию, все Node объекты имеют стандартную опорную точку (0.5, 0.5).

Задать опорную точку просто:

// DEFAULT
mySprite->setAnchorPoint(0.5, 0.5);
// нижний левый угол
mySprite->setAnchorPoint(0, 0);
// верхний левый угол
mySprite->setAnchorPoint(0, 1);
// нижний правый угол
mySprite->setAnchorPoint(1, 0);
// верхний правый угол
mySprite->setAnchorPoint(1, 1);

Чтобы представить это визуально:

image

Свойства спрайтов, на которые влияет опорная точка


Использование опорной точки влияет только на свойства связанные с трансформированием. Такие как: scale, rotation, skew.

Position


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

image

Позицию спрайта можно также задать методом setPosition().

// установка новой позиции спрайта x = 100, y = 200.
mySprite->setPosition(Vec2(100, 200));

Rotation


Изменяет вращение спрайта, на положительное или отрицательное число градусов. Положительные значения поворачивают спрайт по часовой стрелке, в то время как отрицательные поворачивают против часовой стрелки. Стандартное значение – 0.0

// поворот спрайта на +20 градусов
mySprite->setRotation(20.0f);
// поворот спрайта на -20 градусов
mySprite->setRotation(-20.0f);
// поворот спрайта на +60 градусов
mySprite->setRotation(60.0f);
// поворот спрайта на -60 градусов
mySprite->setRotation(-60.0f);

image

Scale


Изменяет масштаб спрайта, либо по каждой оси отдельно, либо равномерно по обеим. Стандартное значение – 1.0

// увеличивает спрайт в 2 раза
mySprite->setScale(2.0);
// масштабирует спрайт по координате x
mySprite->setScaleX(2.0);
// масштабирует спрайт по координате y
mySprite->setScaleY(2.0);

image

Skew


Изменяет наклон спрайта, либо отдельно по осям x и y, либо равномерно для всех. Стандартное значение – 0.0

// устанавливает наклон X на 20.0
mySprite->setSkewX(20.0f);
// устанавливает наклон Y на 20.0
mySprite->setSkewY(20.0f);

Свойства спрайта, на которые не влияет опорная точка


Существует несколько свойств объекта Sprite, на которые не влияет опорная точка. Почему? Потому что они изменяют только внешний вид, подобно свойствам color и opacity.

Color


Изменяет цвет спрайта. Это делается при помощи Color3B. Мы еще не сталкивались с Color3B, но это просто объект, представляющий собой RGB цвет. RGB цвет включает в себя 3 значения (Red, Green, Blue), от 0 до 255. Cocos2d-x также предоставляет предопределенные цвета, из которых вы можете выбрать. Использование их будет немного быстрее, поскольку они уже определены заранее. Вот некоторые примеры:

// установка цвета при помощи предопределенного объекта Color3B.
mySprite->setColor(Color3B::WHITE);
// установка цвета с помощью Color3B.
mySprite->setColor(Color3B(255, 255, 255));
// Тоже что Color3B::WHITE

image

Opacity


Изменяет непрозрачность спрайта на заданное значение. Это свойство принимает значения от 0 до 255, где 255 – полная не прозрачность, а 0 – абсолютная невидимость. Стандартное значение 255 (полная видимость).

// Установим opacity на 30, что сделает этот спрайт непрозрачным на 11.7%.
// (30 / 256 = 0.1171875...)
mySprite->setOpacity(30);

image

Полигональные спрайты


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

Зачем использовать полигональный спрайт?


Ответ прост — производительность!

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

image

Заметили различия между левой и правой версиями?

Слева, типичный Sprite, который прорисовывается, с использованием двух треугольников.

Справа, PolygonSprite, рисующийся большим количеством маленьких треугольников.

Стоит ли идти на такой компромисс, чисто по соображениям производительности, зависит от ряда факторов (форма/детализация спрайта, размер, количество нарисованного на экране, и так далее), но в основном, вершины дешевле пикселей на современных графических процессорах.

AutoPolygon


AutoPolygon – это вспомогательный класс. Его цель – создавать 2d полигональную сетку на основе изображения.

Существуют функции для каждого шага обработки этого процесса, от определения всех точек, до триангуляции. Результат может быть передан в функцию create объекта sprite, для создания PolygonSprite. Пример:

// Автоматическая генерация polygon info.
auto pinfo = AutoPolygon::generatePolygon("filename.png");
// Создание спрайта при помощи polygon info.
auto sprite = Sprite::create(pinfo);


Следующая статья: Обработка действий
  • +12
  • 3,4k
  • 1
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 1
  • +1

    Для опроных точек также существуют предопределенные точки для каждой из девяти основных вариантов расположения


    definition
        /** equals to Vec2(0,0) */
        static const Vec2 ZERO;
        /** equals to Vec2(1,1) */
        static const Vec2 ONE;
        /** equals to Vec2(1,0) */
        static const Vec2 UNIT_X;
        /** equals to Vec2(0,1) */
        static const Vec2 UNIT_Y;
        /** equals to Vec2(0.5, 0.5) */
        static const Vec2 ANCHOR_MIDDLE;
        /** equals to Vec2(0, 0) */
        static const Vec2 ANCHOR_BOTTOM_LEFT;
        /** equals to Vec2(0, 1) */
        static const Vec2 ANCHOR_TOP_LEFT;
        /** equals to Vec2(1, 0) */
        static const Vec2 ANCHOR_BOTTOM_RIGHT;
        /** equals to Vec2(1, 1) */
        static const Vec2 ANCHOR_TOP_RIGHT;
        /** equals to Vec2(1, 0.5) */
        static const Vec2 ANCHOR_MIDDLE_RIGHT;
        /** equals to Vec2(0, 0.5) */
        static const Vec2 ANCHOR_MIDDLE_LEFT;
        /** equals to Vec2(0.5, 1) */
        static const Vec2 ANCHOR_MIDDLE_TOP;
        /** equals to Vec2(0.5, 0) */
        static const Vec2 ANCHOR_MIDDLE_BOTTOM;
    

    Работа с Rect при использовании спрайтов из атласа может обернуться головной болью (например, при реализации полосок загрузки), т.к. все обрезки рассчитываются относительно сдвигов на атласе. По этой же причине могут возникнуть проблемы с масштабированием, хотя после некоторой магии и это разрешимо.

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