Dxライブラリを用いてゲーム制作をしているのですが、再現したいスキルの処理が難しく、思いつきません。
それは、diablo2のチェインライトニングという技で、ある敵に当てると、最も距離の近い敵に雷が飛んでいき、それがまた近い敵に移るといった技です。
この動画の7:10~7:25辺りを見ていただけるとどのようなものかわかると思います。
自分のゲームでは、敵を動的配列(vector)で実装しており、雷が移る対象を最も近い距離ではなく、配列番号の可算によって行おうと思っています。
雷の飛んでいく角度はC言語の標準関数であるatan2を[0]の敵の座標と[1]の敵の座標を用いて求め、実際の移動は求めた角度を各x座標、y座標にcos,sinを用いて代入していく形で移動させていこうと考えています。
がしかし、色々書いてみてはいるのですが上手く動いてくれるものが作れません。
というのも、三角関数を用いるととても小さな角度であった場合、double型からint型にキャストする際に、角度が0となってまったく動かなくなってしまったりしてしまうのです。
どなたかいいアイデアをお聞かせください
Dxライブラリにてあるスキルの再現がしたい
Re: Dxライブラリにてあるスキルの再現がしたい
動画の該当部分を見ましたが、どのようなスキルか、よくわかりませんでした。
>というのも、三角関数を用いるととても小さな角度であった場合、double型からint型にキャストする際に、角度が0となってまったく動かなくなってしまったりしてしまうのです。
int にキャストしないで、double のまま処理するプログラムにすればいいんじゃないですか ? そうすれば、キャストが原因か、はっきりするんじゃないですか ?
>というのも、三角関数を用いるととても小さな角度であった場合、double型からint型にキャストする際に、角度が0となってまったく動かなくなってしまったりしてしまうのです。
int にキャストしないで、double のまま処理するプログラムにすればいいんじゃないですか ? そうすれば、キャストが原因か、はっきりするんじゃないですか ?
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: Dxライブラリにてあるスキルの再現がしたい
このキャッシュは描画関数に値を入れるために行うものです。
整数値にする必要性は画面の解像度に由来しますので、キャストをしないということはできないのです
整数値にする必要性は画面の解像度に由来しますので、キャストをしないということはできないのです
Re: Dxライブラリにてあるスキルの再現がしたい
>このキャッシュは描画関数に値を入れるために行うものです。
>整数値にする必要性は画面の解像度に由来しますので、キャストをしないということはできないのです
整数値を要求される個所が描画関数のみであれば、その関数へ渡すときだけdouble型からint型へキャストすれば十分です。
そしてint型へのキャストで情報が落ちるなら、どの道それはその描画関数では表現できない値です。
新たにdouble型対応の描画関数を作成するしかありません。
軌道計算用の値はdouble型のままパラメータを保持しておけば、そのまま微小量も維持されます。
計算用にはこちらの値を用いれば、問題は無いでしょう。
>雷の飛んでいく角度はC言語の標準関数であるatan2を[0]の敵の座標と[1]の敵の座標を用いて求め、実際の移動は求めた角度を各x座標、y座標にcos,sinを用いて代入していく形で移動させていこうと考えています。
[0]の敵の座標と[1]の敵の座標から、方向ベクトルを求めて移動させる方が良い気がします。
最終的にやりたい事が、[0]の敵の座標→[1]の敵の座標への移動であるなら、atan2を用いて角度の値を算出する必要はありません。
>整数値にする必要性は画面の解像度に由来しますので、キャストをしないということはできないのです
整数値を要求される個所が描画関数のみであれば、その関数へ渡すときだけdouble型からint型へキャストすれば十分です。
そしてint型へのキャストで情報が落ちるなら、どの道それはその描画関数では表現できない値です。
新たにdouble型対応の描画関数を作成するしかありません。
軌道計算用の値はdouble型のままパラメータを保持しておけば、そのまま微小量も維持されます。
計算用にはこちらの値を用いれば、問題は無いでしょう。
>雷の飛んでいく角度はC言語の標準関数であるatan2を[0]の敵の座標と[1]の敵の座標を用いて求め、実際の移動は求めた角度を各x座標、y座標にcos,sinを用いて代入していく形で移動させていこうと考えています。
[0]の敵の座標と[1]の敵の座標から、方向ベクトルを求めて移動させる方が良い気がします。
最終的にやりたい事が、[0]の敵の座標→[1]の敵の座標への移動であるなら、atan2を用いて角度の値を算出する必要はありません。
Re: Dxライブラリにてあるスキルの再現がしたい
オフトピック
> 三角関数を用いるととても小さな角度であった場合、double型からint型にキャストする際に、角度が0となってまったく動かなくなってしまったりしてしまうのです。
何らかの理由で「角度」の値を求める必要性があり,
且つ,その値を(sinやcosに与えるよりも前に)intに丸める必要があるのだとしても,
その結果は,変な方向に動く(角度がラジアンであれば,最大で約60°ほど方向がずれる)ことにはなりそうですが
> まったく動かなく
はならないように想像します.
(何か別の箇所にも問題があったりしませんか.)
何らかの理由で「角度」の値を求める必要性があり,
且つ,その値を(sinやcosに与えるよりも前に)intに丸める必要があるのだとしても,
その結果は,変な方向に動く(角度がラジアンであれば,最大で約60°ほど方向がずれる)ことにはなりそうですが
> まったく動かなく
はならないように想像します.
(何か別の箇所にも問題があったりしませんか.)
Re: Dxライブラリにてあるスキルの再現がしたい
>>TKSさん
確かに方向ベクトルで片付く問題でした!
なぜだか盲点になっていました。
一回そちらのほうで書いてみようと思います、ありがとうございます
確かに方向ベクトルで片付く問題でした!
なぜだか盲点になっていました。
一回そちらのほうで書いてみようと思います、ありがとうございます
Re: Dxライブラリにてあるスキルの再現がしたい
>>ハッカーさん
いえ、問題なく動きます。
既に目標座標に対して追尾するような動作をするものや、希望の角度の方向に物を飛ばすといった動作はできています。
キャストのタイミングはcosやsinにーπからπの値を入れ、移動速度の数値を掛けた後に行っています。代入先は座標です。
このときに、速度を掛けた後の値が1に満たない場合、つまりcos(ーπ<π)の値が非常に小さな値、角度にならない場合は0としてキャストされてしまうため、動作しないという仕組みです。解決するために速度を上げすぎたくもないので限度はあります。
このようなことから、値が0になり動作しないという状況ができるわけです。
とはいえ、このような動作はもっと単純に方向ベクトルを求めればいいという意見を先ほどいただいたので、この移動方法はやめようと思います。
ありがとうございます。
いえ、問題なく動きます。
既に目標座標に対して追尾するような動作をするものや、希望の角度の方向に物を飛ばすといった動作はできています。
キャストのタイミングはcosやsinにーπからπの値を入れ、移動速度の数値を掛けた後に行っています。代入先は座標です。
このときに、速度を掛けた後の値が1に満たない場合、つまりcos(ーπ<π)の値が非常に小さな値、角度にならない場合は0としてキャストされてしまうため、動作しないという仕組みです。解決するために速度を上げすぎたくもないので限度はあります。
このようなことから、値が0になり動作しないという状況ができるわけです。
とはいえ、このような動作はもっと単純に方向ベクトルを求めればいいという意見を先ほどいただいたので、この移動方法はやめようと思います。
ありがとうございます。
Re: Dxライブラリにてあるスキルの再現がしたい
要は,
移動量の大きさVと,atan2で求めた角度θから移動ベクトル(Vx,Vy)を
Vx = V * cos(θ)
Vy = V * sin(θ)
として求めたとき,このVx,Vyをintに丸めてしまうために,0になってしまう,という事が問題ということですよね.
(という話であれば,
> 角度が0となって
とか
> つまりcos(ーπ<π)の値が非常に小さな値、角度にならない場合は0としてキャストされてしまうため
という文言にならない気がするので,違うのかもですけど.
角度θがintに丸められるわけじゃないし,
cos(θ)やsin(θ)の値が小さいことが根本原因であるわけでもない.(cosとsinは常に絶対値が1以下なのだし)
)
問題の内容が上記であるならば,
> 方向ベクトルを求めればいい
というのは,「問題への解決策」ではないように思います.
(「一旦,角度θをわざわざ求めている」ことが問題の要因になっているわけでないならば,
Vx,Vyを(atan2を用いない)別の手段で算出するようにしたとしても,
「それをintに丸めたら0になるかもしれない」 という問題への対処ではない.)
解決策は,別に指摘されている
「内部計算結果はintに丸めずに保持すればいいよね」
の側ですよね.
移動量の大きさVと,atan2で求めた角度θから移動ベクトル(Vx,Vy)を
Vx = V * cos(θ)
Vy = V * sin(θ)
として求めたとき,このVx,Vyをintに丸めてしまうために,0になってしまう,という事が問題ということですよね.
(という話であれば,
> 角度が0となって
とか
> つまりcos(ーπ<π)の値が非常に小さな値、角度にならない場合は0としてキャストされてしまうため
という文言にならない気がするので,違うのかもですけど.
角度θがintに丸められるわけじゃないし,
cos(θ)やsin(θ)の値が小さいことが根本原因であるわけでもない.(cosとsinは常に絶対値が1以下なのだし)
)
問題の内容が上記であるならば,
> 方向ベクトルを求めればいい
というのは,「問題への解決策」ではないように思います.
(「一旦,角度θをわざわざ求めている」ことが問題の要因になっているわけでないならば,
Vx,Vyを(atan2を用いない)別の手段で算出するようにしたとしても,
「それをintに丸めたら0になるかもしれない」 という問題への対処ではない.)
解決策は,別に指摘されている
「内部計算結果はintに丸めずに保持すればいいよね」
の側ですよね.