トップ 差分 一覧 Farm ソース 検索 ヘルプ PDF RSS ログイン

チュートリアル 5: スプライトと背景

これまでで、あなたが作れるのはテキストのゲームだけです。
もっといいゲームを作るには、スプライトと背景について知る必要があります。
(テキストでアドベンチャーか何かを作らない限りね。)

スプライトとは、画面上を動き回るアニメーション画像です。
背景はその名の通り画面を占めて動かない画像のことです。

ビットマップ(BMP)をそのまま画面に表示させることはできません。
RAWイメージファイル(.RAW),パレットファイル(.PAL),そして背景ならマップファイル(.MAP)も必要です。
これらのファイルを作成するには、DSLuaの「「bin」フォルダにある、TRiNiTY作の「gfx2gba.exe」というソフトが必要です。
まずコマンドプロンプトを開きます。スタートメニューを開き、「ファイル名を指定して実行」に「cmd」と入力すれば起動します。

カレントディレクトリがDSLuaのあるメモリーカードのドライブと違う場合は(おそらく、"C:\Documents and Settings\ユーザー名"とかでしょう)、ドライブレターを入力しましょう。(D:とか。)そしてエンターを押します。
そしてcdコマンドを使用して、DSLua/binフォルダへ行きます。
cdと入力した後にスペースを空け、binフォルダへのパスを入力します。
例えば、私のコンピューターではこのように表示されています。

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\The Rutens>[d:]

D:\>cd [d:\jeremy\DSLUA\bin]

D:\jeremy\DSLUA\bin>[_ ]

PCが表示した内容はそのままで、私が入力した内容は[カッコ]で記載しています。
カーソル(_)も[カッコ]で記載していますが、これは入力しなくていいよ :P

そして、スプライトの画像が「sprite.bmp」で、背景が「background.bmp」だとすると、
binフォルダに入った後に入力するコマンドラインは以下の通りです。

D:\jeremy\DSLUA\bin>[gfx2gba -pSPRITE.PAL -t8 sprite.bmp]

D:\jeremy\DSLUA\bin>[gfx2gba -m -pBACKGROUND.PAL -t8 background.bmp]

これらのBMPを作成する良い方法があります。
256色のBMPで、サイズは縦横が16, 32, 64ピクセルのどれかでなければなりません。
どの組み合わせでも良いです。例えば、16x64, 64x64, 32x16, など。

Windows付属のペイントを使って説明します。(もっといい画像ソフトもあるでしょうが。)
まず、新しいファイルを新規作成し、上で書いたサイズを指定します。
スプライトを描き終えたら、「名前を付けて保存」を選択します。ファイル名の下に、ファイル形式を指定するドロップダウンがあります。
そこで「265色ビットマップ」を選択します。これでgfx2gbaで変換する準備ができました。
注意:ペイントを使用した場合、透過色は黒になります。

背景も同じ方法で作成できます。
サイズを256x192(DSの画面と同じ)かそれ以上(DSLuaでは簡単に背景をスクロールできます)にします。
そして、同様に256色で保存すればOKです。

もう一つスプライトの作り方があります。そしてこれはスプラッシュにアニメーションを追加したいときに必要です。
これはフレームストリップと呼ばれます。
全てのアニメーションのスプラッシュは一つのBMPファイルでまかなわれます。
全てのコマが正しいスプライトのサイズでないといけません。(16x64, 64x64, 32x16,など)
例を表示するのが一番のようですね。以下はマリオが走っている3枚のフレームスプライトです。:

ファイルが存在しません。

規格に沿ったBMPファイルなので、そのままダウンロードしてかまいません。
この長いチュートリアルの中で後々使用します。

さて、これでスプライト,背景,アニメーション付スプライトの作り方がわかりましたが、次は画面に表示します。
画面に表示するに前に、ファイルを読み込まなくてはなりません。これには数行かかります。
残りのチュートリアルを「スプライト」と「背景」に分けたいと思います。

スプライト

上のマリオが走るフレームストリップをまだダウンロードしていないのなら、先にしておいてください。
上で言ったように、このファイルはちゃんと 256色BMPです。
そして、はじめのステップで説明したように、このファイルを.raw/.palファイルに変換します。
そして新しい.luaファイルを作成し、「mariorunning.lua」みたいに名前を付けてください。
このセクションの終わりには、マリオが画面を横切るプログラムを作成します。

はじめにパレットファイルであるmario.pal(またはあなたが名前を付けたファイル名で)が必要です。
これを行うコードは以下の通りです。

