Scratchから始めるシューティングゲームの作り方③〜敵の弾・敵の動きを改良する


※ 当ページには【広告/PR】を含む場合があります。
2022/08/01
Scratchから始めるシューティングゲームの作り方②〜弾の連射を自在にカスタマイズする
Scratchから始めるシューティングゲームの作り方④〜スクロールしながら動く背景を作成する
タコキンのPスクール|Scratchから始めるシューティングゲームの作り方③〜敵の弾・敵の動きを改良する



シューティングゲームをより面白くするための重要な要素に、
「敵の種類を充実させる」 ことが不可欠です。
魅力的な敵を出現させることで、ゲームをプレイしてくれるユーザーを飽きさせないようにすることができるので、ゲームを作る側としても、色々と頭をひねりながら、どうすると面白く感じてもられるかをアイデアを色々と考える必要があります。
今回はどうやって敵のバリエーションを増やしていくかについて、簡単な例でブロックコードを作りながら考えていきましょう。
なお、ベースとなるScratchシューティングゲームの作り方を解説したシリーズ最初の記事は、以下のリンクから参考にしてください。

合同会社タコスキングダム|蛸壺の技術ブログ
Scratchから始めるシューティングゲームの作り方①〜最初のプロジェクトを作成

シューティングゲーム作成を通じてScratchでプログラミングを学習していきましょう。


合同会社タコスキングダム|蛸壺の技術ブログ【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ

複雑な動きをする敵を作る



まっすぐに直進してくる敵だけしかいないとシューティングゲームとしてはかなりつまらない作品になってしまいます。
まずは簡単なコード修正で済みそうな、
「敵に複雑な動きのパターンをつける」 ようなプログラムをScratchでどう実装するか見ていきましょう。


敵を追加する2つの方法



前回の続きということで、以下のScratchプロジェクトをリミックスして作業を開始してみましょう。

サンプルプロジェクト|シューティングゲーム②

なお、Scratchプログラムのリミックスの方法については、以前の記事で紹介した内容を参考にしてください。

合同会社タコスキングダム|蛸壺の技術ブログ
【Scratch入門】リミックスのやり方〜気になるプログラムからScratchを自習する方法

気になるScratchプロジェクトをコピーして自分のプロジェクトに追加する「リミックス」の手順について解説します。



さて、単純に「敵を追加する」とはいっても、Scratchプログラミングとしては、
「敵として新しくスプライトを追加する」 ことと、 「既存の敵のスプライトに違う動き・見た目で条件分岐を作る」 ことの主に2つが存在します。
前者のやり方はとてもシンプルで、スプライトを新しくプロジェクトへ追加するやり方です。
このやり方のメリットとしては、ブロックコードの組み立てをさほど複雑化しなくても済むので、Scatchプログラミングに慣れていないうちは、1つの敵に1つのスプライトを作るという方針でも良いかも知れません。
逆にデメリットとしては、シューティングゲームの開発が進み、敵が多くなってくるとゲームプログラム全体の容量が大きくなるので、その分、動作も重くなります。
ということで、Scratchの学習が進んで実力に自信がついて来たら、プロジェクトの早い段階から後者の方法でプログラムを作成していくのが、後々で修正を頑張るよりも、スマートな方法かと思います。
ということでこの記事では、
「できるだけ敵は1つのスプライトにまとめる」 ようにして、ブロックコードを組み立てていきます。
この手のScratchプログラミングで、もう何回も紹介してきましたが、以下の記事で説明する「ローカル変数でクローンに識別番号をつける」テクニックは、必ず理解されておくことをおすすめします。

合同会社タコスキングダム|蛸壺の技術ブログ
【Scratch入門〜中級編】少しだけ難しいスプライトのクローンの高度な利用法

Scratchの中級者向けのテクニックとして、クローンの特殊な使い方を解説します。




ではまず、プログラム全体から敵を番号で配置できるようにグローバル変数・
敵の種類 を作成しておきましょう。

合同会社タコスキングダム|蛸壺の技術ブログ


敵のスプライトへコーディング作業に移り、ローカル変数・
敵の種類_ を追加します。

合同会社タコスキングダム|蛸壺の技術ブログ


