ゲーム開発ラボ:ブラウザーでゲームループ、重力、当たり判定を学ぶ

このラボは、生徒ひとりひとりに自分用の小さなゲーム Catch the stars を渡します。3つのファイルでできていて、index.html がページ、style.css が見た目、game.js がルールです。生徒は JupyterLab のファイルエディターで編集し、同じフォルダーから配信される2つめのリンク Preview でゲームをあそびます。短い Python のスクリプトが game.js を読んで中身を出し、ゲームの計算をもう一度行うので、ゲームを変えるだけでなく、しくみを確かめることもできます。

攻撃のラボではなく、ゲームエンジンもライブラリもありません。ゲームは HTML の canvas の上で動くふつうの JavaScript で、実行するのはブラウザーだけです。どのコピーもインターネットにも他の生徒にもつながらないので、何かをダウンロードしてくることもできず、中から他の人に届くものもありません。

生徒が学ぶこと

ゲームループとは何か。1フレームごとに1回動き、ゲームを更新し、かき、もう一度呼ぶようブラウザーにたのむ関数です。ゲームが数を GRAVITY、PLAYER_SPEED、SPAWN_EVERY のような名前つきの定数に、レベルをデータの表にまとめるしくみ。ゲームを難しくするには、コードではなくデータを変えます。ゲームの重力は、フレームごとに速さへ足される数で、その速さが位置を動かします。そして当たり判定は、2つの箱が縦と横の両方で重なっているかを調べて見つけます。ゲーム開発の入門や、ゲームを使ったプログラミングの入門に向いています。正確な言いまわしは、ご自分の認定団体の単元で確かめてください。ここでは引用していません。

ブラウザーで動かす

ラボはサービスをひとつ、jupyter だけ起動します。jupyter はゲームと、はじめのノートブックと、短いスクリプトを作業フォルダーに書き出し、フォルダー game の上で単純なファイルサーバーを起動します。ラボのページから2つのリンクが開きます。作業台の JupyterLab と、ゲームそのものの Preview です。プラットフォームの入り口が、だれが開いたかをすでに知っているので、JupyterLab はトークンを求めません。ラボの中にはブラウザーがないので、スクリプトはゲームを見せることはできず、コードを読むだけです。生徒は自分のブラウザーで Preview のリンクを開き、矢印キーか画面のボタンであそびます。Preview が見せるのは保存したファイルなので、ファイルを編集したら保存して、Preview を再読み込みします。ラボの横のターミナルには自分の Python がなく、ラボの Python には docker exec jupyter に続けて、中で動かすコマンドを書いて使います。

  1. コンテナーのページを開く. バーの「つくる」を開き、「コンテナーを実行」を選びます。ページは誰でも開けて、Git ラボと SQL ラボはアカウントなしで起動できます。ほかのラボには無料アカウントが必要です。アカウントを作成してサインインし、「起動」を押します。
  2. ラボを探す. 「サンプルラボ」のカードにすべてのサンプルが並んでいます。ゲーム開発:JavaScript のゲームループを探します。
  3. 「起動」を押す. 「起動」はそのまま1回の操作で実行します。「先にファイルを編集」は compose ファイルを開くので、起動する前に変更できます。
  4. 開く. ラボのページには、ラボのバーに2つのリンクがあります。Preview を押してゲームをあそび、次に JupyterLab を押してフォルダー game を開き、game.js をダブルクリックします。そのあと「ターミナルを開く」を押して docker exec jupyter python3 steps/loop.py と入力すると、ゲームの名前つきの定数と関数が一覧になります。

生徒に提出してもらうもの

自分のゲームのファイル、つまりフォルダー game の3つのファイルを、JupyterLab の File、Download でダウンロードしたもの。それに、自分で変えた数、たとえば GRAVITY、PLAYER_SPEED、LEVELS の1行と、それがゲームをどう変えたかを、自分のことばで一、二文。自動採点はなく、その文で理解できたかが分かります。さらに力を伸ばしたいときは、変更の前後で steps/fall.py を実行させて何が動いたかを言わせるか、表に5つめのレベルを足して、スクリプトの出力がどう変わるかを説明させてください。

このラボの基本レッスン

Game Loop Basics は、このラボで進める小さなレッスンです。生徒はゲームの3つのファイルを一覧にし、名前つきの定数と関数と、フレームごとに動くループを読み、表からレベルの数値を計算し、落ちる星を10フレームのあいだ追い、決まった組の箱で重なりの判定を行い、Preview のサーバーにページを求めます。あえて小さくしてあり、ラボで進めるレッスンとは何かを先生に見せるためのもので、あとはラボが担います。変更したいときは、ご自分のモジュールにコピーしてください。

GitHub のコード

compose ファイルには Dockerfile がなく、公開されている標準のイメージをひとつ、Jupyter Docker Stacks の scipy-notebook を日付つきのタグに固定して、権限のない専用アカウントとメモリ 512 MB で動かします。このイメージのライセンスは BSD-3-Clause で、私たちは配布していません。ファイルは起動時に、決まった文章からゲームとスクリプトを書き出すので、どのコピーも同じで、何もダウンロードしません。限界もありのままに書きます。ゲームは小さく、エンジンはなく、インターネットからライブラリを取ってくる方法もなく、ラボの中にはブラウザーがないので、スクリプトはゲームを動かすのではなくコードを読み、星が出てくる位置はあそぶたびにランダムです。ラボが止まると何も残らないので、生徒は先にファイルをダウンロードします。

課題として出す

課題には、何を提出するかを書いてください。

  1. ラボを作る. モジュールで課題を追加し、「コンテナーラボ」のカードを選んでから「GitHub リポジトリ」を選びます。https://github.com/mitsurutech/lab-game-web とブランチ main を指定します。compose ファイルは既定の compose.yaml です。変更したい場合は、たとえば自分用の出発点のゲームを使うときは、先にリポジトリをフォークしてください。
  2. 公開して試す. 「公開」すると、確認したコミットに固定されるので、あとでリポジトリを変更しても、すでに出したラボは変わりません。まず自分のコピーを起動してください。
  3. 配布する. ほかの課題と同じように配布します。期限を付けることもでき、課題には何をするか、何を提出するかを書いておきます。
  4. 提出物を採点する. 生徒のコピーを開いて提出された内容を確認し、採点します。足りない場合は理由を書いて差し戻します。

このラボを試す、そして費用

無料の個人アカウントで、このラボの基本レッスンに取り組めます。毎月、ほとんどのレッスンに足りる無料クレジットがあり、カードは要りません。クラスで使う場合、学校は最初の365日間、生徒50人まで無料で、その後は生徒1人あたりの年額です。すべてのラボが含まれ、教職員は無料です。

よくある質問

リンクが2つあるのはなぜですか。
1つめの JupyterLab は、生徒がファイルを編集してターミナルを使う場所です。2つめの Preview はゲームそのもので、フォルダー game から配信され、あそぶ人が見るとおりに表示されます。ゲームを別のタブに置くので、エディターに囲まれずに済みます。
スクリプトでゲームを見られますか。
いいえ。ラボの中にはブラウザーがないので、スクリプトは game.js を読んで計算をくり返せますが、絵をかくことはできません。ゲームは自分のブラウザーで Preview のリンクを開いてあそんでください。スクリプトは毎回同じ数を出すので、クラスで答えを比べられます。
ファイルを変えたのに Preview が変わりません。なぜですか。
Preview が見せるのは保存したファイルです。エディターでファイルを保存してから、Preview を再読み込みします。それでも同じなら、強制再読み込みを試してください。ブラウザーが古いファイルをおぼえていることがあります。
トークンやパスワードを入力しなくてよいのはなぜですか。
ラボの Web ページには、プラットフォームの入り口を通ってしか届きません。入り口はあなたがだれかをすでに知っていて、あなたと、あなたのモジュールを教える先生だけを通します。だから JupyterLab はトークンなしで起動します。ほかの人が届く機械では、このように起動しないでください。