弓兵など遠距離の攻撃範囲の求め方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
コレジャナイ

弓兵など遠距離の攻撃範囲の求め方

#1

投稿記事 by コレジャナイ » 14年前

あけましておめでとう御座います。

ソースコードを一から書き直し、だいぶ色々とすっきり致しました。
返信して下さった内容にもありましたが、こちらにソースコードを載せ、添削して貰おうとも考えたのですが、昔こちらにソースコードを載せた際にトラウマが出来てしまったので今回は遠慮させて頂く事に致しました。申し訳御座いませんm(_ _)m


さて今回の内容で御座いますが、件名の通りです。

現在隣接マスの攻撃は実装済みでキャラの死亡処理も完了しています。
次の段階と致しまして、遠距離キャラの攻撃範囲を考えておりましたが、中々上手い計算式が思い浮かばず質問させて頂きました。

というのも、何も考えず例えば射程6の攻撃範囲の表示であれば移動範囲の求め方の要領で求められるのですが、弓兵などの場合目の前に敵が居たらその後ろ数マスは攻撃範囲から除外しなければならず・・・困っております。

遠距離と一口に言っても直線に飛ぶタイプ(銃など)、仰角のあるタイプ(弓など)によって範囲の求め方も変わってしまうのも困りもの。

市販のゲームを見てみると、目の前に障害物があった場合、その背後に小さな扇状に狙えない範囲が広がりつつ、仰角があればある一定以上の距離で再度狙えるようになるなど上手く処理されていて感心するばかり・・・。


中々口で説明するのは難しいものですね!
分かり易く画像を載せておきます。

こちらが仰角大での攻撃範囲
http://iup.2ch-library.com/i/i0527899-1325947867.jpg

こちらが仰角小さいでの攻撃範囲です
http://iup.2ch-library.com/i/i0527900-1325947929.jpg


これらの画像のような範囲の求め方は一体どういう計算式なのでしょうか・・・?

段差による射程の増加に関しては、このゲームでは単純に段差が1高くなる毎に範囲が+1されているみたいです。


上手く説明出来た自信が無いので、何かご質問等御座いましたらお気軽にお尋ね下さい。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#2

投稿記事 by softya(ソフト屋) » 14年前

トラウマにしたのは私かも知れませんね。申し訳ないです。本人に直しを要求しすぎる所があるので反省します。

基本処理は移動と同じですが目標点との間に障害物がある場合は除外する処理が必要になります。
これは攻撃キャラから見えるか見えないかを判定するわけですが、攻撃キャラから一番端の目標点に向かっての直線の方程式を求めて通過途中で障害物があれば、その場所以降は攻撃でないポイントすれば良いと思います。y=ax+bってやつを使いましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#3

投稿記事 by コレジャナイ » 14年前

いえいえ、善意で教えて下さっていると分かっているのに単純な事も予測して直す事が出来なかった自分の頭の悪さに辟易しただけですので、どうかお気になさらず・・。


それはつまり攻撃範囲の一番端(外周)のマス座標を割り出し(移動範囲を求める要領で)、そのマスのピクセル座標と攻撃手のマスのピクセル座標から直線の方程式を割り出す・・・ということで間違いないでしょうか?
攻撃範囲内の障害物マスのピクセル座標をその直線方程式へ代入し、式が成り立った場合は障害物以遠のマスを表示させないという処理ですかね。


お恥ずかしながら分からない点が幾つか・・・

①外周のマスの求め方:マップの端、番兵まで索敵再帰関数が来たらリターンする際にそのマスを外周マス認定する事は出来そうですが、射程最大まで索敵した際の外周マスはどのように求めれば良いものでしょうか?
移動索敵のように移動力なるものを用意してそれが0になれば・・・といった安易な方法では0になった地点が必ず外周マスになるとは限りませんし。

②式に用いるピクセル座標について:今の所マスの中心地点の座標は構造体によって保存されており、すぐに用いる事が出来るのですが、中心座標を用いて良いものでしょうか?
少々ズレが生じるような気が致しましたので、何を座標に用いれば良いのやら。。

③障害物以遠のマスの求め方:これは多分②の問題と絡んでいると思いますが、障害物自体はfor文でマップを洗いざらい調べれば特定は容易(攻撃範囲表示されているマスは特定のマップ値にしているため)なのですが、障害物以遠のマスはどのように特定すべきでしょうか?

