弾の透かし方

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

弾の透かし方

#1

投稿記事 by TH » 16年前

仏の顔も三度までと言うのに四回目の投稿…
掲示板の投稿者に自分の名前が並ぶと泣きたくなります…
と御託を並べても仕方が無いので本題に入らせていただきます。

よく東方では「弾が発射される時に少し弾がぼかされてから描画される」事があります。
また、この「弾がぼかされている状態」では弾に当たり判定がなく、また自機と座標が近い場合
その弾が表示されないという事もあります。
例によってこれを実装しようとして行き詰ってしまいました…。

特に分からないのは前者なんです。
弾をぼかす、というのはどういう処理をすればいいのか皆目検討が尽きません。

後者は、弾毎にboss_shot.bullet[n].min_time といった感じに
弾のあたり判定を持つ時間を決めておき、boss_shot.bullet[n].cntがそれを超えた場合に
当たったか当たってないかを判定するようにしようと思っているのですが、
「自機と座標が近い場合」というのをどうするのか分からないのです。

分からない分からないと言って酷く情けなくなってきます。
実際に自機ショットと敵の当たり判定処理、敵ショットと自機の当たり判定処理なども
「何となく三平方の定理使うのかな」と思っているぐらいでさっぱりでございます…。
質問内容に曖昧な点がありましたら出来るだけ早く対応したいと思いますので
何とぞお願いいたします。

nayo

Re:弾の透かし方

#2

投稿記事 by nayo » 16年前

ぼかすのではなくアルファブレンドで少し半透明にして、ではダメなんですかね?
ぼかすといっても色々なぼかし方があるので具体的な例があれば答えやすいかも
東方だとそもそも発射直後は別の弾の画像が見えていて徐々にその弾を薄くしつつ別の弾の画像を濃くしていく、
などとしている場合もあるような気がします(確信は持てませんが

発射直後は当たり判定が無いようにしたい、というのは今考えているようなやり方でいいと思います
当たり判定が有効になるまでの時間をセットして、毎フレームそのカウントを減少させ、
値が0以下になったら当たり判定処理をする、といった感じでしょうか

自機付近では弾が発射されないようにしたい、ということに関しては
龍神録の館の敵弾発射関数で考えるなら
// プレイヤーと弾の距離がrange以下(近い)なら真値を返す
// float x, float yとなってますがここは適宜自分の変数の型に直して下さい
// もし当たり判定を円で考えているならrangeをプレイヤーの当たり判定半径と同じにすれば当たり判定もできます
// pow( a, b ) …… aのb乗を返す関数
bool CheckShotOK( float x, float y, float range )
{
	// 三平方の定理より中心(x,y)、半径rangeの円内にプレイヤーが居たら
	if( pow( (プレイヤーx座標 - x),2 ) + pow(プレイヤーy座標-y),2 ) < pow( range, 2 ) )
	{	// 範囲内なので真値を返す
		return TRUE;
	}

	// 範囲外なので偽値を返す
	return FALSE;
}

// 100カウント中に10発、自機に向かって直線発射(常に自機狙い)
void shot_bullet_H001( int n )
{
	int t = shot[n].cnt;
	int k;
	// 100カウント中10カウントに1回
	if( t >= 0 && t < 100 && t % 10 == 0 )
	{	// 敵がいて、弾が登録可能なら
		if( shot[n].flag != 2 && ( k = shot_search(n) ) != -1 )
		{
			shot[n].bullet[k].x	= enemy[shot[n].num].x;	// x座標
			shot[n].bullet[k].y	= enemy[shot[n].num].y;	// y座標

			if( CheckShotOK( shot[n].bullet[k].x, shot[n].bullet[k].y, 20 ) )
			{	// もしプレイヤーが発射位置に近すぎたら発射フラグは立てずに終わる
				return;
				// もしfor文で同時に複数方向や複数個所から発射しているなら
				// returnをcontinueに変えるといいかも
			}

			shot[n].bullet[k].knd	= enemy[shot[n].num].blknd2;	// 弾登録
			shot[n].bullet[k].angle	= shotatan2( n );		// 角度
			shot[n].bullet[k].flag	= TRUE;			// フラグ
			shot[n].bullet[k].col	= enemy[shot[n].num].col;	// 色
			shot[n].bullet[k].cnt	= 0;				// カウンタ
			shot[n].bullet[k].spd	= 3;				// スピード
			se_flag[0]		= 1;				// 効果音
                }
        }
}
などと、弾の発射フラグを立てる前にプレイヤーとの距離を調べ、
近いなら発射フラグを立てずに終了するといいかと思います

Dixq (管理人)

Re:弾の透かし方

#3

投稿記事 by Dixq (管理人) » 16年前

優曇華みたいなやつですかね?
[nico]http://www.nicovideo.jp/watch/sm548146[/nico]
3:41~

う~ん、アルファブレンドで薄くして、周辺に同じ画像を何度も書いてみてはどうでしょう?
SetDrawBlendMode( アルファ, (この値は何度かやって調整) );

//1ピクセル離れた周辺に描画
for(i=0; i<N(この値は何度かやって調整); i++){
    DrawGraphF( x+cos(PI2/N*i)*1, y+sin(PI2/N*i)*1, ...);
}
//2ピクセル離れた周辺に描画
for(i=0; i<N(この値は何度かやって調整); i++){
    DrawGraphF( x+cos(PI2/N*i)*2, y+sin(PI2/N*i)*2, ...);
}
//中心に描画
DrawGraphF( x, y, ...);
やってみないとうまくいくかどうかわかりませんが、こんな感じでどうでしょうか?

当たり判定についてはすでに館で実装済みですよね。
弾に当たり判定処理をするかどうかのフラグを作り、それがオフになっている弾は当たり判定を計算しないようにすればいいと思います。

kazuoni

Re:弾の透かし方

#4

投稿記事 by kazuoni » 16年前

>管理人さん
あ、ついにウィザードの称号を手にしましたねw
本当にお疲れ様です。w

Dixq (管理人)

Re:弾の透かし方

#5

投稿記事 by Dixq (管理人) » 16年前

おぉ・・気づきませんでしたが、そのようですね^^;
設定した頃はまさか100万ポイントなんて貯まるとは思ってもいませんでしたが・・。

「昇進状態」みてみるといい感じに食物連鎖的な三角形になってますねw
kazuoniさんも是非ウィザード目指して下さいw

TH

Re:弾の透かし方

#6

投稿記事 by TH » 16年前

>>nayoさん
回答ありがとうございます。
サンプルまで作って頂き、恐縮です…。
当たり判定は円で行われていたのですか。
またソースコードを凝視する作業になりそうです…。

>>Dixqさん
ウィザードおめでとうございます。
優曇華の…とは少し違うのでしょうか。キスメのキャプチャーウェブみたいな感じですね。
[nico]http://www.nicovideo.jp/watch/sm6318452[/nico] コレの2:31ぐらいです。
低画質ですが…。
弾の発射している瞬間は紫色に弾の周辺がぼけていますよね(たぶん)
それを実装したいのですが…

それと、この場合タイトルは弾のぼかし方でしたね。
申し訳ございません・・・

Dixq (管理人)

Re:弾の透かし方

#7

投稿記事 by Dixq (管理人) » 16年前

それなら予めぼかした画像を上からかぶせたらいいのではないでしょうか?

TH

Re:弾の透かし方

#8

投稿記事 by TH » 16年前

>>Dixq

なるほど。
確かにそれならぼかしたように見えますね。
ありがとうございました。

閉鎖

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