• [翻译]XNA 3.0 Game Programming Recipes之thirtythree


    PS:自己翻译的,转载请著明出处格
                                                      5-11 从一个XML文件中加载数据
    问题
                  你想从XML文件中加载数据到你的XNA游戏工程中。你可以做这个用从文件中读当你的XNA工程开始默认使用.NET文件的I/O功能函数,但是这是不会工作的,当你运行游戏在XBOX360控制台或者Zune.
                  你想要XML文件被序列化成一个二进制文件通过内容管道,这样你能读数据载入到二进制文件在你的XNA工程中.
    解决方案
                  在XML文件中,简单的把对象你想加载在<XNAContent>和<Asset>标签之间,如在这个例子XML文件所描述一个自定义MapData类对象:
     1 <?xml version="1.0" encoding="utf-8"?>
     2   <XnaContent>
     3           <Asset Type="XMLDataPLine.MapData">
     4               <mapName>Battle In The Middle</mapName>
     5               <numberOfCastles>8</numberOfCastles>
     6               <allies>
     7                   <Item>Humans</Item>
     8                   <Item>Elves</Item>
     9                   <Item>Dwarves</Item>
    10               </allies>
    11           </Asset>
    12    </XnaContent>
    提示:如果你不知道如何创建一个XML文件自动从一个对象,你可以学习如何做这些在这章的结束.
                   这XNA框架带有一个内容导入,能够把XML文件转化成类的对象定义在XML文件中.由于这个对象已经准备在这点完成,你不需要一个处理器,这个对象能立即被序列化成二进制文件.
                   在这种情况,这个对象是自定义的MapData类,所以你必须定义一个自定义TypeWrite和TypeReader因为这是一个自定义类.
    注意:如果XML文件描述一个类的对象,内容管道已经知道如何去序列化,你不必编写一个新的TypeWriter或者TypeReader.
                   图5-22显示完整的原理图.

    它是如何工作的
                   导入一个.xml文件到你的XNA游戏工程中.在这个解决方案资源管理器,选择文件,这样它的属性被显示在屏幕的右下角.表明你想使用这默认的XML内容导入,来自XNA框架,和选择No Processing Required表明导入输出应该被序列化到一个文件没有通过一个处理器.图5-23显示最终的属性结果窗口:
                   如果XML文件包含一个类的对象,内容管道知道如何去序列化和反序列化到/从一个二进制文件,你能立即加载这个对象到一个变量中在你的LoadContent方法中.在这节,无论如何,这MapData类是一个自定义类,所以你必须定义你的TypeWriter.
                   添加一个新的内容管道对象到你的解决方案中通过10个步骤正如4-15节所解释的.这次,尽管,你不需要去定义你的自定义处理器.所有你需要去做的是定义一个MapData类,和一个适当的TypeWriter和TypeReader.
    注意:确保你可以添加一个涉及到你的内容管道的工程,两个为内容入口和你的XNA工程,正如4-15节所解释的.它是被要求的,这样你的主要工程能访问MapData类的定义,它被存储在内容管道工程中.
    定义一个自定义MapData类
                   作为一个例子,这MapData类包含一个字符串,一个整型,一个字符串List.添加这定义到你的内容管道工程中:
    1 public class MapData
    2 {
    3     public string mapName;
    4     public int numberOfCastles;
    5     public List<string> allies=new List<string>();
    6 }  
    提示:核实数据包含在前面的XML文件为这三个变量提供数据.
    定义一个序列化一个MapData类的对象的能力
                   正如4-15节所解释的那样,TypeWrite需要足够的数据准确的序列化从对象中,这样对象能在以后对重建通过TypeReader.一如往常,它同样可以提供TypeReader的位置去被使用:
     1 [ContentTypeWriter]
     2 public class MapDataTypeWriter:ContentTypeWriter<MapData>
     3 {
     4     protected override void Write(ContentWriter output,MapData value)
     5     {
     6         output.WriteObject<string>(value.mapName);
     7         output.WriteObject<int>(value.numberOfCastles);
     8         output.WriteObject<List<string>>(value.allies);
     9     }
    10     public override string GetRuntimeReader(TargetPlatform targetPlatform)
    11     {
    12         return typeof(MapDataReader).AssemblyQualifiedName;
    13     }
    14 
                    你定义这个TypeWriter将会序列化MapData类的对象的能力.这个默认内容管道知道如何去序列化一个字符串,一个整型,一个List,这样你简单的序列化她们到二进制文件.你传递一个连结到MapDataReaderTypeReader,下一步你会定义.
    定义一个TypeReader序列化一个MapData类的对象的能力
                    这个TypeReader简单的创建一个新的MapData对象;读取用字符串,整型,和List(用这正确的顺序!);保存它们在MapData对象的里面.填满对象返回和传送到XNA游戏工程中.
     1 class MapDataReader:ContentTypeReader<MapData>
     2 {
     3     protected override MapData Read(ContentReader input,MapData existingInstance)
     4     {
     5          MapData map=new MapData();
     6          map.mapName=input.ReadObject<string>();
     7          map.numberOfCastles=input.ReadObject<int>();
     8          map.allies=input.ReadObject<List<string>>();
     9          return map; 
    10     }
    11 }
    用法
                    第一行在这个LoadContent方法是足够去读在MapData对象在运行时.你将会插入第二行,它是一个断点在你的代码这样你能检查数据是实际上可用的:
    1 protected override void LoadContent()
    2 {
    3     MapData loadedMap=Content.Load<MapData>("data");
    4     System.Diagnostics.Debugger.Break();
    5 }
                    在最后一行的Break允许你去核查loadedMap变量包含值来自XML文件中.
    注意:请记住,XML文件被转化成二进制文件时当你在编译你的工程时(使用F5).每当项目开始,只有TypeReader被调用到MapData对象结构从二进制文件中.意思是如果你改变XML文件的内容,你必须重新编译以应用于你的变化.
    代码
                   这个自定义内容管道包含唯一个类定义,TypeWriter,和TypeReader,它是你在这一章节很容易找到的。
    课外阅读
    创建一个XNA-Compatible XML文件从一个现有的对象中
                   这节说明如何你能存储任何类的任何对象作为一个XML文件,你可以加载它使用默认的XML导入器.
                   首先,你需要添加这些命名空间到你的使用的block中,这样你能使用它们的功能函数:
    1 using System.Xml;
    2 using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate;
                   这些行的工作,你同样需要添加System.XMLMicrosoft.XNA.Framework.Content.Pipeline引用;你可以添加它们通过选择->添加引用.
                    接下来,既不连接到你的自定义内容管道或者手动从新定义的MapData类通过把这些代码外置到你工程的命名空间:
    1 namespace XMLDataPLine
    2 {
    3     public class MapData
    4     {
    5         public string mapName;
    6         public int numberOfCastles;
    7         public List<string> allies=new List<string>();
    8     }
    9 }

                    如果你重新定义手动的类,确保你把它放在同样命名空间内作为你自定义内容管道(我的被称为XMLDataPLine)和所有的变量是相同的.
                    接下来,回到你的XNA工程的命名空间,确保你已经有一个MapData类的对象:

    1 XMLDataPLine.MapData myMap=new XMLDataPLine.MapData();
    2 myMap.mapName="Battle In The Middle";
    3 myMap.numberOfCastles=8;
    4 myMap.allies.Add("Humans");
    5 myMap.allies.Add("Elves");
    6 myMap.allies.Add("Dwarves");
                    使用这个代码去保存它到一个XNA-compatible XML文件中,称为data.xml:
    1 string fileName="data.xml";
    2 XmlWriter writer=XmlWriter.Create(fileName);
    3 IntermediateSerializer.Serialize<XMLDataPLine.MapData>(writer,myMap,fileName);
    4 writer.Close();
                   当你运行这个程序,data.xml文件将会被创建在图上,这里是你加载.exe的地方.
    注意:你同样也可以在这个例子中找到代码
  • 相关阅读:
    python 格式化打印
    微软开发工具包下载
    win7 Adobe flash player 无法在线更新
    MySQL5.7本地首次登录win10报错修改
    MySQL本地登录及数据库导入导出
    03蓝桥杯特训课笔记总结:
    03第八届蓝桥杯省赛真题- 2.等差素数列
    02填空题
    01蓝桥杯第七届 方格填数(dfs)
    63中国剩余定理
  • 原文地址:https://www.cnblogs.com/315358525/p/1541691.html
Copyright © 2020-2023  润新知