スクラッチでマリオ #16 - 恐怖、壁に引きずり込まれるホラーなバグ!

スクラッチでマリオ #16 - 恐怖、壁に引きずり込まれるホラーなバグ!
じゅうぞう
スクラッチでマリオを作ってたらバグが多かったので直してみた、という回です。こうやって洗練されていく……。
チャレンジ度

壁にめり込むバグをご報告いただきました!

ステージ2で少し先のゴーストをスタート付近におびき寄せて右に向いてダメージを受けると後ろの落ちないようの壁に当たり、地面にめり込むというあまり関係ないバグを見つけました。

sakiyomidaさん

バグ報告してくださったsakiyomidaさん、ありがとうございます。このバグはちょっと痛いので直そうと思います。

そして少し大きめなバグ修正になったので、チュートリアルまるまる1回分として記事化しました。

バグの確認

とりあえずどんなときにどんなバグが起きるのか見ておきます。

壁に追い込まれた状態で敵にぶつかると壁にめり込んでしまうのです……これはマズイ。

ブロック定義「スタックを回避する」を改修する

今回メインで直すのはブロック定義「スタックを回避する」です。

コスを変更する

横向きのスタックを回避したいので、コスを変更します。

ちょっと条件分岐が多いブロック定義なので挿入部分を間違わないように気をつけてください。

障害物に触れているかどうかを判定する

直前のX座標を控えておく

これからX座標を調整していくので、変更前のX座標をバックアップしておきます。

スプライトの大きさと同じ回数チェックする

スプライトが壁にまるまる埋もれてしまってもいいように、大きさの分だけチェックを繰り返すことにします。余裕をもたせたいならここにプラスしてもOK。

試しに逆進させる

向いてる方とは逆側に1座標ずつズラしていきます。

  • 数式を解説しますという口コミを寄せてくれた方 数式を解説します

    まず「向き / 向きの絶対値」を見てください。向きが90度(右向き)なら、90 ÷ 90 = 1となります。向きが-90度(左向き)なら、−90 ÷ 90 = -1になります。これをそのままX座標に加えても前進するだけなので、もっとめりこんでしまう。そこで「0 − 1 = -1」とか「0 - (-1) = 1」にして、値を反転させてます。

脱出できたら止める

X座標に補正値を加えたあとに改めて障害物に触れているか調べます。もう触れてなかったら脱出成功なので、処理を止めます。

脱出できなかった場合はX座標を戻す

  • なんで脱出できなかったって分かるの?という口コミを寄せてくれた方 なんで脱出できなかったって分かるの?

    もし脱出できていたら、「大きさ」回繰り返すループ内の「このスクリプトを止める」が動いて、今回置いた「X座標を直前のX座標にする」まで処理が届かないのです。

    つまり、ここまで処理が来てしまったということはイコール脱出できなかったということになります。

テストする

よぉしいい感じ、おわり、と思いきや別のバグが発生しています。

今度は自分から壁にグイグイ当たるように進んでみます。

すると……。

X座標がどんどんズレてしまって、そのうちプレイヤーがカメラから外れてしまうのです。これは良くないですね。

カメラとX座標の同期を改善しよう

このバグの根本的な原因は、X座標をズラしたのにカメラは動いてない、という点です。

今回はカメラをX軸に動かしているブロック定義「X軸に移動する」を改修することで対応していきたいと思います。

条件分岐を追加する

X座標がズレてない場合は今まで通りの処理を行えばOKなので、条件分岐で仕切ります。

今回ガッツリ処理を追加するのは「でなければ」の方です。

X座標を調整する

X座標が0ではないときだけ、X座標に補正値を加えます。

  • 逆進させていますという口コミを寄せてくれた方 逆進させています

    向きのときと同じですね。まず「X座標 ÷ X座標の絶対値」を見てみましょう。

    X座標がたとえばプラス5のときは画面の中央よりも右側にいます。なのでマイナス5を加えてX座標を0に戻したいですよね。そこで「5 ÷ 5 = 1」を反転させて「0 - 1 = - 1」としてからX座標に加えていきます。

    これで動くたびに1ずつX座標が補正されていきます。

テストする

(動画の下部にあるX座標に注目ぅ、画素が粗くてゴメンね)

壁に当たってX座標がズレても、同時に逆にも補正しているのでX座標が増えないようになりました。

これでバグ修正は終わり……じゃないんです😅

再びブロック定義「スタックを回避する」を改修する

今回の修正で、これまで隠れていたバグが浮き彫りになりました。よくある話です。

スライムが止まらないw

