ゲームは1秒に約60回の繰り返し
ゲームループは、ゲームを1コマずつ進める繰り返しの仕組みです。1コマの中で、状態を更新し、絵を描き、次のコマを呼びます。
スマートフォンのゲームが、指の動きにすぐ反応して見えるのは、この繰り返しが1秒に約60回回るからです。
このレッスンのゴール
メモ
ゲームループが、1フレームに何をするかを説明できる。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| フレーム | ゲームの1コマの絵 | |
| ゲームループ | 1フレームごとに更新と描画を行う繰り返し | |
| 更新 | 位置や点数を、次のコマの値にすること | |
| 描画 | 今の状態を、画面に絵として描くこと | |
| フレームレート | 1秒に描くフレームの数。単位は fps | 60 |
学生が入力するセルは、このプレビューでは空白です。
1フレームは更新と描画の2つの仕事
1フレームの中で、ゲームは2つの仕事をします。更新は、箱の位置や点数を、次の値に変えます。描画は、変えたあとの状態を画面に描きます。
この2つを混ぜないのが大切です。更新では絵を描かず、描画では状態を変えません。そうすると、直す場所が分かりやすくなります。
例: 5フレーム分の更新
<p id="out"></p>
例: 速さ5の箱の位置
| フレーム | 更新の前の x | 更新のあとの x |
|---|---|---|
| 1 | 0 | 5 |
| 2 | 5 | 10 |
| 3 | 10 | 15 |
| 4 | 15 | 20 |
学生が入力するセルは、このプレビューでは空白です。
ブラウザが次のフレームを呼ぶ
ブラウザは、多くの画面で、1秒に約60回、画面を描き直します。ゲームは requestAnimationFrame に自分の関数を渡し、次の描き直しの前に呼んでもらいます。
ラボのゲームでは、loop という関数が更新と描画を行い、最後にもう一度 requestAnimationFrame を呼びます。この終わらない呼び出しが、ゲームループです。
例: ゲームループの形
<canvas id="game" width="400" height="500"></canvas>
ラボで、ゲームループを探す
ラボのスクリプト loop.py は、game.js を読み、名前の付いた数と関数の名前を出します。スクリプトが出す言葉は英語です。
GRAVITY = 0.15 のような行が9つ出て、次に requestAnimationFrame を使うかどうかと、関数の一覧が出ます。
定数と関数を一覧にする
docker exec jupyter python3 steps/loop.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
その呼び出しが、どこにあるか
grep -n は、言葉を含む行を、行の番号を付けて出します。ラボを変えていなければ、requestAnimationFrame の行は、112行目に1つだけ出ます。
次のコマを頼む行を探す
docker exec jupyter grep -n requestAnimationFrame game/game.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
ゲームループは、終わらない while 文で書けばよいと考える人がいます。ブラウザの中では、終わらない while 文が画面の描き直しを止め、ページが固まります。次のフレームは、requestAnimationFrame に頼んで呼んでもらいます。
速さをフレームで決めると画面で変わる
ラボのゲームの速さは、1フレームに何ピクセル動くかで決まります。そのため、1秒に描くフレームの数が違う画面では、同じ箱でも、速さが違って見えます。
下の表は、1フレームに5ピクセル動く箱が、1秒に進む長さです。
例: フレームレートと速さ
| フレームレート | 1フレームの長さ | 1秒に進む長さ |
|---|---|---|
| 30 fps | 約33ミリ秒 | 150 ピクセル |
| 60 fps | 約17ミリ秒 | 300 ピクセル |
| 120 fps | 約8ミリ秒 | 600 ピクセル |
学生が入力するセルは、このプレビューでは空白です。