ゲーム プログラミング

弾丸と壁/人の接触判定を少し真面目に実装してみる|ゲーム作成

投稿日:

フォートナイトみたいなオンラインバトロワゲームを作っています。優秀なサンプルコードから作成を開始したので早い段階で一応形にはなりました。しかし、サンプルをいじりすぎて接触判定に矛盾が生じてきてしまいました。

 ・グラフィック上は弾が当たっているのにダメージがない。
 ・建築して壁を立てているのに弾丸がすり抜けてくる。

Rayを飛ばしてぶつかるポリゴンを探すというのが一般的な手法のようですが、軽い処理でゲーム内に自由に組み込みたいので接触判定の部分を自作してみました。以下、その説明です。(数式等を使用しますが、厳密な数学的表現ではありませんがご了承ください)

接触判定方法:3次元空間での平面と線分の交点を求める

現在の建築の種類は「壁、床、階段」のみなので、建築は全て1平面で表現できます。また、プレイヤーも複数(3〜6)の平面で簡易的に表現することができます。
弾丸は現在のゲーム仕様では速度のある表現となっているので線分で表すことができます。従って、弾が建築(またはプレイヤー)に当たったかどうかは

 平面と線分の交点を求め、交点が平面の範囲内(建築の大きさ)にあるかどうかを求める

事で判別できそうです。

ベクトル、行列表記だと次のようになります。
(添字が小文字でない、その他色々、簡易的な数学表現です。お許しを)

上図にて、矢印のない太字は一座表です。
壁の位置と大きさから、P0, u, vが決まります。
弾丸の位置と進行方向から、b, dが決まります。
行列[A]は3x3です。逆行列は公式があるので{s,t,e}は一発で求まります。
det[A]が0の場合は弾丸の進行方向が壁と並行なので交点がないという事になります。実際のコードではある程度小さな値ならほぼ並行という事で交点なしとします。
det[A]が0でなく{s,t,e}が得られた場合は、その値を場合分して交点が壁の範囲(s, tが0以上、1以下)にあるかを調べます。弾丸が速度を持っている仕様なので1フレームで進む距離を弾丸の長さ(L)と考え、eは0以上、L以下であるかを調べます。
条件を満たしていたら「被弾」の処理をします。
s,tが得られると被弾場所も求めることができます。

以上、弾丸と壁の接触判定の記事でした。

-ゲーム, プログラミング

執筆者:

関連記事

フォートナイトで全然勝てないので自作してみた | Webブラウザゲーム Node.js + Three.js

フォートナイト面白いですね。私もやっています。しかし全く勝てません。高価なスキンを纏ったプレイヤー達に瞬殺されまくっています。もう少し初心者も楽しめる仕様もあったら面白いのでは?、という思いからフォー …

Cycle inside OOO; building could produce unreliable results. Xcodeで史上最高に難解なエラーでハマった話

あるiPhoneアプリを約2年ぶりにアップデートしようと思い、XcodeでArchiveを実行したら見たことのないエラーが出ました。 Cycle inside OOO; building could …

ライフゲームをWebブラウザで遊ぶ Conway’s Game of Life – Javascript (ソースコード公開あり)

ブラウザで遊べるライフゲーム(Conway’s Game of Life)を作成してみました。緑の自セルを配置して赤い敵セルを消してみましょう。基本的なパター …

How to use FFmpeg.wasm. What’s the Cross Origin Isoration?

Nowadays, I got the information that FFmpeg can be used with Javascript and I tried it immediately. …

FFmpeg.wasmの使い方:ブラウザでアップロードした動画をグレー動画に加工

FFmpeg.wasmの使い方の一例として、・ブラウザで動画をアップロード・動画から音声を抽出・動画からすべてのフレーム画像を取得・すべてのフレームをグレースケールに加工・グレースケール動画を作成・グ …

スポンサーリンク