スライムってマジ進撃のスライムなんですよね……当たっても全然止まらない。将棋で言う香車きょうしゃみたいな敵モブなんです……。いや、香車は当たれば止まるか……スライム、厄介だぜ。

こうなる↓

ピューンって上にw

ブロック定義「スタックを回避する」でY座標を戻す

X座標は変数「直前のX座標」に値をバックアップしておいて、回避できなかったらX座標を元に戻してありました。

Y座標ではこれを行っていません。ちゃんとやります。

直前のY座標をバックアップする

回避できなかったらY座標を元に戻す

テストする

うん、上にピューンって行くバグは直った。もう問題ない。ないよね。うん、ないね。ははっ。え?なんかネコが壁にめり込んでないかって?オー、ワタシ、ニホンゴ、ワカラナーイ、ソーリーソーリーナイカクソーリー。

冗談はさておき、はい、またバグってますね。直します、直しますよぉ!バグめぇ!

再びブロック定義「X軸に移動する」を改修する

原因を明らかにしておきましょう。犯人は……ワタシだぁw

いや、バグを憎んで人を憎まず。誰が悪いとかじゃない。

次の動画を見てください↓

X座標とネコの動きが鍵です。

  • 何が起きてるの?という口コミを寄せてくれた方 何が起きてるの?

    さきほどX座標がズレているときはカメラは動かさずに逆進させて補正するという処理を、ブロック定義「X軸に移動する」に追加しました。

    このため、X座標がプラス33のときはカメラが動かさずに、一歩あるくごとにX座標がマイナス1ずつ補正されます。すると、ネコはX33からX32に移動します。これだと、X32に壁があった場合、せっかく脱出した壁に再び埋もれてしまうことになります。

    これでは真の解決からは程遠いのが現状です。

このバグをちょっとマシにしていきます。マシに。

ブロック定義「X軸に移動する」に条件を追加する

X座標を補正する際に壁があったらマズイ?なら壁にぶつかってるときは補正しなければいいよ!という発想です。そしてコレ自体は正しいですが、パーフェクトではありません。

問題点は何か

こうなります↓

壁に埋もれても脱出はできてます。そして、そのまま左に行こうとしても補正が働いて再び埋もれるバグはなくなりました。

しかし!右に進もうとすると壁の中に引きずり込まれてしまいます……ホラーです😫

何が起きているか

X座標と補正で何か間違いが起きています。それを明確にするために次の動画を見てください。

これは壁から脱出した直後です。直後なのでX座標が0ではなくプラスに増えています。この状態で右に歩こうとしています。すると補正が働き、一歩動くごとにX座標がマイナス1されているのです。するとネコはどんどん左側に動いていき、結果的に壁に引きずり込まれるのです。補正が裏目に出ました。

どうしたらいいか

ネコが左に動いていくのに合わせてステージ(カメラ)も左に動かせば壁にめり込むことはなくなります。

ネコが右に動くと左に補正される、なら壁も左に動かせばネコは壁に埋もれないよね、という話です。

  • 変更前)ネコが右に動く→左に補正される→壁があるとめり込む
  • 変更後)ネコが右に動く→左に補正される→壁も左に動かす→壁はないからネコは動ける

こんな↑イメージの改修をしていきます。

カメラを補正する

作業はカンタンです、コピペ。

テストする

だいぶマシになりました。壁には引きずり込まれません。

まだまだ改善の余地はありそうです。

あとちょっと!

最後に微調整する

変数の初期化

処理の順番を調整する

アニメーションとスタックを回避する処理を入れ替えた方が動きがスムーズでした。

ブロック定義「スタックを回避する」を微調整する

コス名のバックアップを取ります。

変数「直前のコスチューム名」を作る

バックアップを取る

コスを元に戻す

テストする

だいぶマシになりました。万が一埋もれてしまっても、無事に脱出できて、かつ壁に引きずり込まれないような処理になっています。

まとめ

1つのバグを直そうとしたら芋づる式にバグがどんどん発生して、けっこうな大改修になりました。よくある。よくあるんです。

こういうバグを潰す作業に集中しちゃう人はけっこうプログラマーに多いかも。

以前プログラマーの先輩から、この世にバグのないシステムなんてない、と聞かされました。

バグはあります。

ホコリみたいなもんです。南極にだってホコリはあるって聞いたこともあります。

みんなの作品にバグがあっても、それは力量不足とか設計ミスとか深く考えず、どうしてバグってるのかを追求してから直すようにしてみてください。

厳選されたスクラッチ人気作品リストがレビュー付きで楽しめます
世界中のヒットゲームをスクラッチで遊ぼう
趣味に関するスクラッチ作品例
勉強になるスクラッチ作品