スクラッチでマリオのゲームを作る特大レッスン#12 リスポーンさせる

スクラッチでマリオのゲームを作る特大レッスン#12 リスポーンさせる
ok-scratch
敵モブがスタックしたらリスポーンさせる手順がわかります!
難しさ

任意)自分の作業中のスクラッチ作品URLを記録しておこう!再開するときに便利だよ。

LOADING...

※ この記録は今使ってるPCに保存されます。別のPCで作業するときは表示されません。

スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。

このスクラッチゲームの作り方への質問もOK このスクラッチゲームの作り方への質問もOK
このスクラッチゲームの作り方に挑戦していて分からないことが発生したら質問してみてね。気づいたタイミングで回答するよ。 質問は 僕のスクラッチのプロフィール で受け付けているよ。

質問テンプレート(素早く3回クリックすると全選択できるのでコピーしよう)

・◯◯ ... 記事のどこまで実装が終わったのかを記入しよう。
・□□ ... どんな問題が起きているのか、どういうときに起きるのか、具体的に書こう。
・共有済みURL ... たまに共有してない作品URLを書いてる人がいるけど、共有しないとこちらから確認できないからよろしくね。

敵がシーンや壁に埋もれてしまうことが確認できています。これを回避するには2通りの方法があります。

1つはリスポーンで、もう1つは埋もれを修正する方法です。

今回は両方とも実装します。

まず埋もれを修正にトライして、それでもダメならリスポーンするという流れです。

一番最初に作る処理は、そもそも埋もれているのかどうかを判定するロジックです。

見ていきましょう!

ok-scratch ok-scratch

今回の埋もれ修正のロジックは、最初ちょっとバグがあったのですが、MeIonbreadさんのご報告と協力で解決しました。記事内容は修正済みです。MeIonbreadさん、ありがとうございます。

敵モブをスタック回避させる

スタックするというのは動けなくなるとか固まるという意味です。現状では敵モブがシーンに埋もれて動けなくなるバグがあります。

今回はここにタックルしていきます。

リスポーンする

まずはシーンに埋もれた時のレスキューとして、最初にスポーンした場所に戻してしまうという方法を実装します。

変数「リスポーンタイマー」を作る

埋もれたらすぐにリスポーンさせるのでは、しょっちゅう敵がリスポーンしてしまい、ゲームが難しくなってしまいます。

そこでリスポーンタイマーという変数を作って、何秒か埋もれた状態が続いていた場合だけリスポーンさせるようにしたいと思います。

ブロック定義「リスポーンする」を作る

オプションにチェックを入れます。

右に1座標ズラして障害物に触れているか調べる

すぐに座標を戻す
障害物に触れていなければタイマーをリセットする

終わるときはリスポーンタイマーをゼロに戻します。

まだリスポーンタイマーに値を設定する前なので分かりにくいですが、このあとすぐにリスポーンタイマーに値を入れるので、とりあえず処理を止めるときにゼロに戻すという処理を入れておいてください。

処理を止める

障害物に触れていなかったので、リスポーンの必要性はありません。この場合はこれで終わりです。

同じことを左でも繰り返す

座標がプラマイ逆になっただけで、まったく同じ処理です。冗長ですが分かりやすいのでOKです。

左右が障害物に触れていた場合を作る

左右が何かに挟まった状態であると解釈して、タイマーをセットします。このタイマーで一定時間経過したらリスポーンの必要があります。

タイマーという値はブロックパレットの「調べる」にあります。

タイマーをセットしたらいったん処理を止めてOKです。

また、スクショではログを書いておきました。なぜタイマーをセットするのか、その理由を書いておきました。

一定時間たったか様子見をする

タイマーをセットした後もなおスタック状態が続いているかを調べます。

ステップ1

タイマーからリスポーンタイマーの値を引いています。

数字で解説します。

タイマーには現在時刻が入っています。

リスポーンタイマーには一瞬前の時刻が入っています。

そして、今の時間から一瞬前の時間を引くと「何秒経ったか」という差分が分かるのです。

ステップ2

差分が3秒よりも大きいかどうかを判断する式です。

3秒はこの段階では適当です。おそらく0.6秒くらいがいいかなと思います。

ステップ3

条件分岐ブロックを追加します。

またログを書いておきました。

