スクラッチでマリオっぽいスクロールゲームを作る上級技⑬ 我が召喚に応えて顕現せよ、NEWステージ!

スクラッチでマリオっぽいスクロールゲームを作る上級技⑬ 我が召喚に応えて顕現せよ、NEWステージ!
グリフパッチ(動画)
ok-scratch(解説)

和訳解説は動画作者のグリフパッチさんご本人から許可をいただいて掲載しております。
チャンネルはYOUTUBE ( by griffpatch )からどうぞ。

ステージコードをデコードして、2面を作ってみよう!
スターター
プロジェクト
なし
難しさ

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

LOADING...

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

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

前回はステージコードのエンコードに成功したね!

エンコードと来たら、デコードだよね!これがあるからステージコードの共有が成立するわけだ。やっていこうぜ!

今回の目標「ステージを復元する」

ということでエンコードされたステージコードをデコードしてステージを復元する。

これを応用すると、あらかじめ2面や3面を作っておいて、それらのステージコードをリストに入れておけば、1面をクリアしたら次のステージコードを読み込む、みたいなロジックによってカンタンに複数ステージを持つ深みのあるゲームが作れるようになるぞ。

ステージコードにちょっと追加する

何個かステージコードに追加しておきたい項目があるので最初にやっておくね。

バージョン情報を追記する

ゲームのバージョン情報をステージコードに持たせておくと便利だよ。後日改造を繰り返していったあとに、もうバージョン1のステージコードは読み込めないな、ってなったらエラーメッセージを出すような処理を作れたりする。本格的なゲーム開発のノウハウだね。

ok-scratch ok-scratch

昔のバージョンが動かなくなることを専門的には「互換性がなくなる」とかって呼ぶよ。

ステージのプロパティを追記する

ステージのサイズも記載しておこう。

横幅

高さ

ステージを複数保存する準備をする

いまは毎回ステージ一覧を消してから新登録しているから、必ずステージが1つになってしまう。これはテスト段階では有意義だったけど、もう必要ないので消そう。

変わりに「◯回繰り返す」ブロックを置くよ。

指定された番号のステージを作る準備をする

そしてブロック定義の引数「ステージ番号」からリスト「ステージ一覧」の長さを引いた回数繰り返すような式を作ろう。

この中ではカラのデータをステージ一覧に追加しておく。これでステージ一覧の数が足りなくなることが防げるよ。この次にエンコード文字列を入れる前準備ってところ。

で、こちらがやっとエンコード文字列を入れる処理だね。直前でステージ一覧に空文字を入れておいたから安全にリストを更新できるよ。

  • 安全にステージが作れるってどういうこと? 安全にステージが作れるってどういうこと?

    そうだね、必ず順番通りに1の次は2,2の次は3ってステージを作るならそこまで必要ないんだけど、1面を作ったあとにいきなりラストステージである10面(仮)を作りたくなった場合を考えてみて。リスト「ステージ一覧」の最後にステージコードを追加する処理では、10面のステージコードが2番目に格納されてしまうから整合性がなくなるよね。そこでここで作ったように、足りない行には空文字を入れておく、って処理をすれば1面の次に10面を作りたくなっても、ステージコードがちゃんとリストの10番目に格納されるようになるんだ。

ステージコードをデコードして、ステージ情報をロードする

いよいよ今回の目玉だ。ブロック定義「ステージをロードする」を作ろう。

引数で渡される「ステージ番号」を使って、リスト「ステージ一覧」からステージコードを取り出すよ。それを変数「エンコード文字列」にセットしよう。

変数「エンコード文字列のインデックス」を作る

デコードする際に、インデックスがあると便利なので用意しておこう。

  • インデックスってなに? インデックスってなに?

    インデックスというのはリストの何番目かという数字です。リストじゃなくても例えば図書館の本棚を想像してみて。本棚の5番目にある本のインデックスは5。19番目にある本のインデックスは19みたいなイメージ。

    プログラミングだとインデックスという言葉は必須知識の1つだから、もし知らなかったらこの機会に覚えよう。

    ちなみにメジャーなプログラミング言語だとインデックスは1番目が0になる。2番目が1になる。でもスクラッチだと1番目は1だし、2番目は2になってるから注意。

初期化する

では1を入れておこう。

ブロック定義「_次の文字を読み込む」を作る

変数「文字」を作る

変数「文字」にエンコードの文字を1文字ずつセットする

インデックスの場所にある文字を取り出すよ。

次の文字を読み込むように1を加算する

このインデックスをズラスことで文字を1文字ずつとるって算段だよ。

数字以外の値が取れるまで繰り返す

では次の文字を読み込む方法を紹介していくね。

ちょっと復習がてら考えておきたい。

タイルのコスチューム番号が必ず1桁ならカンタンなんだけど、場合によっては2桁や3桁のときも考えられるよね。

例えば60で繰り返しが3回、つまりcとかだった場合、60cっていうカタマリがあるよね。

それを1文字ずつ取得しているから、最初に6が取れる。次は数字なのか文字なのか、この段階ではわからないから、数字以外が取れるまで文字を取り続ける、っていう少し強引なロジックを作る。そうすれば60でも6000でも、しっかりタイルのコスチューム番号が取得できるんだ。

この処理を作るよ。

ブロック定義「_次の値を読み込む」を作る

さっき作った定義と似てるけど、今度は「値」を取得するようにしておいて。

変数「値」を作る

で、変数も作るよ。

文字を組み合わせた結果を一時的に保持する変数を用意しておこう。名前はシンプルに「値」にしておくね。

初期化する

ブロック定義「_次の文字を読み込む」を実行する

ここでさっき作った文字を読み込む定義を実行しよう。

これで変数「文字」に次の文字が入ったね。

数字部分を余さず取得する

ここがコアとなる条件式だよ。数字以外を見つけるまで繰り返す式を紹介するね。

ループを設置する

「◯まで繰り返す」ブロックを置いて、条件のところに「または」を置いてね。

条件を作る

ここに以下のような条件を入れるよ。

値を繋げていく

そして値をどんどん繋げていくよ。

さらに次の文字を取得する

ループ内でまた次の文字を読み込むことで、条件がFALSEになるまで文字を読み込み続けるね!

ステージをロードするを続けて作る

この値の読み込み自体は、ステージをロードするところで実行しよう。

値がバグっていたら処理を中断する

念のためこういう処理も入れておこう。ステージコードには何が入ってくるかわからないし、別のゲームのステージコードと間違って入力する人もいるかもしれないからね!

ステージ情報を受け取ろう

大丈夫そうなら、いったんステージグリッドのリストを消そう。

次の値を読み込んで、

まずはステージのプロパティ、つまり設定情報が取れる予定だから、そちらを適切な変数に入れていこう。

最初は横幅。

もう一回値を読み込んで、そしたら高さを保持しよう。

タイル情報を受け取ろう

いよいよタイルを受け取ってステージを復元していく本番の部分だぞ。

ステージの大きさだけ繰り返すループを作ろう。

そこで空文字をリスト「★ステージグリッド」に追加していくよ。これで必要な行を確保できる。事前に確保しておきたいのは、このあと1,2,3...と順番通りにはリストに追加していかないからなんだ。このあたりが不明瞭な場合は、とりあえずこのまま読み進めるか、それでも分からなければいったんグリッドの構造を説明しているシリーズ最初の記事をチェックしてみてほしい。

タイルの情報を受け取る前に、タイルのインデックスを1にしておこう。これを使って1つずつ情報を処理するから重要な変数だよ。

次にエンコード文字列のインデックスが、エンコード文字列の長さよりも大きくなるまで繰り返すループを作ろう。つまり全文字を処理するまで終われまてん!っていうループだよ。

このループの中で、さっき作った定義「_次のを読み込む」を実行するよ。

そして読み込んだ値の判定を行おう。空文字だったら、という判定だ。

空文字って言うことはつまり透明なコスチュームっていうことだよね。これはこの作品特有の仕様だから、のちのち忘れる可能性もあるので要注意。どこかにコメントしておくといいかもね。

