前回、GameComponent について説明しましたが、あれは更新用のみのクラスでした。実は同じように描画用のコンポーネントも作成することが可能です。それが「DrawableGameComponent」です。
DrawableGameComponent は GameComponent クラスと IDrawable インターフェースを継承して描画メソッドをオーバーライドできるように追加されています。
このクラスはテンプレートには用意されていないので自分で作成する必要があります。
● 今回のサンプル
Character コンポーネントを作成してスプライトを描画しています。操作は出来ません。
● Character コンポーネントクラスを作成する
LoadGraphicsContent メソッドと Draw メソッドをオーバーライドしているところ以外は今までとほとんど同じなので、ざっと眺めてください。
後、コンストラクタには Game クラスではなく GameMain クラスを渡すようにしています。
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace UseDrawableGameComponent
{
public partial class Character : Microsoft.Xna.Framework.DrawableGameComponent
{
GameMain game = null;
SpriteBatch sprite = null;
Texture2D texture = null;
public Character(GameMain game)
: base(game)
{
this.game = game;
}
public override void Initialize()
{
base.Initialize();
}
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
this.sprite = new SpriteBatch(this.game.Graphics.GraphicsDevice);
this.texture = this.game.Content.Load<Texture2D>("Wankuma");
}
base.LoadGraphicsContent(loadAllContent);
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
this.sprite.Begin();
this.sprite.Draw(this.texture, new Vector2(200.0f, 200.0f), null, Color.White,
0.0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0.0f);
this.sprite.End();
base.Draw(gameTime);
}
}
}
● GameMain クラス
フィールドをコンポーネントで呼べるようにプロパティ化したのと、Game コンストラクタを以下のようにした点以外は手を付けていません。これもコンポーネントクラスを使用していることによって LoadGraphicsContent メソッドと Draw メソッドがコンポーネント側で自動で呼ばれるからです。
GraphicsDeviceManager graphics = null;
public GraphicsDeviceManager Graphics
{
get { return this.graphics; }
}
ContentManager content = null;
public ContentManager Content
{
get { return this.content; }
}
public GameMain()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
this.Window.Title = "DrawableGameComponent";
this.IsMouseVisible = true;
this.Components.Add(new Character(this));
}
一応ざっとコードを書いてきましたが、コンポーネントとしてはあまり好ましい書き方ではないと思います。なぜならコンポーネントが GameMain クラスに依存してしまっているからです。
それよりもなによりも、Direct3D では描画順というものが大きく関わっているので、今回のように1体だけを描画するのであれば問題ないのですが、複数になった場合、スプライトをまとめるクラスなどを作って SpriteBatch を効率よく使えるように工夫しなくてはいけません。
特に3Dオブジェクトなんかになると「透明」「不透明」によっても描画順が変わるので、「DrawOrder」プロパティを使用して制御しなければいけないと思います。
このように、描画が関わってくるといろいろ面倒なことが多くなってくるので、よく考えた上でクラス構築をしていく必要があると思います。
サンプルプロジェクトです。