0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ビリヤードっぽいゲームの基礎パーツ

0
Last updated at Posted at 2026-06-30

ビリヤード物理実験室

HTML、CSS、JavaScriptだけで動作する、ビリヤード風の物理シミュレーションゲームです。

ショットの方向や強さに加え、摩擦や反発係数を自由に変更し、ボールの転がり方、衝突、クッション反射の違いを観察できます。

外部ライブラリやWebサーバは不要です。htmlをブラウザで開くだけで利用できます。

デモ

ソース


1. 主な機能

1.1 ショット操作

  • 白球からドラッグしてショット方向を指定
  • ショットの強さを5~100%で変更
  • 照準線と矢印による方向表示
  • ボタンまたはキーボードからショット実行
  • ボール停止中の白球移動

1.2 物理設定

  • 摩擦の調整
  • 反発係数の調整
  • 完全弾性衝突への切り替え
  • ボール同士の円形当たり判定
  • クッションに対する斜め反射
  • 反発係数に応じた衝突時のエネルギー減衰

1.3 表示機能

  • ボールの速度ベクトル表示
  • ボールの軌跡表示
  • 衝突回数表示
  • 白球速度表示
  • 総運動エネルギー表示
  • 運動中・停止中の状態表示

1.4 ステージプリセット

以下の設定を選択できます。

プリセット 摩擦 反発係数 特徴
標準テーブル 0.45 0.96 通常のゲーム向け設定
めっちゃ滑る 0.015 0.99 ボールが長時間滑り続ける
全然転がらない 2.40 0.82 ショット後すぐに減速する
超反射 0.12 1.00 摩擦が小さく、衝突時の速度損失がない
エネルギー吸収 0.35 0.45 衝突するたびに大きく減速する

プリセット選択後も、摩擦と反発係数は個別に変更できます。


2. 起動方法

  1. billiards_physics_lab.htmlを任意のフォルダに保存します。
  2. Google Chrome、Microsoft Edge、FirefoxなどのWebブラウザで開きます。
  3. 画面が表示されたら、そのまま操作できます。

インストール、ビルド、Webサーバの起動は不要です。


3. 操作方法

3.1 マウスまたはタッチ操作

白球からドラッグする

白球を押したまま狙う方向へドラッグし、離すとショットします。

ドラッグ中は照準方向が更新されます。

テーブル上をクリックする

白球以外の場所をクリックすると、その位置へ向けて照準を変更できます。

クリック後にポインターを離すと、その方向へショットします。

白球の起点を移動する

すべてのボールが停止している状態で、Shiftキーを押しながら白球をドラッグします。

白球はクッションの内側の範囲で移動できます。

3.2 キーボード操作

キー 動作
Space 現在の照準方向へショット
R ボールを初期配置へ戻す
S すべてのボールを停止する
Shift+白球ドラッグ 白球の起点を移動する

4. 画面項目

4.1 ショット

強さ

ショット時の白球の初速度を指定します。

設定可能範囲は5~100%です。

内部では、次の式で初速度を計算しています。

初速度 = 1250 × 強さ / 100

狙った方向へショット

現在表示されている照準方向へ白球を発射します。

ボールが動いている間は、新しいショットは実行されません。

全停止

すべてのボールのX方向速度とY方向速度を0にします。

初期配置には戻しません。

初期配置

白球と15個の的球を初期位置へ戻し、以下の情報も初期化します。

  • 衝突回数
  • 軌跡
  • 照準方向

4.2 ステージ物理

摩擦

ボールが進むにつれて速度を減少させる値です。

設定可能範囲は0.00~3.00です。

  • 値が小さいほど長く滑ります。
  • 値が大きいほど早く停止します。
  • 0.00にすると、衝突以外ではほぼ減速しません。

内部では、おおむね次の式で速度を減少させています。

減速度 = 摩擦 × 230 × 経過時間

このゲームの摩擦値は、実際の物理単位ではなく、遊びやすさを目的としたシミュレーション用の値です。

反発係数

ボール同士またはボールとクッションが衝突したときに、どの程度速度を維持するかを指定します。

設定可能範囲は0.20~1.00です。

挙動
1.00 衝突による運動エネルギー損失がない理想状態
1.00未満 衝突するたびに速度の一部を失う
小さい値 衝突後に大きく減速する

完全弾性衝突

有効にすると、反発係数を強制的に1.00として計算します。

この間、反発係数のスライダーは操作できません。

完全弾性衝突では、摩擦による減速を除き、衝突前後の運動エネルギーが理想的に保存されます。


4.3 表示

速度ベクトルを表示

移動中のボールに、現在の速度方向と大きさを黄色い線で表示します。

線が長いほど、そのボールの速度が大きいことを示します。

軌跡を表示

ボールが通過した位置を点として残します。

最大160フレーム分の履歴を保持します。

表示を無効にすると、保存されていた軌跡も削除されます。

衝突回数を表示

