最終更新:ID:FgDQsZQ5iw 2015年01月14日(水) 11:59:23履歴
戦闘時の距離計算の具体的な仕組みについて説明。
戦闘での行動速度は、スキルレベル・対象との距離で計算されている。
戦闘に参加している敵味方全てに座標が割り振られ、それを元に距離が算出される。
座標は縦・横・高さの3種類だが、パーティ戦の距離計算では高さ0なので除外。
縦(X)と横(Y)座標に限定して解説する。
なお、乗除算は、プログラム上では全てシフト演算で行われているので、小数点以下切捨て。
戦闘に参加している敵味方全てに座標が割り振られ、それを元に距離が算出される。
座標は縦・横・高さの3種類だが、パーティ戦の距離計算では高さ0なので除外。
縦(X)と横(Y)座標に限定して解説する。
なお、乗除算は、プログラム上では全てシフト演算で行われているので、小数点以下切捨て。
「ダートホッパー×3」を例に取ると、敵の各座標は以下の通り。
3体とも対象となる場合、この中でのXY各座標の最大と最小を元に座標が計算される。
その中間の数値(例で言えばダートホッパーBのY座標の値)は計算には関係しない。
X座標 −60+(12−(−60))/2=−24
Y座標 −36+(108−(−36)/2=36
上記のダートホッパー3体を対象とした場合の座標は(−24,36)。
3体とも対象となる場合、この中でのXY各座標の最大と最小を元に座標が計算される。
その中間の数値(例で言えばダートホッパーBのY座標の値)は計算には関係しない。
モンスター | X座標 | Y座標 |
---|---|---|
ダートホッパーA | 12 | 108 |
ダートホッパーB | −60 | 84 |
ダートホッパーC | −60 | −36 |
Y座標 −36+(108−(−36)/2=36
上記のダートホッパー3体を対象とした場合の座標は(−24,36)。
上の例の座標を対象として、味方側の隊列1番目からの全体攻撃として速度計算に使われる距離を求める。
まず、各座標の差を2乗した数値の合計を求める。
(技・術使用者のX座標−対象のX座標)²+(技・術使用者のY座標−対象のY座標)²+(技・術使用者のZ座標−対象のZ座標)²
(36−(−24))²+(−36−36)²=8784
その後、これを4096倍し、4で割る。
正確にはこの4で割るという除算処理は8−X回右シフト(2̽−8乗する)されているが、
このXがどのように決まるのかが現時点では不明。
とりあえず調べた限りではパーティ戦で行動順を決定する際には、X=6。
8784×4096/4=8994816
そしてここまでの計算結果に、6115501を「足したもの」と「引いたもの」に分け、
片方にもう片方の数値を前の計算の倍の数で割った数値を足し引きしていく。この処理を7回繰り返す。
(つまりこれまでの計算結果の微分。)
この計算や6115501という数値の根拠は不明。加筆・修正求む。
まず、6115501を足した値=A、引いた値=Bとする。
8994816+6115501=15110317 A
8994816−6115501=2879315 B
Bが正の数値か、負の数値かで、次の処理が異なる。
Bが正の数値になる場合
A−B/2=A'
B−A/2=B'
Bが負の数値になる場合
A+B/2=A'
B+A/2=B'
2つの数値に対してこの処理を7回繰り返す。
そしてA'の計算結果を、更に32で割る。
この32で割る処理も、正確には−{(8−X)/2−6}回右シフトされている。
それを4096で割った数値が、4段階に分かれた距離補正を決定する際に用いられる。
対象との距離
A'''''''/32/4096=対象との距離
例に当てはめると以下の通り。
対象との距離
12285459/32/4096=93
48未満が1番目の距離の補正。
96未満が2番目の距離の補正。
192未満が3番目の距離の補正。
それ以上が4番目の距離の補正。
3番目の距離が1、2番目の倍あることから見て1、2番目が近距離、3番目の距離を中間の距離、4番目の距離を遠距離とした方が妥当なのかもしれない。
行動速度に関わる距離補正のデータは、各種計算式を参照。
各戦闘における敵味方の配置パターンや座標、それを元に計算される距離や行動速度については、
表計算に個別の戦闘シーンからデータを抽出する形でまとめてある(xlsファイル)。
ファイルを開けない場合は、フリーのオフィスソフトで閲覧可能。
レジストリなどは汚さないので安心して使用できる。
X座標 | Y座標 | ||
---|---|---|---|
技・術使用者 | ウィル・ナイツ(隊列1番目) | 36 | −36 |
対象 | ダートホッパー×3(複数対象座標) | −24 | 36 |
(技・術使用者のX座標−対象のX座標)²+(技・術使用者のY座標−対象のY座標)²+(技・術使用者のZ座標−対象のZ座標)²
(36−(−24))²+(−36−36)²=8784
その後、これを4096倍し、4で割る。
正確にはこの4で割るという除算処理は8−X回右シフト(2̽−8乗する)されているが、
このXがどのように決まるのかが現時点では不明。
とりあえず調べた限りではパーティ戦で行動順を決定する際には、X=6。
8784×4096/4=8994816
そしてここまでの計算結果に、6115501を「足したもの」と「引いたもの」に分け、
片方にもう片方の数値を前の計算の倍の数で割った数値を足し引きしていく。この処理を7回繰り返す。
(つまりこれまでの計算結果の微分。)
この計算や6115501という数値の根拠は不明。加筆・修正求む。
まず、6115501を足した値=A、引いた値=Bとする。
8994816+6115501=15110317 A
8994816−6115501=2879315 B
Bが正の数値か、負の数値かで、次の処理が異なる。
Bが正の数値になる場合
A−B/2=A'
B−A/2=B'
Bが負の数値になる場合
A+B/2=A'
B+A/2=B'
2つの数値に対してこの処理を7回繰り返す。
そしてA'の計算結果を、更に32で割る。
この32で割る処理も、正確には−{(8−X)/2−6}回右シフトされている。
それを4096で割った数値が、4段階に分かれた距離補正を決定する際に用いられる。
0回目 | 1回目 | 2回目 | 3回目 | |
---|---|---|---|---|
Bが正の数値 | B≧0 | B'≧0 | B''≧0 | |
Aの計算結果 | a+6115501=A | A−B/2=A' | A'−B'/4=A'' | A''−B''/8=A''' |
Bの計算結果 | a−6115501=B | B−A/2=B' | B'−A'/4=B'' | B''−A''/8=B''' |
Bが負の数値 | B<0 | B'<0 | B''<0 | |
Aの計算結果 | a+6115501=A | A+B/2=A' | A'+B'/4=A'' | A''+B''/8=A''' |
Bの計算結果 | a−6115501=B | B+A/2=B' | B'+A'/4=B'' | B''+A''/8=B''' |
4回目 | 5回目 | 6回目 | 7回目 | |
Bが正の数値 | B'''≧0 | B''''≧0 | B'''''≧0 | B''''''≧0 |
Aの計算結果 | A'''−B'''/16=A'''' | A''''−B''''/16=A''''' | A'''''−B'''''/32=A'''''' | A''''''−B''''''/64=A''''''' |
Bの計算結果 | B'''−A'''/16=B'''' | B''''−A''''/16=B''''' | B'''''−A'''''/32=B'''''' | B''''''−A''''''/64=B''''''' |
Bが負の数値 | B'''<0 | B''''<0 | B'''''<0 | B''''''<0 |
Aの計算結果 | A'''+B'''/16=A'''' | A''''+B''''/16=A''''' | A'''''+B'''''/32=A'''''' | A''''''+B''''''/64=A''''''' |
Bの計算結果 | B'''+A'''/16=B'''' | B''''+A''''/16=B''''' | B'''''+A'''''/32=B'''''' | B''''''+A''''''/64=B''''''' |
A'''''''/32/4096=対象との距離
例に当てはめると以下の通り。
0回目 | 1回目 | 2回目 | 3回目 | |
---|---|---|---|---|
Bの数値 | 2879315≧0 | −4675843<0 | −1258178<0 | |
Aの計算結果 | 8994816+6115501= 15110317 | 15110317−2879315/2= 13670659 | 13670659+(−4675843)/4= 12501698 | 12501698+(−1258178)/8= 12344425 |
Bの計算結果 | 8994816−6115501= 2879315 | 2879315−15110317/2= −4675843 | −4675843+13670659/4= −1258178 | −1258178+12501698/8= 304534 |
4回目 | 5回目 | 6回目 | 7回目 | |
Bの数値 | 304534≧0 | −466992<0 | 303344≧0 | −80912<0 |
Aの計算結果 | 12344425−304534/16= 12325391 | 12325391+(−466992)/16= 12296204 | 12296204−303344/32= 12286724 | 12286724+(−80912)/64= 12285459 |
Bの計算結果 | 304534−12344425/16= −466992 | −466992+12325391/16= 303344 | 303344−12296204/32= −80912 | −80912+12286724/64= 111068 |
12285459/32/4096=93
48未満が1番目の距離の補正。
96未満が2番目の距離の補正。
192未満が3番目の距離の補正。
それ以上が4番目の距離の補正。
3番目の距離が1、2番目の倍あることから見て1、2番目が近距離、3番目の距離を中間の距離、4番目の距離を遠距離とした方が妥当なのかもしれない。
行動速度に関わる距離補正のデータは、各種計算式を参照。
各戦闘における敵味方の配置パターンや座標、それを元に計算される距離や行動速度については、
表計算に個別の戦闘シーンからデータを抽出する形でまとめてある(xlsファイル)。
ファイルを開けない場合は、フリーのオフィスソフトで閲覧可能。
レジストリなどは汚さないので安心して使用できる。
このページへのコメント
この一連の計算は単に平方根を計算している。(CORDIC双曲線計算モードによるアルゴリズム)
N=6115501とする。(これは本当は何でもよい。)
まず、このアルゴリズムでは、入力値が(2*N, 8*N)に入っている必要があるので、入力値を(4のn乗)倍することでこの範囲におさめる。(Xを使って書けば、n = 2 + X/2)
次に、数学的な性質により、7回操作を繰り返した後のAの値は、求めたい平方根を {F = sqrt(2*N) * sqrt(3/4) * sqrt(15/16) * ... * sqrt(16383/16384)}倍した値(の近似値)となるようになっている。したがって、AをFで割ることで平方根を求めることができる。
最後に、前処理でルートの中身を(4のn乗)倍していたので、得られた平方根をさらに(2のn乗)で割ると求める答えになる。
Nは大きいほど誤差が小さくなるので良いが、N=6115501とすると、F=4096となるので、割り算を右シフトで行うことができる。
このように、PSのCPUで使うことのできる整数計算のみで平方根が計算できる工夫がなされているといえる。(おそらくそういう汎用のライブラリがあるのであろう。)もっともこの場面に限って言えば、そもそも平方根を計算せずにルートの中身を48の二乗、96の二乗・・・などと比較すれば十分なのではあるが・・・。