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

读取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。横批:笔者哭泣。
  笔者觉得笔者不适合编程,对了有哪家公司需要不写程序的策划,笔者愿意从扫地做起?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值