このブロック定義は、各条件がNOであるとスクリプトを止める構造なので、ブツブツ切れているような作りになっています。こういう構造はログがないと分かりづらいので、こまめにログを書いてあります。

リスポーン処理をする

これがリスポーンの本質的な処理です。変数「初期化済みかどうか」を1から0に戻してから自分のクローンを作り、自分自身は消しています。

こうするとまた最初のスタンバイ状態に戻ります。

ok-scratch ok-scratch

おっと、0ではなく定数「■いいえ(NO)」を使うべきでしたね。

ブロック定義全体を確認する

動作確認する

埋もれを修正する

リスポーンに成功しました。しかし、スタックしたらリスポーンではなく、まずは埋もれた状態を改善できないかどうかを試みたいと思います。

プレイヤーのときに埋もれてしまったプレイヤーをレスキューするロジックを作りました。

https://scratch.coach/lesson/mario5-5/

敵モブでも同じように埋もれ修正を行います。それでもダメならリスポーンするという流れにします。

作戦としては、敵モブを上下左右に何座標か動かしてみて、一番近くのスペースを探します。そして見つかったスペースに敵モブをワープさせるという感じです。

まずはスペースを探すロジックを作ります。

ブロック定義「埋もれ修正する」を作る

オプションにチェックを入れます。

利用する
リスポーンの処理を整えておく

埋もれ修正後にリスポーンする部分を少し変更します。

ブロック定義「埋もれ修正する」の直後に、障害物に触れているかどうかを判定します。

触れていなければ埋もれ修正できたということです。

リスポーンタイマーをリセットしてスクリプトを止めます。

また、ログも修正してあります。

ログを追加する

リスポーンのところにもログを打っておくと分かりやすいです。

変数「埋もれ修正値」を作る

初期化する

30回繰り返す

30というのはまだ適当です。何座標まで埋もれ修正を試みるか、適切な数値は微調整しながら見つけてください。

あまり大きな数値にすると、埋もれ修正のレベルを逸脱してしまいます。微調整する際は、そのあたりのバランスを考えながら調整します。

埋もれ修正値を1ずつ増やす

XとYに埋もれを修正する

XとY両軸に2回ずつ埋もれ修正を試みます。2回というのは、プラス方向とマイナス方向の2回です。

つまりXの1回目は左、Xの2回目は右、Yの1回目は上、Yの2回目は下、という要領です。

X方向の埋もれ修正にトライする

まずはX方向、つまり横にずれたら脱出できないか試します。

X方向に敵モブをズラす

障害物に触れているか調べる

敵モブの位置を戻す

X軸の移動は「★カメラのX座標」と「スポーンするX座標」と「移動距離X」といった変数を駆使して行っているので、X座標を直接ずらしても解決になりません。

ではナゼ座標をズラしたかというと「現在地からズレたら埋もれが解決するのか」を知りたかったからです。

そのため、いったんこの段階でズラして分は戻しておきます。

障害物に触れていたか調べる

もう触れていなかったら埋もれを修正して終わり

埋もれから脱出できる座標が見つかったら、変数「移動距離X」に変数「埋もれ修正値」の値を追加して、脱出させます。

そしてこれ以上ループを繰り返す必要はないのでスクリプトを止めて終了です。

まだ触れていたら逆方向を調べる

まだ触れていたら、逆方向を調べる準備をします。

仮にX方向1回目のループなら、埋もれ修正値は1です。ここで「0 - 1 = -1」として次はマイナス1座標分X方向にズラす準備をします。

X方向2回目なら、「 0 - (-1) = 1 」となるのでプラス1に戻った状態でY方向のループに進みます。

Y方向の埋もれ修正にトライする

次は縦方向に脱出を試みます。

Y方向に敵モブをズラす

障害物に触れていたか調べる

もう触れていなかったら処理を止める

X座標のときは変数「移動距離X」への追加をする事情があったため、ズラした分を戻したり変数に加算したりしましたが、Y軸はシンプルなものです。

単純に見つけたスペースまでY座標をずらせばいいだけなので、単純にズラした分を元に戻さなければOKです。

まだ触れていたら逆方向を調べる

まだ埋もれていたら、Xのときと同じように、埋もれ修正値を反転し、ズラした座標も元に戻します。

そして逆方向を調べていきます。

