スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。
Scratchの「緑の旗2回押してね」問題、ちゃんと理解しよう!
Scratchで遊んでると、説明欄に「緑の旗を2回クリックしてね!」って書いてある作品、たま〜にあるよね?
「なんで2回も押さなきゃいけないの?バグ?」って思わん?
結論から言うと、Scratch本体のバグ…とも言い切れない。でも、コードの書き方次第で起きちゃう「あるある」な問題なんだ。この記事ではその原因と、カンペキな対策を解説するよ!
そもそも何が起きてるの?
たとえば、こういうゲームを作ったとしよう。
ネコのスクリプト:

オバケのスクリプト:

一見ふつうに動きそうだよね?でもこれ、たまに1回目の緑の旗でいきなりゲームオーバーになることがある。
なんで?
原因は「レースコンディション」
カッコよく言うとレースコンディション(競合状態)っていうやつ。
Scratchで「🏴緑の旗が押されたとき」を複数のスプライトに置くと、どっちが先に動くかはScratchが勝手に決める。毎回同じ順番になるとは限らない。
さっきの例だと:
- ネコが先に動いた場合 → ライフが3にセットされる → オバケが確認 → ライフは3だからセーフ ✅
- オバケが先に動いた場合 → ライフはまだ前回の「0」のまま → 即ゲームオーバー ❌
つまり、2つのスクリプトが「よーいドン!」で走り出して、どっちが先にゴールするかわからない状態。これがレースコンディションだ。
「2回押してね」って言ってる作品は、1回目で変数がリセットされるから、2回目はちゃんと動く……っていう力技で乗り切ってるわけ。
「ずっと」ループがなくても起きるの?
起きる。 たまに「ずっとループが悪さをしている?」という意見もあるけど、それは関係ない。上の例を見ての通り、ループなんてなくても発生する。
ポイントは「ループがあるかどうか」じゃなくて、「あるスクリプトが、別のスクリプトの結果に依存してるかどうか」だ。
変数のセットを待たずにその変数を使うコードがあると、ループの有無に関係なくアウト。
完璧な解決法:「ブロードキャスト作戦」
答えはシンプル。緑の旗ブロックは1つだけにして、そこから「メッセージを送る」で順番に処理を始めるんだ。
ネコのスクリプト:

オバケのスクリプト:

こうすれば:
- 緑の旗 → まず変数が全部初期化される
- 「メインループ」が送られる → 各スプライトが動き始める
順番が保証されるから、レースコンディションは起きない!
「送る」と「送って待つ」の使い分け
もっと細かく順番を制御したいときは「〇を送って待つ」を使おう。
🏴緑の旗が押されたとき
「初期化」を送って待つ ← 全スプライトの初期化が終わるまで待つ!
「メインループ」を送る
「送って待つ」は、メッセージを受け取ったすべてのスクリプトが完了するまで次に進まない。初期化処理が複雑な作品ではこっちのほうが安全だよ。
まとめ
| やりがちなこと | ベストプラクティス |
|---|---|
| 各スプライトに🏴を置いて初期化 | 🏴は1か所にまとめる |
| 「2回押してね」でごまかす | ブロードキャストで順番を制御 |
| いきなりゲーム処理を始める | まず変数を初期化 → そのあとメッセージを送る |
「緑の旗を2回押してね」と書かなきゃいけない作品は、ちょっとだけコードの書き方を見直すチャンスだよ! ブロードキャスト作戦を覚えたら、キミの作品はワンランク上になる 💪
と、言ったけど別に2回押して動くなら全然OKだと思ってもいる!正しく動くかどうかもいいけど、自分の思ったものを作るっていうことに力を使うのが大切って思っている〜。
アスクラッチで質問する