テーブル左上に、以下を合計した衝突回数を表示します。

  • ボール同士の衝突
  • ボールと左右クッションの衝突
  • ボールと上下クッションの衝突

画面下部のステータス欄では、この設定にかかわらず衝突回数を確認できます。


5. ステータス表示

状態

  • 停止中:すべてのボールの速度が停止判定値未満
  • 運動中:いずれかのボールが移動中

白球速度

白球の現在速度を表示します。

X方向速度とY方向速度から、次の式で求めています。

速度 = √(X方向速度² + Y方向速度²)

衝突回数

ゲーム開始または初期配置後から発生した衝突の累計です。

総運動エネルギー

すべてのボールの運動エネルギーを合計した値です。

各ボールの質量は1として、次の式で計算しています。

運動エネルギー = 1 / 2 × 質量 × 速度²

実際のジュール値ではなく、設定変更前後の比較や、エネルギー減衰の観察に利用するための相対的な値です。


6. 物理モデル

6.1 ボールの表現

各ボールは、平面上の円として扱っています。

主なデータは次のとおりです。

  • 中心座標 x, y
  • X方向速度 vx
  • Y方向速度 vy
  • 半径
  • 質量
  • 番号

すべてのボールは、同じ半径、同じ質量として計算します。

6.2 ボール同士の当たり判定

2つのボールの中心間距離が、半径の合計より小さくなった場合に衝突と判定します。

中心間距離 < ボールAの半径 + ボールBの半径

ボール同士が重なった場合は、それぞれを衝突法線方向へ半分ずつ移動させ、重なりを解消します。

その後、衝突方向に対する相対速度と反発係数から力積を求め、両方の速度を更新します。

6.3 クッション反射

ボールがテーブルの有効範囲を越えた場合、位置を内側へ戻し、該当する速度成分の符号を反転します。

左右のクッションではX方向速度、上下のクッションではY方向速度を反転します。

左右反射: vx = -vx × 反発係数
上下反射: vy = -vy × 反発係数

このため、斜めにクッションへ入射した場合も、入射角に応じた斜め反射になります。

6.4 計算の安定化

1画面更新分の物理計算を3回に分割して処理しています。

これにより、速度が高い場合にボール同士がすり抜ける現象を軽減しています。

また、1フレームの経過時間は最大0.025秒に制限しています。ブラウザが一時停止した場合などに、再開直後の計算が極端に大きくなることを防ぎます。


7. 簡略化している要素

本ゲームは、物理現象を理解しやすくするため、平面上の並進運動に絞っています。

現在は、次の要素を計算していません。

  • ボールの回転
  • 順回転、逆回転、横回転
  • キューの撞点
  • マッセやカーブ
  • スリップ状態から転がり状態への移行
  • 空気抵抗
  • テーブルクロスの方向性
  • ボールと布の静止摩擦
  • ポケット
  • 得点やゲームルール

そのため、実際のビリヤードを完全に再現するものではなく、摩擦、反射、円同士の衝突を試すための簡易物理実験環境です。


8. ファイル構成

billiards_physics_lab.html

billiards_physics_lab.htmlの内部に、以下をすべて記載しています。

HTML  : 画面構造
CSS   : レイアウトとデザイン
JavaScript : 描画、操作、物理計算

画像、JavaScriptライブラリ、CSSライブラリなどの外部ファイルは使用していません。


9. 対応環境

HTML5 CanvasとPointer Eventsに対応した、比較的新しいブラウザを対象としています。

主な対象ブラウザは次のとおりです。

  • Google Chrome
  • Microsoft Edge
  • Mozilla Firefox

PCでのマウス操作を基本としていますが、Pointer Eventsを利用しているため、対応端末ではタッチ操作も可能です。


10. 改造しやすい箇所

初期配置

resetBalls()関数で、白球と的球の位置を定義しています。

ショット最大速度

shoot()関数内の次の値を変更します。

const speed = 1250 * power;

摩擦の効き方

physicsStep()関数内の次の係数を変更します。

const decel = friction * 230 * dt;

ボールの大きさ

world.ballRadiusを変更します。

ballRadius: 16

物理計算の分割数

アニメーションループ内のsubStepsを変更します。

const subSteps = 3;

値を大きくすると高速衝突時の安定性が向上しやすくなりますが、計算負荷も増加します。


11. 今後の拡張候補

  • ポケットと落球判定
  • 得点ルール
  • 手球と的球の選択
  • キューによる撞点指定
  • ボールの回転
  • スピンに応じたクッション反射
  • 質量や大きさが異なるボール
  • 障害物の配置
  • ステージエディター
  • 重力方向の設定
  • スローモーション
  • 一時停止と1フレーム送り
  • 衝突前後の速度・運動量表示
  • 設定値の保存と読み込み
  • 効果音

物理計算と画面描画がJavaScript内で関数ごとに分かれているため、学習用の改造題材として利用できます。


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?