今回は、スネークゲームのつくり方について紹介します。
スネークゲームはシンプルなルールで一度やり出すとなかなか終われない少し中毒性のあるゲームだと個人的には思っています。
Scratchでつくるスネークゲームには、クローンを使うパターンやスタンプを使うパターンがありますが、今回はクローンを使うパターンで作ってみたいと思います。
この記事を読んでいただくと、クローンを使ったスネークゲームのプログラミング技法(アルゴリズム)が分かります。
スクリプトの作り方
完成した動き
緑の旗でスタートすると、ステージのマス目を描いた後、中央にスネーク(プレイヤー)とオレンジ色のえさがランダムな場所に出現します。
キーボードの矢印キー、またはスマホやタブレットの場合は画面下の矢印ボタンをタップすることでスネークの動く方向をコントロールします。
1度動き出すと止めることはできません。外側の壁やスネーク自身の身体にぶつからないようにえさを取っていきます。えさを取るとスネークの身体が1マス分長くなっていきます。
完成したスクリプト
使用したスプライトと完成したスクリプトの全体です。
【スプライト】
スプライトは「スネーク」「えさ」「マス目」「上」「右」「下」「左」の合計7個です。
「スネーク」と「えさ」スプライトは、縦横32×32ピクセルの正方形でつくっています。サイズはこれと同じに合わせる必要はありませんが、形は正方形か円形が望ましいです。
「マス目」スプライトは、スタンプを使ってスクリプトで描画しているのでコスチュームには何も描かれていません。
また、パソコンでしか操作しない場合は、必要なスプライトは「スネーク」「えさ」「マス目」の3つだけあれば大丈夫です。その他の「上・右・下・左」スプライトはキーボードがないスマホやタブレットで操作するために必要です。
上 下 右 左
【スネークのスクリプト】
「スタート」メッセージは、「マス目」スプライトから受け取ります(マス目の描画が終わったタイミングで)。
- クローン番号:このスプライトのみ
- 食べたエサの数:すべてのスプライト用
- 経過時間(秒):すべてのスプライト用
【えさのスクリプト】
「えさ」スプライトは、スタート直後とスネークの頭の色(0x3655c7)に触れたらランダムに位置を変えて表示させています。
【マス目のスクリプト】
ステージのマス目と外周をスタンプで描きます。ペンの色は共通の緑色(0x4ba33e)にしています。
マス目は20ピクセル幅の正方形です。
「マス目を描画」定義ブロックでは、細いたて線とよこ線でマス目を描くようにしています。
「枠線を描画」定義ブロックでは、太い線で外周を描くようにしています。
【上・右・下・左のスクリプト】
スタート直後は大きさと座標を設定しています。
スプライトが押されたらそれぞれメッセージを送っています。(「スネーク」スプライトで受け取ります。)
スクリプトの説明
ここからはプログラムをつくっていく中でポイントとなる部分について説明します。
ポイント①:エサを食べたら「食べたエサの数」変数を1ずつ増やす
スネークがエサを食べたら「食べたエサの数」変数の値を1ずつ増やします。
条件には「もし(スネークの頭の色に触れた)なら」を設定しています。
「食べたエサの数」変数は「すべてのスプライト用」で作っているので、他のスプライトから値を読み取ることができます。
【えさのスクリプト】
ポイント②:エサを食べたらスネークの身体を1マス増やす
ここからが超重要のポイントです。ポイント①で説明した内容がここで生きてきます。
【スネークのスクリプト】
「自分自身のクローンを作る」ブロックの直前に「(クローン番号)を(食べたエサの数)にする」ブロックがあります。「クローン番号」変数は「このスプライトのみ」でつくっているので、自分自身のクローンを作ったとき、作られたクローンにはそれぞれ「クローン番号」を保持した状態になります。
どういうことかと言うと、例えば「クローン番号」が0のとき、つまり「食べたエサの数」が0のときですね。このときに作られたクローンが持っている「クローン番号」変数の値は0になります。
次にエサを1個食べた時、「食べたエサの数」変数の値が1になって「クローン番号」変数の値も1になります。このときに作られたクローンが持っている「クローン番号」変数の値は0になります。
これらのことを「0.2秒ごと、20歩動くごと」に「クローン変数」を持ったクローンが作成されているわけです。
ただし、これだけだと1歩ずつ動かくたびにクローンが作成され続けてしまいます。そして、全くエサを食べていなければ、それらのクローンが持っている「クローン番号」変数の値は下図のようにすべて0のままになります。
この点を解決するためにポイント③が重要になります。
ポイント③:不要なクローンを削除する
ポイント②に続いてここも超重要ポイントです。
【スネークのスクリプト】
ポイント②で最後に述べた『クローンが作られ続けてしまう問題』はどう解決したら良いでしょうか?(こういう疑問を持って解決方法を考えることが大事です)
答えは『要らないクローンは消せばいい』です。
下図のスクリプト(「要らないクローンを消す」メッセージ)を同じスネークのスクリプトの中から送ってもらいます。呼び出し側は「ずっと」ブロックの中にあって、1マス動くごとにこのスクリプトを呼び出しています。
スクリプトの内容は、「(クローン番号)を-1ずつ変える」、そして「(クローン番号)が0より小さいなら」「クローンを削除する」というものです。
これはつまり、「(クローン番号)を-1ずつ変える」ブロックで、すべてのクローンの「クローン番号」変数の値から1を減らすということです。(今の値が3だったら2に、2だったら1に、という具合)
そして、今の値が0だったら-1となり、0より小さくなるので該当するクローンは削除される、というロジックです。
これを図で表すと下の図のようになります。
「食べたエサの数」変数の値が3だった場合、スネークの頭とその後ろに身体部分が3つ繋がった状態になります。
身体部分の「クローン番号」変数の値は頭に近い方から2,1,0と1つずつ少ない状態になっています。
頭の部分には、「クローン番号」変数の値が3の状態でクローンが作られますが、すぐに1マス移動してしまうのでその状態は一瞬でしかありません。
そして、頭から遠いクローンたちは、既に「クローン番号」変数の値が0より小さくなっているので削除されていることになります。
ポイント④:マス目をつくる
順番が逆になってしまいましたが、マス目や枠が無くても一応スネークゲームは楽しめるので最後に持ってきました。
マス目も枠もペンを使って描いています。マス目の太さは1で、枠の太さは35に設定しています。
マス目の方だけ説明しますが、たて線22本、よこ線16本で作っていて、線の幅は縦も横も20ピクセルにしているのでマス目は20×20ピクセルの正方形になっています。
【マス目のスクリプト】
線と「スネーク」や「えさ」のスプライトが重なってしまわないよに上手く座標をずらして調整する必要があります。
ここまでのポイントを押さえてスクリプトを組むことが出来たら、クローンを使ったスネークゲームのプログラムは完成です!
失敗しやすいポイント
特にはありません。
応用編
今回紹介したプログラムを開始(緑の旗でスタート)すると、まずマス目と外周の線を緑色の線で描くところから始まります。
これは、上で説明した「マス目」のスクリプトの中の「マス目を描画」と「枠線を描画」の2つの定義ブロックが動いているためです。
この定義ブロックには、「画面を再描画せずに実行する」というオプション機能がついていて、言葉の通り定義ブロック内のプログラムの動きが画面に表示されないままプログラムの最後まで実行される、という機能です。
「画面を再描画せずに実行する」にチェックを入れてOKボタンを押してから再度プログラムを実行するとマス目の描画が一瞬で終わるようになります。
線を1本1本引く動作をいちいち画面に表示せず、結果だけを画面に表示するため、処理速度が格段に速くなります。
まとめ
さいごに、今回の記事で説明した『簡単でシンプルなスネークゲームの作り方(クローンを使ったプログラミング技法(アルゴリズム))』についてのポイントをまとめます。
- ポイント①:エサを食べたら「食べたエサの数」変数を1ずつ増やす
- ポイント②:エサを食べたらスネークの身体を1マス増やす(クローンごとに値を持たせて識別できるようにする)
- ポイント③:不要なクローンを削除する(「クローン番号」変数をつかう)
- ポイント④:マス目をつくる(スネークやエサと重ならないように座標を調整する)
どうでしたか?上手く再現できたでしょうか?
ネットで調べてみると、同じスネークゲームでもスタンプを使った作品が多いような気がしました。結構複雑なプログラムが多くて、もっと簡単にできるのにな~ということで今回の作品をつくってみました。
画面の隅に配置したボタンを使えばタッチパネルでも操作できると思うので、良ければあそんでみてください。(動作確認してないので不具合があったら教えてください)