XNA メモ – スクロールする(流れる)背景の作り方

Posted: 2012年1月28日 カテゴリー: プログラミングメモ, XNA, XNAメモ
タグ:, , , , , , ,

今回は、2DのSTGなどによくある流れる背景の作り方をメモります。

実装方法は基本的に:

–       背景を毎フレーム移動

–       もし、背景の位置がテクスチャアの高さを超えたら一番上までもどす

–       描画時には、一回現在地で描画し、その後描画した背景の上にもう一回描画する

を繰り返すことです。背景を2回描画することによって背景が途切れないように見えます(2回目の描画は一回目の真上に描画されるため、一つの大きな画像に見えます)。

実装するにはまず、クラスと必要な変数を宣言します

class ScrollingBackground
{
Texture2D m_texture; // 背景
Vector2 m_position;  // 背景の位置
Vector2 m_textureOrigin; // テクスチャアの原点
float m_scrollSpeed; // 背景を流す速度
int m_screenHeight; // 画面の高さ

次に、コンストラクタを実装します。テクスチャアの原点はわざと真ん中の天辺になるようにずらしてますが、これは楽だったからこう実装しただけなので、他の部分の変更も忘れなければ、自由に変更してください。スタート時の位置も同じです。

public ScrollingBackground(Texture2D texture, int screenHeight, float scrollSpeed)
{
m_scrollSpeed = scrollSpeed;
m_screenHeight = screenHeight;
m_texture = texture;

// 原点を、画像天辺の真ん中にする
m_textureOrigin = new Vector2(texture.Width / 2, 0);

// スタート地点
m_position = new Vector2(m_textureOrigin.X, screenHeight / 2);
}

次に、更新処理を実装します。これはシンプルに上で書いたように背景を移動し、ある位置を越えたら上に戻すだけです。

public void Update(float delta)
{
// 背景の移動
m_position.Y += m_scrollSpeed * delta;

// もし背景が画面から外れたら、上に移動
if (m_position.Y >= m_texture.Height)
{
m_position.Y = 0.0f;
}
}

ちなみに、このif文は`%`オペレーターを使うことで実装することも出来ます:

public void Update(float delta)
{
// 背景の移動
m_position.Y += m_scrollSpeed * delta;

// もし背景が画面から外れたら、上に移動
m_position.Y = m_position.Y % m_texture.Height;
}

後は、描画処理です。上で書いたように必要がある場合は、2回描画します。

public void Draw(SpriteBatch sp)
{
if (m_position.Y < m_screenHeight)
{
// まだ画面内にある場合、描画する
sp.Draw(m_texture, m_position, null, Color.White, 0.0f, m_textureOrigin, 1.0f, SpriteEffects.None, 0.0f);
}

// 先に描画した背景の上にもう1回描画する
sp.Draw(m_texture, m_position - new Vector2(0, m_texture.Height), null, Color.White, 0.0f, m_textureOrigin, 1.0f, SpriteEffects.None, 0.0f);
}

これで後はGame1クラス(もしくは別の背景を使うクラス)内でインスタンスを作り、Update()とDraw()を呼ぶだけです。

ScrollingBackground background;

protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

Texture2D texture = Content.Load<Texture2D>("back");
background = new ScrollingBackground(texture, graphics.PreferredBackBufferHeight, 64.0f);
}

protected override void Update(GameTime gameTime)
{
background.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
background.Draw(spriteBatch);
spriteBatch.End();

base.Draw(gameTime);
}

以上です。実装後はこんな感じになります(つまらない動画ですが):

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中