で、空白はコスチューム番号2だよね。だから値を2で置き換えておくよ。

そしてこれだ。aからzに数字的な意味を持たせておいたよね。ここで文字を数字に変換して、何回連続でタイルを設置するかを判断するよ。

このループ内で、タイルのインデックスを使うよ。リスト「★ステージグリッド」の中に「値」を入れていこう!

そして直後にタイルのインデックスに、変数「★ステージグリッドの高さ」の値を加算するよ。ここが1ずつ加算なら事前に空文字をリストに割り当てる必要はなかったんだけど、インデックスが高さずつ変わるからリストには事前に空文字を入れて、行を確保しておく必要があったんだ。

タイルのインデックスを修正する

ただこのままだと全てのリストの行が埋まらないから、一定の条件下でタイルのインデックスを修正する必要があるんだ。見ていこう。

以下のような条件ブロックを式を置いてみて。

左側にはタイルのインデックス、右側には横幅と高さを掛けた値を入れてほしい。

この条件がTRUEなら、インデックスの値を修正するよ。

修正内容は「1-(横幅 x 高さ)」だよ。

これでリストの行が全て埋まるようになるんだ。少し不可解な事前処理があったけど、この修正処理があることで意味が通るはずだよ。

ステージをセーブとロードを実行する

さぁ、ずっと定義を直接クリックしてテストしてきたけど、そろそろ新しいメッセージを通してステージの保存を実行しよう!

ステージを保存する

保存、セーブ、どっちでもいいよ。

合わせて新しい変数も作るよ。「全てのスプライト用」で作っていこう。

このメッセージを受け取ったら保存を実行するよ。その際に今作った変数を引数として渡そう。

ok-scratch ok-scratch

ぶっちゃけ「すべてのスプライト用」だからわざわざ引数で渡さなくても使えるんだけど、このあたりはスクラッチというよりはプログラミングのお作法に近い。深く考えると今は混乱するから、とりあえずスルーしてもらってw

でも、こういうのもいつかしっかり伝えたいなぁ!

ステージをロードする

新しいメッセージを作ろう!

同じくこのメッセージを受け取ったらロードを実行するよ。

スプライト「エディター」を開いてね。

ここで変数「★現在のステージ」を初期化するよ。

さらにリスト「★ステージグリッド」も削除しよう。

そしてステージをロードするメッセージを送って待つ

送るだとバグることもあるから、必ず送って待つブロックを使おう。

0キーを押したら保存する

0キーを押されたタイミングで保存が実行されるようにしよう。

エディターモードの場合

さらにここで新しいメッセージを作って欲しい。

このメッセージを条件式の最初で実行して、ついでに(後で表示する予定の)変数「★現在のステージ」を隠すブロックも置いておこう。

(メッセージを置くスクショ抜けてましたm(_ _)m ↓コレ見てもらえたらと)

さらにさらに新しいメッセージを作ります。

これを送るようにするよ。

ここまでは「もし〜」の部分ね。

ゲームモードの場合

ここからは「でなければ〜」の中に移るよ。

メッセージ「ゲームをストップします」を送って待つを置き、エディターを1にしよう。

現在のステージ情報を表示するようにしておこう。ここは見えると便利なんだ。

メッセージ「ステージをロードします」を送って待つを置くよ。

続けてメッセージ「ゲームをスタートします」を送るよ。

ゲームのスタートとストップに対応する

新しく作ったゲームのスタートとストップというメッセージに対応する処理を作り込んでいくよ。

マリオ

スプライト「マリオ」を開こう!

まずはメッセージを受け取るブロックを置こう。

ストップ

スクリプトを止めよう。

スタート

メイン処理を実行すればOK!

エディター

l(エル)キーが押されたとき

lが押されたらステージをロードするようにするよ。ロード(Load)のエルってことだね。

ゲームモードならスクリプトを止めよう。

そしてユーザーに質問するよ。

どのステージを編集したいか、っていう番号を教えてもらいたい。

