首页 > 代码库 > Ogre之简易地模拟人物退格血条

Ogre之简易地模拟人物退格血条


写在前面:

首先,在制作该人物血条前,我需要声明以下几点:

1.人物的血条属于简易制作的退格方式,不是连续的进度条类型。

2.该血条制作纯属快速开发完成,没有达到精细的程度,高手可以绕道。


以以上两点为前提,我粗略的讲述一下我在OGRE中用CEGUI制作血条的过程。

首先,人物头像用了一张我很喜欢的全职猎人中奇伢的图片:


紧接着,为了配合紫色色调,我我选取了一种紫色的血条单元:


有了血条单元(这里我称之为紫星),之后,用图片制作工具拼接制作了11张图片,

从0星紫星一直到10星紫星,取名为purple_x.jpg(x为紫星数量),为了便于理解,这里附

一张九星紫星的图片:


到此为止,素材准备好了,便开始在OGRE中完成我的程序部分了,

以下是我完成图片,文字,及窗口绘制部分的代码,我将其封装在一个函数中:

(CEGUI为0.8.3版本)

//----------------------------------【CreateSrcBloodShowWindow()函数】----------------------------------
// Desc:创建主模型血量显示的窗口
//------------------------------------------------------------------------------------------------------
void NinthCEGUI::CreateSrcBloodShowWindow(float ratio /* = 1.6f */)
{
	CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
	
	//创建退格血条,血量数量,人物头像三个窗口
	m_BloodW = wmgr.createWindow("WindowsLook/StaticImage", "Beyond/Blood");
	m_BloodNumW = wmgr.createWindow("OgreTray/StaticText", "Beyond/BloodNum");
	CEGUI::Window* head = wmgr.createWindow("WindowsLook/StaticImage", "Beyond/head");
	//载入相关图片
	CEGUI::ImageManager::getSingleton().addFromImageFile("head", "head.jpg");
	for (size_t i = 0; i <= 10; i++)
		CEGUI::ImageManager::getSingleton().addFromImageFile("purple"+
		Ogre::StringConverter::toString(i), "purple_"+ Ogre::StringConverter::toString(i)+".jpg");
	//将图片添加到窗口中
	MyCEGUISystem::getSingletonPtr()->addImageToWindow(head, "head", 0.02f/ratio, 0.02f, 0.1f/ratio, 0.1f);
	MyCEGUISystem::getSingletonPtr()->addImageToWindow(m_BloodW, "purple10", 0.12f / ratio, 0.085f, 0.25f/ratio, 0.035f);
	m_BloodNumW->setArea(CEGUI::UDim(0.13f / ratio, 0), CEGUI::UDim(0.05f, 0), 
		CEGUI::UDim(0.2f / ratio , 0), CEGUI::UDim(0.04f, 0));

	//去掉血量窗口的文本边框和背景,设置文本为浅紫色
	m_BloodNumW->setProperty("FrameEnabled", "false");
	m_BloodNumW->setProperty("BackgroundEnabled", "false");
	m_BloodNumW->setProperty("TextColours", "tl:FFFFAAFF tr:FFFFAAFF bl:FFFFAAFF br:FFFFAAFF");

	//添加到根窗口
	CEGUI::Window* root = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow();
	root->addChild(m_BloodW);
	root->addChild(m_BloodNumW);
	root->addChild(head);
}


我在退格血条的上方显示了血量的具体数值,为了配合整体色调,将其设置为浅紫色,

以下是我自己封装完成的MyCEGUISystem州农工addFromImageFile和addImageToWindow具体细节:

//----------------------------------【addFromImageFile()函数】--------------------------------------
// Desc:添加一张图片
//--------------------------------------------------------------------------------------------------
void MyCEGUISystem::addFromImageFile(const CEGUI::String& imageName, const CEGUI::String& fileName)
{
	CEGUI::ImageManager::getSingleton().addFromImageFile(imageName, fileName);
}
//----------------------------------【createImageWindow()函数】-------------------------------------
// Desc:创建静态图片窗口
//--------------------------------------------------------------------------------------------------
void MyCEGUISystem::addImageToWindow(CEGUI::Window* window,const CEGUI::String& imageName, 
	float left /* = 0.0f */, float top /* = 0.0f */, float width /* = 1.0f */, float height/* = 1.0f */)
{
	window->setArea(CEGUI::UDim(left, 0.0f), CEGUI::UDim(top, 0.0f),
		CEGUI::UDim(width, 0.0f), CEGUI::UDim(height, 0.0f));
	window->setProperty("Image", imageName);
}


之所以CreateSrcBloodShowW()函数中使用ratio参数是因为适应游戏窗口的变化,以致于人物头像和血条不至于变形,

这里的ratio=窗口宽度/窗口高度。


-------------------------------------------------------------------------------------------------------------------------------

人物头像,血量,血条的创建部分描述过了,接下来便讲述一下人物血量及血条的更新显示部分,

以下是frameRenderingQueued()中相关部分的核心代码:

	//血量及退格血条更新
	m_NinthCEGUI->getSrcBloodNumW()->setText("Blood: "+ Ogre::StringConverter::toString((int)m_HP));
	static int ibloodPart = -1;
	int i = 0;
	while (1)
	{
		if (m_HP <= i * MODEL_MAX_BLOOD / 10)
		{
			if (ibloodPart != i)
			{
				m_NinthCEGUI->getSrcBloodW()->setProperty("Image", "purple" + Ogre::StringConverter::toString(i));
				ibloodPart = i;
			}
			else
				break;
		}
		else
		{
			i++;
			if (i > 10)
				break;
		}
	}

有了以上代码,便会在每一帧中更新人物的血量,一旦退格血条越出了血量每X/10(X=0,1,2...9)边界,便会自动更新绘制并显示。


最后,我附上一张完整的整体效果图以便于大家理解: