1

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の原則のいくつかの側面を破ることは間違いありません。

私は、xmlレベルのファイルを読み取ることを唯一の目的とするxmlLevelReaderクラスを作成できると考えています。このクラスは、上記の各クラスのLoad()メソッドから呼び出すことができるメソッドを公開できます。

たとえば、TileLayerクラスのLoad()メソッドはxmlLevelReader.GetTiles()を呼び出すことができ、これはIEnumerable<Tile>

このアプローチはうまくいくと思いますか?
何か困難を予見できますか?
このアプローチは単純すぎたり複雑すぎたりしませんか?
建設的な批判は歓迎します!

ありがとう

4

2 に答える 2

2

あなたのコメントに基づいて、あなたはTiledMapEditorを使用しているようです。これにより、TiledLibを使用することをお勧めします。これは、ゲームで使用するために.tmxファイルをインポートして起動して実行する方法の簡単な説明です。

コンテンツパイプラインの概要

ファイル->コンテンツのインポート->コンテンツプロセス->コンテンツの書き込み->.xnb->ContentRead->ゲームオブジェクト

TiledLib

TiledLibContentImporterは、上の図の一部のみを処理します。基本的に.tmxXMLの読み取りを処理し、実行時に必要なオブジェクトにデータを処理できるようにします。幸い、TiledLibの作者は、ダウンロードのデモセクションも提供しています。

基本的なタイルマッププロセッサのデモ

  • BasicDemoContentManager.Load呼び出しを含むメインゲームプロジェクト。
  • BasicDemoContentTiledの.tmxファイルがあるプロジェクト
  • BasicDemoContentPipelineを持っているプロジェクトContentProcessor
  • TiledLibこれはContentImporter

ContentProcessorTiledLibがすべてのインポートを処理するため、実際にはどのように機能するかを心配する必要があります。さまざまなクラスを調べて、XMLがどのように逆シリアル化されているかを理解することをお勧めします(教育目的で)。

ContentProcessor基本デモプロジェクトの例では、 (TiledLib)MapContentからオブジェクトを受け取り、ビルド時に.xnbにシリアル化され、実行時にオブジェクトに逆シリアル化されたオブジェクトを出力します。完全に処理された後のマップを表すクラスは次のとおりです。ContentImporterDemoMapContentMap

[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;
}
  • AMapには、タイルの幅、タイルの高さ、およびのリストが含まれMapLayersます。
  • AMapLayerには、幅、高さ、およびのリストが含まれTilesます。
  • AMapTileには、テクスチャ、ソース長方形(タイルセット内の適切な長方形)、およびオプションのスプライト効果(私はこれまで使用したことがありません)が含まれています。

作り方

ContentProcessor何が起こっているのかを理解するためにのコメントを読むことをお勧めしますが、簡単に言えば、これが基本です:

  • タイルセットのテクスチャデータをロードする
  • テクスチャ内から各タイルのソース長方形を取得します
  • マップのすべてのレイヤーを反復処理します
  • レイヤーごとに、すべてのタイルを繰り返し処理します
  • タイルごとに、適切なテクスチャとソースの長方形を取得します
  • 入力から出力にすべてのデータを適切に割り当てます

警告

基本的なタイプ(あいまいな、私は知っています)に固執する限り、コンテンツパイプラインの一部ContentWriterについても心配する必要はありません。ContentReaderビルド時と実行時に、それぞれ.xnbファイルを自動的にシリアル化および逆シリアル化します。私がこれについて尋ねた質問を参照してください:ここ

また、Tiled内からオブジェクトレイヤーを使用している場合、デモではそれらの処理方法が示されていません。TiledLibはそれらを適切にインポートします。データを引き出して、適切なクラスに貼り付けるだけです。その方法の例を使って、後でこの回答を編集してみます。

于 2012-10-19T23:28:12.930 に答える
1

データをまったく操作せずにXMLをロードしたいだけの場合は、組み込みのXNAコンテンツシリアライザーを使用できます。

基本的に、xml形式にマップするクラスを定義してから、XMLをそのクラスのインスタンスに読み込みます。

例えば。ここで、ロードするクラスを定義します。

SpriteRenderDefinition.cs

あなたが説明する場合のようにネストされたクラスがあるので、私はこれを選びました。XNAソリューションのContentDefinitionsプロジェクトに入ることに注意してください。

これが、SpriteRenderDefinitionのコンテンツを入力するxmlファイルです。

Sprite.xml

そのXMLの形式は、SpriteRenderDefinitionのメンバー名に直接マップされます。

そして最後に、実行時にそのXMLデータを実際のオブジェクトに実際にロードするコードは非常に簡単です。

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

その行を呼び出すと、SpriteRenderDefintionオブジェクトにXMLファイルのすべてのコンテンツが入力されます。これが私が書いたすべてのコードです。他のすべてはXNAに組み込まれています。あなたがそれを理解するのに1時間かそこらかかるならば、それは本当に非常に滑らかで便利です!

于 2012-10-20T01:55:13.413 に答える