④これで最後になりますが仰角のある攻撃範囲で、障害物以遠一定の距離の後再び攻撃可能になるような処理について:段差を考慮してしまうとより難しくなりそうですが、障害物より何マス(ピクセル単位で距離を求めた方が良いですね)先からなら攻撃可能と予め定めて置けば良いのでしょうか?


以上となります。
お暇が御座す時にご回答頂けると助かりますm(_ _)m

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#4

投稿記事 by beatle » 14年前

全部数学的な計算のお話に帰着する気がします.

1.外周マスの求め方
プレイヤー中心座標と各マスの座標との距離を算出するのがミソです.3平方の定理で求まりますね.

2.式に用いるピクセル座標
「マス中心座標が射程内だったら,そのマスは射程内とする」のか,「マス全体が射程内だったら,そのマスは射程内とする」のかで異なります.

3.障害物以遠のマスの求め方
プレイヤー中心から障害物の左右に接線を引きます.そうすると,プレイヤー中心から障害物までを半径とする円,プレイヤー中心から射程外周までを半径とする円,2本の接線,の計4本の線に囲まれた,バームクーヘンの一切れのような形の領域ができますね.その領域が障害物以遠の領域ですから,その領域に中心座標が含まれるマスを計算すればOKです.

4.仰角のある攻撃
銃は直線に飛ぶと言いますが,あれも実は放物線を描きます.
一般に,ある地点からある地点へと物を投げるには2通りの軌道があります.まっすぐ相手に向かって投げるか,丁度相手の頭上に落ちるように上方に投げるかです.直射と曲射です.
物を投げるスピード,標的までの距離,自分を基準にした標的の高さが分かると,その2つの軌道は計算で求められます.その求めた軌道が障害物に当たる場合,その標的には攻撃不可能ということで,射程から除外すれば良いと思います.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#5

投稿記事 by softya(ソフト屋) » 14年前

大体はbeatleさんの説明通りですが、私の考えていた違うところだけ説明します。
つまりいろいろな考え方が出来るので答えは一つではありません。

[射程] 射程の計算は移動力の処理と同じで地形補正として考えます。段が下がる場合は移動力の減少が少ないと考え段が上がる場合は移動力の減少が大きいと考えます。
[外周マス] 上記の範囲計算時に端に到達した場所をリスト化して覚えておいて後で使います。
[当たらない範囲]  直線の方程式で座標計算して1マスごとに攻撃が当たるかチェックします。障害物が有ったらそれ以降にあるマスは当たらない所としてマーキングします。
[仰角攻撃補正] 上の直線の方程式と絡みますが単純に障害物があったら一定期間当たらなくする方法(段差補正は必要)。か、まじめにbeatleさんの説明通り放物線の計算を行うかです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#6

投稿記事 by コレジャナイ » 14年前

>>beatleさん
とても分かり易いご回答感謝致しますm(_ _)m
おっしゃる通り全てプログラムとはあまり関わりが無い内容でしたね・・・、文系故こういった初歩的な数学の計算も思い浮かばずお恥ずかしい限りですorz

ご回答の中で気になった点を質問させて下さい。

①三平方は盲点でした・・・。確かに事前に射程の値で距離を求めておけば問題ないですね。
 気になったのは三平方を用いるとどうしてもルートが出現してしまうと思うのですが、これはどの型で保存すれば良いのでしょうか・・・?
 普段intとdoubleくらいしか用いないもので、知識に疎く申し訳御座いません。
 あ、そのままルートせず二乗した状態で保存しておけば良いのかな。

②3の内容も拝見しました所、中心座標の方が何かと都合が良さそうですので、中心座標で行きたいと思います。

③図を描いてみた所なるほどこれはとても分かり易く感動しました。
 判定に際してはif文にて 外円内であり、内円の中ではない。かつ接線の上下で不等式を用れば出来そうですが、接線を引く基準となる障害物の左右というのは何を指していらっしゃるのでしょうか?
勝手にマスの端と端、プレーヤーから見て一番都合の良い位置を選んで図を描いてしまっていたのですが、よく考えるとこの端の地点を一体どうやって割り出せば良いのか全く想定してませんでした。。

④ここで用いる距離は二乗した値ではなく、ルートになりますよね・・・。どう保存すれば良いのやら・・・。
 それはさておき、なにやらこの項目に関しては完全に自分の理解の範疇を越えてしまっているようです。。
 高さということはキャラの身長なども考慮に入るという事になりますよね。
 この値はまだ保存していなかったため、構造体に新たな項目を設けねば・・・。
 物を投げる速度というのが一番の課題ですね。
 何を基準に設定すれば良いのか全く分からず・・・、この計算は何という名前の公式を用いたものなのでしょうか?

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#7

