※ 当ページには【広告/PR】を含む場合があります。
2022/08/20
Scratchから始めるシューティングゲームの作り方⑤〜長い背景の作り方と敵の出現パターンを設定する
Scratchから始めるシューティングゲームの作り方⑦〜敵の落としたアイテムでパワーアップさせてみる
Scratchで本格的なシューティングゲームを作成することを目指すシリーズ記事の第6回目です。今回は、敵に耐久性がある場合の、より高度な当たり判定をどのように実装していくかと、さらにステージ(フィールド)で様々な敵を配置する方法を考えていきます。なお、Scratchシューティングゲームの作り方のシリーズ最初の記事は以下のリンクを参考にしてください。Scratchから始めるシューティングゲームの作り方①〜最初のプロジェクトを作成シューティングゲーム作成を通じてScratchでプログラミングを学習していきましょう。
今回も前回までの開発途中のプロジェクトをベースに改造しながら解説していきます。参考|シューティングゲーム⑤
【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ
当たり判定の改良
例えば耐久性ある敵の代表として、シューティングゲーム上の「ボス」の存在があります。またボスに限らず、耐久性のある(何回か弾を当てないと消えない)敵をScratchゲーム内に出現させようと思うと、「その敵に何回当たったか」を情報として対象のクローン敵に保持しておく必要が出てきます。【Scratch入門〜中級編】少しだけ難しいスプライトのクローンの高度な利用法Scratchの中級者向けのテクニックとして、クローンの特殊な使い方を解説します。
まずは耐久性ある敵を新しいスプライトとしてプロジェクトに敵2
として追加してみるところから始めます。「ステージ(背景)」からいろんな敵の出現タイミングを制御する
敵の出現タイミングは、前回の話で、敵
のスプライトのブロックコードに実装していました。Scratchから始めるシューティングゲームの作り方⑤〜長い背景の作り方と敵の出現パターンを設定するScratchのシューティングゲームで、横に大きい画像からステージ背景と敵の出現ポイントを作ります。
このスプライトがゲーム中に出現する敵を操作する際の、「司令塔」としての役割を果たしているので、タイマー
や出現ポイントのリスト
などの重要なパーツを持たせていました。なので、今回のように、追加で敵のスプライトを追加するたびに、すべて敵
のスプライトの処理コードを経由して、各敵のスプライトのクローンを経由するようなプログラミングは少々面倒です。今後、いろんな敵を効率良く制御することを考えたときに、一番プログラミングに都合の良いスプライトは、前回追加した「背景」
のスプライトになります。まず敵
のスプライトから背景
のスプライトへ、タイマーと出現ポイントのリスト機能をすべて「お引っ越し」することとなります。ここでの図の赤枠で囲った場所が修正したコードです。ポイントは、背景のスプライトの処理メインループで、[敵]のクローンを作る
ブロックを呼び出して使っています。よって、元の敵
のクローンは、敵の出現に関する「司令塔」の役割を持たなくても済むので、以下のようにブロックコードを修正できます。ここまで修正したら、一旦ゲームを起動して、コード修正の前後でもちゃんと変わらずに動作するか確認しておきましょう。敵のスプライトを切り替える
先程の修正で、新しい敵のスプライトがゲームに追加しやすくなりました。ということで、先程作っておいた敵2
スプライトに、敵
のコードをコピーして、以下のブロックコードのように修正します。これまでの敵のスプライトとほぼ一緒ですが、表示するレイヤーは9層目
、敵の番号は5番目
で指定しています。この新しい敵のクローンがゲームに表示できるように、背景
のスプライトのコードも以下のように修正します。グローバル変数・敵の種類
の値により、0〜4までなら敵
のスプライトのクローンを、5なら敵2
のスプライトのクローンがそれぞれ出現してくれるようになります。また、各弾のスプライトとの当たり判定もちゃんと修正しておきましょう。例えば弾
のスプライトでの当たり判定のコード部分を以下の条件に拡張します。これで、一旦、ゲームを開始し、出現する敵が指定した数で消滅するかを確認します。ちゃんと消えてくれたらOKです。敵と弾との当たり判定
ここからは「耐久性を持つ敵」を敵2
のスプライトで作成していくことにします。耐久性ある敵は、クローン個体ごとにライフ数を記録して、弾が当たるたびに減少させ、ゼロになった時点でそのクローンを削除する必要があります。そこでローカル変数・「敵のライフ_」
を敵2
のスプライトに作成してみます。このローカル変数を使って、ここでは弾が2回当たることで敵のクローンが削除するようにプログラムを修正してみます。これでクローンごとに与えられたライフの値がゼロになったときにだけ、弾が当たった敵のクローンだけ消滅させることができます。敵とプレーヤーとの当たり判定
先程の敵と弾との当たり判定はまだ単純でしたが、敵とプレーヤーの当たり判定は少し頭をひねる必要があります。これまでの簡単なScratchゲームでの、敵のスプライトとプレーヤーのスプライトの当たり判定では、「敵はプレーヤーに当たった瞬間消える」というシンプルなロジックでした。それがシューティングゲームに消えない敵が存在すると、プログラミングの難易度がいきなり難しくなります。そこで敵に当たった直後から少しの時間だけは、プレーヤーの残りライフが減らないように、「一時敵な変数への書き込み保護(ロック)機能」を新たに追加してみます。まず、敵2
のスプライトにローカル変数・「当たった時間_」
を作成し、敵クローンとプレーヤーが当たった時間を記録させることにします。あとは、敵とプレーヤーが衝突したときだけ、「当たった時間_」
にシステムタイマーの時間を記録し、前回当たった時間と現在の時間の差・[タイマー] - [当たった時間_]
が1秒より長いなら“当たった”、短いなら“当たっていない”をいう条件を作ります。これで耐久性を持った敵とすれ違っても、プレーヤーは即時ライフがゼロになることは無く、一定時間(ここでは1秒)の間、“無敵状態”となります。これでようやくScratchのシューティングにも、何回か弾を当てないと倒せない、タフな敵を登場させることができました。
【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ
フィールドに様々な敵のパターンを配置する
この記事の後半の内容として、これまで作ってきた敵も配置ごとにパターンが変化するように、出現ポイントのリストを修正していくことにします。これまで作ってきたScratchシューティングでは、手動で一種類の敵パターンしか画面に出現させられない状態でしたので、ここでようやく様々な敵をステージフィールドに出現させることができるようにプログラムを改良させていきましょう。敵の出現ポイントのリストを工夫する
基本的にScratchでは、データ一つに対して、それに対応するリストを一つ用意することになります。これまで敵の出現座標で使っていた出現ポイント
のリストと同数の要素を持つ、出現タイプ
というリストを新たに生成して、こちらには敵のパターン番号を保持するようにしておきましょう。あとはこの2つのリストを使って、敵の出現位置とそのときの種類を同時に選択できれば、ゲーム中の敵のパターンも含めて自由に配置することが可能です。複数のリストを使うと、特に気になるのは、初期化の際の遅延時間(ここではリスト1つあたり0.5秒ほど待っています)の存在です。リストはあればあるほど、ゲーム開始時のロード時間に余裕を持ったプログラム設計が必要になるかもしれません。Scratchの落とし穴〜「リストの処理はかなり重い」
ここからはちょっとScratchプログラミング的な余談です。ゲームの最初に利用するリストの数が少なければ、ロード時間が速くできるかというと、そう簡単にはいきません。下手すると、逆にゲームの処理時間は圧倒的に伸びてしまう恐れさえあります。以前、リストのデータを集約するために、行の文字列をコンマ切りさせて、一つの行から複数のデータを取り出すというテクニックを紹介したことがあります。【Scratch入門】リストから数値データを使いこなすScratchのリストを使って、テキストから読み込んだ大量のデータを上手くプログラムで利用する方法を解説します。
ここではこのテクニックを使って、コンマ切りのデータから敵の出現ポイントと行動パターンの識別番号を取得してみます。例えば今回のようなデータを1つのリストでまとめたとすると、以下のようなリスト構造を使うことになるでしょう。ここでは、[ゲームのステージ座標],[敵のパターン番号]
という並びの形式でデータを使っています。例えば先程の2つのリストのデータを1つのリストに集約したとすると以下のようにできると思います。ここからリストの各行の文字列を使って、コンマで区切られた座標と敵のパターン番号の値として分けて取りだすには、いくつかのローカル変数が必要になってきます。例えば、1文字ずつの文字列の読み取り用にローカル変数・「文字の位置_」
、コンマで区切られた文字列がどの変数に当たるかを表したローカル変数・「_変数の番号」
、読み取った座標値を一旦保持しておくためのローカル変数・「出現座標_」
、敵のパターンの番号を一旦保持しておくためのローカル変数・「敵の種類_」
など4つ程度が処理に必要になります。これらのローカル変数を利用して、処理の効率化のために引数ありの定義ブロック・「文字列を分ける」
を以下のように実装します。あとは、リストからコンマ区切りで取り出した値が、出現座標_
と敵の種類_
に入力されるので、メインの処理ループの中で、例えば以下のように使えばゲームとしての動作を行うことは可能です。...でプログラムが動くならそれで良いでは無いかというと、残念ながらそうは単純にはいきません。ここでは、一行ごとに文字を分ける処理に、1ループあたり数百ミリ秒もかかってしまうようで、同じループ処理に入っている、ゲームの座標を増加させていく処理がスムーズに行かず、阻害されてしまう結果になるでしょう。ここで気に留めておくべきは、「Scratchのリストの操作は基本的に重い」、「Scratchの文字列の分割はかなり重い」、という話です。知らず知らずに、この2つ処理を同時にやってしまうと、ゲームとしてはかなり重く、最悪まともに動かないプログラムになる可能性があるので注意が必要です。
【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ
まとめ
以上、今回のScratchシューティングゲームの改造内容をひとまとめにしたものは以下のようになります。※最初にゲームをスタートすると、スペースキーを押しても弾が出ない場合があります(...バグ?)。そんなときは、お手数ですが、一旦プログラムをストップして、もう一度スタートしてみてください。今回で、ステージに出現する敵にもバリエーションを出すことができるようになりました。Scratchで本格的なシューティングゲーム作りも、これからようやく後半戦に差し掛かるように感じてきましたが、ステージボスや、ドロップアイテムでのプレーヤー強化など、まだまだ歯ごたえのある作り込みが控えています。もうしばらくこのブログ記事の内容にお付き合いいただけたら幸いです。