前回までの記事でアクションゲームにおける背景スクロールや登場キャラクターのアクションとアニメーションをつくってゲームの基本的な骨格ができたので、これ以降は思いついたテーマごとに記事を書いていこうと思います。
無料素材の中にちょうどカメと甲羅(こうら)のキャラクター画像があったので、今回はそれを使ってスーパーマリオ風にカメを踏んづけて、甲羅になったカメを蹴っ飛ばすアクションとアニメーションのプログラムをつくっていきます。
この記事を読んでいただくと、アクションゲームでスーパーマリオ風にカメを踏んづけて甲羅を蹴るプログラミングの方法が分かります。
なお、記事中に主人公がジャンプしたり地面やブロックに着地したり、ブロックに横から当たると跳ね返される動き(プログラムを組み込んでいる箇所)がありますが、これらは以前の記事で説明済みなのでこの記事では詳しく触れません。代わりに過去記事へのリンクを随時貼り付けたりしますので詳しくはそちらを参照してください。
また、この記事で使用しているスプライト(キャラクター・背景・オブジェクト・音声など)はすべてパブリックドメインの無料の素材をダウンロードして使用しています。
完成品
この章の内容をご自身のScratch環境に反映すれば、同じ動きを再現することができます。
完成した動き
メインキャラクター(主人公)がジャンプして、上からカメを踏むとカメは甲羅に隠れてしまい、素早い動きに切り替わります。
ブロックにぶつかると跳ね返されて反対方向に向きを変えて動き続けます。
カメが甲羅の状態で動いているところを上から踏むと動きを止めます。再度踏むと再び素早く動き出します。
また、動きを止めた状態で横から甲羅をつつくと、甲羅は主人公が向いている方向に向きを変えて動き出します。
使用したスプライト
スプライトは「キャラ1」「地面1」「背景1」「天気1」「ブロック」「カメ」の6つです。
アクションゲーム用の背景・キャラクター・アイテム等の画像や音声は、パブリックドメインである「スーパーパワーアセットパック(CC0)のprehistoric-platformer」を使っています。
「キャラ1・地面1・背景1・天気1」スプライトについては、こちらの記事の「使用したスプライト」の章で詳しく説明していますので参照してください。↓↓↓
【Scratch 3.0】アクションゲーム ジャンプと地面にめり込まないように着地する方法(Tips)
「ブロック」スプライトについてはこちら↓↓↓
【Scratch 3.0】アクションゲーム ブロックで足場や壁の作り方【当たり判定の方法】(Tips)
【カメのスプライト】
「カメ」スプライトは、スーパーパワーアセットパックの「prehistoric-platformer\monsters」フォルダ内にある「turtle-1.png」ファイルを使用しています。
画像ファイル「turtle-1.png」は、下の図のように縦4行×横6列のキャラクター画像の集まりになっているので等間隔で分割してからコスチュームにアップロードする必要があります。
分割するためには、Windowsであれば「PL_ImageConstructor」などのフリーソフトで可能です。
また、元の画像はすべて左向きでつくられています。Scratchは向きの初期値が90度なので、このままだと画像とプログラムが180度ずれた状態になってしまいます。
そのため、アップロードしたらコスチュームタブ内の操作ですべての画像(コスチューム)を右向き(90度の向き)に方向を変えておく必要があります。
分割した画像を下の図のようにそれぞれの動作パターンごとにグルーピングして、別々の定義ブロックにまとめます(「歩く」定義ブロックなど)。
ただし、実際に使うときにはプログラムを組んで動きを確かめてから調整(待ち時間・コスチュームの増減)するようにします。
また、甲羅の画像は別にあって「prehistoric-platformer\items」フォルダ内にある「18.png」ファイルを使用しています。このファイルをコスチュームにそのままアップロードします。
完成したスクリプト
完成したスクリプトの全体です。
今回のテーマの内容(カメに関する動き)に絞るため、すべてのスプライトのスクリプトから以前の記事で説明した背景スクロールや一部の当たり判定など、今回の説明に必須でないブロックは削除しています。
【キャラ1のスクリプト】
今回のテーマである「カメを踏む・蹴る」ために追加したブロックに赤枠をつけています。
赤枠以外の部分のスクリプトについては、以前に説明済みの内容ですのでこちらの記事でご確認ください。
- ジャンプ力:このスプライトのみ
- 地面に触れた:このスプライトのみ
- 側面がブロックに触れた:このスプライトのみ
- コスチューム保存用:このスプライトのみ
- ステータス:このスプライトのみ
【地面1のスクリプト】
【背景1のスクリプト】
【天気1のスクリプト】
【ブロックのスクリプト】
【カメのスクリプト】
下図で使用している変数はすべて「このスプライトのみ」でつくっています。
- 側面がブロックに触れた:このスプライトのみ
- コスチューム保存用:このスプライトのみ
- 踏まれた:このスプライトのみ
- ステータス:このスプライトのみ
スクリプトの作り方
ここからはプログラムを作っていく中でポイントとなる部分を説明します。
今回のプログラムの主な仕様は、以下のようになっています。
- カメは左右に動き、ブロックで跳ね返って動き続ける
- カメは上から背中を踏まれると甲羅に閉じこもる
- 甲羅になると速く動く
- 甲羅は上から踏まれると動きを止める、もう1度踏まれると再び動き出す
- 止まっている甲羅は横からつつかれると主人公から遠ざかる方向へ向きを変えて動き出す
ポイント①:カメの当たり判定をつくる
当たり判定用のコスチューム
「カメ」スプライトの当たり判定のプログラムを組む前に当たり判定につかうコスチュームを準備します。
下の図のようにカメの頭部に「水色の四角形」を描いて追加します。これはブロックに当たったときの判定に使います。
かめの背中の部分に「ピンク色の四角形」を描いて追加します。これは上から踏まれたときの判定に使います。
コスチュームの名称は「当たり判定用」と分かりやすい名前を付けておきます。
ブロックにぶつかったときの当たり判定
まず「当たり判定」定義ブロック全体で共通しているのは、最初に直前のコスチューム名を「コスチューム保存用」変数に保存してから判定を開始するということです。
そして定義ブロックの最後で保存しておいたコスチューム名を呼び出して、当たり判定前のコスチュームに戻すようにしています。
本題の横(進行)方向の当たり判定ですが、下の図の「もし(水色が茶色に触れた)なら」で始まる条件文の箇所になっています。
水色は上で説明したカメの当たり判定用コスチュームに付け加えた四角形の水色で、茶色はブロックの縁(ふち)の色をスポイトで取得して設定しています。
この「もし~なら」の条件を満たした(ブロックに触れた)ら「側面がブロックに触れた」変数の値を1に、それ以外は0に設定します。(この値を使う場面はポイント②で説明します)
上から背中を踏まれたときの当たり判定
カメが踏まれたときの当たり判定ですが、下の図の「もし(ピンクが紫色に触れた)かつ(キャラ1のコスチューム名=”egg-shell_15”)なら」で始まる条件文の箇所になっています。
ピンク色は上で説明したカメの当たり判定用コスチュームに付け加えた四角形のピンク色で、紫色は主人公(キャラ1スプライト)の脚の付け根あたりの色をスポイトで取得して設定しています。
まあ今回の場合は、落下用のコスチュームが一意に決定されるのでここは「~色が~色に触れたら」ではなく単純に「キャラ1に触れたら」に変更しても良かったのですが、このコスチュームを準備していない場合に汎用性がなくなるのであえて色で判定するようにしています。
この「もし~なら」の条件を満たした(カメが踏まれた)ら「踏まれた」変数の値を1にします。
この変数を0に戻すスクリプトはどこにも作ってませんので、1度踏まれて甲羅になったら2度と元には戻らないことになります。
本家のスーパーマリオのように時間が経つと再びカメになって歩くようにしたい場合は、この変数を上手く使ってスクリプトを作れば実現できると思います。
つぎに「ステータス」変数の役割ですが、甲羅になったカメの動きを止めたり動かしたりをコントロールする変数です。
「ステータス」変数の値が0のときは1に変更し、1のときは0に変更し、と交互に値を切り替える変数です(0:ストップ、1:動き出す)。(実際のどのように使うかはポイント②で説明します)
ポイント②:カメの動きをつくる
ブロックにぶつかったとき
カメがブロックにぶつかったとき、「側面がブロックに触れた」変数が1になることはポイント①で説明しました。
そうすると「-1×(向き)度に向ける」ブロックが動き出します。これは向きを真逆(正反対)の方向へ変えるということになります(右なら左へ、左なら右へ)。
またブロックに触れてない(「側面がブロックに触れた」変数=0)ときは、「踏まれた」変数が0のときとそうでないときで条件が設定されています。
「踏まれた」変数が0のときはつまり、まだ1度も踏まれてないときなのでコスチュームはカメが歩いている状態です。このときは3歩ずつゆっくり動かしています。(「踏まれた」変数が1のときについては次で説明します)
歩いている状態のアニメーションは以下のブロックで実現しています。
上から背中を踏んづけられたとき
カメが背中を踏まれたとき、「踏まれた」変数が1になることはポイント①で説明しました。
そうすると次は「ステータス」変数の値が1かどうかをチェックしています。もし1なら「10歩ずつ動かす」ブロックが実行されるので速く動くようになります。
もし「ステータス」変数が0なら、動くブロックが何もないので『動かない=止まる』ということになります。
なお、このときも「もし(側面がブロックに触れた=1)なら」の条件はずっとチェックされているので、ブロックに触れたら跳ね返る動きはきちんと動作します。
踏まれたあとのコスチュームは下図のブロックで実現しています。アニメーションではなく「こうら」コスチューム固定になっています。
ポイント③:主人公がカメを踏んづけたときの当たり判定をつくる
主人公(「キャラ1」スプライト)がカメを踏んづけたときの当たり判定の条件は、以下の2つを設定します。
- カメに触れたかどうか
- コスチュームが「egg-shell_15」であるかどうか
この2つの条件を満たしたら「ステータス」変数の値を1に変更します。(この変数の使い方はあとで説明します)
この「ステータス」変数は「このスプライトのみ」で作成します。※「カメ」スプライトにも同じ名前で変数を作っていますがいずれも「このスプライトのみ」で作っているので、それぞれ別の変数という扱いになります。
コスチュームの「egg-shell_15」とは下の図のもので、ジャンプした後や高い所から落ちるときに使用しているコスチュームです。
そのため、主人公が(ジャンプした後か何かで)落ちる姿勢と取っている状態でカメに触れたら、踏んづけたと判定しています。
「かめを踏んづける」定義ブロックと「当たり判定」定義ブロックを並列に置いているのは、判定スピードが異なるためです。
「かめを踏んづける」定義ブロックの中身を「当たり判定」定義ブロックの中に入れると、プログラム的にはすっきりしたように見えますが、実際の動きでは反応が鈍かったりしますので得策ではありません。
ポイント④:主人公がカメを踏んづけたときの動きをつくる
ポイント③で説明した「ステータス」変数をつかってスプライトをコントロールしているのは1か所です。
下の図でいうと、「着地するまで」定義ブロックの中の「もし(ステータス=1)なら」の部分です。
この条件が成立してスクリプトが実行されると、「ジャンプ力」変数の値を5にし、「ステータス」変数の値を0にしています。
「ジャンプ力」変数を5にするのは小さくジャンプさせるため、「ステータス」変数を0に戻すのは次に踏まれたときに再びこのスクリプトを実行させるためです。
そして重要なのが「着地するまで」定義ブロックの部分です。
これは「着地するまで」定義ブロックの中に「着地するまで」定義ブロックが入っています。
このような形をしているプログラムを『再帰プログラム』といいます。(再帰=自分が自分自身を呼び出す)
再帰プログラムはちょっと分かりにくいですが、解釈の仕方は通常と変わらないので上から順に1つずつ読んでいけば大丈夫です。
カメを踏んで「ステータス」変数が1になったときに「着地するまで」定義ブロックが呼ばれています。
その直前では「ジャンプ力」変数=5、「ステータス」変数=0にしています。
これらの値を使って「着地するまで」定義ブロックを実行すれば良いのです。そうすると「もし(ステータス=1)なら」の部分は条件を満たさないので実行されませんね。
もし連続でカメを踏んづけたとしたら、「ステータス」変数は1になっているので「着地するまで」定義ブロックは何度でも呼び出されることになります。
ポイント⑤:主人公がカメを蹴ったときの当たり判定と動きをつくる
カメを横から蹴るときには、以下の3つの条件がそろったときに実行するようにしています。
- 主人公の進行方向の側面とカメが触れたかどうか
- カメが甲羅の状態かどうか
- カメが停止しているかどうか
判定条件1つ目の「主人公の進行方向の側面とカメが触れたかどうか」については、「キャラ1」スプライトにも判定用のコスチュームを用意していて、カメの当たり判定のときと同じようにコスチュームを切り替えて判定しています。
「キャラ1」スプライトの進行方向の側面には黄色の四角形が配置されているため、その色を使っています。
また、カメの甲羅の緑色は下の図のあたりの色をスポイトで取得しています。
キャラ1の当たり判定用のコスチュームは、こちらの記事で解説していますので参照してください。
判定条件2つ目の「カメが甲羅の状態かどうか」は、カメのコスチューム名が「こうら」になっているかどうかで判別しています。
3つ目の「カメが停止しているかどうか」は、「カメ」スプライトが持っている「ステータス」変数の値が0のときが止まっている状態でしたのでそれを使っています。
この3つの条件がいずれも成立すると、「かめの向き変更」メッセージを送ります。(これを受け取るのは「カメ」スプライトの方になります)
そして「カメ」スプライトの側では、以下のスクリプトが実行されます。
まず「キャラ1」スプライトと同じ方向に向きを変えます。つぎに「ステータス」変数の値を1に変更します。
こうすることで、甲羅の状態で動きを止めていたカメが、主人公が向いている方向にふたたび動き出す、という動きになります。
ここまでのポイントを押さえれば、アクションゲームでスーパーマリオ風にカメを踏んづけて甲羅を蹴るためのスクリプトを完成させることができると思います。
失敗しやすいポイント
カメのプログラムに下図左側の「かめアニメーションを受け取ったとき」で始まる2つのスクリプトがあります。
カメが踏まれたときに「歩く」アニメーションから「こうら」コスチュームに切り替わる部分ですね。
これは右のように簡単にまとめることができます。プログラムは出来るだけ重複がないようにシンプルにつくるのが基本の考え方なので、右のように修正して動かしてみましょう。
下のアニメーションを見ていただくと分かるかと思いますが、何度かに1回はカメを踏んだ瞬間に甲羅に切り替わらずにしばらく歩いてから甲羅になっている場面があると思います。
この理由は「歩く」定義ブロックは下図のようになっていて、「~秒待つ」ブロックが含まれていることによります。
たまたま「歩く」定義ブロックを実行中にカメを踏んだため、歩いている状態が終わるまで次の処理に移ることができないためです。
このように「~秒待つ」ブロックが含まれるスクリプトとそれ以外のスクリプトは相性が悪いので、適宜スクリプトを分けてつくる必要があります。
応用編
主人公がダメージを受けてやられる部分のプログラムを追加してみました。
前回『自分がダメージを受けた場合の当たり判定』の記事を書いていますのでその応用です。
まとめ
さいごに、今回の記事で説明した『アクションゲームでスーパーマリオ風にカメを踏んづけて甲羅を蹴るためのプログラミング』のポイントをまとめます。
- ポイント①:カメの当たり判定をつくる(当たり判定用コスチュームと判定条件)
- ポイント②:カメの動きをつくる(変数の値[0, 1]で動きをコントロール)
- ポイント③:主人公がカメを踏んづけたときの当たり判定をつくる
- ポイント④:主人公がカメを踏んづけたときの動きをつくる
- ポイント⑤:主人公がカメを蹴ったときの当たり判定と動きをつくる
今回はなかなか面白い動きができたのではないかと思います。
今回登場した再帰処理は、まったく同じ動きを違う条件で行いたいときに使うことができます。たとえば、今回のように同じジャンプだけど高さが違う(跳び箱の踏み台・トランポリン・etc…)とか、同じ円を描くけど半径が違うとか、覚えておくと色々と応用ができるようになると思います。
どうでしたか?上手く再現できたでしょうか?
他にも役に立つTips(ティップス)記事をたくさん書いてますので、ぜひ見てみてください。(記事のタイトルに「Tips」と書いていたり「Tips」タグを貼ってあります)