У цьому пості ми спробуємо створити першу власноруч написану програму. Поки що вона не буде нічого робити, ми просто візьмемо кілька зображеннь космічних кораблів з безкоштовного набору та покажемо їх на екрані. Основна мета — навчитись працювати з класом Sprite.
Cocos2d використовує “шкільну” систему координат:
Центр системи координат знаходиться в опорній точці (anchor point). Положення опорної точки можна задавати окремо для кожного об'єкту Node методом setAnchorPoint. Метод отримує два параметри у діапазоні від 0 до 1, найчастіше це значення 0, 0.5 або 1. Наприклад:
Щоб побачити. як це все працює, ми візьмемо малюнок, що складається з клітин розміром 160х120 пікселів і використаємо його, як фонове зображення для програми.
Робиться це за допомогою такого коду, розміщеного у фунції init сцени:
const char backFilename[] = "background.png";
Sprite* sprite = Sprite::create(backFilename);
if (sprite == nullptr) {
printf("Error while loading: %s\n", backFilename);
return false;
}
sprite->setAnchorPoint(Vec2(0,0));
sprite->setPosition(0,0);
addChild(sprite, 0);
Спрайт створюється за допомогою статичного методу create. Це стандартна для Cocos2d практика — майже у кожного класу є такий метод, за допомогою якого і треба створювати об'єкти.
Потім ми встановлюємо опорну точку спрайту у лівий нижній кут і ставимо спрайт на центр координат сцени (який теж знаходиться у лівому нижньому куті).
Метод addChild додає новостворений спрайт на сцену. Другим параметром цього методу є z-order: якщо без подробиць, це число, яке визначає порядок “перекривання” елементів. Елементи з більшим числом будуть намальовані пізніше, відповідно, менші стануть для них фоном.
Тепер додамо до сцени ще пару спрайтів. Один за допомогою ось такого коду:
const char shipFilename[] = "ships/playerShip3_blue.png";
Sprite* sprite = Sprite::create(shipFilename);
sprite->setAnchorPoint(Vec2(0.5,0.5));
sprite->setPosition(Vec2(160, 240));
addChild(sprite, 10);
А інший ось так:
const char shipFilename[] = "ships/playerShip3_blue.png";
Sprite* sprite = Sprite::create(shipFilename);
sprite->setRotation(45);
sprite->setPosition(Vec2(160, 120));
addChild(sprite, 10);
Відмінність у тому, що в другому випадку спрайт додатково повертається на 45 градусів.
В обох спрайтів опорна точка знаходиться в центрі (0.5, 0.5). Відповідно, після встановлення позиції центр спрайту опиниться на перетині квадратів, ось так:
Створимо ще два спрайти, ось таким чином:
const char shipFilename[] = "ships/playerShip3_green.png";
Sprite* sprite = Sprite::create(shipFilename);
sprite->setAnchorPoint(Vec2(0,0));
sprite->setPosition(Vec2(480, 240));
addChild(sprite, 10);
і таким:
const char shipFilename[] = "ships/playerShip3_green.png";
Sprite* sprite = Sprite::create(shipFilename);
sprite->setAnchorPoint(Vec2(0,0));
sprite->setRotation(45);
sprite->setPosition(Vec2(480, 120));
addChild(sprite, 10);
Тут опорна точка спрайтів встановлюється у нижній лівий кут, також другий спрайт повертається на 45 градусів.
Результат виглядає таким чином:
Опорна точка у зелених кораблів знаходиться на перетині квадратів, тому самі спрайти опинились правіше і вище. У другому випадку поворот здійснено навколо опорної точки.
Обє'кти класу Node можна використовувати для групування об'єктів. Наприклад, можна зібрати власний корабель, скомбінувавши три зображення:
Для цього потрібен такий код:
const char cockpitFilename[] = "parts/cockpitRed.png";
Sprite* cockpitSprite = Sprite::create(cockpitFilename);
const char wingFilename[] = "parts/wingRed.png";
Sprite* rightWingSprite = Sprite::create(wingFilename);
Sprite* leftWingSprite = Sprite::create(wingFilename);
Node* resultNode = Node::create();
resultNode->setAnchorPoint(Vec2(0.5,0.5));
//
rightWingSprite->setAnchorPoint(Vec2(0.5,0.5));
rightWingSprite->setScale(1, -1);
rightWingSprite->setPosition(Vec2(60, 15));
rightWingSprite->setRotation(90);
resultNode->addChild(rightWingSprite);
leftWingSprite->setAnchorPoint(Vec2(0.5,0.5));
leftWingSprite->setPosition(Vec2(-60, 15));
leftWingSprite->setRotation(90);
resultNode->addChild(leftWingSprite);
resultNode->addChild(cockpitSprite);
//
resultNode->setAnchorPoint(Vec2(0.5,0.5));
Спершу ми створюємо три спрайти (два крила та фюзеляж) і порожній об'єкт Node, який об'єднає ці елементи.
Спрайти крил повертаються та встановлюються у потрібне положення. Координати для їх встановлення (60, 15) підбираються емпірично, так, що більш-менш гарно виглядало. Крім того, спрайт правого крила треба відзеркалити викликом setScale(1, -1).
В кінці окремі спрайти додаються у якості дітей до вузла-результату. Робота з фінальним об'єктом не відрізняється від роботи з одиноким спрайтом, тому я тут не буду наводити цей код. Як і все інше, його можна знайти у проекті-прикладі на гітхабі.
В результаті наша тестова програма стане такою:
На цьому поки що все, дякую за увагу. У наступних постах зображення почнуть рухатись, стане цікавіше :)