質問のあとに以下のような条件ブロックを置こう。

答えを念のため四捨五入するよ。

0などの1より小さい値だったら、回答ミスということで処理を止めるよ。

そうでなければ、メッセージを2つ送って待つよ。

そして現在のステージに答えの四捨五入した値を入れよう。

このあとまたメッセージを2つ送るよ。ステージをロードしますは送って待つ、ゲームをスタートしますは送るだけでOK。

rキーが押されたとき

rが押されたらステージを削除するようにするよ。Reset(リセット)のrってことだね。

この処理全体を複製しよう!

こんどはrも作るよ。

いらない部分を削除しようか。

質問を変えよう。ここではステージを消すかどうか、最終確認をするよ。

はい、っていう答え以外なら中断しよう。

はい、なら消すよ!

ゲームをストップしますを送って待つ

その後、新しいステージの横幅を聞くよ。

念のため条件ブロックを作って答えを確認するよ。

空白でないならOKだ。

変数に答えの値を入れよう。

高さでも同じことを繰り返そう。

そして地形を生成しよう。

これでカラのステージとしてリセットされたぞ。

新しくメッセージを作ろう。

地形を生成したあとにこのメッセージを送って待つよ。

最後にゲームをスタートしますを送ろう。

修正

ここで一部の処理を修正するよ。

定義「_地形を生成する」から2つブロックを取り外して、メッセージ「地形を生成します」を受け取ったときに移動してほしい。

変更前

変更後

ステージ

いよいよ大詰めだよ。

スプライト「ステージ」を開こう。

メッセージ「ステージをロードします」を受け取ったら、ステージをロードして、そのあとに完了した旨を通知したい。送って待つブロックを置くので注意。

タイル

今度はスプライト「タイル」を開いてね。

こっちではロードが完了したメッセージを受け取るよ。

次のような条件ブロックを作ろう。

中でステージグリッドのインデックスを調整するよ。

少し複雑な処理だから注意深く真似してね。

式についてはここまでのチュートリアルで出てきた内容だから説明は割愛するよ。

そして次にこのインデックスを高さずつ加算する処理を加えれば完成だ!

シェアしようぜ!

さぁ長かったけど、これで新しくステージを作って、そのステージを保存してロードするという一連の処理が完成した。

ただ完成しただけではなくて、短いステージコードのおかげでコメント欄で共有もできるし、友達とシェアすることが可能な、これぞスクラッチ!って感じのステージコードになってるよ。

やっぱりシェアしないと得られない学びがある、って僕は思う。シェアしてはじめて見える世界ってあるじゃん。これは作品をシェアして知らないスクラッチャーからコメントを貰って一喜一憂した経験がある人なら分かると思うんだ。プラスにもマイナスにも本当に心が動くからこそ、本当の学びになるって思うよ。

必ずしもスクラッチのコメント欄でシェアする必要はなくて、リア友に教えるとかでもいいと思う。スクラッチのコメント欄を使うのは本質ではなくて、シェアすることが本質だから。

ok-scratch ok-scratch

で、そんなシェア体験をするきっかけにこのステージコードがなったらめっちゃ嬉しいなって思う!いぇい(*^^*)

ok-scratch ok-scratch

このチュートリアルではみんなが作った作品をスタジオに掲載していこうと思ってるので、もし自分のアレンジを見てほしい!という人がいたらスタジオのコメントで作品URLを教えてね。

あと挑戦したけど上手くいかなくて、自分ではもう無理・挫折寸前、みたいな人もコメントで状況を教えてくれたら、時間が割けるときにチェックしてみるよ。

https://scratch.mit.edu/studios/33795511

完成サンプルがあるよ
おつかれさま!今回のチュートリアルには完成サンプルがあるから、作ってて分からなくなったり、 動作確認をしたいときはチェックしてみてね。
ブクマよろしくお願いします! ブクマよろしくお願いします!
どんどん追記・更新していくので、ブックマークやシェアよろしくお願いします!

スクラッチゲーム攻略

スクラッチゲーム

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