緊急企画DirectXを使おうの巻・その2


 前回HSPによるDirectXの使い方をザッと紹介しましたが、大事な部分をまだ説明していませんでした。そう、スプライトの使い方です。DirectXを使って実際にプログラムを組んだことがないと「画像をコピーするだけなのに何でそんな機能があるの?」とか「使い分けがわからない」などと思うことでしょう。ちなみに筆者もスプライトの使い方まで覚えるのが面倒で「コピー命令(es_copy)で代用すればいいや」と思ったことがありますが、実はes_copy命令ではゲームを作る際に不便な点があるのです。
 それは何かというと、「クリッピングの関係でコピーする画像が画面外にはみ出す場合表示されずに消滅する」んですね(HSPDXFIXでは直っています)。意味が分からない人は、HSPに付属のサンプル「test1.as」を下の表を参考にいじって確認してください。ちなみにクリッピングというのはグラフィックの描画が画面外に及ぶときに、その部分を描画しないことを言います。

行数 元のスクリプト 変更内容
53 es_set 0,myx,myy,0 gmode 1,64,64
64 es_pos 0,myx,myy pos myx,myy
68 (空行) es_copy 0,64,64

 変更したら、そのままキャラクタを左右か上の端へと移動させてください。・・・消えたでしょ? これではゲームを作るには致命的なものがありますので、スプライトを使う必要があるわけですね。

●スプライトを使おう
 というわけで、スプライトの使い方です。

  1. スプライトの初期化
     DirectXの初期化を行うときに、同時にスプライトの初期化を行うことになります。「es_ini p1,p2」がそうです。p1が画面に表示するスプライトの最大数、p2が登録するキャラクタの最大数です。これらを省略するとそれぞれ512と1024が入ります。これらのパラメータは小さな数値にしても処理速度はあまり変わりませんし、数値によってはプログラム終了時に「不正な処理」ダイアログが表示されてしまいますので、とりあえずは省略しておくといいでしょう。
     なお、このパラメータに上限はありません。つまり、メモリの許す限りスプライトやキャラクタを用意できるというわけです。
  2. キャラクタ設定
     スプライトを使うには、前もって使用する画像をキャラクタとして指定する必要があります。まず、キャラクタのサイズなどの情報を「es_size p1,p2,p3,p4」で設定してやります。p1,p2がキャラクタのサイズで、p3はあたり判定の大きさ、そしてp4が不透明フラグです。
     キャラクタサイズは、オフスクリーンバッファのサイズ以内であればどれだけでも指定できます。
     p4は、スプライトをBG(背景)の代わりに使わない限り0(rgb=0の色を透かす)でいいでしょう。
  3. 画像を読み込む
     複数のバッファに画像を読み込むときは、キャラクタの登録を済ませてから次の画像を読み込まないとキャラクタが間違って登録されてしまいますので気をつけましょう。なお、2と3は逆でもかまいません。
  4. キャラクタ登録
     設定をして画像を読み込んだら、続いて「es_pat p1,p2,p3,p4」でキャラクタを登録しましょう。p1がキャラクタ番号、p2,p3がサイズ、p4がアニメーションを行うときの表示フレーム数です。アニメーションについては後で説明しますのでとりあえず省略してください。
  5. スプライト登録
     これでようやくスプライト登録の準備ができたにすぎないわけで、まだこれからスプライトを表示するために登録を行わなければなりません。スプライトを登録する命令は「es_set p1,p2,p3,p4」です。p1はスプライト番号、p2,p3が初期の表示座標、p4がキャラクタ番号です。
  6. 表示領域の設定
     「es_window p1,p2,p3,p4」でスプライトの表示範囲を任意の大きさにすることができます。p1,p2が左上の座標、p3,p4が大きさを表します。これは別に設定しなくてもよいのですが、縦画面シューティングのように画面の横などを狭くしたい場合に使います。これによって処理速度が上がることはありません。
     「es_area p1,p2,p3,p4」でスプライトが存在できる範囲を指定できます。es_windowとの違いは、es_areaで指定された範囲を超えたスプライトは消滅するということです。消滅したスプライトを登場させるには再度設定してやる必要があります。ちなみにデフォルトではes_windowの範囲の127ドットまで外に出てもよいことになっています。
  7. 移動したら座標を変える
     これまででスプライトの設定は終わりましたので、ここからはプログラムのメインルーチン内のお話になります。
    キー入力などでキャラを動かしたのであれば、当然それを反映させなければ意味がありません。で、反映させる命令が「es_pos p1,p2,p3」です。pos命令にスプライト番号がついただけです。p1がスプライト番号で、p2,p3が座標となっています。
  8. 表示
     スプライトは登録さえされていれば「es_draw」ですべてまとめて表示してくれます。スプライト番号の小さいスプライトほど手前に表示されるようになっています。また、この命令の後でes_copyなどの描画命令を行うことでスプライトより手前に表示させることができますので、もしもスプライトが表示されないときはes_drawのあとに大きな画像をコピーしているか、es_clsをやっちゃっているかのどちらかでしょう。

 以上が簡単な使い方です。

