ゲームはくり返しの仕組み
パラパラ漫画を思いうかべてください。1ページが1枚の絵で、めくると動いて見えます。ゲームも同じで、1秒に60回、いまどこに何があるかを計算し、絵を1枚かき、また最初からやり直します。Catch the stars はそういう小さなゲームです。上から星が落ちてきて、下で箱を左右に動かして受けとめ、取りのがした星ごとにライフがひとつ減ります。
このレッスンが終わると
メモ
ゲームループが1フレームごとに何をするかを言えて、短いスクリプトでゲームの重力と当たり判定を確かめることができる。
キーワード
- フレーム:ゲームの1枚の絵。1秒に何回もかきかえられます。
- ゲームループ:1フレームごとに1回動くコード。更新してから、かきます。
- 定数:コードの先頭に置く名前つきの数。たとえば
GRAVITYで、1か所だけ変えれば済みます。 - 重力:落ちているものの速さに、フレームごとに足される数。
- 当たり判定:2つのものがふれたかどうかを、箱を比べて調べること。
- ゲームの状態:ゲームがおぼえていること。たとえば得点とライフ。
はじめに:もう知っていること
メモ
頭の中で答えてください。1. ボールを落とすと、下まで同じ速さで落ちますか。2. 紙にかいた2つの箱が重なっているかどうか、どうやって調べますか。3. ゲームに負けたあと、何が表示されてほしいですか。答え: いいえ、だんだん速くなる。片方がはじまる位置が、もう片方の終わりより前かどうかを、横と縦で調べる。メッセージと、もう一度あそぶ方法。
始める前に
メモ
レッスンの上のバーにある ラボを開始 を押し、動いていると表示されるまで待ちます。コンテナはひとつ、jupyter だけで、ターミナルからは docker exec jupyter でその中の Python を使います。これはコンテナの中でコマンドをひとつ実行する命令です。リンクは2つあります。1つめの JupyterLab は編集用の画面で、ポート 8888 です。2つめの Preview(プレビュー)はゲームそのもので、ポート 8000 です。自分のブラウザーのタブで開いて、いまのうちに1回あそんでみましょう。下の 実行 ボタンは、それぞれのコマンドをラボのターミナルに、同じセッションの中で順番に入力します。様子を見たいときや自分で入力したいときは、バーの ターミナルを開く(新しいタブ) を押します。
ゲームは数個の単純なファイルでできている
ls game はゲームの3つのファイルを一覧にします。ページの index.html、見た目の style.css、ルールの game.js です。2つめのコマンドは大きさを出します。667、442、4399 バイトで、合わせて 5508 バイトです。ゲームのほとんどは game.js に入っています。エンジンもライブラリもなく、ブラウザーにもともとあるものだけで動きます。
docker exec jupyter ls gameここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
docker exec jupyter python3 steps/sizes.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ゲームループ
スクリプトは game.js を読んで、先頭にある名前つきの定数を出します。GRAVITY は 0.15、PLAYER_SPEED は 6、SPAWN_EVERY は 50 で、50フレームごとに新しい星が出ます。そのあと関数を一覧にします。大事なのは2つです。update はすべてを動かして何が起きたかを調べ、draw は絵をかきます。loop 関数は両方を呼んでから、requestAnimationFrame で、次のフレームにもう一度呼ぶようブラウザーにたのみます。このおわらない呼び出しがゲームループです。
docker exec jupyter python3 steps/loop.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
確かめよう
ヒント
ループは1フレームごとに何をしますか。また、新しい星が出る間隔を決める定数はどれですか。答え: ゲームを更新してから、かく。SPAWN_EVERY。
定数とレベルの表
よいゲームは、数を見つけやすい場所にまとめます。LEVELS はデータの表で、Drizzle、Shower、Storm、Meteors の4行があり、得点 0、5、12、20 からはじまります。各行は基本の数を何倍かにし、スクリプトがその結果を計算します。重力は 0.150 から 0.360 まで大きくなり、星と星の間かくは 50 フレームから 25 フレームに縮みます。つまりゲームは、コードではなくデータを変えるだけで難しくなります。やってみましょう。game.js の GRAVITY を変えて保存し、スクリプトをもう一度実行して、Preview であそびます。
docker exec jupyter python3 steps/levels.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
重力はフレームごとに足される数
重力だけでは星は動きません。重力は、フレームごとに星の速さに少しだけ足され、その速さが星を動かします。スクリプトは、game.js の定数を使って、ひとつの星を10フレームのあいだ追います。速さは1フレームごとに 0.15 ふえて 1.50 になり、星は合わせて 8.25 ピクセル落ちています。どのフレームも前のフレームより大きく進むので、星は落ちながら速くなるように見えます。
docker exec jupyter python3 steps/fall.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
当たり判定は2つの箱についての質問
星を受けとめたかどうかを、ゲームは2つの箱が重なっているかで調べます。横も縦も、それぞれの箱がもう片方の終わりより前にはじまっていれば、重なっています。スクリプトは同じ判定を Python で、決まった6組の箱に行います。重なる組と、箱の中に別の箱が入る組は True、はなれた箱は False、ふちだけが接している箱も False です。ゲームはこの判定を、すべての星について、フレームごとに行います。
docker exec jupyter python3 steps/collide.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ゲームを配信して、あそぶ
Preview は単純なファイルサーバーです。スクリプトは、ブラウザーと同じように、ページとスクリプトとスタイルシートを求め、どれも 200 で答えます。ラボの中にはブラウザーがないので、ゲームを代わりにあそんでくれるものはありません。自分のタブで Preview を開き、左右の矢印キーかボタンで箱を動かしてください。星を3つ取りのがすと Game over と出て、スペースキーか Restart でもう一度はじまります。
docker exec jupyter python3 steps/serve.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある思い込み
注意
大きな数にすればゲームがかならずよくなる、と思っている人は多いです。そうではありません。GRAVITY が大きすぎると、だれも反応できない速さで星が落ち、PLAYER_SPEED が小さすぎると、箱が星の下に間に合いません。数はいちどにひとつだけ変えて、あそんで、見たことを書きとめてから、つぎの数を変えましょう。
ノートブックでの同じ確かめ方
バーから JupyterLab を開き、start.ipynb をダブルクリックします。セルは、定数を読み、2つの箱で重なりの判定を行い、Preview にページを求めます。セルをクリックして Shift と Enter を押すと実行されます。最後のセルは自分の変更のための場所です。GRAVITY を変えて保存し、10フレーム後に星がどこにあるかを計算してみましょう。
最後の確認
ヒント
前に戻らずに答えてください。1. ゲームループは1フレームごとにどんな2つの仕事をしますか。2. 重力はフレームごとに、位置と速さのどちらを変えますか。3. 2つの箱はいつ重なりますか。4. レベルをひとつずつコードに書くより、レベルの表のほうがよいのはなぜですか。答え: 更新とかく。速さを変え、その速さが星を動かす。横も縦も、それぞれがもう片方の終わりより前にはじまっているとき。コードではなくデータを変えるだけで済むから。
先生へ
ヒント
このレッスンは、ラボで進めるレッスンの小さな例です。手順と実行ボタンがレッスンで、ラボは生徒ひとりひとりのコピーです。ラボはサービスがひとつで、小さなゲームをその場であそべる JupyterLab です。自動採点はありません。生徒は game にある3つのファイルを自分で変えたものを JupyterLab からダウンロードして、変えた数とその効果についての一文といっしょに提出します。学習のポイント:1. ゲームは更新とかくことのくり返し。2. 重力は速さを変え、速さは位置を変える。3. 当たり判定は箱についての判定で、数は名前つきの定数と表に置く。よくある思い込み:数をいちどに何個も変えてしまう。用意するもの:ラボとブラウザー。ラボの中にはブラウザーがなく、ゲームは生徒自身のブラウザーであそびます。ヒント:再読み込みの前に、変更でどうなるかを予想させてください。ゲームとスクリプトは決まった文章から作られるので、どのコピーでも同じ数になりますが、星が出てくる位置はランダムです。ご自分のモジュールにコピーして変更するか、レッスンビルダーのラボメニューから一から作ってください。