簡體   English   中英

從XNA中的xml文件加載級別數據

[英]Loading level data from xml file in XNA

我正在XNA中創建一個基於磁貼的游戲,並將從xml文件加載級別信息。 我沒有加載xml數據的問題,但我想反饋我正在考慮用於讀取xml文件的方法。

代碼具有類層次結構,以便:

Level類包含:
- TileLayers的集合
- Tilesets的集合

TileLayer類包含
- 瓷磚的集合

Tileset類包含:
- TilsetTiles的集合

TilesetTile類包含:
- 一個TileId
- TileProperties的集合
- TileRectangle

上述每個類都需要xml級別文件中的一些信息。

當我加載一個級別時,我想簡單地調用Level.Load();

我的意圖是每個類都有一個Load()方法,它將:
1.從xml文件加載所需的任何特定信息。
2.在其子節點上調用Load()。

我看到的問題是處理xml的代碼將分散在不同的文件中,使更改難以實現(例如,如果我決定加密xml文件),毫無疑問會破壞SOLID原則的幾個方面。

我有這個想法,我可以創建一個xmlLevelReader類,其唯一目的是讀取xml級文件。 然后,該類可以公開可以從上述每個類中的Load()方法調用的方法。

例如,TileLayer類的Load()方法可以調用xmlLevelReader.GetTiles(),它將返回一個IEnumerable<Tile>

你認為這種方法有效嗎?
你能預見到任何困難嗎?
這種方法過於簡單/復雜嗎?
任何建設性的批評都歡迎!

謝謝

根據您的評論,我看到您正在使用Tiled Map Editor。 這導致我建議你使用TiledLib。 以下是如何啟動和運行導入.tmx文件以便在游戲中使用的簡要說明。

內容管道概述

文件 - >內容導入 - >內容處理 - >內容寫入 - > .xnb - > ContentRead - >游戲對象

TiledLib

TiledLib只處理上圖中的ContentImporter部分。 它本質上處理讀取.tmx XML並允許您將數據處理為運行時所需的任何對象。 幸運的是,TiledLib作者也在下載中提供了演示部分。

基本平鋪地圖處理器演示

  • BasicDemo主游戲項目,包含ContentManager.Load調用。
  • BasicDemoContent項目,其中包含Tiled的.tmx文件
  • 具有ContentProcessor BasicDemoContentPipeline項目
  • TiledLibContentImporter

您真的只需要擔心ContentProcessor工作原理,因為TiledLib會為您處理所有導入。 雖然我建議查看不同的類以了解它如何反序列化XML(用於教育目的)。

該示例ContentProcessor在基本演示項目以在MapContent從物體ContentImporter (TiledLib),並輸出一個DemoMapContent其序列在構建時對.xnb和反序列化到對象Map對象在運行時。 以下是完全處理后代表地圖的類:

[ContentSerializerRuntimeType("BasicDemo.Map, BasicDemo")]
public class DemoMapContent
{
    public int TileWidth;
    public int TileHeight;
    public List<DemoMapLayerContent> Layers = new List<DemoMapLayerContent>();
}

[ContentSerializerRuntimeType("BasicDemo.Layer, BasicDemo")]
public class DemoMapLayerContent
{
    public int Width;
    public int Height;
    public DemoMapTileContent[] Tiles;
}

[ContentSerializerRuntimeType("BasicDemo.Tile, BasicDemo")]
public class DemoMapTileContent
{
    public ExternalReference<Texture2DContent> Texture;
    public Rectangle SourceRectangle;
    public SpriteEffects SpriteEffects;
}
  • Map包含圖塊寬度,圖塊高度和MapLayers列表。
  • MapLayer包含寬度,高度和Tiles列表。
  • MapTile包含一個紋理,一個源矩形(tileset中的適當矩形)和可選的精靈效果(我從未使用過任何)。

這個怎么做的

我建議閱讀ContentProcessor的注釋以了解正在發生的事情,但簡而言之,這是基礎知識:

  • 加載圖塊集的紋理數據
  • 從紋理中獲取每個圖塊的源矩形
  • 迭代地圖的所有圖層
  • 對於每個圖層,迭代所有圖塊
  • 對於每個圖塊,獲取適當的紋理和源矩形
  • 正確地將輸入中的所有數據分配給輸出

注意事項

只要你堅持基本類型(模糊,我知道),你也不必擔心內容管道的ContentWriterContentReader部分。 它將分別在構建和運行時自動序列化和反序列化.xnb文件。 看到我問過這個問題: 這里

此外,您會注意到如果您在Tiled中使用對象圖層,則演示不會向您展示如何處理這些對象圖層。 TiledLib正確導入它們,您只需要將數據拉出並將其粘貼到適當的類中。 我稍后會嘗試編輯這個答案,並舉例說明如何做到這一點。

如果您只是想在不操作數據的情況下加載XML,則可以使用內置的XNA Content Serializer。

基本上,您定義了一個映射到您的xml格式的類,然后將XML讀入該類的實例。

例如。 在這里,我定義了要加載的類:

SpriteRenderDefinition.cs

我選擇了這個,因為它有嵌套類,就像你描述的情況一樣。 請注意,它會進入XNA解決方案的ContentDefinitions項目。

現在這里是填充SpriteRenderDefinition內容的xml文件:

Sprite.xml

該XML的格式直接映射到SpriteRenderDefinition的成員名稱。

最后,在運行時將XML數據實際加載到實際Object中的代碼非常簡單:

SpriteRenderDefinition def = GameObjectManager.pInstance.pContentManager.Load<SpriteRenderDefinition>(fileName);

在調用該行之后,您將擁有一個SpriteRenderDefintion對象,其中填充了XML文件的所有內容! 這就是我寫的所有代碼。 其他一切都內置於XNA中。 如果花一個小時左右的時間來弄清楚它,它真的非常光滑和有用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM