見出し画像

FALさんの「Processingでゲーム制作」で学ぼう! 3

Processing Community Day 東京 でのワークショップ講師の FAL さんによって公開された「Processingでゲーム制作」の資料で勉強させてもらってます。

前回は弾にあたった敵機や、敵機に当たった自機の爆発効果を追加しました。
でも、爆発が一瞬だけでなんか物足りない…

前回の記事はこちら。

FALさんの「Processingでゲーム制作」で学ぼう! 2

普通爆発ってどうだっけ?

前回実現させた爆発効果は、一瞬パッと出るだけのものでした。

物足りないですよね。
これは1フレームだけの描画で終わってるからです。

これを複数フレームにわたって描画するようにすれば、それらしい爆発になるのではないでしょうか?

爆発を独立したエレメントとして実装すれば?

敵機や自機はエレメントとして実装されていて、出現から消滅まで複数フレームに渡って存在し続けます。
爆発もこれと同様にエレメントとして実装すれば、複数フレームにわたっての爆発が実現できるのでは?

こんな感じで敵機や自機が消滅するときに newExplosion というエレメントを生成する!

if (element.isDead) {
 Element newExplosion = new Element(
                                    new SquareDisplayer(),
                                    new DefaultUpdater(),
                                    new DummyDestroyer()
                                    );
 newExplosion.position.set(element.position.x, element.position.y);
 explosionElements.add(newExplosion);
 iterator.remove();
}

…あれ? でもこれ newExplosion エレメントが消滅するときにもまた newExplosion が生成されてしまうのでは?
あ、ダメだコレ。

そもそも論

う〜ん、上手く行きませんね。ちょっと考え直してみましょう。

そもそも爆発しているのは敵機や自機であり、衝突して爆発してから消滅ですよね。
前回のコードだと衝突したら即死(element.isDead)であり、死んでたら爆発させるということになっています。

この考えはちょっと変かもしれませんね。
敵機が場外に退場する際も爆発しちゃってますし。

まず、爆発はそれぞれのエレメントが爆発するんだから、エレメントのメソッドとして爆発があるべきではないでしょうか?
衝突は破壊をもたらし、破壊は爆発を呼び、爆発しきったら死、という感じ。
・死とは別に破壊とライフというステータスを持つ
・衝突は破壊をもたらし、破壊後は1フレームごとにライフが減る
・ライフがゼロになると死
・場外は即死

という考えなら納得感あるし、コードにも起こせそうです。

あらためてコーディング

この考えをコードに起こしてみましょう。
前回のコードは捨てて、前々回のコードを元にします。

まずはこれ。
・死とは別に破壊とライフというステータスを持つ

Element.pde 中の class Element に isBroken と life というフィールドを追加します。

class Element {
 PVector position, velocity;
 boolean isDead = false;
 boolean isBroken = false;
 int life = 30;


・衝突は破壊をもたらし、破壊後は1フレームごとにライフが減る

これはまず衝突時に破壊というステータスを立てます。

ElementList.pde の class ElementList 中の collide メソッドでの衝突判定。

       if (distance < 50) {
         element.isDead = true;
         other.isDead = true;
       }

ここを isDead ではなく isBroken を立てるようにします。

       if (distance < 50) {
         element.isBroken = true;
         other.isBroken = true;
       }

そして、破壊後にライフを減らすのは、 ElementComponent.pde の class DefaultUpdater と class PlayerUpdater それぞれの run メソッド中に実装します。
これをメソッド中の最後に追加。

   // Shorten life if broken
   if (element.isBroken) {
     --element.life;
     ellipse(position.x, position.y, 100.0, 100.0);
   }

life を1減らして、爆発効果として ellipse を描画しています。
class DefaultUpdater と class PlayerUpdater で描画を変えれば、敵機の爆発と自機の爆発の効果を変えることが出来ますね。


・ライフがゼロになると死

ElementList.pde の class ElementList 中の update メソッドに消滅のコードがあります。

     if (element.isDead) iterator.remove();

この直前にコードを追加しましょう。

     // Die if life <= 0
     if (element.life <=0) element.isDead = true;


・場外は即死

これは ElementComponent.pde 、 class DefaultUpdater の run メソッド中に元々入っているコードそのままで OK ですね。

   // Die if out of screen
   if (position.x < 0 || position.x > width ||
       position.y < 0 || position.y > height) {
     element.isDead = true;
   }

できた!爆発効果を長くできましたよ。

もうひと工夫

でも、弾にもライフがあるから、敵機を複数なぎ倒していっちゃいますね。

これは弾のライフの初期値を小さくすれば解決できそうです。
ついでに爆発効果ももう少し派手にしてみましょう。

Element を生成する際にライフの初期値を指定できるようにします。
それには Element.pde の class Element のコンストラクタを変更して、

 Element(ElementComponent displayer, ElementComponent updater, int life) {
   position = new PVector();
   velocity = new PVector();
   // Set components
   this.displayer = displayer;
   this.updater = updater;
   this.life = life;
 }

Element の生成時に3番目のパラメータでライフ値を指定するようにします。
弾の生成の場合はライフを 1 にしてすぐ消滅するように。

     Element newBullet = new Element(
                                     new BulletDisplayer(),
                                     new DefaultUpdater(),
                                     1
                                     );

爆発効果の方は、例えば乱数を使ってこんな感じに。

     float rndX = random(-50.0, 50.0);
     float rndY = random(-50.0, 50.0);
     float eW = sqrt(rndX * rndX + rndY * rndY);
     ellipse(position.x + rndX, position.y + rndY, eW, eW);

そうするとこう!

うん!まずまず!

自機が一回の衝突で破壊されちゃう

今回は弾のライフを 1 にすることによって衝突後にすぐ弾が消滅するようにしましたが、ライフが長くて弾が敵機を突き抜けていくのも気持ちいいですね。

自機がパワーアップした時にこうなったらゲームっぽくなりそうです。

あと、自機が一回の衝突で破壊されてしまうのもちょっと寂しい感じ。
衝突毎にライフが減っていって、何回か衝突後に破壊されるといいかも。

コード的にはライフを減らすのにインスタンスのフィールドを外部から直接変更している点が気になります。

解決にはどうすれば…?






この記事が面白かったらサポートしていただけませんか? ぜんざい好きな私に、ぜんざいをお腹いっぱい食べさせてほしい。あなたのことを想いながら食べるから、ぜんざいサポートお願いね 💕