前回までの3つの記事で敵キャラクターとその動作をアニメーションで表現するプログラムをプロジェクトに追加しました。
今度は、個々の敵キャラクターにダメージを与える部分のプログラムを追加していきます。
メインキャラクター(主人公)が放ったパンチが敵キャラクターに当たると敵のHP(ヒットポイント)が減っていき、最後はダウンするところまでをつくっていきます。
この記事を読んでいただくと、アクションゲームで登場する敵キャラクターにダメージを与える方法とそれをアニメーション付きで動かすプログラミングの方法が分かります。
なお、前回までの記事で紹介した「メインキャラクターのジャンプと着地」「敵キャラクターの追加とアニメーション」などのプログラムを組み込んでる箇所が出てきますが、その部分についてはこの記事では詳しく触れません。代わりに過去記事へのリンクを随時貼り付けたりしますので詳しくはそちらを参照してください。
また、この記事で使用しているスプライト(キャラクター・背景・オブジェクト・音声など)はすべてパブリックドメインの無料の素材をダウンロードして使用しています。
完成品
この章の内容をご自身のScratch環境に反映すれば、同じ動きを再現することができます。
完成した動き
メインキャラクター(主人公)が打ったパンチが敵キャラクターにあたったら、拳の先からパンチの効果(空気振動のような)がアニメーション表示されます。
また、敵キャラクターの身体の色が変化し、ビックリ!したようなアニメーションが表示されます。
パンチが1発当たるごとにHP(ヒットポイント)が1ずつ減っていき、0になると敵キャラクターがダウンして動かなくなります。
使用したスプライト
スプライトは「キャラ1」「地面1」「背景1」「天気1」「ティラノ」「パンチ効果」の6つです。
アクションゲーム用の背景・キャラクター・アイテム等の画像や音声は、パブリックドメインである「スーパーパワーアセットパック(CC0)のprehistoric-platformer」を使っています。
【パンチ効果のスプライト】
「パンチ効果」スプライトは、スーパーパワーアセットパックの「prehistoric-platformer/fx/effects」フォルダ内にある「4.png」ファイルを使用しています。
この画像ファイル「4.png」は、下の図のように縦1行×横6列の画像の集まりになっているので等間隔で分割してからコスチュームにアップロードする必要があります。(※6等分後の6枚目の画像は何もないので削除してOK)
分割するためには、Windowsであれば「PL_ImageConstructor」などのフリーソフトで可能です。
この画像をGIFアニメーションにすると以下のようになります。
「パンチ効果」以外のスプライト(キャラ1・地面1・背景1・天気1)については、こちらの記事の「使用したスプライト」の章で詳しく説明していますので参照してください。↓↓↓
【Scratch 3.0】アクションゲーム ジャンプと地面にめり込まないように着地する方法(Tips)
また、「ティラノ」スプライトについてはこちらの記事で解説していますので参照してください。↓↓↓
【Scratch 3.0】アクションゲーム 敵キャラクターの追加とアニメーション①(Tips)
完成したスクリプト
完成したスクリプトの全体です。
【キャラ1のスクリプト】
今回のテーマである「敵キャラクターにダメージを与える方法」のために、追加したブロックに赤枠をつけています。
たくさんスクリプトがありますが、ほとんどがすでの過去の記事で説明済みの内容です。今回追加したのは「パンチ効果」定義ブロックの部分だけです。
※追加する前のスクリプトはこちらの記事で説明しています。
- ジャンプ力:このスプライトのみ
- 地面に触れた:このスプライトのみ
- コスチューム保存用:このスプライトのみ
【地面1のスクリプト】
※内容を当たり判定に絞るため、以前までの記事の内容から背景スクロールさせる部分のブロックを削除しています。
【背景1のスクリプト】
※内容を当たり判定に絞るため、以前までの記事の内容から背景スクロールさせる部分のブロックを削除しています。
【天気1のスクリプト】
※内容を当たり判定に絞るため、以前までの記事の内容から背景スクロールさせる部分のブロックを削除しています。
【ティラノのスクリプト】
今回のテーマである「敵キャラクターにダメージを与える方法」のために追加したブロックに赤枠をつけています。
スクリプトの内容は、「ティラノ」スプライトがダメージを受けたときのアニメーションとHP(ヒットポイント)の減少です。「キャラ1」スプライトに対するとの当たり判定については別の記事で説明します。
※内容を当たり判定に絞るため、以前までの記事の内容から背景スクロールさせる部分のブロックを削除しています。
- アクション:このスプライトのみ
- HP:このスプライトのみ
【パンチ効果のスクリプト】
スクリプトはシンプルに出来ています。
クローンがつくられたら「キャラ1」スプライトの場所(座標)に移動させて、向きは「キャラ1」と同じ方向を向けて距離を50px分離す。その後、表示してコスチュームを次々変えながらアニメーションを表示します。
スクリプトの作り方
ここからはプログラムを作っていく中でポイントとなる部分を説明します。
今回のプログラムは以下の仕様としています。
- スペースキーを押すと主人公(キャラ1)はパンチをくり出す、そのパンチが敵(ティラノ)に当たったら「パンチ効果」アニメーションを拳の辺りに表示する
- 敵がパンチに当たると点滅し、「ヒット」アニメーションを表示し、HPを1減らす
- HPが0になったら、敵は「ダウン」アニメーションを表示し、動かなくなる
- 主人公はその後もゲームを続けることができる
ポイント①:パンチが敵キャラクターに当たったらアニメーション効果を発動する
「キャラ1」スプライト(メインキャラクター)には、敵にパンチを当てる部分のプログラムをつくっていきます。
これまでの記事で「スペースキーを押したら「攻撃」定義ブロックでアニメーションを表示する」部分のプログラムは出来ていますので、その直後にプログラムを追加します。
追加する内容は、もし「ティラノ」に触れたら「パンチ効果」スプライトのクローンをつくるようにします。ここでは「パンチ効果」定義ブロックをつくって組み込んでいます。
ここで「何がティラノに触れたかどうかを判別しているのか?」と考えてみましょう。
「キャラ1」スプライトにプログラムを追加しているので、もちろん「キャラ1がティラノに触れたかどうか」という意味になるのですが、「パンチ効果」定義ブロックの直前に「攻撃」定義ブロックがあります。
細かく言うと、この「攻撃」定義ブロックの最後の状態で、キャラ1がティラノに触れたかどうかを判定しています。(最後の状態というところがミソです)
「攻撃」定義ブロックは下図の内容なので、さいごは「egg-shell_26」という名前のコスチュームの状態になっていることが分かります。
「egg-shell_26」という名前のコスチュームは下図の状態です。パンチの恰好をしていることが分かりますね。
この恰好をしている状態で「パンチ効果」のアニメーションが出てきてほしいので、先ほどの位置にプログラム(パンチ効果定義ブロック)を追加したわけです。
一方で「パンチ効果」スプライトには、「キャラ1」からクローン作成を指示された後のプログラムをつくっていきます。
まず、クローンされたら「キャラ1へ行く」ブロックで「キャラ1」の位置に移動させます。
つぎに「キャラ1」と同じ方向に向きを変えます。そして50歩移動させます。
こうすることで「キャラ1」が右向きなら右方向に50px、左向きなら左方向に50px位置をずらすことができます。※これはパンチ効果を「キャラ1」の中心ではなく拳の先に登場させるためです。
あとは表示したい順番にコスチュームを切り替えることでアニメーション表示されます。
さいごに使い終わったクローンを削除することを忘れないようにしましょう。
※「隠す」ブロックでは削除したことにはなりません。
ポイント②:当たり判定(ダメージを受ける部分)を追加する
「ティラノ」スプライトのプログラム(下の図)を見ると、「もし(パンチ効果に触れた)なら」は2か所に存在しています。
1つは「アクション」定義ブロックの中に、もう1つは「パンチ当たり判定」定義ブロックの中です。
まず「アクション」定義ブロックの中ですが、「HP」変数が0より大きい場合と0以下の場合で条件を分けています。0以下になると「ティラノ」はダウンするのですが、これについてはつぎのポイント③で説明します。
HPが0より大きい場合でキャラ1との距離が近づいた状態で「パンチ効果」に触れると「ヒット」定義ブロックが実行される流れになっています。
もう一方の「パンチ当たり判定」定義ブロックの中ですが、「パンチ効果」に触れると「ティラノ」が2回点滅してHPから1を減らす処理を行います。
なお、どうして「(ティラノアニメーション)を受け取ったとき」「(ティラノコントロール)を受け取ったとき」「パンチ当たり判定」と大きく3つのスクリプトのかたまりに分かれているかというと、それぞれのかたまりの中に「~秒待つ」ブロックがあることが理由です。
同時並行として動かしたいブロックがあるときに、その前後に「~秒待つ」ブロックが挟まっているとつぎの処理に移るまでに設定された時間だけ待ち時間が発生してしまい、思うような動きになってくれないことが多くあります。
そのため、同時に並列に動かしたい処理同士は何らかの方法(定義ブロックやメッセージを送るブロック)でスクリプトのかたまりを分ける必要が出てきます。
ポイント③:HPがなくなったら敵はダウン・ただしゲームは続行
下にポイント②と同じ画像を貼り付けていますが、今度は点線赤枠の場所が異なっていて、HPが0以下になったとき(敵がダウンしたとき)の動きについてです。
HPが0以下の場合、「アクション」変数の値が「ダウン」に変わることで、「ダウン」定義ブロックのアニメーションが実行されます。
このあと「このスクリプトを止める」ブロックが実行されるので、「(ティラノアニメーション)を受け取ったとき」で始まっているスクリプトだけが停止し、その他のスクリプトは実行中のままになります。そのため、ゲーム全体が止まることはありません。
※「すべてを止める」ブロックにすると、「キャラ1」スプライトなども含めて本当にすべて止まってしまうので留意してください。
なお、以前紹介した背景スクロールを組み込んだ場合は、「アクション」定義ブロックの中にも「このスクリプトを止める」ブロックを組み込まないといけません。
ここまでのポイントを押さえれば、アクションゲームで登場する敵キャラクターにダメージを与える方法とそれをアニメーション付きで動かすスクリプトを完成させることができると思います。
失敗しやすいポイント
「アクション」定義ブロックも「パンチ当たり判定」定義ブロックも「ずっと」ブロックの中に入れる必要があります。
どちらの定義ブロックにも「~秒待つ」ブロックが含めれているため、「ずっと」ブロックを分けてスクリプトをつくっていることを上で説明しました。
試しに同じ「ずっと」ブロックの中に入れてみると、どのような動きになるかやってみましょう。
下のGIFアニメを見て違いが分かるでしょうか?実はパンチが当たっているにもかかわらず、HPが減らないことがあります。
これは「アクション」定義ブロックの中の「もし(パンチ効果に触れた)なら」は実行されるけれど、その後「パンチ当たり判定」定義ブロックの中の「もし(パンチ効果に触れた)なら」を実行しようとするタイミングではすでに「パンチ効果」は消えてしまっているためです。
たまにHPが減ることがありますがこれは、連続でパンチを打つと1回目にパンチ効果が表示されたときは「アクション」定義ブロック内が実行され、2回目にパンチ効果が表示されたときはたまたま「パンチ当たり判定」定義ブロック内が実行されることがあるためです。
応用編
以前の記事で紹介した背景スクロールとブロックを組み込んでいます。
まとめ
さいごに、今回の記事で説明した『アクションゲームで登場する敵キャラクターにダメージを与える方法とそれをアニメーション付きで動かすプログラミング』のポイントをまとめます。
- ポイント①:パンチが敵キャラクターに当たったらアニメーション効果を発動する
- ポイント②:当たり判定(ダメージを受ける部分)を追加する
- ポイント③:HPがなくなったら敵はダウン・ただしゲームは続行
どうでしたか?上手く再現できたでしょうか?
他にも役に立つTips(ティップス)記事をたくさん書いてますので、ぜひ見てみてください。(記事のタイトルに「Tips」と書いていたり「Tips」タグを貼ってあります)