X2回、Y2回のループが終わったら、今度は埋もれ修正値を1から2に変えて同じことを繰り返します。

これを合計30回繰り返すことで、上下左右に30座標までにスペースが見つかれば埋もれ修正します。

見つからなければリスポーンですね。

動作確認する

完成です!埋もれてもピョコっと上がってきます。ずっと埋もれてたらリスポーンしてくれます。

プレイヤーを微調整したら土台は完成!

長い道のりでした。

あとはちょっと微調整します。

そうしたらいったん完成です。

その後はマリオらしい敵モブを作ったり、コースを考えたり、ワクワクを盛り込みまくりましょう。

完成サンプルがあるよ
おつかれさま!今回のチュートリアルには完成サンプルがあるから、作ってて分からなくなったり、 動作確認をしたいときはチェックしてみてね。

スクラッチャーからのコメント

kirbyfan0515 kirbyfan0515 2024-07-27
質問失礼します。マリオ風のゲームを作ったのですが、突然フリーズしてしまうことがあります。敵モブのスタックが原因だと思うのですがよくわかりませんお力をお借りしてもらえればと思います。長文失礼しました。
ok-scratch ok-scratch 2024-07-29
@kirbyfan0515 なるほど、それは厄介ですね。これはどのチュートリアルになりますか?URLなど教えてもらえたらと。予想ですが、スタックを解消するロジックで無限ループが発生して処理が重たくなっているのかなぁ?とも。
ok-scratch ok-scratch 2024-07-29
@kirbyfan0515 おー、あのマリオチュートリアルは僕もバグ多かったから、分かりにくかったかもしれません。作品はこちらの作品ですか? https://scratch.mit.edu/projects/979814784/
kirbyfan0515 kirbyfan0515 2024-07-30
@ok-scratch はい、こちらで間違いないです
kirbyfan0515 kirbyfan0515 2024-07-30
@ok-scratch あとこれは関係ないんですがプロフィールにかいてあるタクテとはなんですか?
ok-scratch ok-scratch 2024-07-30
@kirbyfan0515 タクテ=TACT-AIM。今日の夜にこのページからみんなでタクテをプレイして遊ぶので時間合えば是非。 https://scratch.coach/2024/03/30/tact-aim/
MeIonbread MeIonbread 2022-12-06
おお! 水色のやつは治ってますけど おばけはバグ修正でyが上がりましたが垂れてるところがまだめり込んでます。
MeIonbread MeIonbread 2022-12-06
@MeIonbread 触れてるときにNew変数を使い+1ずつ変えますその分を繰り返しブロックでy+3&New変数−1                          ↑New変数=0まで繰り返す) これでどうでしょうか、、、
ok-scratch ok-scratch 2022-12-06
@MeIonbread スゴイ助かりました!教えていただいた方法とは最終的に変わりましたが、そこを起点にして発想を広げて直すことが出来ました。修正前後の違いも書いておきます!!ありがとうございますm(_ _)m
ok-scratch ok-scratch 2022-12-06
@ok-scratch ■修正前) 4方向に回転させてスペースを探して、スペースを見つけたら座標を修正していた。 →問題発生)この方法だと、縦と横のサイズが違うコスチュームの場合はバグる。なぜなら0度に向けた状態でY方向に1座標ズラしてスペースを見つけたら90度に戻してY座標にプラス1していたため。
ok-scratch ok-scratch 2022-12-06
@ok-scratch ■修正後) 4方向に回転するのをやめた。 方向は左右で固定したまま、Xに2回、Yに2回ずつ座標をずらしてスペースを見つけるようにした。
MeIonbread MeIonbread 2022-12-06
@ok-scratch 凄いです!こうやって解決方法を思いついて成功するなんて!良ければ...今僕が作ってるゲームの 問題点の解決する方法を教えていただきたいです!(_ _)青色のリンクわからないhttps://scratch.mit.edu/projects/630597540 ←ここ
ブクマよろしくお願いします! ブクマよろしくお願いします!
どんどん追記・更新していくので、ブックマークやシェアよろしくお願いします!

スクラッチゲーム攻略

スクラッチゲーム

    • 厳選されたスクラッチ人気作品リストがレビュー付きで楽しめます
      趣味に関するスクラッチ作品例
      勉強になるスクラッチ作品