ゲーム プログラミング

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

投稿日:

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

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

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が得られると被弾場所も求めることができます。

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

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

執筆者:

関連記事

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

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

フォートナイト 花編集マップ世界最速に挑む ?

ゲームでタイムを競った最後の記憶を辿るとF-ZEROが思い起こされます。最初のコースを5周するやつでどう頑張っても2分が切れなかった記憶があります。古い思い出は置いておき、相変わらずフォートナイトにハ …

iPhoneアプリ公開でAppStoreにて言語が英語になる場合の対処 | Xcode

日本語にしか対応していないアプリを作成してAppStoreConnectでも言語を日本語しか選択していないのに、公開したらAppStoreでの言語表記が「英語」に。日本語にしたい場合の対処法です。[対 …

Macでフォートナイトが起動できない場合の対処 – MacBook Pro

目次 チャプター2シーズン4Macでチャプター2シーズン4をプレイする方法チャプター2シーズン3Epic Game Launcherが起動できない場合の対処法諦めてゲーミングWindowsPCを購入 …

Node.jsゲーム公開はHerokuが良い

ゲーム開発初心者が簡単なNode.jsオンラインゲームを作成して公開したい場合はHerokuで公開するのが良いです。Node.jsゲームの公開手段は様々ありますが、Herokuは無料プランで十分にテス …

スポンサーリンク