Для більш-менш великих ігрових проектів, таких як стратегії або платформери, вам знадобиться окремий засіб для проектування карт рівнів. Таким засобом є Tiled — універсальний редактор рівнів з відкритим кодом.
Інтерфейс Tiled в цілому схожий на інші редактори, тому я не буду тут його детально описувати (але, якщо треба, варто глянути сюди). Суть в тому, що ви берете створений художником набір елементів (tileset) і використовуєте його для побудови карти.
Для нашого першого прикладу візьмемо цей тайлсет, а також анімацію чарівника та лицаря.
Є деякі особливості, специфічні для Cocos2dx:
*.tsx) був в одній папці з файлом карти (*.tmx), інакше можуть виникнути проблеми під час завантаженняКарта завантажується дуже просто, фактично одним рядком:
const char mapFilename[] = "beach/beach_map.tmx";
TMXTiledMap* mapNode = TMXTiledMap::create(mapFilename);
if (mapNode == nullptr) {
// обробка помилки
}
addChild(mapNode, ZO_BACKGROUND);
TMXTiledMap::create створює звичайний об'єкт-нащадок Node і далі з ним можна робити все те ж саме, що з іншими, зокрема, використовувати у якості фону.
Скоріш за все, під час створення рівня вам треба буде зберегти на карті якусь додаткову інформацію. Наприклад, вказати місце появи головного героя, а по позначити квадрати, на які герой не може заходити.
Для того, щоб це зробити, використовується такий прийом:
Службовий тайлсет може виглядати так:
Немає значення, що саме зображено на квадратах; в даному випадку це просто цифри і позначки.
До кожного елементу тайлсету треба додати спеціальну властивість — числовий код, за допомогою яких програма відрізнятиме тайли один від одного. На малюнку вище така властивість названа ‘MetaCode’, додається вона після натиснення на синій “+” внизу панелі.
Завантаження службового шару виглядає так:
bool SimpleNoScrollScene::loadMetaInfo(TMXTiledMap* const mapNode) {
const string metaLayerName = "meta";
TMXLayer* const metaLayer = mapNode->getLayer(metaLayerName);
if (metaLayer == nullptr) {
printf("Failed to find %s layer\n", metaLayerName.c_str());
return false;
}
const Size mapSize = mapNode->getMapSize();
obstaclesMapWidth = mapSize.width;
obstaclesMapHeight = mapSize.height;
obstaclesMap = new bool[obstaclesMapWidth*obstaclesMapHeight];
memset(obstaclesMap, 0, (obstaclesMapWidth*obstaclesMapHeight));
for (int tileX = 0; tileX < mapSize.width; tileX++) {
for (int tileY = 0; tileY < mapSize.height; tileY++) {
const int tileGid = metaLayer->getTileGIDAt(Vec2(tileX, tileY));
const Value prop = mapNode->getPropertiesForGID(tileGid);
if (prop.isNull()) {
continue;
}
const ValueMap vm = prop.asValueMap();
const auto frez = vm.find("MetaCode");
if (frez == vm.end()) {
continue;
}
const int metaCode = frez->second.asInt();
switch (metaCode) {
case MMC_OBSTACLE:
obstaclesMap[obstaclesMapWidth*(obstaclesMapHeight - tileY - 1) + tileX] = true;
break;
case MMC_MAGE_START:
mageStartX = tileX;
mageStartY = mapSize.height - tileY - 1;
break;
case MMC_KNIGHT_START:
knightStartX = tileX;
knightStartY = mapSize.height - tileY - 1;
currentKnightX = knightStartX;
currentKnightY = knightStartY;
break;
// Note there is no suitable default action here
// default:
}
}
}
metaLayer->setVisible(false);
return true;
}
Тут ми отримуємо шар методом getLayer і обходимо всі його квадрати. Для кожного квадрату намагаємось отримати значення параметру “MetaCode”, якщо таке є. В залежності від значення, це може бути або стартове місце, або позначка квадрату, на який не можна заходити.
У Tiled квадрат з координатами “0:0” знаходиться у верхньому лівому куті карти, а вісь Y зростає зверху до низу. Це суперечить підходу Cocos2dx, у якому точка “0:0” знаходиться зліва внизу, а Y збільшується вверх. Тому при завантаженні координати Y доводиться перераховувати, використовуючи вираз типу knightStartY = mapSize.height - tileY - 1;.
Таким чином, можна взяти таку карту:
Робота з Tiled
В програмі вона буде виглядати так:
Лицар рухається до берега
Цифри тайлсету позначають стартові позиції мага та лицаря, хрестики — місця, де не можна ходити. Лицар запрограмований так, щоб пересуватись на один квадрат вправо, доки у наступному квадраті не буде позначки-заборони. Повний прилад можна переглянути тут.
Tiled — не єдиний редактор рівнів, при бажанні можна знайти посилання. Крім того, теоретично можна спробувати написати свій власний редактор.