投稿記事 by コレジャナイ » 14年前

>>ソフト屋さん
すみません、投稿前にどうやらご回答を頂いていたらしくまとめての返信が出来ませんでした。

外周マスについてですが、朝方書いたように自分が作っている再帰探索関数だと移動力が0になった地点が端であるとは限らない(同じ場所を探索してしまう事がある)ためその方法では上手くいかない恐れがありますorz

一度探索したマスの値を特別な値に変えておくという事も考えてみましたが、ぁ。
上手くいくのかな・・・。
returnした時特別な値のせいで探索出来ない領域が生まれると思ってましたが、意外と上手く行く気がしてきました。

当たらない範囲については失礼しました
自分の回答見直した所何故か一部削除してしまっておりました。(一応自己解決していたのですが)
これは攻撃手の座標と目標座標から方向を割り出し、方向から定まったX、Yの大小に応じて障害物以遠のマスを特定した後直線の方程式に代入し式が成立するか調べれば出来そうですよね。
あぁ駄目か。自分の方法だとマスの中心座標という限定的な値では正確に求めれなさそうでした(中心座標からxが値1でもズレていたらヒットしませんし)

ソフト屋さんがおっしゃる直線の方程式での座標は何を用いているのでしょうか?
一マスごとにとおっしゃっているので、攻撃手と目標地点の中心座標から割り出した計算式に、一マス内に存在するx、yを全て代入し式が成立するかを確かめていくということでしょうか。
あぁ、なるほど。これなら障害物以降のマス特定も簡単ですね!

仰角については数学的な計算が出来そうにない自分としてはソフト屋さんの方法の方が良さそうな気がしております・・・。

ちょっと返信に時間が掛かり過ぎているので(こんな文なのにもう30分も・・・)一旦投稿いたします

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#8

投稿記事 by コレジャナイ » 14年前

今紙に書いて検証していたら申し訳無いです、簡単とか言っておいて全然簡単ではありませんでした。

返信が間に合うと良いのですが・・。

やはり障害物以遠の求め方が分かりません。
一マスごとにどの範囲のX,Yが存在しているかを求めるすべが無いため(一マスは64×64のひし形なのですが、この中に特定のX,Yが存在するかどうかを調べる方程式が分からないため)
直線の式を求め、そこにfor文でXを0から手当たり次第代入し(終わりは目標地点の中心X座標かな)、式が成立したらマウス座標からマス座標を割り出す関数の内容を利用し(よく考えてみたらこの関数が上の方程式なんですが)、どのマスが射線上に乗るかは判別出来ます。
そこで得た座標から障害物のある座標を特定した後・・・あぁ、ここからはピクセル単位ではなく、攻撃方向から割り出したマス座標X,Yの大小で比較すれば求められますか。

すみません自己解決しました。
やっぱり実装出来そうです。

先ほど投稿した求め方と違うと思いますので、一応こちらも投稿しておきます。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#9

投稿記事 by コレジャナイ » 14年前

失礼
解決を押し忘れておりました。

取り敢えずお二人の方法をそれぞれ確かめてみて上手くいくかどうか調べてみたいと思います。

その過程で何か問題が発生した際はまたこちらへ質問させて頂きますm(_ _)m

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#10

投稿記事 by beatle » 14年前

ルートというのは単に計算なので,計算結果もまた実数になります.
√2 = 1.414...
引数(2)も実数だし,結果(1.414...)も実数です.ということで
double r = sqrt(a * a + b * b);
のような感じで距離rを求められます.まあ,全部2乗した値にして比較するとsqrtを呼ばなくて済むので多少速いかも知れませんね.

接線を引く基準となる障害物の左右
ええと,文字通り障害物の左右を指しているわけですが...マスに何か障害物があるわけですよね?その障害物は,プレイヤーから見ると大雑把にいえば円柱形をしていますよね?その円柱の左右に接線を引けば良いと思いました.
簡単なのは,マスに内接する円を描き,その円に接線を引くことでしょうか.

高さということはキャラの身長なども考慮に入るという事
はい,その通りですね.障害物の高さが重要になります.
物を投げる速度というのは,実際の武器を参考にしたら良いと思います.弓兵なら弓を射るときの初速,銃なら銃の初速などなど.もしかしたらゲーム用に調整が要るかも知れませんけど.
計算式自体は公式ではないと思います.

なんか図を書いてるうちにいっぱいレスがついてましたが気にせず投稿!
添付ファイル
直射と曲射.png
直射と曲射.png (13.32 KiB) 閲覧数: 14205 回

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#11