SCREEN_TOP = 1
PALETTE_MARIO = 0 -- これがパレット番号です。 0は読み込むパレットの番号です。
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
-- これで「mario.pal」を読み込みました。「PALETTE_MARIO」変数を用いて表示させることができます。

さて、これでパレットの読み込みは完了です。1行で全ての作業を行うこともできますが、この方法の方が読みやすいです。
しかもどの番号がどのパレットなのかをいちいちチェックする必要もありません。
(Sprite.LoadPalette( 1, 0, "mario.pal" )のように読み込むことができます)

これで「mario.raw」を読み込む準備はできました。2つの異なる機能を用いて行います。

FrameStrip.Create()はDSLuaにどの画面に表示するか、各フレームのサイズ、どれだけの色数があるか(いつも256ですが)を伝えます。

SpriteName:LoadBin()はどの .rawファイルをSpriteNameに読み込むか、そして.rawファイルにはいくつのフレームがにあるかをDSLuaにに伝えます。

SCREEN_TOP = 1
PALETTE_MARIO = 0
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
MarioFrames = FrameStrip.Create( SCREEN_TOP, 32, 32, "256" )
MarioFrames:LoadBin( "mario.raw", 3 ) 

「32, 32」は全てのフレームが32x32であることを示し、「256」は256色のBMPであることを示します。
LoadBin()内の「3」は3フレームあることを意味します。
これで画面にスプライトを表示する準備が整いました。Sprite.Create()を使うだけです。

SCREEN_TOP = 1
PALETTE_MARIO = 0
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
MarioFrames = FrameStrip.Create( SCREEN_TOP, 32, 32, "256" )
MarioFrames:LoadBin( "mario.raw", 3 )

Mario = Sprite.Create( MarioFrames, 0, PALETTE_MARIO, 112, 80 )
DSLua.WaitForAnyKey() 

このコードは正常に動きます。マリオが画面の真ん中に表示されます。が、動きません。
まず、一つ目に Sprite.Create()の説明をします。
まずフレームを読み込んだ変数、つまり「MarioFrames」です。
この文字の後の「0」は、このスプライトには0個のフレームがあるということを意味します。
フレームストリップのはじめのフレームが0フレーム目です。
2コマ目が「1」です。3コマ目が「2」です。
「PALETTE_MARIO」はスプライトに使用しているパレットです。
最後の2つの番号である「112, 80」がDSLuaにどこにスプライトを描写するかを伝えます。
「112, 80」なら画面の真ん中あたりになるはずです。

次に、マリオに画面上を走ってもらいます。
これにはSpriteName:MoveTo( x, y )を使用します。
今回のスプライト名は「Mario」なので、Mario:MoveTo( x, y )と記述します。
このコードでマリオは画面の端まで走ります。

SCREEN_TOP = 1
PALETTE_MARIO = 0
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
MarioFrames = FrameStrip.Create( SCREEN_TOP, 32, 32, "256" )
MarioFrames:LoadBin( "mario.raw", 3 )

x = 0
Mario = Sprite.Create( MarioFrames, 0, PALETTE_MARIO, x, 80 )

while x < 256 do
     x = x + 1
     Mario:MoveTo( x, 80 )
     for delay=1,500 do
     end
end 

あなたはこれを理解できるでしょう。あとはループの説明です。
これは私が「ディレイループ」と呼んでいるものです。
これがないと、マリオはほぼ一瞬で画面を横切ってしまいます。

そこで、マリオが1ピクセル動くたびに、DSを500カウントさせて遅らせています。
コンピューターやDSの速度によってこの値を変更する必要があるかもしれません。
(私はこのプログラムをDS上でテストするための装置を持っていないのでテストできません。)
アニメーション付きにする前に、マリオが画面の端まで行ったら左端へ戻るようにコードを少し変更する必要があるでしょう。

SCREEN_TOP = 1
PALETTE_MARIO = 0
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
MarioFrames = FrameStrip.Create( SCREEN_TOP, 32, 32, "256" )
MarioFrames:LoadBin( "mario.raw", 3 )

x = -16
Mario = Sprite.Create( MarioFrames, 0, PALETTE_MARIO, x, 80 )

while Stylus.Down() == false do -- Touch the touch screen to quit
     x = x + 1
     if x < 256 then
          Mario:MoveTo( x, 80 )
     else
          x = -16
     end
     for delay=1,500 do
     end
end 