これらの変数を使って、敵のスプライトの初期化の部分で、敵の種類を指定できるように以下の修正を加えます。

合同会社タコスキングダム|蛸壺の技術ブログ


これで、ゲーム中の処理から、自由に
敵の種類 の値を書き換えることで、敵のスプライトに様々な変化を与えることができます。
初期値として、これまでの敵(とその敵の動き)を
敵の種類 = 0 と定義して、以降の内容では、追加したい敵や動きを増やすたびに 敵の種類 を1づつ足していきます。

進むスピードが変則的に変わるパターン



手始めに、ある一定の時間周期をつけて、動きが遅くなったり、速くなったりと、敵の動きが変則的になる効果を作ってみましょう。。
ここでは時間によって敵の動きのパターンを変えるのに、もっとも単純なやり方として、
「システム・タイマー変数」 を利用してみましょう。

合同会社タコスキングダム|蛸壺の技術ブログ



なお、タイマーの詳しい使い方は以前の記事で特集しましたので、そちらをご覧ください。

合同会社タコスキングダム|蛸壺の技術ブログ
【Scratch入門】タイマーの基本と使い方のポイント

Scratchプログラミングの「タイマー」の基本的な使い方を解説します。



シューティングゲーム内でのシステムタイマーは、他のスクリプトからも共通変数としても利用するため、基本としてリセットはゲーム開始の一回だけで、ゲーム中は
「読み取り専用」 で使います。
このシステムタイマーの値を使いながら、とりあえず敵の動きを速い・遅いの2つのモードで切り替えてみましょう。
なお、この新しく追加する敵の動きは、
敵の種類_ = 1 で識別することにします。
コードは以下のように修正します。

合同会社タコスキングダム|蛸壺の技術ブログ


①の箇所で、ゲームスタート時のシステムタイマーの値を一度だけリセットします。
②はとりあえず手動で
敵の種類 を1にしておきます。
③の部分がポイントで、敵のクローンが特定の種類(ここでは
敵の種類_ = 1 )であるときに、条件分岐から、それに対応した処理を選択できるようにしています。
ここではシステムタイマーの値を使って、敵の動きを遅く・速くを切り替える時に、
[タイマーを6で割った余り] という割り算の余りの値を使って、この値が3より小さければ敵の動きを遅く、3より小さけれ速くなるようにしています。
割り算の余りは、数学的に
『余剰(よじょう)』 といいますが、プログラミング言語で周期的に処理を行わせたい場合、余剰を使ったアルゴリズムも多いので、ここで良く覚えておかれると良いとおもいます。
これを実行してみると、ゲーム内の時間に合わせながら、画面上の全ての敵が足並みを揃えて、3秒毎に速いと遅い繰り返しながら攻撃してきます。

合同会社タコスキングダム|蛸壺の技術ブログ


やってみると分かりますが、全ての敵が一斉に同じ動きをするので、ゲームとしてはちょっと単調に思えます。
やはり敵がそれぞれバラバラに動いたほうが面白い感じもしますので、もうひと頑張りして、コードを修正してみましょう。
敵のクローンを作成する際に、システムタイマーの時間をローカル変数・
敵の時間_ として、クローンそれぞれに記録しておけるようにします。

合同会社タコスキングダム|蛸壺の技術ブログ



あとはクローンの処理ループの中で、システムタイマーの値から、クローンごとに記録してある
敵の時間_ を引き算した値を使って、先程と同じような条件分岐で、動きを切り替えてみましょう。
コードは以下のように修正します。

合同会社タコスキングダム|蛸壺の技術ブログ


①の箇所で、ローカル変数・
敵の時間_ にシステム時間を記録させることで、その後のクローンを生成するときに 敵の時間_ の値をそれぞれのクローンに渡すことができます。
②の中で、
[タイマー] - [敵の時間_] という値が、 「クローンが生成してからの経過時刻」 とみることができます。
この経過時間を割り算させてから、その余剰を使って動きを切り替えることで、各敵が一体一体、別の動きで緩急が付いていることが確認できると思います。

合同会社タコスキングダム|蛸壺の技術ブログ


