GameComponent

ページ更新日 :
ページ作成日 :

Gamecomponent とは

上記のリンク先にも書いてあるとおり、コンポーネントとは「プログラムの部品」と言われています。本体のアプリケーションは様々な部品(コンポーネント)を組み合わせて作られることが非常に多いです。車で言うと、車全体がアプリケーションで、タイヤ、いす、ハンドルなどの部品がコンポーネントだと置き換えることも出来ると思います。

プログラムで言えば、DirecrX SDK なんかも一種のコンポーネントです。それ単体では何も出来ませんが、アプリケーション側から使用することによってゲームなどのマルチメディアアプリケーションが出来上がるのです。

で、今回は GameComponent についての説明になるのですが、そのまんまゲーム用のコンポーネントになります。この GameComponent をあらかじめ作っておくことによって、様々な XNA アプリケーションで汎用的に使用することもできるようになります。

XNA ではこのGameComponent を有用に使用できるような仕組みが出来ているので、今回はそれを試してみたいと思います。


今回のサンプル

時間に応じて回転量を増やすコンポーネントを作成し、それを使用してスプライトが自動で回転するようになっています。

自動でスプライトが回転


GameComponent を作成する

XNA では GameComponent を作成するテンプレートクラスがすでに用意されています。下の手順で作成することが可能です。

プロジェクトから新しい項目を選択します

新しい項目追加

「Game Component」というテンプレートがあるので、それを選択します。ファイル名(クラス名)は「AutoRotator.cs」とします。

Game Component

すると、プロジェクトにファイルが追加されます。

プログラム追加


GameComponent のメソッド

ファイルを作成したら、コードの中身を見てみましょう。

public partial class AutoRotator : Microsoft.Xna.Framework.GameComponent

作成したクラスは「Microsoft.Xna.Framework.GameComponent」クラスを継承しています。XNA ではこのクラスを継承してコンポーネントを作成するといろいろ便利なところがあります。

作成したクラス内には、コンストラクタと「Initialize」「Update」メソッドをオーバーライドしているメソッドがあることが分かります。

コンストラクタでは Game クラスを引数として渡せるような形になっています。コンポーネントが Game クラスのデータにアクセスしたい場合に使用できます。Game クラスは他の XNA アプリケーションでも共通で使えるクラスなので何かと便利です。

Initialize クラスは主にグラフィックデバイスを作成した後、データを初期化したいときに使用します。

Update クラスは何らかの更新処理を行うときに使用します。

主にこの3つのメソッドがありますが、コンポーネントなのでフィールドやメソッドを自由に追加してかまいません。このコンポーネントがしっかりと設定できれば、のちのち作業の効率化に結びつけることが可能です。


AutoRotator クラスを実装する

/// <summary>
/// 回転量(radian)
/// </summary>
float rotate = 0.0f;
/// <summary>
/// 回転量(radian)
/// </summary>
public float Rotate
{
    get { return this.rotate; }
}

/// <summary>
/// 更新処理
/// </summary>
/// <param name="gameTime">このメソッドが呼ばれた時点でのゲーム時間</param>
public override void Update(GameTime gameTime)
{
    // TODO: ここに更新処理を記述します

    this.rotate += (float)gameTime.ElapsedGameTime.TotalSeconds;

    base.Update(gameTime);
}

今回は単純に「時間によって回転量を増加させる」という簡単なコンポーネントを作成することにします。上記がコードに手を加えた部分です。

フィールドには回転量を保持するために「rotate」を宣言しています。更新された回転量を取得するために「Rotate」プロパティも用意しています。

更新処理では回転量を増加させています。「GameTime.ElapsedGameTime.TotalSeconds」プロパティには前回更新された時間から、今回の処理を行うまでの時間を「秒」で取得することが出来ます。この値で増加させることによって、どのパソコン上(Xbox360 含み)で実行しても、1秒で1ラジアン回転させることが可能になります。オンラインゲームなどではこのような形での計算が好ましいと思います。


メインクラス

自動回転コンポーネントがこれで終わりです。ではメインクラスの実装を見てみましょう。いままで使用していたスプライト描画処理を再利用します。


フィールド

/// <summary>
/// 自動回転クラス
/// </summary>
AutoRotator rotator = null;

作成した「AutoRotator」コンポーネントをフィールドとして用意しておきます。


コンストラクタ

// 自動回転クラス作成
this.rotator = new AutoRotator(this);

// ゲームクラスのコンポーネントに追加
this.Components.Add(this.rotator);

自動回転クラスを作成しています。今回は使っていませんが、Game クラスを引数に渡しておきましょう。

続いて Game クラスの Components に作成したコンポーネントを追加しています。実はこれが重要で、それは後に分かると思います。


スプライト描画

// スプライトの描画
this.sprite.Draw(this.texture, new Vector2(200.0f200.0f), null, Color.White,
    this.rotator.Rotate, this.origin, Vector2.One, SpriteEffects.None, 0.0f);

基本的に今までと変わりませんが、スプライトの回転量に、作成したコンポーネントの「Rotate」を渡しています。


コードを書いたら実行してみましょう。スプライトがきちんと回転していることが分かると思います。

ここで「あれ?」と思った方もいるかと思います。回転クラスの更新メソッド「Update」を一度も読んでいないのに、きちんと回転量が更新されているのです。

実は Game.Components に作成したコンポーネントを追加したのが理由で、Game コンストラクタでコンポーネントを追加すると、「Initialize」「Update」の各メソッドが自動で呼ばれる仕組みになっています。そのため、わざわざ更新メソッドや初期化メソッドを記述しなくでもいいので、コードがすっきりするようになるのです。これが GameComponent が便利な点でもあります。