投稿記事 by beatle » 14年前

「放物線が2種類ある」は誤解を招きそうなので捕捉しておくと,物を投げるときのスピードを固定した場合,2種類あるということです.スピードを変えていいなら,それこそ無限の種類の放物線があります.
ただし,目標地点(a,b)をだんだん遠くしていくと,2種類の放物線が重なり,1種類になる瞬間があります.そこが最大射程ということになります.

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#12

投稿記事 by コレジャナイ » 14年前

>>beatleさん
ご回答有難う御座います。
公式が無い・・とすると具体的な計算方法はどのようになりますでしょうか?
こちらの方法をもししっかりと実装出来ればよりリアリティのあるものが作れそうですので、出来る限り頑張りたいと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#13

投稿記事 by softya(ソフト屋) » 14年前

まじめに計算すると
「放物線運動の軌跡について | OKWave」
http://okwave.jp/qa/q241776.html
「★雑木話★#044 放物線を描く」
http://homepage1.nifty.com/tadahiko/ZOKI/ZOKI-044.HTML
って感じになります。
空気抵抗は無視して良いとして、擬似的な重力加速度は何らかの値を定義しないといけません。
まぁ、これはテストしながら様子をみるという手があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#14

投稿記事 by beatle » 14年前

図中のa, bと弾を投げ出すスピードvは決まっているとします.重力加速度gも決まっているとします.
投げ出す仰角をθとすると,vとθから目標地点に弾が到達する時間Tに関する方程式が立ちます.
Tvcosθ = a
また,T秒後に弾が高さbになるということから,高さ方向に関する方程式が立ちます.
∫(vsinθ - gt)dt = b (0からTの範囲での積分)
この2つの方程式を使ってθを解けば,2種類の値が出ます.計算はちょっと難しいかもですが.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#15

投稿記事 by softya(ソフト屋) » 14年前

そういえば、飛んでゆく矢をアニメーションして表示させるならまじめに計算する必要はありますね。それっぽく見えませんから。
[補足]
ボールを投げるときの事を考えてもらうと分かるのですが、人はボール投げるときに距離や高さや障害物の有無でボールを投げる角度や初速を経験に基づいて微調整しています。
なので、矢も同様に計算しないとリアルっぽくはなりません。つまり、角度と初速の調整が必要になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#16

投稿記事 by softya(ソフト屋) » 14年前

斜方投射シミュレータ。接触の計算方法が適当です(めり込みます)。
[補足]実際の計算は、目標点の位置、障害物の位置を考慮して逆計算する必要がありますけどね。

コード:

#include "DxLib.h"
#include <math.h>

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
int gpUpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
	GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
	for( int i=0; i<256; i++ ){ 
		if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
			Key[i]++;     // 加算
		} else {              // 押されていなければ
			Key[i] = 0;   // 0にする
		}
	}
	return 0;
}

typedef struct {
	int x;		//横座標
	int w;		//幅
	int h;		//高さ
	int color;	//色
	char *name;	//名前
} box_t;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

	const double g = 3.0;		//	重力加速度	ピクセル/時間
	double v0 = 60;				//	初速		ピクセル/時間
	double r = 35.0/180.0*PHI;	//	発射角
	const int grand_line =450;	//	地面
	
	//	障害物と高台
	const int box_nums = 2;
	box_t box[box_nums] = {
		{240,60,100,GetColor(0,0,255),"障害物"},
		{500,140,130,GetColor(255,255,255),"高台"},
	};

	// while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
	while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){
		
		if( Key[ KEY_INPUT_RIGHT ] >= 1 ){ // 右キーが押されていたら
			v0+=1.0;//初速アップ
		}
		if( Key[ KEY_INPUT_DOWN  ] >= 1 ){ // 下キーが押されていたら
			r -= 1.0/180.0*PHI;//角度ダウン
		}
		if( Key[ KEY_INPUT_LEFT  ] >= 1 ){ // 左キーが押されていたら
			v0-=1.0;//初速ダウン
		}
		if( Key[ KEY_INPUT_UP    ] >= 1 ){ // 上キーが押されていたら
			r += 1.0/180.0*PHI;//角度アップ
		}
		
		//	地面
		DrawBox( 0,grand_line, 640,480, GetColor(255,128,64), TRUE );
		//	パラメータ
		DrawFormatString( 0,0, GetColor(255,0,0), "カーソル上下で角度 カーソル左右で初速を調整出来ます");
		DrawFormatString( 0,20, GetColor(255,0,0), "重力加速度=%5.1f 初速=%5.1f 発射角=%5.1f°", g, v0, r/PHI*180 );
		//	障害物・高台
		for( int i=0 ; i<box_nums ; i++ ) {
			DrawBox( box[i].x, grand_line-box[i].h, box[i].x+box[i].w,grand_line, box[i].color, TRUE );
		}
		
		//	軌跡
		for( double t=0 ; t<40.0 ; t+=0.25 ) {
			double vx = v0 * cos(r);
			double vy = v0 * sin(r);
			double x = t * vx;
			double y = 450 - t * vy + g * t * t;
			DrawCircle( (int)x, (int)(y-3),3, GetColor(0,255,255), TRUE );
			//	地面との接触計算
			if( y > grand_line ) {
				DrawFormatString( 0,40, GetColor(255,0,0), "地面に落下 x=%5.1f y=%5.1f", x, (double)grand_line-y );
				break;
			}
			//	障害物との接触
			int crash = 0;
			for( int i=0 ; i<box_nums ; i++ ) {
				double x1 = (double)(box[i].x);
				double y1 = (double)(grand_line-box[i].h);
				double x2 = (double)(box[i].x+box[i].w);
				double y2 = (double)(grand_line);
				if( x1 <= x && x <= x2 ) {
					if( y1 <= y && y <= y2 ) {
						DrawFormatString( 0,40, GetColor(255,0,0), "%sと接触 x=%5.1f y=%5.1f", box[i].name, x, (double)grand_line-y );
						crash = 1;
						break;
					}
				}
			}
			//	衝突なら終了
			if( crash ) {
				break;
			}
		}
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}  
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#17

投稿記事 by beatle » 14年前

softyaさんが僕とほぼ同じ目的の,しかも衝突判定まである凄いソフト作ってて驚きなのですが,せっかく3Dで作ったので投稿してみます.(そこ,ポイント稼ぎとか言わない!)
添付ファイル
simthrow.zip
(1.64 MiB) ダウンロード数: 193 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#18

投稿記事 by softya(ソフト屋) » 14年前

beatle さんが書きました:softyaさんが僕とほぼ同じ目的の,しかも衝突判定まである凄いソフト作ってて驚きなのですが,せっかく3Dで作ったので投稿してみます.(そこ,ポイント稼ぎとか言わない!)
環境依存しているみたいです。
error.png
error.png (24.67 KiB) 閲覧数: 14171 回
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#19

投稿記事 by コレジャナイ » 14年前

ソフト屋さんの作られたプログラムを試してみましたが、これは凄いですね・・・。
即席ですし、感動するばかりです。

ただ残念な事にこのプログラムを活かす段階にたどり着けるか怪しいですorz
積分は流石に文系だと荷が重かったOTL
今勉強し直してますが。。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#20

投稿記事 by コレジャナイ » 14年前

おはようございます。

解決済みにしてしまいましたが、質問が出てきましたのでこちらに質問させて頂きます。
新トピックを建てることも検討致しましたが、こちらのトピックの内容ですので乱立してもいけないと思い留まりました。

外周マスを特定する関数をせっせと組み立てている途中でふと気付いたのですが、単純に段差(下り)があれば射程を+1するという処理では駄目でした。(冷静に考えたら当たり前ですが。)
よくよくゲームを確認してみると、やはりこんな単純な処理は施されておらず、恐らく放物線の方程式を用いていると思われました(あくまで予想ですが・・・)


以前ご回答頂いた放物線の方程式では距離、高さ、速度が求まれば方程式が解けるとの事でしたので自分なりに考えてみたのですが・・・。
速度は何か適当な値を定めておくとして

距離→ステータスの射程の値から算出。平地同士であれば射程1の値=隣接マス同士のマス中心座標の二点間距離

高さ→取り敢えず同じ高さ同士

この情報は外周マスを特定しないでも算出出来るので放物線の方程式は攻撃範囲索敵前でも求める事が出来る?と考えてます。
(この時点で仰角の値を保存しておく。)

そこで事前に射程分の攻撃範囲を調べておき(攻撃手を中心に射程分探索し、特定のマップ値に変えるだけの単純な関数)、攻撃手の高さよりも高度が高い座標と低い座標をFor文で洗いざらい調べます。

その後特定した座標から距離を算出し、事前に求めておいた放物線方程式へ高さと距離を代入し(仰角は保存していたものを使用)、式が成り立つか調べます。

もし式が成り立てば、高度が低いマスならマップ値を攻撃可能範囲に変更し(式が成り立つ&高度が高いマスは元から攻撃可能範囲内のはずです)、成り立たなければ高度が高いマスの場合、マップ値を攻撃可能範囲から通常の値へ戻す処理をします。

その後でマップの攻撃可能範囲値内を探索し、ようやく外周マスの特定をする。


という行程を考えたのですが、これで正しいのでしょうか・・・?

どうも放物線の式が未だにしっかり理解出来ておらず(積分自体の知識は大して大事ではなかったのですが、三角関数などもあり四苦八苦)、その辺がとても自信がありません・・・。

ご回答お待ちしておりますm(_ _)m

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#21

投稿記事 by beatle » 14年前

きっと,放物線の方程式云々を言い出した僕が答えるべきでしょうが,僕にはコレジャナイさんが書かれた行程が良く理解できませんでしたので,誰か他の人よろしくお願いします.

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#22

投稿記事 by コレジャナイ » 14年前

>>beatleさん
恐らく自分の行程自体が丸っきり間違っているのだと思います。
beatleさんのお考えになられている方法ですと攻撃手よりも高さの低いマスは攻撃範囲を増加させ、高さの高いマスへの射程は減少させるという処理はどのように行っていらっしゃるのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#23

投稿記事 by softya(ソフト屋) » 14年前

射程を伸ばすのではなく段差は移動力の補正だけで計算できませんか?試していないので断言できる話ではないのですが。
それと放物線ですが射る速度を一定にすると距離に合わせて仰角を変えるしか無いので攻撃マスごとに仰角も計算し直す必要があります。私のシミュレータで確認できます。
ただ、障害物がなければ射抜ければ良いだけなので目標点を通過する仰角で良いことになり、距離を伸ばす場合(45度が最大距離になります)や障害物を超える場合には仰角を調整する必要が出てきます。などなど考えてみるとややこしい事だらけですね。
これは、多分何日か悩んで試行錯誤しないと良い仕組みにたどり着かない可能性が高いです。自分でやってもゲームの最後の方まで調整してそうな処理になる気が。
全部に放物線の方程式を使わなくても何とか成るんじゃないか?って気もするのですがモヤモヤっとアルゴリズムは霧の中です(勘です)。

とりあえず失敗してもやってみるしか無いと思いますので、やってみてください。ゲーム作りってそんなものです。試行錯誤で得た経験で良いアルゴリズムを思いつく事も多いです。
【補足】解決は外しておきます。

【追記】
申し訳ないのですがソースコードが無いので仮定の話が多くなるのと、参考プログラムを組むには大きな手間が掛かるレベルの話ですのでおいそれとは手を出せません。数式やアルゴリズムだけで一日以上あーでもないこーでもないと考えを巡らす可能性も高いです。作ったことがないものは実際に作ってみないと的確には答えられないんですよね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#24

投稿記事 by コレジャナイ » 14年前

とにかく手を動かし色々と試してみました。
が、やはり最初の攻撃範囲を求める段階で躓いてしまいましたorz

過程を説明すると
まず放物線方程式 sin(2θ-α) = 1/√x*x+y*y( (g/v*v)*x*x + y*y)   (g = 10, v = 50で固定)
(αは sinα = y/ √x*x+y*y などから求まりますが、仰角制限の際に必要なだけですので取り敢えずは無視)
この放物線方程式の左辺が-1より大きく1より小さければ攻撃範囲内とする事にしました。(高低差の関係で仰角が0より小さくなる事もあるため)

この条件で攻撃範囲を表示させた所確か上に範囲が広く、横の範囲が狭い歪な攻撃範囲が求まってしまいました。
これについては描画していたマスの座標が横64 縦32 と縦横で数値が異なっている事が原因だと分かりました。


そのため攻撃範囲用に、マス構造体に等間隔で座標の値を保存しました。(原点0,0 右下32,32などなど)
これにより攻撃手を中心としてかなり綺麗な円形で攻撃範囲が求まったのですが、よくよく攻撃範囲限界までのマスをカウントした所、5マス掛かっていたり7マス分の距離があったりと微妙な差がありました。

これの原因が何故か調べていたら移動ではニマス必要な距離に差が出来ている事が原因でした。

参考画像
http://iup.2ch-library.com/i/i0532414-1326338478.png

この赤色から青色マスまでの距離が同じでないと攻撃範囲が上手く求まらないという事に気付いたのですが・・・。
等距離にするために座標をいじったら、今度は放物線の式がめちゃくちゃな事になってしまいそうですし、どうしたもんかなぁ・・・と困り投稿させて頂きました。


ソースコードに関してはかなり乱雑であり、とても他の方にお見せ出来る代物では御座いません・・・。
ただどうしても必要な場合はお渡しする事も考えておりますが、無関係の方には非公開にしたい場合どのようにすれば宜しいのでしょう?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#25

投稿記事 by softya(ソフト屋) » 14年前

説明が良くわかりませんが見かけの表示の話と内部での座標系の話がごっちゃに成っている気がします。内部と外部で同じ座標系を使わなくて良いんですよ。
それとソースコードを全部もらっても追いかけきれないと思いますのでテスト用のコンパクト版の作成をお願いします。

私の方は画像で連絡が取れますのでアップローダサイトとパスワードを教えてもらえばOKです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#26

投稿記事 by コレジャナイ » 14年前

テスト用のコンパクト版の作り方が分からないのですが・・・どのように作成すれば宜しいのでしょうか?
取り敢えず即実行可能なアプリケーションだけお送り致します。
一人目を待機した後動かせる二キャラ目が遠距離仕様となっておりますので、攻撃を押して範囲の確認を宜しくお願い致しますm(_ _)m

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#27

投稿記事 by コレジャナイ » 14年前

上手く送れませんでしたので、無事送れましたらこちらに書き込みます

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#28

投稿記事 by softya(ソフト屋) » 14年前

コレジャナイ さんが書きました:上手く送れませんでしたので、無事送れましたらこちらに書き込みます
巨大なものは添付して送れませんので、アップローダサイトを使ってくださいね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#29

投稿記事 by コレジャナイ » 14年前

メールを送らせて頂きました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#30

投稿記事 by softya(ソフト屋) » 14年前

受け取りました。

これ絵的にはパースが掛かっていますが、内部的には45度回転させた四角形で構成された普通のマップとして処理できますよ。

コード:

     +---+      
     |   |      
 +---+---+---+  
 |   | ・ |   |  
 +---+---+---+  
     |   |      
     +---+      
そう考えた上で問題と成るのはどういう所でしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#31

投稿記事 by コレジャナイ » 14年前

正方形と捉えた場合

上方向へニマス進んだ距離

斜め方向のマス(右上ですとか左下)への距離

これが同じにならなくて困っている状態です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#32

投稿記事 by softya(ソフト屋) » 14年前

コレジャナイ さんが書きました:正方形と捉えた場合
上方向へニマス進んだ距離

斜め方向のマス(右上ですとか左下)への距離
これが同じにならなくて困っている状態です。
絵的に見ても上方向へニマスと斜め方向のマス(右上ですとか左下)は違う距離だと思いますが?
上方向は2で斜め方向は√2で1.4じゃないでしょうか?

コード:

    +---+    
    | 2 |    
+---+---+---+
|1.4| 1 |1.4|
+---+---+---+
| 1 | 0 | 1 |
+---+---+---+
ななめ方向を2とするのは数学的に破綻すると思いすけど。

【補足】
斜め方向は、歩くのがマスに縛られているので移動力を2消費しますが攻撃は移動力とは違うので斜め移動も有効にして計算しないと破綻します。
距離は整数ではなくdoubleで計算しましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#33

投稿記事 by コレジャナイ » 14年前

おっしゃる通りなのですが・・・。
射程6とした時、攻撃範囲限界までのマス数を6に設定したいのですよね。
したいというより、様々なゲームでこういう仕様になってまして・・・。

そうするためには斜めと上ニマスを等距離にする必要があり、おっしゃる様に破綻してしまいました・・・・orz

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#34

投稿記事 by コレジャナイ » 14年前

距離はdoubleで計算してます

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#35

投稿記事 by beatle » 14年前

射程が6の場合,6歩で到達可能なマスをすべて射程内にしたいということでしょうか.
(1マス移動するのが1歩だと仮定)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#36

投稿記事 by softya(ソフト屋) » 14年前

射程をキャラを中心とする距離で計算すると問題があるのでしょうか?
まぁ、キャラの移動範囲処理を使い回すことはできなくなりますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#37

投稿記事 by コレジャナイ » 14年前

beatleさんのおっしゃる通りですが、それに+αして高低差により範囲を増減させたい形です。(段差が低い場所へ向かっては範囲を増加ささせる等)

ソフト屋さん
距離で計算した場合高低差の問題で悩んでいる状態で御座いますorz
高低差が無ければ、それこそ移動関数の使いまわしで問題ないのですが・・・。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#38

