常玩日本游戏的朋友们应该都知道。日本RPG中经常有一些场景切换的画面。比如在角色走动过程中,突然进入战斗状态,他会先把先前的场景渲染成一张图片,然后移开这张图片,在渲染另一个场景,譬如是战斗场景。
最近在休闲网络游戏时,也碰到一个这样的需求。就是在一局游戏中动态的切换场景。
这个项目时间比较紧迫,场景直接用了解析OFusion的OSM文件来做。但是我遇到一些问题是OfusionLoader这个东西,只有装载没有卸载。如果这样的话,就很难满足项目中的需求。(就算没有这个需求,卸载场景还是需要做的)
好在并不是太困难,只要按照OFusion的状态方式,把他所装载的东西都记录下来就可以了。
比如我先把装载的场景中的状态的静态模型都记录到一个容器中
程序代码
void OSMScene::createEntities(TiXmlElement* pEntityNode, Ogre::SceneNode* pSceneRoot)
{
// Iterate all meshes, creating them.
for (TiXmlElement* pMeshElem = pEntityNode->FirstChildElement();
pMeshElem != 0; pMeshElem = pMeshElem->NextSiblingElement())
{
// Ogre could cast an exception, in which case we just try to
// continue reading the other meshes
try
{
const char *pszName = pMeshElem->Attribute("name");
const char *pszFileName = pMeshElem->Attribute("filename");
// try to create the mesh
Entity *pEntity = mSceneMgr->createEntity(pszName, pszFileName);
if(pEntity==0) continue;
// Check if the object should cast shadows
const char *pszCastShadows=pMeshElem->Attribute("CastShadows");
if(pszCastShadows && stricmp(pszCastShadows, "no")==0)
pEntity->setCastShadows(false);
else
pEntity->setCastShadows(true);
// Create node with full information
SceneNode *pObjNode=createNode(pMeshElem, pSceneRoot);
// Attach the mesh entity to node
pObjNode->attachObject(pEntity);
StaticModel * staticModel = new StaticModel();
staticModel->mEntity = pEntity;
staticModel->mSceneNode = pObjNode;
mStaticModelList.push_back(staticModel);
// Notify
if(mCallbacks)
mCallbacks->OnEntityCreate(pEntity, pMeshElem);
// Add to entity list
mEntities.push_back(pEntity);
} catch(...)
{
continue;
}
}
}
然后再清理场景之间清理掉他们
程序代码
// Delete all entity
void OSMScene::deleteEntities(void)
{
std::vector<StaticModel * >::iterator StaticModelIter;
for(StaticModelIter = mStaticModelList.begin(); StaticModelIter != mStaticModelList.end(); ++StaticModelIter)
{
Ogre::Entity * pEntity = (*StaticModelIter)->mEntity;
Ogre::SceneNode * pSceneNode = (*StaticModelIter)->mSceneNode;
pSceneNode->detachObject(pEntity);
mSceneMgr->destroySceneNode(pSceneNode);
mSceneMgr->destroyEntity(pEntity);
delete *StaticModelIter;
}
mStaticModelList.clear();
}
其他象摄像机,灯光都按照这样的方法装载、卸载掉。
程序代码
最后清理场景
bool OSMScene::destroyScene()
{
try
{
deleteEntities();
deleteLight();
deleteCamera();
.............................................................
return true;
}
catch(...)
{
LogManager::getSingleton().logMessage("Error");
}
return false;
}
当然由于OFusion也沿用了Ogre的文件管理系统,因此在加载前他把自己的资源目录添加到Ogre的资源配置文件中去了,在卸载的时候我们也需要删除它们,防止那个资源目录爆炸式的增加
程序代码
void OSMScene::undeclareResources(void)
{
if(!mXMLDoc.isNull())
{
TiXmlElement* rootElem = mXMLDoc->RootElement();
try
{
// Get mesh filename from entities
TiXmlElement *pMeshNode = rootElem->FirstChildElement("entities");
if(pMeshNode)
{
// Iterate all meshes, creating them.
for (TiXmlElement* pMeshElem = pMeshNode->FirstChildElement();
pMeshElem != 0; pMeshElem = pMeshElem->NextSiblingElement())
{
// Declare mesh resource
const char *pszFileName = pMeshElem->Attribute("filename");
ResourceGroupManager::getSingleton().undeclareResource(pszFileName, "Mesh");
}
}
} catch(...)
{
}
}
}
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/wangwang123654/archive/2009/12/10/4977800.aspx