オノデラの研究日記 in わんくま

思いついたネタを気ままに書いていくブログ

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  209  : 記事  5  : コメント  5961  : トラックバック  40

ニュース

プロフィール

  • ●おのでら
    宮城県在住
    主に業務向けソフトを製作

Twitter

ニュース

主なリンク

XNA 関連リンク

アイテム

ゲーマーカード

その他

記事カテゴリ

書庫

日記カテゴリ

クマー


 前回、GameComponent について説明しましたが、あれは更新用のみのクラスでした。実は同じように描画用のコンポーネントも作成することが可能です。それが「DrawableGameComponent」です。

 DrawableGameComponent は GameComponent クラスと IDrawable インターフェースを継承して描画メソッドをオーバーライドできるように追加されています。

 このクラスはテンプレートには用意されていないので自分で作成する必要があります。


● 今回のサンプル

 Character コンポーネントを作成してスプライトを描画しています。操作は出来ません。

Character コンポーネントで描画


● Character コンポーネントクラスを作成する

 LoadGraphicsContent メソッドと Draw メソッドをオーバーライドしているところ以外は今までとほとんど同じなので、ざっと眺めてください。

 後、コンストラクタには Game クラスではなく GameMain クラスを渡すようにしています。

  • Character.cs
#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
{
    /// <summary>
    /// キャラクタークラス
    /// </summary>
    public partial class Character : Microsoft.Xna.Framework.DrawableGameComponent
    {
        /// <summary>
        /// コンテンツ管理クラス
        /// </summary>
        GameMain game = null;

        /// <summary>
        /// スプライトバッチ
        /// </summary>
        SpriteBatch sprite = null;

        /// <summary>
        /// テクスチャー
        /// </summary>
        Texture2D texture = null;


        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="game">ゲームクラス</param>
        public Character(GameMain game)
            : base(game)
        {
            this.game = game;
        }


        /// <summary>
        /// 初期化処理
        /// </summary>
        public override void Initialize()
        {
            // TODO: ここに初期化処理を追加します

            base.Initialize();
        }

        /// <summary>
        /// グラフィクスコンテンツの読み込み処理を行う
        /// </summary>
        /// <param name="loadAllContent">全コンテンツ読み込みフラグ</param>
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                // TODO: 自動管理リソースの読み込みをここに書きます

                // スプライトバッチ作成
                this.sprite = new SpriteBatch(this.game.Graphics.GraphicsDevice);

                // スプライト用テクスチャーの読み込み
                this.texture = this.game.Content.Load<Texture2D>("Wankuma");
            }

            // TODO: 手動管理リソースの読み込みをここに書きます

            base.LoadGraphicsContent(loadAllContent);
        }


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

            base.Update(gameTime);
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれた時点でのゲーム時間</param>
        public override void Draw(GameTime gameTime)
        {
            // スプライトの描画は「Begin」「End」の間に記述する
            this.sprite.Begin();

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

            this.sprite.End();

            base.Draw(gameTime);
        }
    }
}

● GameMain クラス

 フィールドをコンポーネントで呼べるようにプロパティ化したのと、Game コンストラクタを以下のようにした点以外は手を付けていません。これもコンポーネントクラスを使用していることによって LoadGraphicsContent メソッドと Draw メソッドがコンポーネント側で自動で呼ばれるからです。

/// <summary>
/// グラフィクスデバイス管理クラス
/// </summary>
GraphicsDeviceManager graphics = null;
/// <summary>
/// グラフィクスデバイス管理クラス
/// </summary>
public GraphicsDeviceManager Graphics
{
    get { return this.graphics; }
}

/// <summary>
/// コンテンツ管理クラス
/// </summary>
ContentManager content = null;
/// <summary>
/// コンテンツ管理クラス
/// </summary>
public ContentManager Content
{
    get { return this.content; }
}


/// <summary>
/// コンストラクタ
/// </summary>
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」プロパティを使用して制御しなければいけないと思います。

 このように、描画が関わってくるといろいろ面倒なことが多くなってくるので、よく考えた上でクラス構築をしていく必要があると思います。


 サンプルプロジェクトです。

投稿日時 : 2007年2月12日 11:53

コメント

# re: XNA : DrawableGameComponent 2007/02/12 18:47 ひろき
ビデオチュートリアルなどがあればなあ なんてこのごろ思います。

# re: XNA : DrawableGameComponent 2007/02/12 19:08 オノデラ
さすがにそれはつらいっす。(ここの XNA Tips のことですよね?)

# re: XNA : DrawableGameComponent 2007/02/12 21:48 ひろき
やっぱり時間的に無理ですよね。
自分でためしにやったんですけどファイル量がでかくて
どうすればちいさくできるのか 

# re: XNA : DrawableGameComponent 2007/02/17 6:57 ひろき
ビデオチュートリアルの件なんですけど、DebugMODEのWINK 2.0というソフトを見つけました。ちまちま作っています。
自分も近いうちにホームページ開設するつもりです。
超初心者対象なんですけど

# re: XNA : DrawableGameComponent 2007/02/17 11:58 オノデラ
> ビデオチュートリアルの件なんですけど、DebugMODEのWINK 2.0というソフトを見つけました

 へぇ~、そういうソフトもあるんですか。私の場合ビデオチュートリアルのことはほとんど意識していないから、現在どういうソフトがあるのか分からないので結構参考になります。

> 自分も近いうちにホームページ開設するつもりです

 開設したらぜひご連絡くださいね(^^)

Post Feedback

タイトル
名前
Url:
コメント