この場合、敵の動きはゲームのシステム時刻とは関係がなくなるので、各敵の動きのパターンは全く同じになります。


波状に進んでくるパターン



今度は敵の動きが蛇行して攻撃してくるように、スプライトのブロックコードを修正していきましょう。
蛇行を座標として表現するには、
「三角関数」 を使うのが一番手っ取り早いです。
三角関数の中でも初期値がゼロであるサイン関数(sin)がこの場合利用しやすいので、以下のように敵のスプライトのブロックコードを変えます。
ただし、数学で三角関数を学校で真面目に学ぶのは、「高校1年」からということなので、小学生・中学生の方がサイン関数の考え方を理解するのは、大変かも知れません。
イメージだけの話ですが、以下の図のように、高さが
-1から1 というヘンテコな真ん丸の山を登山する人を考えた時に、スタートする場所を0、ゴールを360として、この山をぐるりと一周して登るときの山の高さが、サイン関数というものになります。

合同会社タコスキングダム|蛸壺の技術ブログ


今の時点であまり深くは考えずに、
「0と360の間の数を入れると、-1から1の間の数に変えてくれるブロック」 くらいに思っておきましょう。
新しく追加する敵の動きを
敵の種類 = 2 としてみます。

合同会社タコスキングダム|蛸壺の技術ブログ


まずは①の箇所で、手動で
敵の種類 を2にしています。
敵を波状に動かすアルゴリズムは、②のブロックの中の計算が重要になってきます。
順に説明すると、

            1. [タイマー] - [敵の時間_] を計算して、敵の経過時間を計算する
2. その1で計算した値を、[2で割ったを余り]から余剰を計算する
3. その2で計算した値から、2で割り算し、余りを0から1の間の数にする
4. その3で計算した値に、360をかける
5. その4で計算した値を使って、サインで計算する
6. その5で得たsinの値(-1から1)を、増幅するために5をかけて、-5から5にする

        

という計算を行っています。
この場合、y座標の増加分が、-5から5の値の間を2秒間かけてぐるりと一周するので、上下に波状の動きとして敵が動くことになります。
これで、ゲームを実行してみると、敵が蛇行しながら攻めてくるようになりました。

合同会社タコスキングダム|蛸壺の技術ブログ

プレーヤーを見つけて飛んでくるパターン



先ほどまでの敵に動きとは対照的に、敵が画面に現れたタイミングで、現在のプレーヤーの方へ一直線に飛んでくる効果もやってみます。
これを行うためには、敵をクローンする直前で、プレイヤーへ向かう方向を更新し、その向きへ移動するようにxとyの増分を計算させる必要があります。
このような座標の初期計算をScratchプログラミングで行うと、以下のようになるでしょう。

合同会社タコスキングダム|蛸壺の技術ブログ


①の箇所で、この動くを
敵の種類 = 3 としています。
②の箇所で、敵のスプライトが、特定のスプライトの方向への角度を計算してくれるブロック・
[●●]へ向ける を利用します。
敵のスプライトとプレイヤーのスプライトの現在の位置関係を調べるために、これまでクローンの処理コード内にあった、
[x座標を220、y座標を-130から130までの乱数にする] というブロックを、 スプライト1へ向ける の直前に移動させます。
これで、常に敵とプレイヤーとの向きの情報が適切に更新されるようになります。
この敵とプレイヤーとの向きの値は、
向き という値のブロックで取り出すことができます。
③の箇所では、敵がプレーヤーに近づくためのxとyの増分を計算しています。
x座標の増分に
[向き]のsin 、y座標の増分に [向き]のcos の値を割り振ることで、一定の速度で敵がプレーヤーに近づくようになります。
ちなみに、これらの値に5をかけているのは、近づくスピードを調整しています。 このかける値が小さければ遅く、大きければ速く動きます。
これで、プログラムを走らせると、最初にプレーヤーを見つけて一目散に飛んでくるような敵の動きを作ることができます。

合同会社タコスキングダム|蛸壺の技術ブログ


