Создание Flash HUD
Материал из CryWiki Russia
Создание Flash HUD
CryENGINE поддерживает Scaleform GFx, чтобы загружать и обрабатывать элементы Flash внутри игры.
Чтобы загружать flash файлы, следуйте указаниям в статье Scaleform GFx and CryENGINE.
Вызов функции Flash
Для того, чтобы это сделать, создайте глобальную функцию в вашем flash-файле:
setHealth = function(_intHitpointsPercent) { // установить текст в поле динамического текста (не забудьте внедрить шрифты или набор символов) txtHealth.text = "Health: " + _intHitpointsPercent.toString(); }
и вызовите следующую функцию в вашем С++ коде:
CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor()); if (pActor != NULL) { int health = pActor->GetHealth(); pFlashPlayer->Invoke1("setHealth", health); }
Существует 3 функции вызова, которые позволяют инициировать методы flash:
pFlashPlayer->Invoke0( "flashFunction" ); // 0 аргументов pFlashPlayer->Invoke1( "flashFunction", arg1 ); // 1 аргумент SFlashVarValue args[3] = { arg1, arg2 , arg3 }; m_pFlashPlayer->Invoke( "setPlayerPos" , args , 3 ); // 2 или больше аргументов
Загрузка мини-карты
Редактор Sandbox имеет функционал для генерации миникарты вашего уровня. Больше информации можно найти в статье Creating Mini Maps.
После того, как вы создали .dds и .xml файлы с вашего уровня, вы можете легко загрузить файл миникарты .dds в ваш HUD.
Вам нужно будет создать функцию внутри Flash файла, которая загружает файл с данным именем в MovieClip:
setMiniMap = function(_strPathToMiniMap) { //_strPathToMiniMap: scaleform-совместимый путь к изображению карты, должен быть в формате .dds loadMovie("img://"+ _strPathToMiniMap, MiniMapMC); }
теперь вы можете ызвать эту функцию из С++
pFlashPlayer->Invoke1("setMiniMap", "Levels\\PacificIsland\\PacificIsland.dds");
Возможно, вы захотите отображать на карте некоторые динамические элементы, к примеру, позицию игрока.
Чтобы это сделать, вам придётся считывать .xml файл, который создал редактор Sandbox, чтобы получить начальные и конечные координаты мини-карты.
float mapStartX = 0; float mapStartY = 0; float mapEndX = 1; float mapEndY = 1; IXmlParser* pxml = gEnv->pGame->GetIGameFramework()->GetISystem()->GetXmlUtils()->CreateXmlParser(); if(pxml != NULL) { XmlNodeRef node = GetISystem()->LoadXmlFile("Levels\\PacificIsland\\PacificIsland.xml"); if (node != NULL) { node = node->findChild("Minimap"); if (node) { node->getAttr("startX", mapStartX); node->getAttr("startY", mapStartY); node->getAttr("endX", mapEndX); node->getAttr("endY", mapEndY); } } } float mapDimX = mapEndX - mapStartX; float mapDimY = mapEndY - mapStartY; // Примечение: вы также можете проверять измерения на равенство 0!
Теперь просто задайте значения позиции от 0 до 1, и отошлите их в Flash:
CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor()); if (pActor != NULL && pActor->GetEntity() != NULL) { Vec3 pos = pActor->GetEntity()->GetWorldPos(); float posx = (pos.x - mapStartX) / mapDimX; // value from 0 to 1 float posy = (pos.y - mapStartY) / mapDimY; SFlashVarValue args[3] = { posx, posy , pActor->GetAngles().z *180.0f/gf_PI-90.0f}; // обратите внимание, что миникарта повёрнута на -90 градусов m_pFlashPlayer->Invoke("setPlayerPos", args, 3); }
На стороне Flash вы можете реализовать функцию, которая устанавливает на карте позицию и угол поворота клипа, который представляет положение игрока на миникарте:
setPlayerPos = function(_floatPosx, _floatPosy, _intRot) { // the created minimap .dds file has dimensions 512*512 var pX = _floatPosy * 512; // т.к. карта повёрнута на -90 градусов, поменяем координаты x и y местами var pY = _floatPosx * 512; PlayerPosMC._x = pX; PlayerPosMC._y = pY; PlayerPosMC._rotation = -_intRot; }