さて、次のセクションで取り掛かる背景を除けば、後すべきことはアニメーション化するだけです。
今の段階だと、マリオはただ右にスライドしているだけでしょう?動きをつける必要があります。
マリオに走ってもらいましょう。そのためにはMario:SetFrame() が必要です。
Mario:SetFrames( MarioFrames, framenumber )のように使用します。
framenumberはスプライトを変更するフレームストリップのフレームをあらわします。
1つ目のフレームが「0」です。2つ目が「1」です。覚えておいてください。
このプログラムでは、forループを使用するのが良いでしょう。
0から2までをカウントし続け、そのたびにそのframenumberを使用します。以下がコードです。

SCREEN_TOP = 1
PALETTE_MARIO = 0
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
MarioFrames = FrameStrip.Create( SCREEN_TOP, 32, 32, "256" )
MarioFrames:LoadBin( "mario.raw", 3 )

x = -16
Mario = Sprite.Create( MarioFrames, 0, PALETTE_MARIO, x, 80 )

while Stylus.Down() == false do -- Touch the touch screen to quit
     for framenumber = 0, 2 do
          x = x + 1
          if x < 256 then
               Mario:MoveTo( x, 80 )
          else
               x = -16
          end
          for delay=1,500 do
          end
          Mario:SetFrame( MarioFrames, framenumber )
     end
end

Mario:SetFrame( MarioFrames, 0 )
Mario:Free() 

プルグラムの最後に、Marioスプライトを開放(Free)しました。
音楽やサウンドエフェクトのチュートリアルで説明しましたよね?

Free()はメモリからスプライトを開放し、他のスプライトやプログラム,音楽などに明け渡します。
しかし、下から2行目が何かのかと思いませんか?
Mario:Free()の上で、フレームを0にセットしました。

これはdaltonlaffs氏が教えてくれたglitchを回避するためです。
フレームをはじめのフレーム、つまり0にセットしないとスプライトをFree()できないのは明らかです。
whileループはforループが終わったときにだけスタイラスがタッチされているかどうかをチェックするので、このプログラム例を終了するときはいつもフレームは0です。
glitchについてを知ってもらうために、この2行を追加しました。

背景

これはスプライトより簡単です。なぜなら、
(1)背景とスプライトは共通点が多く、あなたは既にスプライトのことを理解しているから。
(2)背景は動かないから。

ただ、背景のスクロールはできます。
上で使用したマリオが走る例を利用します。だから今まで例で使用していたプログラムを削除しないでくださいね。
さて、以下は背景を読み込んで画面に表示するコードです。

SCREEN_TOP = 1
BGTopMap = Screen.LoadTileBG()
BGTopMap:LoadPalette( "map.pal" )
BGTopMap:LoadTiles( "map.raw", 256 ) -- 256 colours
BGTopMap:LoadMap( "map.map", (1024 / 8 ), ( 192 / 8 ) ) -- 1024はマップの横幅です。192は高さです。マップは8つのタイルに分けられるので、この例でも8ずつに分けています。
Screen.Initialize( SCREEN_TOP, BGTopMap ) 

マップのスクロールは簡単です。ScrollXY( x, y )を使用するだけです。
x,yで指定した位置にスクロールされます。

下に記載している最後のコードは、1024ピクセルのマップを使用しています。
(マップの大きさはメモリが許す限り大きくできますが、サイズは8の倍数にしてください)
ここからマップをダウンロードできます。

ファイルが存在しません。

このチュートリアルのはじめに説明した方法で、マップを.raw/.pal/.mapに変換してください。
また、背景が動いている間はマリオは動かないことも注意してください。

SCREEN_TOP = 1
PALETTE_MARIO = 0
Sprite.LoadPalette( SCREEN_TOP, PALETTE_MARIO, "mario.pal" )
MarioFrames = FrameStrip.Create( SCREEN_TOP, 32, 32, "256" )
MarioFrames:LoadBin( "mario.raw", 3 )

Mario = Sprite.Create( MarioFrames, 0, PALETTE_MARIO, 5, 80 )

BGTopMap = Screen.LoadTileBG()
BGTopMap:LoadPalette( "map.pal" )
BGTopMap:LoadTiles( "map.raw", 256 )
BGTopMap:LoadMap( "map.map", (1024 / 8 ), ( 192 / 8 ) )
Screen.Initialize( SCREEN_TOP, BGTopMap )

x = 0

while x < 1024 do
     for framenumber = 0, 2 do
          for delay=1,500 do
          end
          x = x + 1
          BGTopMap:ScrollXY( x, 0 )
          Mario:SetFrame( MarioFrames, framenumber )
     end
end

Mario:SetFrame( MarioFrames, 0 )
Mario:Free() 

注:スプライトのフレームストリップは18個まで可能です。