От переводчика
Приветствую! Мы продолжаем переводить документацию к движку cocos2d-x. Эта статья содержит сразу две главы, небольшие по объему. Как вы уже догадались, в первой мы разберем способы работы со сценами, а в конце рассмотрим еще несколько типов узлов.
Надеюсь, вы найдете для себя много полезного!
Что такое сцена?
Объект Scene является контейнером, содержащим спрайты, лейблы, узлы и прочие объекты, необходимые вашей игре. Scene отвечает за запуск игровой логики и рендеринг контента в каждом кадре. Вам понадобится как минимум одна сцена, чтобы начать игру. Думайте о вашей игре как фильме. Когда Scene запущена, пользователи видят, что происходит в режиме реального времени. В вашей игре может быть любое количество сцен и вы можете легко переключаться между ними. Cocos2d-x способен осуществлять переходы между сценами и вы даже можете делать это с классными эффектами.
Создание сцены
Сцену создать очень просто:
auto myScene = Scene::create();
Помните граф сцены?
В первой части руководства мы узнали о Scene Graph и о том, как он влияет на рисунок нашей игры. Важно помнить, что он определяет порядок рисования элементов GUI(графического пользовательского интерфейса). Также помните про z-порядок!
Простая сцена
Давайте построим простую сцену. Помните что Cocos2d-x использует правую декартову систему координат. Это означает, что координата 0,0 находится в левом нижнем углу экрана/дисплея. Чтобы грамотно позиционировать элементы вашей игры, необходимо заранее всё просчитать. Давайте создадим простую сцену и добавим к ней несколько элементов:
auto dirs = Director::getInstance();
Size visibleSize = dirs->getVisibleSize();
auto myScene = Scene::create();
auto label1 = Label::createWithTTF("My Game", "Marker Felt.ttf", 36);
label1->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
myScene->addChild(label1);
auto sprite1 = Sprite::create("mysprite.png");
sprite1->setPosition(Vec2(100, 100));
myScene->addChild(sprite1);
Если мы запустим этот код, мы должны увидеть простую сцену, содержащую Label и Sprite. Это немного, но только пока что.
Переход между сценами
Вам может потребоваться возможность перемещения между сценами в вашей игре. Вероятно при начале новой игры, смене уровня или при ее завершении. Cocos2d-x предоставляет некоторое количество способов перехода между сценами.
Способы замены сцены
Есть много способов смены ваших сцен. Каждый обладает определенной функциональностью. Давайте пройдёмся по ним.
Дано:
auto myScene = Scene::create();
runWithScene() — используется только для первой сцены. Этим методом мы задает сцену для начала игры.
Director::getInstance()->runWithScene(myScene);
replaceScene() — непосредственная замена сцены.
Director::getInstance()->replaceScene(myScene);
pushScene() — приостанавливает выполнение текущей сцены, добавляя её к стеку приостановленных сцен. Вызывайте только при наличии активной сцены.
Director::getInstance()->pushScene(myScene);
popScene() — эта сцена встанет на место активной. Текущая сцена будет удалена. Вызывайте только при наличии активной сцены.
Director::getInstance()->popScene(myScene);
Смена сцен с эффектами
Вы можете добавить визуальные эффекты для смены ваших сцен.
auto myScene = Scene::create();
// Смена выцветанием
Director::getInstance()->replaceScene(TransitionFade::create(0.5, myScene, Color3B(0,255,255)));
// Кувырок по X
Director::getInstance()->replaceScene(TransitionFlipX::create(2, myScene));
// Смена вставкой
Director::getInstance()->replaceScene(TransitionSlideInT::create(1, myScene) );
Другие типы узлов
Вы уже используете Sprite, Label и Action — объекты в своей игре и это прогресс. Кроме основных типов узлов, описанных в предыдущих главах, Cocos2d-x предоставляет более продвинутые типы узлов, обладающие особой функциональностью. Возможно вы хотите сделать игру, основанную на тайлах? Или, может быть, 2D-платформер? Или может вы хотите добавить партикловые эффекты в свою игру? Cocos2d-x предоставляет Node-объекты, которые помогут вам в этом!
TileMap
TileMaps — это карты, состоящие из тайлов (плиток). Каждый тайл может иметь независимое от других поведение. TileMaps хранятся в основанном на XML формате карт, который называется TMХ. TMX был изначально разработан для тайловых карт, но он так же подходит для создания общих игровых уровней благодаря поддержке различных типов объектов. TMX-объекты легко создать:
// чтение карты тайлов
auto map = TMXTiledMap::create("TileMap.tmx");
addChild(map, 0, 99); // с меткой "99"
Тайл-карты могут иметь несколько слоёв, определённых z-порядком. Вы можете получить доступ к определённому слою по его имени:
// как получить определённый слой
auto map = TMXTiledMap::create("TileMap.tmx");
auto layer = map->getLayer("Layer0");
auto tile = layer->getTileAt(Vec2(1, 63));
Каждый тайл имеет уникальную позицию и ID. Это позволяет очень легко выбирать необходимый тайл. Вы можете получить любой по его идентификатору (id):
// получение идентификатора конкретного тайла
unsigned int gid = layer->getTileGIDAt(Vec2(0, 63));
Пример слоёв в тайл-карте:
Как сделать карту из тайлов? Есть много инструментов, которые делают это. Tiled — популярная утилита. Он активно развивается и имеет отличное комьюнити. Скриншоты сверху — реальные проекты в Tiled.
Эффекты частиц
Возможно ваша игра нуждается в эффектах, таких как огонь, заклинания или взрывы? Как вы реализуете столь сложные эффекты? Возможно ли это? Конечно! Используйте системы частиц. Particle system — это технология компьютерной графики, использующая большое количество очень маленьких спрайтов или других графических элементов для симуляции нечётких объектов, которые иначе очень трудно воспроизвести с помощью обычных методов рендеринга. Некоторые реальные примеры могут включать очень хаотичные системы: природные явления или процессы, вызванные химическими реакциями. Вот пара примеров эффектов частиц:
Инструменты для создания эффектов частиц
Хотя вы можете создавать эффекты вручную, указывая каждое свойство на свой вкус, для этого существует несколько сторонних утилит. Некоторые из инструментов:
- Particle Designer: очень мощный редактор эффектов на Mac.
- V-play particle editor: кросс-платформенный редактор систем частиц для Cocos2d-x.
- Particle2dx: онлайн-дизайнер эффектов частиц.
Эти инструменты на выходе дают .plist файл, который вы можете прочитать с помощью Cocos2d-x, чтобы использовать ваше творение внутри вашей игры. Как и во всех других классах, с которыми мы работали, мы используем метод create():
// создание из .plist файла
auto particleSystem = ParticleSystem::create("SpinningPeas.plist");
Встроенные эффекты частиц
Вы готовы добавить эффектов в свою игру? Вам пока трудно создавать собственные эффекты? Для простоты есть ряд встроенных эффектов частиц, из которых вы можете выбрать. Взгляните на этот список:
- ParticleFire: точечная система частиц. Использует режим гравитации.
- ParticleFireworks: точечная система частиц. Использует режим гравитации.
- ParticleSun: точечная система частиц: Использует режим гравитации.
- ParticleGalaxy: точечная система частиц. Использует режим гравитации
- ParticleFlower: точечная система частиц. Использует режим гравитации
- ParticleMeteor: точечная система частиц. Использует режим гравитации
- ParticleSpiral: точечная система частиц. Использует режим гравитации
- ParticleExplosion: точечная система частиц. Использует режим гравитации
- ParticleSmoke: точечная система частиц. Использует режим гравитации
- ParticleShow: точечная система частиц. Использует режим гравитации
- ParticleRain: точечная система частиц. Использует режим гравитации
Используя, например ParticleFireworks, вы можете легко создавать встроенные эффекты:
auto emitter = ParticleFireworks::create();
addChild(emitter, 10);
Результатом является эффект, выглядящий примерно так:
Но что делать, если ваш эффект частиц не совсем такой, каким бы вы хотели его видеть? Да, вы можете вручную изменять его! Возьмём тот же самый фейерверк и изменим его свойства:
auto emitter = ParticleFireworks::create();
// зададим длительность
emitter->setDuration(ParticleSystem::DURATION_INFINITY);
// модификация радиуса
emitter->setEmitterMode(ParticleSystem::Mode::RADIUS);
//модификация радиуса: 100 пикселей от центра
emitter->setStartRadius(100);
emitter->setStartRadiusVar(0);
emitter->setEndRadius(ParticleSystem::START_RADIUS_EQUAL_TO_END_RADIUS);
emitter->setEndRadiusVar(0); // не используется, когда start = end
addChild(emitter, 10);
Параллакс
Parallax — представляет собой уникальный тип узлов, который имитирует параллакс скроллинг. Пара.. что? Да, параллакс. Проще говоря, вы можете рассматривать параллаксовый узел, как специальный эффект, который создает различную видимость позиции и направления объекта, в зависимости от точки обзора. С параллаксом мы встречаемся постоянно, когда смотрим телевизор или снимаем что-то на камеру. Вы можете вспомнить много игр, которые работают таким образом. Super Mario Bros — классический пример. Параллаксовые узлы могут перемещаться путем выполнения последовательности, а также вручную мышкой, касанием или с помощью клавиатуры.
Параллаксовые узлы немного сложнее, нежели обычные узлы. Почему? Потому что они требуют несколько узлов для своей работы. Параллаксовые узлы не могут работать сами по себе. Нужно как минимум 2 узла для работы. Как обычно, в Cocos2d-x параллаксовые узлы легко создавать:
// создадим параллаксовый узел
auto paraNode = ParallaxNode::create();
Нам потребуется несколько Node-объектов, они тоже легко добавляются:
// создание параллаксового узла
auto paraNode = ParallaxNode::create();
// фон передвигается в соотношении 0.4х, 0.5у
paraNode->addChild(background, -1, Vec2(0.4f,0.5f), Vec2::ZERO);
// средний слой передвигается в соотношении 2.2х, 1.0у
paraNode->addChild(middle_layer, 1, Vec2(2.2f,1.0f), Vec2(0,-200) );
// верхнее изображение передвигается в соотношении 3.0х, 2.5у
paraNode->addChild(top_layer, 2, Vec2(3.0f,2.5f), Vec2(200,800) );
Окей, выглядит знакомым, правда? Обратите внимание на несколько вещей! Каждому добавленному узлу присваивается уникальный z-порядок, чтобы они накладывались друг на друга. Также обратите внимание на дополнительные два параметра типа Vec2 в вызове addChild(). Это соотношение и смещение. Эти параметры можно рассматривать как отношение скорости внутренних узлов к скорости родительского узла.
Трудно показать параллаксовый узел в тексте, но вы можете сами попробовать написать этот код, или же запустить тестовый проект — Programmer Guide Sample, чтобы увидеть его в действии!