投稿記事 by softya(ソフト屋) » 14年前

私の考える方法としては2つです。
実際に組んでんいないのでしっくりは来ていないんですが。

[その1] 強引に済ませる。
・射程は移動と同じ方法で計算。
・放物線は直線距離で計算。移動距離とは異なるが気にしない。
矛盾は出ると思います。

[その2] まじめに計算。
・平面時の射程は円状。
・届くかどうかを直線距離で放物線だけで計算する。
最大距離は射程の2~3倍とか縛りは必要だと思う。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#39

投稿記事 by コレジャナイ » 14年前

下の方法を取りたいですが、どういう事なのか正確に把握出来ませんでした・・・orz

巷のSLGでは一体どのように範囲取得しているのでしょうかね・・・。
遠距離の範囲はどのゲームも当たり前のように表示してますし、SLG製作の課題はAIだと言われてましたので、正直こんな壁が潜んでいるとは・・・予想しておりませんでしたorz

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#40

投稿記事 by softya(ソフト屋) » 14年前

私も初心者がいきなり難しいタクティクスオウガ系SLGに手を出すのは予想外でした。アマチュアで殆ど見かけないのは難易度が高いからと言うことでしょう。

真面目な方ですが自分を中心として射程距離の2倍?の円を描いて円の中にあるすべてのブロックに対して届くかどうかを放物線で計算します。
計算式は次の式を使い逆算的に求めます。vx0とvy0は普通初速と射角から求めますが着弾点から射角を逆算する必要があります。
加速度aは固定値。xは直線距離でyは高低差。tは時間ですが、これは直線距離から逆算でしょうね。
x = vx0*t
y = vy0*t + 1/2 * a * t^2
ちゃんと式を解いてませんしテストもしていませんので頑張ってみてくださいとしか言えませんが色々やってみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#41

投稿記事 by コレジャナイ » 14年前

何もいきなりこのジャンルへ飛び込んだ訳ではないのですが、自分の実力自体がそう思われても仕方ない程度だということですね。
全く反論の余地がないです。

やはり初心者が手を出すべきではないジャンルですよね。
自分もその点は重々承知しプログラムを組んでおりました。
仮に挫折したとしてもそこへ到達するまでの部分は自分の糧になると思っておりましたので。(実際こんな初歩的な状態ではありますが、このプログラムを組んで既に多くの事を学びました)

ただ段階を踏めという意見はごもっともだと思いますし、一旦このプログラムは中断して色々と考えてみたいと思います・・・。


長い間お付き合い下さって有難う御座いましたm(_ _)m

コレジャナイ

Re: 弓兵など遠距離の攻撃範囲の求め方

#42

投稿記事 by コレジャナイ » 14年前

これで解決とさせて頂きます

YuO
記事: 947
登録日時: 15年前
住所: 東京都世田谷区

Re: 弓兵など遠距離の攻撃範囲の求め方

#43

投稿記事 by YuO » 14年前

解決となっていますし,技術の話ではないですが……。


個人的にSRPGは遊ぶ側として好きなジャンルですが,遊ぶ側からみた場合,数学や物理学に則る必要はないと考えます。
例えば,移動についてマスを単位とする場合,ゲーム中の距離は移動にかかるコストがすべてのマスで同一とみなした状態において,経由するマスの最小数と定義してもゲームは成立します。
# 例に出てきたタクティクスオウガでも,距離はマスの数ですよね。

簡単な方法で,かつ無理を感じさせない方法を考えてみてもよいかと思いますよ。
例えば,「射程範囲は対象が基点より3単位高さ低いと1増える,2単位高さ高いと1減る」という程度でもそれっぽく見えると思います。
# ざっと考えたのでこのままでは仕様として使えませんが。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 弓兵など遠距離の攻撃範囲の求め方

#44

投稿記事 by softya(ソフト屋) » 14年前

平面SLGしか組んだことが無いのでアドバイスとして中途半端だったのは申し訳ないです。
ゲームというのは自分の出来る範囲をちょっとオーバーする程度じゃないと中々最後が見えて来ません。難しい物にチャレンジしたら壁にぶつかるのは当たり前ですから。
そういう時は、アルゴリズムの実験のプログラムだけを組んでみるとか、紙の上で悪戦苦闘してみるとか一週間からひと月ぐらい七転八倒してみても良いと思います。
ずっと考えているとある日突然アルゴリズムのひらめきがやってくる事があります。これがプログラミングの醍醐味だと私は思っています。
楽しんで、頑張ってください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る