●もっと使いたい!
 えー正直な話これだけだったらes_copy命令のクリッピングを改善すればそっちの方が簡単なので意味ありません。HSPには1フレームごとにスプライトを直線移動させる処理というものがありまして、シューティングゲームの敵弾のような単純なアルゴリズムの処理であればその命令を1回実行するだけで後はなにもしなくても勝手に動き、画面から消えたら勝手に消滅してくれます。これをうまく使えばスクリプトは小さくなりますし、よけいな処理を行わないぶん処理速度の向上にも一役買うことになります。現在は直線移動に限定されていますが、将来(ver 2.5?)は移動経路を設定することの可能になるとのことです。

 この3つは結構重要です。覚えておきましょう。

 ワラワラと敵を出現させたり、大量の弾幕を発生させたりといった処理をゲームでは要求させられます。そして、それらに使われるスプライトがいくつ必要なのかとか、何番のスプライトをあけておく必要があるかなどというのはプログラマの知るところではありません。必要になったときに未使用のスプライトに割り当てるのがもっとも普通なやり方だと思います。そんなわけで新しい敵や弾を発生させるたびに未使用のスプライトを検索してやる必要が出るわけですが、だからといってrepeat-loop命令などを駆使していちいち検索していたのでは、HSPの速度では厳しいものがあります。以上、ネタふり。
 そこで登場するのが、「es_new p1,p2」です。ふつうは「es_new a,0」とでもやっておいてes_setでa番のスプライトをセットします。p2が検索開始時のスプライト番号なので、たとえば「敵の弾は敵などよりも奥に表示したい」というときにはp2に大きな値(100とか)を入れておきます。

●アニメーションさせてみる
 キャラクタを設定するときに4番目のパラメータに0以上の数値を入れると、そのパラメータのフレーム数だけ表示して次のキャラクタへと表示が移ることになります。これでアニメーションを自動的に行わせることができるわけです。

 まず、当然のことながら必要な分だけアニメーションのパターンを用意しておきましょう。そしたら、次にそれらをキャラクタ登録するのですが、このとき連番で登録しないとアニメーションできません。たとえば、4コマのアニメーションを10,11,12,13番に登録するのはよいですが、10,12,17,21番のような登録の仕方ではアニメーションになりません(というか、バグッたようにみえる)。前にも書いたとおり、es_patの第4パラメータで表示させるフレーム数を指定します。
 以下に、10番から13番までの4コマのアニメーションを行うプログラム例を示しますが、アニメーションの方法によって2通りの組み方になります。

アニメーションを繰り返す アニメーションを繰り返さない
es_pat 10,0,0,1
es_pat 11,32,0,1
es_pat 12,0,32,1
es_pat 13,32,32,1
es_link 13,10
es_pat 10,0,0,1
es_pat 11,32,0,1
es_pat 12,0,32,1
es_pat 13,32,32,0

 ポイントは4コマ目のキャラクタを設定するところから後です。アニメーションを繰り返す場合は4コマ目にもフレーム数を指定し、最後に「es_link」という命令でアニメーションをつなぐことで繰り返しアニメーションを繰り返すことができるようになります。アニメーションを繰り返さない場合は最後のコマについてはフレーム数を0にすればアニメーションはそこでストップします。
 勘のいい人は気づいたかもしれませんが、キャラクタ番号が不連続でもes_linkを使えばアニメーションを行うことができます。ただし、プログラムに無駄ができるのであまりおすすめできません。

 以上でスプライトをある程度使うことができますが、実はまだやり残しがあります。そこで、次回は当たり判定についてや、実際の使用例をいろいろ載せたいと思います。いつになったら終わるやら。


戻る