您的位置:首页 > 其它

2D游戏引擎制作:读取XML文件 1

2018-02-28 23:18 232 查看

读取XML文件 1

前言

  渲染底层部分暂时结束,等用到了再继续写。

  

   之前创建的窗体大小800和600还有标题等信息是写死在代码里的,但笔者们一般需要将它提出来放在一个文件里,以便修改这些属性时不用重新编译代码。或者需要将游戏运行中产生的一些数据保存下来,比如存档之类的,都需要与文件进行交互。交互的方法有很多,笔者比较喜欢使用以XML格式进行存储和读取,它可以在外部使用笔记本或notepad++打开,数据结构清晰,方便修改,最重要的是有很多开源库可以直接使用,比如TinyXML,SlimXML,MSXML等,教程也很多。所以笔者使用tinyXML与XML文件进行交互。

  

   But

  

  当准备使用下载的开源库时,笔者突然发现一个策划在使用C++写对图片进行压缩和加密的工具,当时就老实了。太恐怖了,才回想起他场景多次到程序部来探讨学术问题,他究竟是程序部派到策划部以便减轻程序员工作的卧底,还是高层暗自在策划部培养的用来取缔程序部的叛徒。不行,这样迟早会被抹杀存在的。最后还是决定自己写读取xml文件的方法,虽然之前学过编译原理,但是全完了,只记得最后考试全程翻书找答案。

正文

  额,写了几天,总算是能读取了。笔者把思考过程大致整理一下,大家看看就好,开心就好,千万不要在意!

  对了,先说一下word的快捷键,默认缩进为什么是Ctrl+M和Ctrl+Shift+M而不是Ctrl+Tab和Ctrl+Shift+Tab,虽然可以修改,但感觉不习惯。

  XML文件如下:

<Game shenMeShenMeProperty="shenmeshenme" >
<ASD name="asdf" />
<Game/>


  第一阶段,伪代码如下:

wifstream file(filename);//打开文件
file.imbue(locale("chs"));//兼容汉字
wchar_t tempchar;
wstring tempwstring;//两个临时变量
stack<ShenMeShenMeBase *> zhan;//使用栈在存数据,先进后出与xml文件结构正好匹配。ShenMeShenMeBase是一个基类,里面声明了读取和导出文件的虚方法,想要从XMl文件中读取就要基础这个类,具体实现由子类完成。
//以下假设XML文件里以Game为根节点。
while (!file.eof())//循环读取
{
bool canPop = false;
file >> tempchar >> tempwstring;//先读取一个符号一般是“<”,然后读取直到空格
if (tempwstring[0] == '/')//这个判断用来做“</Game>”节点结束标记。
{
if (zhan.size()>0)
{
zhan.pop();
}
continue;
}
if (tempwstring == L"Game")//这个判断用来做“<Game>”节点开始
{//以下为读取节点的属性,应为单独方法,为方便理解直接写到这儿了。
wchar_t tempchar;
wstring tempwstring;
while (true)
{
file >> tempwstring;
wstring tempw = tempwstring.substr(0, tempwstring.find_first_of(L"="));//截取到“=”之前,没有读到就返回所有。

if (tempw == L"/>")
{
return true;
}
if (tempw == L">")
{
return false;
}
if (tempw == L"shenMeShenMeProperty")//属性名,每有一条属性就要多一个判断,把可读取的属性写死在代码里。
{
shenMeShenMeProperty = APIHelper::SubWStringBy(tempwstring, '"');//帮助类,是用来提取双引号中间的内容。
}
}
continue;
}
//以下是读取子节点
ShenMeShenMeBase * it = nullptr;
if (tempwstring == L"ASD")
{
it = new ASD();
}
else if(tempwstring == L"QWE")
{
it = new QWE ();
}
if (zhan.size()>0)
{
zhan.top()->AddNode(it);
}
canPop = it->ReadFromFile(file);//子节点的读取方法与前文类似,返回值用来检验是否可以弹出,其实就是是否需要添加到栈里。为了应对“<ASD name=”asdf” />”的情况,这种情况就不需要添加到栈里。
if (!canPop)
{
zhan.push(it);
}
}
file.close();
读取完成。


 上述代码最大的特点就是代码量比较少,顺着XML可以很好理解,最严重的问题要把所有的类名写死在代码里。不过至少可以读到内容了。

结束语

  问东问西一星期,走南走北两公里,心上心下比Tiny,一天一地Orz。横批:笔者哭泣。

  笔者觉得笔者不适合编程,对了有哪家公司需要不写程序的策划,笔者愿意从扫地做起?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: