レーザーの実装について

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

レーザーの実装について

#1

投稿記事 by 名無し » 16年前

レーザーの当たり判定について質問があります。

龍神録プログラミングの館の34・35章を参考にレーザーを作っていたのですが、
レーザーの当たり判定が出現した瞬間、本来の当たり判定以外の場所(画面全体)に判定が出てしまいます。
画面全体に判定が出るのはその時だけで、以降は正しいレーザーの当たり判定になっています。

これまで1章のプロジェクトファイルを更新する形で作ってきていて、
34章及び35章のプロジェクトファイルと出来る限り見比べてみたのですが、相違が見つかりませんでした。
この場合、不具合の原因は何が考えられるのでしょうか?

ソースコードを貼れればいいのですが、怪しいと思われる場所が特定できませんでした。申し訳ないです。
ちなみにコンパイルの時点ではエラーは発生していません。

yu

Re:レーザーの実装について

#2

投稿記事 by yu » 16年前

>>この場合、不具合の原因は何が考えられるのでしょうか?

う~ん・・・
やはりどこかが違っているのだと思います


>>ソースコードを貼れればいいのですが、怪しいと思われる場所が特定できませんでした。

アップローダーを利用してプロジェクトを全て上げてください。
分からなかったら
out.cpp, out_lazer.cpp, shot.cpp, boss_shotH.cpp
以上のフェイルを添付して見せてください

名無し

Re:レーザーの実装について

#3

投稿記事 by 名無し » 16年前

>>out.cpp, out_lazer.cpp, shot.cpp, boss_shotH.cpp
やはりこの辺が怪しいという事ですよね…。何度も確認してはみたのですが。
プロジェクトファイルを添付しました。
どうぞ宜しくお願いします。

yu

Re:レーザーの実装について

#4

投稿記事 by yu » 16年前

main.cpp内の 
shot_main() と boss_shot_main() の実行する順番を変えてみてださい

レーザーの当たり判定の場所(outpt)を計算する前に
自機とレーザーの当たり判定を計算していました


>>out.cpp, out_lazer.cpp, shot.cpp, boss_shotH.cpp
>>やはりこの辺が怪しいという事ですよね…。何度も確認してはみたのですが。

見事に外れました。orz
これだけのファイルだったら見つけられませんでした

名無し

Re:レーザーの実装について

#5

投稿記事 by 名無し » 16年前

yuさんありがとうございます。解決しました。
main.cpp内で計算する順番が間違っていたのですね。
当たり判定の計算自体が誤っているものとばかり…。
本当にありがとうございました。助かりました。

初心者

レーザー

#6

投稿記事 by 初心者 » 16年前

過去のログに、
東方文花帖でよく使われるレーザーの作り方について
http://www.play21.jp/board/formz.cgi?ac ... &rln=38530
を参考にしていたんですが、

双方向循環リストを使うのは理解したんですが、
それをどうやって2Dのポリゴンで描画するんでしょうか?

チルチル

Re:レーザー

#7

投稿記事 by チルチル » 16年前

簡単に説明すると、ノードの座標を原点として
ノードの角度に対して前後に長さだけ移動
そこから左右に幅だけ移動して4頂点の座標を求め
2Dポリゴンの構造体に代入して描画します

過去ログの時点では未完成でしたが
現在は暫定的に完成しているのでコードを添付します
わからない所があったら言ってください

初心者

Re:レーザー

#8

投稿記事 by 初心者 » 16年前

回答ありがとうございます^^

 Flag の各値の説明をお願いしていいですか?


あと、もし面倒でなければ、
使用例みたいなものを1つ教えて欲しいんですが、

よろしくお願いします。

チルチル

Re:レーザー

#9

投稿記事 by チルチル » 16年前

線形リストの場合は全部同じノードで構成する事により
手順を簡略化できるので、何のノードかをFlagで判断します
まあノードから別の線形リストを伸ばしても良いんですが
それはそれで問題が多いので・・

Flagの値が

-1,削除待ちノード
 0,補間ノード(ボムとかで消された弾ノード)
 1,弾ノード
 2,弾ノード(ボムとかで消えない)
 3,管理ノード
 4,管理ノード(多重描画型)
 5,番兵ノード

見たいな感じです

使用例ですが、これは上で添付したコードを追加して
メインループや初期化処理を追加して、使用する準備を整えた後に
最も簡単な飛行虫ネストみたいなレーザーを下に撃つ場合の処理です

//ザコ敵の移動パターンの処理とかで行う処理
if( Enemy.Count==30 )SetNode(New,3,Enemy.x,Enemy.y,PI/2,3,0,10,10,1,0,0,0,10);//管理ノードを登録

//管理ノードのパターン内で行う処理
if( P->Count<30 )SetNode(P);//弾ノードを登録
if( DeleteJudge(P->Next->x,P->Next->y) )P->flag=-1;//最後尾の弾が画面外に出たら管理ノードを削除

こんな感じです
簡単なレーザーなら3行で撃てます
実行すると添付画像のように見えます

共通部分の機能は弾ノードの並びの形に画像を変形して判定するので
レーザーごとに最低限書くのは
・管理ノード登録処理
・弾ノード登録処理
・管理ノード削除処理
ぐらいですね、目に見えない場合は2番目は必要ないですけど・・
なので特殊なレーザーの場合でも弾ノードを表示したい形に配置するだけでOKです

ねこ

Re:レーザー

#10

投稿記事 by ねこ » 16年前

スレと関係ないのですが、ポリゴン座標求める際角度±90度してますが
ここは前・今・後の三点の中心角度に対して伸ばしたほうが良いですよ。
例えば正三角形の三点をイメージすると線分の終始点に対して90度足すと明らかに変な位置にポリゴン座標が連続しちゃいますよね。
これは三点が鋭角になった時は全てそうなので、始点・終点は現在の方法、その間は三点角度を考慮するとレーザーが壁ではねかえるような描画になっても違和感が多少マシになります。

厳密にはさらに基準点から伸ばした線分同士のの交差判定で補正すると変に角ばった描画になったりするのは大体拭えます。これは分割数によっては計算コストが多いので不要かもしれません。

チルチル

Re:レーザー

#11

投稿記事 by チルチル » 16年前

そういえばそうですね・・
今回は機能面を重視したので描画は結構汚いです
終点始点も最低限の補間なので長いとバリが出たりしますね

中心角度はよくわからないですね・・
そもそも四角形の連続で描画するので
曲げた時にガタガタしないようにするのと
表示がチラチラしないように分割数がかなり多いので
そんなには目立たないのが幸いですね
まあ現状では三点で三角形は描画できないんですが・・

ねこ

Re:レーザー

#12

投稿記事 by ねこ » 16年前

書き方悪かったですね。三角形の描画をするんではなく、正三角形の三点をノードとして登録した場合です。
左下・上・右下。というような。鋭角の説明だったので正三角形はイメージとして挙げただけです。
その際の左下から上の点に向けての角度に±90度は明らかに変な位置に座標取っている事になるので、と(以下略

まぁスレ本題とは関係ないのでこのへんでやめておきます。

チルチル

Re:レーザー

#13

投稿記事 by チルチル » 16年前

角度の補間は結構難しいですね・・

区画の中間はノード同士の中間点を原点にするので
現状で仮に正三角形の三点をノードとして登録すると
多分1回り小さい上下反転した正三角形になりますね
まあ辺の部分にも弾を並べれば問題無いんですが・・

補間する機能を付けると意図的にガタガタさせたい時に不便なので
今の所は現状の方法が無難のようです

この辺は次回への課題ですね・・

初心者

Re:レーザー

#14

投稿記事 by 初心者 » 16年前

>チルチルさん

 理解することができました^^有難うございます
 大変お世話になりました。

>ねこさん

 Angle=(
atan2(p->Next->y - p->y, p->Next->x - p->x) -
atan2(p->y - p->Prev->y, p->x - p->Prev->x)
)/2
 っていうことでしょうか?

初心者

Re:レーザー

#15

投稿記事 by 初心者 » 16年前

Angle=(
atan2(p->Next->y - p->y, p->Next->x - p->x) +
atan2(p->y - p->Prev->y, p->x - p->Prev->x)
)/2

+でした

ねこ

Re:レーザー

#16

投稿記事 by ねこ » 16年前

>初心者さん
ノードの変数見てないので少し予想入りますが
atan2(p->Next->y - p->y, p->Next->x - p->x) +
(atan2(p->y - p->Prev->y, p->x - p->Prev->x) - atan2(p->Next->y - p->y, p->Next->x - p->x) ) / 2.0;
こうかな。2角度を求めて、その差を2で割ってPrev側に足す感じで。
なお、ノードはPrevとNextが無い場合があるので、その場合はPrev⇒Prevの次に対して±90度(逆も同様)、もとい既存処理で良いと思います。

初心者

Re:レーザー

#17

投稿記事 by 初心者 » 16年前

なるほど、有難うございました^^

閉鎖

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