スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。
準備
このレッスンは前回「スクラッチでマリオゲームの作り方#04 ゴールして次へ」の続きです。
「スクラッチでマリオ」シリーズの最終ゴールをチェック
最後までレッスンを進めるとこのようなマリオゲームの土台となるプロジェクトが完成する予定です。
当レッスンの完成品を確認する
スクラッチプロジェクトをコピーして保存する
ファイル>コピーを保存する、を選んでプロジェクト名を「マリオプロジェクト005 ブロック」としておきます。
コスチューム付きのスプライトをダウンロードする
今回はブロックのコスチュームを使うので、こちらのスプライトをダウンロードしてスクラッチエディタでアップロードしてください。
ブロックのコスチュームが用意されたスプライトなので、これをダウンロードせずに自作でブロックを描いてもOKです。スプライト名をブロックにするところだけお忘れなく。
ブロックの基本を作る
ブロックはマリオの特徴的な仕組みの1つですね。ブロックの仕様はゴールに似ているので、ゴールを作り終わったこのタイミングで取り組むのがベストでしょう。
仕様を確認する
ブロックの仕様は次のとおりです。
- プレイヤーが近づいたら表示されて、離れたら隠れます。
- ただし、ゴールと違って最終シーンにスポーンされるとは限りません。
- こちらが指定した場所にスポーンするようにします。
- また、プレイヤーが触れたときの挙動もゴールと異なります。
- マリオと同じように、下からジャンプしてブロックに触れると壊れるようにします。
- 上や横からブロックに触れても壊れません。
- また、プレイヤーはブロックに乗ることができます。
- 破壊不可能なブロックもあり、これを壊そうとするとバフンっと揺れます(謎い)
表示するところまでゴールと同じように作る
最初はゴールの動きとほとんど同じです。
旗が押されたとき
とりあえず旗を使って確認していきます。
変数「スポーンするシーンのX座標」を作る
ゴールでも作った変数です。
初期化する
ゼロに入れる式を作ります。とりあえず最終シーンにスポーンさせます。ゴールと全く同じです。
からの
からの
これでOK。あとでシーンの数については変更します。
変数「スポーンするX座標」を作る
初期化する
式は次の通りです。50のところは後々変えます。
Y座標を指定する
30くらいに出しておきます。
「ずっと」ループを置く
条件ブロックを置く
条件式を入れる
ここもゴールと同じく、スポーンするX座標をプレイヤー(カメラ)が通り過ぎたら、という条件式にします。
表示と非表示を切り替える
最初はブロックを隠しておいて、プレイヤーが近づいたら表示するようにします。
動作確認する
スポーンされましたか?
変数「スポーンするX座標」1030を、変数「★カメラのX座標」が過ぎたらブロックが表示されました。
うまくいかない場合は、ここまでの式が正しいか、大なり小なりの向きが合ってるか確かめてください。
カメラに合わせてブロックを動かす
プレイヤーが左右に動いたら、ブロックも合わせて動くようにしていきます。
変数「★画面右端のX座標」を作る
前回レッスンでマジックナンバーになってしまっていた画面右端を表す240ですが、このタイミングでしっかり変数化(定数化)しておきます。
でもスクラッチ3.0にはまだ定数という機能がないので、引き続き変数と呼びます。
初期化する
ステージで変数「★画面右端のX座標」を初期化しておきます。
X座標の調整ブロックを置く
式をつくる
からの
からの
これを
X座標の値にセットします。
動作確認する
これでプレイヤーに合わせてブロックが動くようになりました。ゴールの挙動と同じです。
通り過ぎても隠す
ゴールと違って、ブロックはプレイヤーがスルーしてしまうこともあります。その場合は、画面左端にずっと残ってしまうので、しっかり隠したいと思います。
変数「スポーンするシーンのX座標」を調整する
シーンの合計数ではなく、直接2と入れておきます。動作確認のために暫定的な数値にしておきます。
これで変なところにスポーンします。
そして通り過ぎても表示されてしまうことも確認できました。
これを隠したいわけです。
X座標が左端にいったら隠す
隠すための判定方法は色々考えられると思いますが、今回はブロックのX座標が−240(左端)を越えたら隠すようにします。
式にするとこのような感じです。
この式を「かつ」ブロックで既存式と組み合わせることで、表示と非表示を切り替えます。
また、「もし」ブロックを「もし〜でなければ〜」ブロックに置き換えて、隠すブロックを「でなければ」に移動してください。
ブロック定義「スポーンする」を作る
基本的な動きの締めとして、ブロック定義を作ります。
ブロックは1つではなく、たくさん配置されるはずです。
そのため、このタイミングでクローン化もしておきます。
オプションへのチェックもしておきます。
変数の初期化部分を移す
引数を割り当てる
変数「スポーンするY座標」を作る
初期化する
初期コスチュームを明示する
ブロック1に着替える処理を入れておきます。
クローンを作る
クローンされたときの処理にメイン処理を移す
Y座標に変数を割り当てる
適当に指定してあった30の代わりに変数を割り当てます。
動作確認する
旗が押されたときにブロック定義「スポーンする」を叩いて、うまくブロックが配置されるかチェックします。
すると変な子がいました。
これは何か予想がつきますか?
そう、これはスプライト本体です。
隠し忘れていました。
本体を隠す
これでOKです。
色々上手くいったと思いきや、レベル2でも同じ位置にブロックがスポーンしてしまいました。
レベルによってブロックの配置を変える
ブロックを消していませんから、レベル1でスポーンしたブロックはそのままレベル2でも表示されてしまっています。
レベルによってブロックの配置は変えたいので、改善していきます。
スポーン処理のタイミングを変える
旗が押されたときにスポーンするのではなく、メッセージ「レベルの初期化が終わりました」を受け取ったときにスポーン処理をするよう変更します。
本体を隠す処理はそのまま
レベルごとの条件分岐ブロックを追加する
ここは泥臭く「もし」ブロックでレベル1なら、レベル2なら……と指定する方法がもっともシンプルです。
メッセージ「ゴールしました」を受け取りクローンを消す
これでレベルごとにブロックは刷新されます。古いものは消され、新しい配置が行われます。
レベル2のブロックも配置する
すべてうまく行ったか試すために、レベル2のブロックも適当でいいので配置してみてください。
動作確認もして、ブロックがレベル1とは違う場所に出ていることをチェックします。
ブロックを壊す
基本的な動作はこれでOKです。ここからはブロックを破壊する機能にタックルしていきます。
現状ではプレイヤーとブロックが接触しても何も起きません。
当たり判定を作る
まずはカンタンな当たり判定を実装してみてスタートとします。
これでブロックに触れると色が変わることを確認してください。ここから実装を始めます。
確認できるなら色じゃなくても何でもOKです。
ブロック定義「壊れたか調べる」を作る
ブロック定義の中身を作る
今しがた作った「プレイヤーに触れたら〜」の処理をブロック定義に移動します。
変数「壊れたかどうか」を作る
プレイヤーが触れたら変数「壊れたかどうか」を1にする
色をつけるブロックは消してOKです。
クローンされたときの処理に条件文を追加する
これで動作を確認してください。ブロックにプレイヤーが触れたら「壊れた!」と言うはずです。
ただ、これだとプレイヤーがブロックのどこに触れても「壊れた!」と言います。
当たり判定用のコスチュームを作る
ジャンプで下から当たったときだけ壊れるようにしていきます。そのため、ブロックの「弱点」をコスチュームで決めます。
- ブロック1のコスチュームを複製します
- 色は適当でいいので、ブロックの下部に四角を作ります。少し両サイドを空けておきます。
- ブロックの部分は不要なので消します
- コスチューム名を「ブロック_弱点」に変更します
当たり判定の前後でコスチュームを変える
最初に今作った「ブロック_弱点」に着替えます。そして処理の最後にコスチュームをもとに戻します。
いまはブロック1で固定なので、そのまま指定すればOKです。
動作確認する
動作を確認したいのですが、今はプレイヤーがブロックをすり抜けてしまうので、しっかり確認できません。
ブロック定義「壊れたか調べる」のチェックは後回しにして、まずプレイヤーとブロックが接触するロジックに取り組みます。
プレイヤーのブロック定義「シーンに触れているか調べる」を変える
「または」ブロックを使って、シーンかブロックに触れたらTRUEにします。
これはプレイヤーのスプライトです
名称も変える
シーンに触れているか調べるという名称を「障害物に触れているか調べる」に変えます。
変数「シーンに触れているかどうか」の名称も変える
変数も「障害物に触れているかどうか」に変えます。
動作確認する
ブロックに乗れるようになりました。ジャンプ力が足りずに乗れない場合は、いったんマウスを使ってプレイヤーを掴んで乗せても良いでしょう。
乗ってもブロックの弱点には触れていないので、壊れることはありません。
一方、下からジャンプしてブロックの弱点に触れると「壊れた!」というデバッグ用のセリフが出ます。ブロックに関しては意図した通りの振る舞いですね。
ブロックが壊れる振る舞いを作り込む
そろそろ「壊れた!」と言わせるのを止めて、壊れる振る舞いを作り込みます。またブロックのスプライトを選択しておいてください。
音を鳴らす
壊れるときの音を決めて鳴らします。ここではCrunchという音を選びました。クランチは噛み砕くという意味ですが、なんとなくブロックが壊れる感があったので選びました。
他の音でも、もちろんいいですよ。
「○と言う」ブロックを外して「音を鳴らす」ブロックを入れました。
コスチュームを変えるループを置く
壊れる動作のコスチュームは5個あるので、「5回繰り返す」ループを置いてください。
壊れながらフェードアウトする
ブロックのコスチュームが変わるごとに、徐々にブロックが崩壊していきます。それに合わせて幽霊効果を高くしていき、徐々に透明化します。
最終的には5 * 20 = 100となり、完全に透明になります。これに音が合わさり、ブロックが壊れた感を演出します。
クローンを削除する
透明にするだけではなく、最後にクローンを消して本当に消滅させることで終了です。
動作確認する
ブロックが意図したとおりに壊れてフェードアウトしていくか確かめてください。
プレイヤーの頭が当たった振る舞いを作る
ブロックの壊れた感は演出できましたが、現状ではプレイヤーがブロックを突き抜けてジャンプしてしまいます。
頭が当たったときは、バウンドするように落下したほうが自然に思います。
コスチューム「当たり判定エリア上」を作る
- 「当たり判定エリア下」を複製します
- 目安として歩く1のネコを配置します
- 頭に隠れる程度の位置に四角を描きます。色にはこだわりません。
- コスチューム名を「当たり判定エリア上」に変えます
- 最後にネコは消してOKです
ブロック定義「Y軸に移動する」を変える
今は当たり判定エリア下のみチェックしているので、当たり判定エリア上でもチェックするように変えていきます。
コスチュームを変えるブロックを移す
ループの外でコスチュームを変えていましたが、ループ内で変えるようにブロックを移動します。
移動前
移動後
コスチューム変更から下を複製する
ごっそりコピーします。
当たり判定エリア上に着替える
上のスクショでは、「コスチュームを当たり判定エリア上にする」ようにしてあるので、みなさんも変えておいてください。
ログも変える
ログも「上が触れました」に変えておくと分かりやすいです。
落下させる
プレイヤーが上昇中に頭が当たったら落下処理を始めてほしいです。
コスチューム「当たり判定エリア上」の状態で障害物に触れたとき、変数「スピードY」の値がプラスであれば、上昇中に頭が当たったとします。そしてこのタイミングで滞空時間にプラスの値を入れます。数値は大きめに99を入れておきます。
また変数「スピードY」の値をゼロにしておきます。上に向かう力であるスピードYをゼロにすることで、これ以上プレイヤーが上昇することはなくなります。
上昇する力がゼロで、空中にいることを示す滞空時間にプラスの値が格納されているため、常に重力の影響を受けているプレイヤーは落下を始めます。
バウンドさせる
ただ落下するのではなく、ブロックに当たって跳ね返るようにバウンドして落下させたいので、Y座標をガクッと減らします。
どのくらい減らすかはお好みでOKです。
動作確認する
ブロックに当たるとプレイヤーの上昇が止まり、かつ下に10座標分ガクッと下がるので、バウンドしているように見えます。
これでプレイヤー側もブロックに当たった感の演出ができました。
ブロックをリファクタリングする
破壊不可能なブロックを作り込む前に、少しだけリファクタリング(改善)しておきます。
ブロック定義「表示・非表示を切り替える」を作る
表示と隠すブロックの処理をブロック定義にまとめておきます。
移動前
移動後
ブロック定義「壊れる」を作る
壊れる処理もブロック定義にまとめます。
移動前
移動後
壊せないブロックを作る
破壊可能なブロックばかりだと、単なる足場として置いておきたいブロックなども壊れてしまい、ゲームが進めなくなってしまいます。
そこで、破壊可能なブロックと破壊不可能なブロックの両方を作れるようにしていきます。
ここでは変数「破壊可能かどうか」というフラグ変数を使う作戦で行きます。
ブロック定義「スポーンする」を編集する
もともと作ってあるブロック定義「スポーンする」を右クリックして編集します。ラベルと引数を下図のように追加します。
変数「破壊可能かどうか」を作る
初期化する
破壊可能なときだけ壊れるようにする
壊れたか調べる処理に、変数「破壊可能かどうか」を使った条件分岐を追加します。
これで破壊可能ではないブロックは、そもそもブロック定義「壊れたか調べる」が無効になります。
ブロック定義「スポーンする」の引数を指定する
ブロックをスポーンさせるところで、各ブロックに0か1の値を入れておきます。
- 0なら壊れません
- 1なら壊れます
動作確認する
破壊不可能なブロックにジャンプで当たっても何も起きません。これで正しいのですが、なんだか分かりづらいという印象を受けました。
破壊不可能エフェクトを作る
マリオのゲームでは破壊不可能なブロックを壊そうとすると、バフンっと揺れるようなエフェクトが起きて「あ、これは壊せないのね」と直感的に分かります。
ここでもそういった動きを実現したいと思います。
これにはブロック定義「壊れたか調べる」を使います。この中身を少々複雑に変更するので、作り直すような手順で解説します。
「もし〜でなければ」ブロックを置く
まずこういう条件分岐を作ります。
コスチューム「ブロック_弱点」を付ける
破壊可能な場合にプレイヤーに触れた際のブロックを追加する
すいません、ここ間違ってます。あとで気づきます。もう少し読みすすめていただくと修正する作業があります。いったんこのようにしておいてください。m(_ _)m
最後にコスチュームを戻す
これで現状の「壊れたか調べる」と同じ処理ができました。次に「でなければ」の中身を作ります。
コスチュームを戻すブロックを追加する
Y座標をずらす処理を作る
バフンっというエフェクトを表す処理を作ります。とりあえずY座標を1ずつ合計3ずらして戻すブロックを作ります。
合体させる
動作確認する
すると上手くいき……ませんでした。
すいません、間違いに気づきました。みなさんは何が間違っていたか気づきましたか?なんて問題みたいに言ってますが、普通に凡ミスです……m(_ _)m
修正する
「プレイヤーに触れたら」という条件分岐を一番外側に配置して、コスチュームを戻すブロックも外側に移動します。
分かりづらいと思いますので、修正作業を動画にしておきました。
動作確認する
今度こそブロックを壊そうと飛びつくとバフンっと上下にブロックが動き、壊れませんよアピールをします。
成功です。
しかし、横に歩きながら壊そうとしてみてください。カクカクしてしまいます。上下に動く部分はそのままですが、横に瞬間移動するようにカクカクっと動いてしまうのです。
これはカメラが移動している処理に関連しています。
また、もうちょっとバフン感を修正したいです。縦に3は大きすぎたので1か2に直します。
破壊不可能エフェクトを修正する
X方向にカクカクしてしまう原因は、カメラが動いているのにブロックがY座標にのみ動いているため、カメラに付いてこれてない瞬間があるからです。
そこで、XもYも同時に動くようブロックを変更します。
X座標にはカメラの動きに合わせて動く演算を入れます。これはすでに作った演算をコピペするとよいでしょう。
そしてY座標にはとりあえず「Y座標 + 1」を入れておきます。
マイナスの挙動も作る
ブロック定義「位置を調整する」を作る
カメラに合わせて動かす処理は、3箇所に散らばっています。ほとんど同じ処理なので一元管理しておきたいと思います。
3箇所というのは「クローンされたとき」に1箇所、「壊れたか調べる」に2箇所です。
実装する
引数を適用する
引数を適用します。
また、Y座標の部分を変数「スポーンするY座標」を利用することにしました。
ブロック定義「壊れたか調べる」内を置き換える
バフンっ感ですが、結局2回繰り返すくらいがちょうどいいかなと感じました。これもお好みでOKです。
「クローンされたとき」内を置き換える
XとYには0を入れておいてもOKです。
動作確認する
どうでしょうか。納得のいくバフンっ感がでました。
この段階のメッセージ関係図
メッセージ関係図も更新しておきました。今はこんな感じです。
メッセージ関係図の描き方はこちら↓です!
コインをゲットせよ
ブロックを壊せるようになりました。しかし、何か足りませんね。そうです、マリオではブロックを壊したら中からコインが出たり、キノコがでてきたりしますよね。
スクラッチ版マリオでも、コインをゲットできるようにします。
数日以内に更新します!ブックマークよろしくお願いします♪
そのまえにバグ修正のレッスンを更新しましたm(_ _)m
- ① 横スクロールを制覇せよ
- ② ジャンプせよ
- ③ 壁・坂を攻略せよ
- ④ ゴールして次へ
- ⑤ ブロックを壊せ (いまここ)
- ⑥ スタックを回避せよ (バグ修正の回)
- ⑦ コインをゲットせよ
- ⑧ 敵モブを召喚せよ1 (クローン化、スポーン、横移動など)
- ⑨ 敵モブを召喚せよ2 (方向転換や重力)
- ⑩ 敵モブを召喚せよ3 (アニメーション)
- ⑪ バトル開始1 (ダメージを受ける・与える)
- ⑫ バトル開始2 (ダメージのアニメーション、フィードバック)
- ⑬ 敵モブをリスポーンさせる
- ⑭ iPadに対応する
- ⑮ 迫りくるパタパタ (敵モブに新しい動きを追加する手順が分かる)
- ⑯ パタパタのバグ修正 (ジャンプのバグを直す)
- ⑰ 壁に埋もれるバグ修正 (バグがバグを呼ぶ、でも諦めない)