※ 当ページには【広告/PR】を含む場合があります。
2022/07/28
2022/08/02
Scratchから始めるシューティングゲームの作り方①〜最初のプロジェクトを作成
Scratchから始めるシューティングゲームの作り方③〜敵の弾・敵の動きを改良する
シューティングゲームを丸々一本作れるようになると、Scratchプログラミングの腕前もかなりのものと言えます。このシリーズ記事では、シューティングゲームの基本から、楽しく遊べるプログラムに仕上げるまでを詳しく特集していく内容で連載しております。前回までのScratchシューティングゲームの作り方の基本を解説した記事は、以下のリンクから参考にしてください。Scratchから始めるシューティングゲームの作り方①〜最初のプロジェクトを作成シューティングゲーム作成を通じてScratchでプログラミングを学習していきましょう。
では今回は、前回作った簡単なシューティングゲームで改善すべき課題となっていた、弾を発射する時の『連射』の機能をもっといい感じにできないか、さらに深く考えていきます。
【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ
正しく弾が連射できるようにコードを修正する
まずは問題の確認からいきましょう。前回までの完成品プログラムで、スペースキーを押しっぱなしにして、「連射」を試してみてください。...いかがでしょうか。ボタンを押しっぱなしにしたとき、プログラム側で何の処理もしていないと、時間の間隔もバラバラな弾が好き放題に飛んでいく「なんとなく連射」になっていることが分かるとおもいます。※動作しているブラウザやパソコンのスペックによって連射の挙動は異なります。ここはちゃんとScratchプログラムとして“デザイン”された「正しい連射」にする必要があります。シューティングゲームでの「正しい連射」っていうと、考え方は人それぞれですが、ここでは、というような制約を弾の発射ルールに持たせる、という意味合いで使っています。このようなゲーム上での制約は、弾の発射に限らず、全体的なゲームバランスを調整する上で、とても重要な条件になってきます。弾の発射を時間間隔でコントロール
まずは、弾のスプライトにローカル変数・うち出しタイマー
という値を準備します。この時間を記録するローカル変数によって、この値が一定時間以上に溜まらないと、新しい弾が撃てないように制限します。こういうプログラムで内部時間を利用する場合に使うのが、『タイマー』です。Scratchのタイマーの基本的な使い方は別の記事していますので、そちらをご覧下さい。【Scratch入門】タイマーの基本と使い方のポイントScratchプログラミングの「タイマー」の基本的な使い方を解説します。
ここではうち出しタイマー
にシステムのタイマーの値を一定間隔で記録させることで、弾の撃ち出しタイミングを決めています。まず図の①のブロックで、ゲームが開始されたら直ぐにうち出しタイマー
を初期化します。次に②のパートで、ゲーム中スペースキーを押すと、そのままクローン弾を生成させずに、条件ブロックで、現在のタイマー時間と、前回弾を撃ち出したときに記録した時間を比較して、その差が一定値よりも大きければ、次に弾を打ち出す(+その時間を記録)させています。つまり、ゲームのタイマー時間とうち出しタイマー
の値に十分な間隔がないと、弾は発射されずにロックしてくれるようになります。このプログラムを実行してみると、うち出しタイマー
の値が0.5秒以上になってから、弾が飛んでいることが分かります。弾の発射数を数量でコントロール(※読み飛ばし可)
弾の発射時間の間隔だけの制限だと、幾つでも発射できてしまうことに変わりないので、ゲームの難易度もかなり簡単になってしまうことがあります。ここでは、画面上に存在している弾の総数が、ある一定数以上にならないように制限をかけるようにしてみます。まずはスプライト共通で、グローバル変数・弾の数
を追加してみます。先ほどはローカル変数を使って、弾の撃ち出し間隔時間を記録していたのに、ここではグローバル変数にしているかというと、後でパワーアップ・アイテムをゲットした際に、この弾数を増やすようにしたいからです。まだ現時点で作成してはいないですが、アイテムのスプライト側のプログラム処理から、このグローバル変数を書き換えるだけで、全体で撃てる弾の合計数を変更するようになります。画面全体の弾の数を調整するには、クローン弾の数を常にコントロールする必要があります。クローン弾を撃つたびに、弾の数
をひとつづつ減らしていき、クローン弾が消滅したら弾の数
をひとつ増やし、弾全体の数を調整します。ただし、先ほども説明したように、グローバル変数として弾の数
を定義したということは、プログラムのどのスプライトからでも弾の数
を書き換えられてしまう可能性があります。プレーヤーが弾を撃っている途中に、弾の数
がいきなり変わってしまったら困るので、弾のスプライトだけが使えるローカル変数・弾の数_
を用意して、弾の数_
の値に弾の数
の値をコピーして使えるように工夫します。プログラム内でスプライトが共通して使うグローバル変数を直接使わずに、各スプライトだけがアクセスできるローカル変数にコピーして使う、というテクニックはScratchプログラミングになれてくると、頻繁に目にしますので、覚えておくと良いでしょう。ということで、ブロックコードを修正すると、以下のようになります。①の箇所のコードは、先ほど説明したよう、グローバル変数・弾の数
とローカル変数・弾の数_
にゲーム開始直後の初期値を設定しているパートです。②の箇所で、弾の数_
がゼロより大きい場合のみ、弾をクローンして打ち出せるような条件ブロックを追加し、弾を打ち出せるなら、弾の数_
を1つ減らします。③の部分が今回の大きなポイントになっていて、弾が消えるタイミングを弾を消す
という新しいイベントを使ってまとめています。これで弾が消えるタイミングを漏らさずに、クローンから受けとることができるようになります。④のコードの箇所で、画面上に存在するまだ消えていない弾が消えると、弾の数_
が1つ戻り、初期値として設定した数に弾の数がバランスします。Scratchプログラミングに慣れていないと、下の図の左側のブロックコードでも、一見ちゃんと弾の数が元に戻るような気になると思います。ですが、実際に動かしてみると、左のブロックでは、ローカル変数・弾の数_
に+1されることはありません。これは弾の数_
が、クローン元のオリジナルのスプライトが専用に使えるローカル変数であって、そこからクローンされたスプライトであってもこの変数にアクセスすることができないからです。同じような理屈で、クローンされたスプライトが使えるのは、やはりクローンされたローカル変数・弾の数_
がまた別に裏で存在していることになり、これはそのクローン以外からはアクセスできないプライベートは変数になっています。初心者にとって、Scratchプログラミングの最大の難関は「クローンの使い方」である、と思います。クローンの処理コードの中で、変数を読み出したり・書き換えたりすると、クローンの数が多いほど意味不明な挙動になるケースが多く、混乱しやすいプログラムに陥ります。これ以上の説明は込み入った話になりますので、クローンの特殊な性質のより詳しい説明に興味があれば、以下の記事も一読ください。【Scratch入門〜中級編】少しだけ難しいスプライトのクローンの高度な利用法Scratchの中級者向けのテクニックとして、クローンの特殊な使い方を解説します。
ともかくこのコードを実行すると、画面に初期値に設定していた3つ以上の弾が同時に存在できないように制限できます。複雑な処理をするクローンの多用は非推奨?
ここまでで、弾数を制限する機能を追加しておきながら言うのもアレですが、実際にスペースキーをしばらく押しっぱなしにして、連射を続けてみると、多数のクローンを発生・消滅を短い時間で繰り返す処理が、次第に重くなり、画面全体のアニメーションがカクカクし始めてしまいます。Scratchのクローンは便利な機能である反面、削除されないままの処理待ちのクローンが多すぎると、ゲーム全体への演算の負荷が大きくなったり、メモリなどのリソースをかなり消費してしまった結果、ゲームのパフォーマンスが著しく低下します。このため、イベントのような複雑な処理待ちを内部にもったクローンを多用するプログラムは、あまり推奨されません。先程のScratchのシューティングゲームで弾数を絞るコードは、連射を続けると、ゲーム自体が遅くなるので、あまり良いコードとは言えないかもしれません。...Scratchプログラミングのお勉強と思って、とりあえず残しておきましょう。動きながらでも弾が発射できるようにする
今のままだと、弾を撃つためにスペースキーを入力すると同時に他のキーが受け付けないので、プレーヤーが移動しながら弾を撃ち出すことができません。Scratchプログラムは原則として、2つ以上のキーを同時に検知することができません。つまり、スペースキーを押しっぱなししている状態から、方向キーのどれかを押しっぱなしした場合、後から入力されたキーが優先されて、スペースキーが無効化されしまいます。複数のキーによるイベントを同時に処理する場合には、〇〇キーが押された
判定ブロックを上手くコーディングする必要があります。弾のスプライトのブロックコードで、下の図のように左側の元のコードから、右側のコードへ修正を加えます。これだけで、スペースキーの状態は常に監視されるため、同時に複数のキーイベントが起こっても、スペースキーを使った処理が無効化されずに、弾の発射とプレーヤーの移動という2つの処理を共存させることができます。
【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ
シューティングゲームの連射のバリエーションを増やす
まだScratchシューティングゲームとしては作成していませんが、シューティングゲームの面白さの要素に「拾ったアイテムでプレーヤーがパワーアップ」というものがあります。ゲームの最初は前方向に弾が1つしか打ち出せないプレーヤーも、パワーアップを繰り返すことで、強力なビームが出せたり、色んな方向に弾がたくさん打ち出せるように成長していきます。このような「連射のバリエーション」をここでいくつか考えてみましょう。ゲーム中で弾を切り替えるには?
弾の種類が切り替えられるように、グローバル変数・弾の種類
をプレーヤー側で作成しておきます。これで、この弾の種類
の番号をゲーム中で切り替えられるようにしておけば、色々な弾の種類に切り替えることができるようになります。とりあえず今回の例では、弾の種類はプレーヤーのコードの変数の初期化だけで、手動で切り替えて利用します。ゲームスタート時から撃てる弾の種類
を0として、あとはゲームの途中で使えるようになるより強力な弾の種類を、1、2、3、...というように弾の種類
の値で割り振っていくようになります。そこで、撃ち出す弾を弾の種類
に併せて、オン・オフするようにして切り替えるので、例えば弾の種類
が0である弾の場合、のように各弾のスプライトのコードのメインループの中に弾の種類 = [番号]
条件ブロックで、適切に分岐させてあげる必要もあります。連射の同時発射数を増やす
先ほど上のパートでも説明した通り、グローバル変数の弾の数
を書き換えるやり方です。先ほどのもので、ゲーム起動中に直接弾の数
の値を書き換えてやると、弾の数が増えていることが確認できます。また、弾の撃ち出し間隔時間も小さくすると、より多くの弾を発生させることができます。こうしてあげると、一度に連射できる弾数が多くすることができます。なお今回は変数のブロックコードに、値を直接代入していますが、今後のブログ記事で、弾数を増やせるようなパワーアップアイテムを登場させた、ゲームプレー中での弾数の増やし方も解説していく予定です。複数方向に弾が打てるような連射
こちらは弾の進行方向を工夫して撃ち出せるようにしたタイプの連射法です。新しく弾の種類を追加する場合、まず、弾のスプライト自体をコピーしてから新しいスプライト・Ball2
として作業を始めます。弾の色を変えるため、コスチュームから別の色のボールに換えてみます。弾の色はさておいて、Ball2
のコードを修正していきましょう。今回は3方向に同時に弾を射出させるので、飛ばす方向として、前方を0、斜め上方向を1、斜め下方向を2、と定義し、ローカル変数・飛ぶ方向_
をクローンの識別番号として使う方法を使ってみます。なお、このテクニックの詳細は、以下の記事で詳しく解説しています。【Scratch入門〜中級編】少しだけ難しいスプライトのクローンの高度な利用法Scratchの中級者向けのテクニックとして、クローンの特殊な使い方を解説します。
Ball2のコードブロックは以下のようにしてみます。①の箇所で、この弾の種類を1として、グローバル変数・弾の種類
で切り替えられるようにしています。また三方向に撃ち出す処理は、三連射
という定義ブロックを作って②でまとめています。この②の中で、ローカル変数・飛ぶ方向_
をクローンの識別番号として利用しています。このクローンごとの識別番号を③のクローン内のコード処理の中で、どの方向に飛んでいけばよいか条件分岐させて利用しています。これで、弾を撃ち出しする一回のループで、3つの弾をそれぞれの方向に連射することができるようになります。なお、前節の、「弾の発射数を数量でコントロール」で説明した弾の数
で弾数を調整するテクニックは、このスプライトでは使わないことにしています。実際にやってみたら分かりますが、同時に3つのクローン弾を撃ち出し、さらにその弾の消滅のタイミングを完璧に制御しようとすると、クローンの処理のコードはそれなりに大掛かりになります。リストなどの仕組みを使って、コーディングを頑張れば、Scratchでも出来なくはないですが、処理待ちになるクローン弾の数が多けれ多いほど、ゲームとしては重くなってカクカクと処理落ちする原因にもなります。前のパートでも説明していましたが、弾の数の制御にはあまり今の段階でこだわる必要はないでしょう。仕上げとして、この弾Ball2
と敵のスプライトとの当たり判定の条件を更新するために、敵のスプライトのコードに以下のブロックを追加します。これで、Ball2と敵のスプライトが衝突して、お互いに消滅することになります。全方向で連射
これはよくある打ち上げ花火のような状態の弾の連射です。内容としては、先程のBall2のスプライトとほぼ同じやり方で、作成可能です。まずBall2をコピーしてから新しいスプライト・Ball3
として作業を始めます。コピーしたBall3
のコードを以下のように修正します。単純に先程のBall2のスプライトコードを、3方向から8方向へ分岐数を増やしただけのコードです。ただし、真面目に全ての分岐条件でコードを書き出して行くと、非常に縦長のコードになって見にくいブロックコードになるので、コード効率化のために、上手く定義ブロックを使うと多少はマシな長さに収まると思います。弾を撃ち出しする一回のループで、計8つの弾を8方向に射出するようなコードになっています。弾数が多ければ多いほど派手ですが、やはりこれもやりすぎると、知らず知らずの内に、ゲーム自体の処理が重くなる原因になってしまいます。こちらも仕上げとして、この弾Ball3
と敵のスプライトとの当たり判定の条件を更新するために、敵のスプライトのコードに以下のブロックを追加します。これで、Ball3と敵のスプライトが衝突して、お互いに消滅することになります。ビーム状の連射
シューティングゲームでは、強力な弾として登場するのがこの「ビーム」です。このタイプだと、弾数といった考え方は無いので、新しくビーム専用のスプライトで対応します。Ball2あたりの適当なスプライト自体をコピーしてから新しいスプライト・ビーム
として作業を始めます。まずは、ビームに見立てた長い横棒を描いたコスチュームに追加しましょう。次にコピーしたビーム
のコードを以下のように修正します。ビームは通常の弾のように、画面上にいくつも存在する訳ではなく、撃つか/撃たないかの場合で済むので、基本的に1つのスプライトがあれば十分です。ということで、ビームのコードの実装はかなり単純で、クローンも必要なく、表示する
/隠す
の切り替えだけでOKです。注意点としては、ビームが表示される場所をプレーヤーのスプライトの手前で表示させられるように、上手く調整することくらいで、これまでの弾の連射を理解していただいた読者にはかなり簡単に感じられると思います。これを実行すると、となり、ビームの発射線上にいる敵は全て薙ぎ払われるような、最強の攻撃方法の一つと言えるでしょう。ただしビームも、画像がただの棒線一本だと味気ないのですが、いくつかのコスチュームを組み合わせてアニメーションを用いて、ビーム弾が発射して伸びたり、一定時間でスッと消えるような演出を追加しても面白いと思います。ビームの演出はアイデア次第で、色々と応用が効くので、とりあえずここでは棒線一本ビームの紹介までとさせていただきます。こちらも仕上げとして、このビームと敵のスプライトとの当たり判定の条件を更新するために、敵のスプライトのコードに以下のブロックを追加します。これで、ビームと敵のスプライトが衝突して、敵が消滅することになります。
【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ
まとめ
今回はScratchでシューティングゲームを作成の話で、弾の連射方法を詳しくみていきました。今回使ったScratchプロジェクトの練習で仕上がった作品は以下のようになりますので、勉強の参考になればと思います。なお、弾の種類を変えてみるときは、Scratchのプロジェクト内から、ブロックコードの変数を直接変更して貰えれば、弾の種類が変更可能です。連射方法の実装は、シューティングゲームの開発者が色々と頭をひねり、工夫をこらすことで、よりゲームを面白くすることのできる要素です。Scratchプログラミングに慣れてきたら「こんな連射方法があったら面白いんじゃないか」とひらめいたときに、ぜひともオリジナル連射方法のコードを書いてみましょう。