Demo 3

Demo3 も、Demo1、Demo2 の続きになっている。新しい部分だけを説明していくので、分からないところが出てきたら前のページに戻って欲しい。

さて、Form の private を見ると解る通り、新しい変数が定義されている。px と KillDuration だ。Duration の意味が辞書に載ってなかったが、それは今回のプログラムを調べる意味で何の障害でも無い。プログラムのはじめの部分に OnInitialize イベントがあるが、これら二つの変数の初期化が加わっただけで、何の変化も無い。

procedure TForm1.DGCScreen1Flip(Sender: TObject);
        :
        :
        :
        :
     //Draw and update the players ship based on a collision test.
     //Image[0] = Invader, Image[1] = Players Ship. If the collision
     //test is True then draw the all white ship (Images[2]) otherwise
     //draw the normal ship (Images[1])
     if DGCScreen1.Images[0].CollisionTest(x, y, DGCScreen1.Images[1],
        px, 450, True) then
        Killduration := 10;

     if KillDuration > 0 then
     begin
        DGCScreen1.Back.Draw(px, 430, DGCScreen1.Images[2], True);
        Dec(KillDuration);
     end
     else
        DGCScreen1.Back.Draw(px, 430, DGCScreen1.Images[1], True);



     //Update the Ship position based on the arrow keys
     if (DGCScreen1.KeyDown(VK_LEFT)) and (px > 2) then
        Dec(px, 2)
     else
         if (DGCScreen1.KeyDown(VK_RIGHT)) and (px < 605) then
            Inc(px, 2);
end;
ここからが本題となる。まず新しいメソッドの CollisionTest だが、このメソッドは2つのイメージがそれぞれの位置に配置された場合、衝突しているかどうかを調べることが出来る。返り値は Boolean で、衝突していた場合 True となる。ところで、CollisionTest は DGCSurface のメソッドであるが、DGCScreen1 と CollisionTest の間に Images[0] が挟まっている。こんなことでいいのか? と思ったら、TDGCScreen の Images プロパティは、TDGCSurface クラスだった。

つまり、Direct Draw の初期化の際にこのイメージを TDGCSurface にコピーして使っているのである。この時コピーされるのは、プライマリサーフェイスでもバックバッファサーフェイスでもない。どこだろう? 通常このようなスプライトを置いておくのは、「オフスクリーンサーフェイス」または「オーバーレイサーフェイス」と呼ばれるサーフェイスである。このように専用の DGCImageLib Component を使うことによって、初期化時に自動でオフスクリーン用の TDGCSurface を作ることが出来るのである。(でも本当にそうなっているかどうかは知らない)

もう一つ、この命令の最後のパラメータに True が渡してあるが、これは衝突判定の方法を指定している。このパラメータが True だと、お互いの透過色の部分が重なっていても、衝突とは判定されない。したがって、厳密な意味での衝突判定が出来るのである。逆に False だった場合は、お互いのイメージ全体の領域が重なっていた場合に衝突と判定される。(この時は IntersectRect function が呼ばれると書いてある)

これで衝突判定は出来た。もし衝突していれば、ここで例の KillDuration に 10 を代入している。この変数は衝突からの時間を示しており、次の行からはその値によって自分の分身であるスターシップの表示を変化させている。もし KillDuration が0よりも大きいなら、つまり衝突から時間が経っていなければ Image[2] を描画して、KillDuration から1を引いている。そして、そうでなければ Image[1] を描画している。もう一つの新しい変数である px は、このスターシップの座標である。

このデモプログラムでは、前回主人公であったはずの「ハネカニモドキ(仮称)」は地球を侵略するエイリアンであり、新しいスターシップが主人公である。しかしこの主人公はハネカニモドキから逃げるしか手立てが無い。その逃げる手だてが次の行にある。

  //Update the Ship position based on the arrow keys
  if (DGCScreen1.KeyDown(VK_LEFT)) and (px > 2) then
     Dec(px, 2)
  else
      if (DGCScreen1.KeyDown(VK_RIGHT)) and (px < 605) then
         Inc(px, 2);
ここには新しいメソッドが登場している。KeyDown メソッド(イベントではない)は、与えられた仮想キーに対応するキーが、現在押されているかどうかを調べる。DGC には DGCJoystick というコンポーネントがあり、これを使えばコントローラーの状態を見ることが出来るが、キーボードは DGCScreen の KeyDown で調べることになる。

この部分もやっていることは簡単で、カーソルが押されていれば移動する、ただし範囲外へは行けない。移動量は1回の呼び出しに対して 2 pixels となっている。

今回のデモプログラムの説明はここまで。いよいよゲームらしくなってきたが、決定的に寂しい部分がある。どこって? それは次の Demo4 で明らかになる。

もどる