ローグライク と呼ばれる類のゲームでは FOV (Field of Vision) というのが重要な要素のひとつになってます。これはプレイヤーやモンスターの視界を決定するもので、実装もいろいろあるらしい。その中の Shadow casting というもの (に近いもの) を JavaScript で実装してみた。
あまり細かいとこ詰めずに雰囲気実装だけどそれなりにそれっぽくなったので満足。
※ pre にフォーカスして hjkl です。意味ないけど壁に埋まることもできます (衝突判定を実装してないだけ)
アルゴリズムの詳細についてははリンク先の図をみるとなんとなく分かる……。
そもそもあるタイルが見える/見えないというのがどういうことか、の定義でも実装は変わるんだけど、今回の場合は、注目しているタイルはそのタイルの中心点として、壁は正方形として考える。つまり、視点とタイルの中心点とを結ぶ線分が壁であるタイルのいずれかの辺と交わると、そのタイルは視界に入らない。これは視点からのタイルの中心や壁の四隅の点への角度を計算することで判定できる。
手順としては
- 視点のまわりを方角によって 8 分割 (今回の実装では 4 分割) し、それぞれについて
- 視点の近くから 1 行ずつ走査していく
- 視界を遮るタイル (壁とか) があったら次以降の行ではそのタイルによって見えない部分を走査しない。あとは再帰
こんな感じのもよう。これを JS でたいへん非効率に実装した。視点を @ にするくらいすればよかったな……。
ソースコードは https://github.com/motemen/rl-js で今回のメイン部分は https://github.com/motemen/rl-js/blob/master/lib/FOV.js .