フレームワークの一連の流れ
gameクラスを継承しインスタンス化する → メイン関数内でgame.run()する → initialize() → LoadContent() → BeginRun()
以上が行われるとゲームループに入る、このループは規定値の場合1秒間に60回繰り返され Exit()関数でゲームを終了させるまで永遠に回る → Update() → Draw() →
ゲームの終了時は → EndRun() → UnloadContent() が処理される
<要点>
- gameクラスを継承しインスタンス化する事によりXNAのさまざまなサービスが利用できる。たとえば継承したクラス内でgameクラスのメンバーをオーバライドしたりプロパティから利用したい機能(WindowやGraphicsDeviceプロパティ等)を使うことができる。参考資料:Game Members
- Update() 及び Draw() メソッド内で寿命の短いインスタンスを生成するとガベージコレクションが頻繁に発生しパフォーマンスに悪影響を与えるので注意
- ゲーム画面を描画するにはグラフィックデバイスの初期化が必要。制御には GraphicsDeviceManager を使う。これらの作成や変更操作はフレームワークの設計上、gameクラスを継承したクラスのコンストラクタ内が適切。initialize()メソッド内等では変更が反映されないなどの不具合が見られるので注意
- XNAでフルスクリーン画面にした場合、ウインドウズフォームのボタンなどの各コントロールは非表示になる(機能は残っているっぽい)
- ゲームのループ内で処理落ちが発生した場合、Update()関数が優先されDraw()関数は省略される。つまりデータの更新が優先される。その際、GameTimeオブジェクトのIsRinnningSlowlyプロパティがtrueになるので、これを調べる事でゲームループが遅れているかどうか知る事ができます
using System;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
namespace MyNamespace
{
class TestXNA :Game
{
private GraphicsDeviceManager manager;
public TestXNA()
{
manager = new GraphicsDeviceManager(this);
}
protected override void Initialize()
{
IsMouseVisible = true;
Window.Title = "TestXNA";
Form form = (Form)Control.FromHandle(Window.Handle);
Button button = new Button();
button.Text = "Test";
form.Controls.Add(button);
base.Initialize();
}
}
class MyClass
{
static void Main()
{
using (TestXNA game = new TestXNA ())
{
game.Run();
}
}
}
}
- オーバーライドした関数は必ずベースオブジェクトの関数も呼び出す事。そうしないとフレームワークの誤動作を招く可能性がある
protected override void Initialize()
{
//自分が必要な関数をここに書く
base.Initialize(); //ベースオブジェクトの呼び出し
}
フレームワーク各工程の一般的な処理
- gameクラスで必要と思われるメンバー
- GraphicsDeviceManagerのインスタンス
- gameクラスを継承したクラスのコンストラクタ内
- initialize()
- ウインドウ関連の初期化
- ウインドウズフォームが必要であればフォームの初期化
フレームワークの各メンバー関数の特徴
protected virtual void Update(GameTime gameTime)
protected virtual void Draw(GameTime gameTime)
このふたつの関数のパラメータの gameTime はフレームワークが自動で更新し代入しています
利用者は関数内でGameTimeクラスのプロパティにアクセスすることでゲーム内時間を知ることができる
固定フレームレートの解除(処理速度内で最大限ループ処理を行うには)
以下の様にふたつのプロパティを false する。タイミングはゲームのコンストラクタ内
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.SynchronizeWithVerticalRetrace = false;
IsFixedTimeStep = false;
}
GraphicsDevice自体はGameのコンストラクタとintialize()メソッドの処理の間で生成されている
つまりGraphicsDeviceManagerに対しての操作はGameのコンストラクタで
GraphicsDeviceに対しての操作はinitialize()メソッド以降で行う必要がある
最終更新:2012年06月26日 18:14