ポンの作り方:最初のビデオゲームを再現
遊びを見つける執筆にClaudeを使用しています。

1972年にアタリが発売した「Pong」は、商業的に成功した最初のビデオゲームとして広く知られています。白い四角いボールが二本のパドルの間を行き来する、それだけのゲームです。画面の説明は10秒で終わります。しかし「自分でゼロから作れますか」と聞かれると、意外に手が止まります。 この記事では、Pongを再現するために必要なロジックを整理し、HTMLとJavaScriptだけで動く版を作る手順を示します。「最初のビデオゲームを作る」という体験は、ゲーム開発の基本的な考え方――ゲームループ、衝突判定、スコア管理――をひととおり学べる小さな実験台にもなります。歴史の再現でありながら、現代の入門課題としても有効です。
Pongを再現するとはどういうことか
まず、Pongの仕様を整理します。オリジナルのPongはアナログ回路で動くアーケード機なので、完全な「再現」は厳密にはできません。ここで目指すのは、プレイの体験として同じに見える版です。具体的には次の要素が揃えば十分です。
- 画面中央からボールが打ち出される
- ボールは上下の壁で跳ね返る
- 左右にパドルがあり、ボールを返す
- パドルを外すと相手にポイントが入る
- スコアが画面上部に表示される
AIや物理エンジンは不要です。必要なのは座標計算と条件分岐だけです。「シンプルすぎて逆に難しい」と感じる部分は、ボールとパドルの衝突判定です。ここだけ丁寧に理解すれば、全体の7割は理解できたと言えます。
画面とゲームループの設計
HTMLのCanvas要素を使います。Canvasは「描画用のキャンバス」で、JavaScriptから座標を指定して図形を描けます。ゲームの画面はこのキャンバス一枚です。
ゲームループとは、「消す→計算する→描く」を毎フレーム繰り返す処理です。Pongであれば次の手順が1フレームの中で行われます。
- 前のフレームの描画を背景色で塗りつぶして消す
- ボールの座標を速度ベクトル分だけ進める
- 壁・パドルとの衝突を確認し、必要なら速度の向きを反転させる
- スコアを確認し、得点が入った場合はボールをリセットする
- ボール・パドル・スコアを描画する
requestAnimationFrame(ブラウザが次の描画タイミングで指定の関数を呼ぶ仕組み)を使うと、このループを毎秒60回程度動かせます。setIntervalでも動きますが、タブが非アクティブのときの挙動が不安定になりやすいため、requestAnimationFrameが定番の選択です。
衝突判定の考え方
Pongの核心は衝突判定です。ボールとパドルはどちらも四角形なので、矩形同士の重なりで判定します。
二つの矩形AとBが重なっているとき、次の4条件がすべて成立します。
- AのX左端 < BのX右端
- AのX右端 > BのX左端
- AのY上端 < BのY下端
- AのY下端 > BのY上端
この条件を外れた瞬間が「当たっていない」状態です。逆に言うと、この4条件が成立していれば衝突中です。
衝突が検出されたらボールのX方向の速度を反転させます(velocityX = -velocityX)。このとき、パドルのどの位置にボールが当たったかで、Y方向の速度も調整するとオリジナルに近い挙動になります。オリジナルのPongはパドルの中央付近で当たるとまっすぐ、端に近いほど急角度で跳ね返ります。パドル中央からの距離を正規化して速度のY成分に掛けると、この動きを近似できます。
壁との衝突は上下のY座標の範囲チェックだけです。ボールのY座標がキャンバス上端を超えたらY速度を正に、下端を超えたらY速度を負に反転します。
パドルの操作とAI
プレイヤーが操作するパドルはキーボード入力で動かします。keydownとkeyupイベントを使い、キーが押されているあいだパドルのY座標を加減算します。「押した瞬間だけ動く」実装は操作感が悪くなるため、押下状態をフラグで管理してゲームループの中で座標を更新するのが自然です。
2人対戦でなく1人用にする場合、相手パドルをCPUが操作します。Pongレベルの簡易AIはボールのY座標にパドル中心を追従させるだけで十分です。追従速度に上限を設けることで難易度を調整できます。追従が速すぎると絶対に負けないので、プレイヤーのパドル速度より少し遅い値を設定するのが調整の出発点になります。
スコアとリセットの処理
ボールが画面左端を越えたら右プレイヤーに1点、右端を越えたら左プレイヤーに1点を加算します。得点後はボールを画面中央に戻し、速度の向きをランダムに設定して再スタートします。
スコアはキャンバス上部にfillTextで描画します。フォントにモノスペースのサンセリフを使うと雰囲気が出ます。オリジナルのPongは7点先取がゲームセットでしたが、再現版では好みで変更して問題ありません。
失敗しやすいポイントが一つあります。ボールをリセットするとき、速度ベクトルのX成分がゼロに近いとボールがほとんど横に動かず、パドルに届くまでに時間がかかりすぎます。初期速度を設定するときはX成分に一定の最小値を持たせることを忘れないでください。
完成後にできる拡張
ここまでで動くPongができます。そこから先は任意の拡張です。いくつか例を挙げます。
- ボールの加速:ラリーが続くたびに速度を少しずつ上げると緊張感が増します。
- 効果音:Web Audio APIで短いビープ音を作るとオリジナルの質感に近づきます。
- モバイル対応:タッチイベントでパドルを操作できるようにするとスマートフォンでも遊べます。
- 2人対戦:1台のキーボードで片方をWS、片方を矢印キーに割り当てると対面プレイができます。
これらの拡張は、それぞれ独立して追加できます。コアのロジックを壊さずに機能を足せるかどうかを確かめる作業は、コードの設計を振り返るよい機会でもあります。
次の行動
作ったPongはHTMLファイル1つで完結するため、アソバースにそのままアップロードして公開できます。誰かに遊んでもらうことで、操作感や難易度の問題点が見えてきます。「動いた」から「遊ばれる」へ進む一歩として、ぜひ公開まで試してみてください。
参考資料
- MDN Web Docs「Canvas API」
- MDN Web Docs「requestAnimationFrame」
- MDN Web Docs「Web Audio API」