さらなる応用として、敵をクローンして生成するときの初期化のときだけでなく、プレーヤーと敵の方向を頻繁に更新させることで、常にプレーヤーの方向目指して進んでくるような敵も作ることが可能です。
このような敵は、執拗に追いかけてくるため、シューティングゲームでの敵の中でもかなり強力な敵に使えるアルゴリズムといえます。
ここではコードの実装まで具体的に紹介せず、「宿題」として残しておきます。
余裕があればご自身で、その答えを導きだしてみてください。


合同会社タコスキングダム|蛸壺の技術ブログ【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ

弾を打ってくる敵を作る



シューティングゲームでは、フィールドに固定されて、弾をプレーヤーに向かって飛ばしてくるタイプの定番の敵が存在します。
先ほどのプレーヤーを目がけて飛んでくる敵のスプライトの延長で、敵の弾というスプライトをScratchプロジェクトに追加してみましょう。

合同会社タコスキングダム|蛸壺の技術ブログ


ここでは適当に、敵の弾として
Basketball のサンプルのスプライトを追加して使います。
ではこの敵の弾のスプライトに以下のようなブロックコードになるように、
Basketball のスプライトに以下のコードを編集します。

合同会社タコスキングダム|蛸壺の技術ブログ


先程の解説していたプレーヤーをめがけて迫ってくる敵と、基本的には同じアルゴリズムになっています。
ただし、敵の撃ち出す弾の処理で、重要なポイントになるのは、図中の赤枠で囲った
x座標を[敵の弾のx座標]、y座標を[敵の弾のy座標]にする というブロックの存在です。
話は前後しますが、
「敵から発射させる敵」 という処理を可能にするために、2つのグローバル変数・ [敵の弾のx座標][敵の弾のy座標] を値を利用する必要があります。

合同会社タコスキングダム|蛸壺の技術ブログ


弾を発射する敵も“クローン”ですので、そこから弾の“クローン”を生成をするということは、
「あるスプライトのクローンから、別のスプライトのクローンを作る」 ということになります。
この処理はScratchの処理の中でも、難易度の高いテクニックの一つで、良くクローンのことを理解していないと使うことができません。
2つのグローバル変数が必要な理由は、
「クローンの座標は、そのクローンの処理コードの中でしか使うことができない」 ので、弾を発射させたいクローンの座標を一時的にグローバル変数に記録させて、別のスプライトのクローンへその値を渡すためです。
と言うことで、弾を撃ってくる敵の動きのパターンを
敵の種類 = 4 として、敵のコード側を以下の図の赤枠のように修正します。

合同会社タコスキングダム|蛸壺の技術ブログ


ここでは弾を撃ってくる敵の動きは、一定速(x座標の増分を-3)で左に流れてくる単調な動きにしておきます。
この敵は2秒間隔で、弾を撃ってくるように、クローンのローカルタイマーが2秒経過するごとに処理させるような、条件ブロックを用意しています。
敵からは、
[Basketball]のクローンを作る ブロックを呼び出すことで、弾を撃つ処理が実行されるのですが、弾を撃つ直前に、このクローンの現在のx座標とy座標を、グローバル変数の [敵の弾のx座標][敵の弾のy座標] へ値をコピーすることで、撃ち出す弾の初期位置が敵の弾のクローンへ正しく設定することができます。
これでようやくプログラムを実行すると、一定時間で、弾をプレーヤーに発射してくる敵が完成します。

合同会社タコスキングダム|蛸壺の技術ブログ


こうなると、常に敵から狙われるので、プレーヤーも逃げ回らなければ、すぐさまゲームオーバーになるほど厄介な敵になるでしょう。


合同会社タコスキングダム|蛸壺の技術ブログ【Pschool厳選】Scratchをしっかり学ぶためのオススメ書籍まとめ

まとめ



以上、今回のScratchシューティングゲームの改造内容をひとまとめにしたものは以下のようになります。



いろんなタイプの敵がいると、とても面白い作品になります。
敵の動きや特徴をアルゴリズム化して、ブロックコードで表現できるような力は、Scratchのみならず、他のプログラミング言語のソフトウェア開発においても、最も求められている力になると思います。
是非とも、面白いオリジナル効果を考えてみて、いい感じのものが出来たら、Scratchプロジェクトで公開してみましょう。