ページ 11

画像の重なり

Posted: 2008年11月28日(金) 22:37
by yu
度々と質問ばかりですみません;
なるべく自分で解決しようとしているのですが・・・

ちょっと言葉で説明しにくいのです。
同じ画像を弾の座標に合わせて何回も描画して段々小さくしていくようにして
弾の軌道を描こうと思ったのですが、
少しおかしなことになりました。


画像を何度も描画しているとたまに小さくなっていくのがわかるときがあります。
・・・すみません分かりにくくて;


小さくなっていく時の画像を添付しました
動画のほうが分かりやすかったかな・・・


以下、関係がありそうなところのソースです(管理者様の龍神録をベースに作成してあります。)
#define SHOT_START 500


//弾発射時描画用構造体
typedef struct{
	//フラグ、種類、カウンタ、色、消す時間
	int flag,knd,cnt,col,delcnt;
	//座標、消す速さ、大きさ
	double x,y,delspd,r;
}shot_start_t;


int sertch_shot_start(){//空き番号を返す
	for(int i=0;i<SHOT_START;i++){
		if(shot_start.flag==0)
			return i;
	}
	return -1;
}

//弾発射時のエフェクト登録
//x,x座標、カウント、描く頻度(例:3なら3回に一回かく)、小さくなるスピード、大きさ、種類、色
void shot_graph(double x, double y,int kaisu, double delspd,double r, int knd, int col){
	int k;
	static int cnt;
	if((k=sertch_shot_start())!=-1){
	  shot_start[k].flag  = 1;
	  shot_start[k].cnt   = 0;
	  shot_start[k].delcnt=kaisu;//書く頻度
	  shot_start[k].delspd=delspd;//小さくなるスピード
	  shot_start[k].x     = x;//表示するx座標
	  shot_start[k].y     = y;//表示するy座標
	  shot_start[k].r     = r;//最初の大きさ
	  shot_start[k].knd   = knd;//種類
	  shot_start[k].col   = col;//色 数はkndできまる
  if(cnt%kaisu!=0)//1ならすべて描画
	shot_start[k].flag=0;
  }
  cnt++;
}

//登録例です
void boss_shot_bulletH000(){
#define TM000 200
	int i,t=boss_shot.cnt%TM008;
	if(t%100==0){
		bullet_way(boss.x,boss.y,1,bossatan2(),0, 2,8,1,0,0);
	}
	for(i=0;i<BOSS_BULLET_MAX;i++){
		if(boss_shot.bullet.flag>0){
			shot_graph(boss_shot.bullet.x,boss_shot.bullet.y,1,3,1,0,4);
		}
	}
}


//計算
for(int j=0;j<SHOT_START;j++){
  if(shot_start[j].flag>0){
	shot_start[j].cnt++;
	if(shot_start[j].cnt<3)
	  shot_start[j].r+=0.13;
	if(shot_start[j].cnt>4)
	  shot_start[j].r-=0.01*shot_start[j].delspd;
	if(shot_start[j].r<0)
	  shot_start[j].flag=0;
  }
}


//描画処理(graph_bullet()内にあります)
if(boss_shot.flag>0){//弾幕データがオンなら
   for(j=0;j<SHOT_START;j++){//弾発射時描画
    if(shot_start[j].flag>0){
	DrawRotaGraphFdF(shot_start[j].x, shot_start[j].y,
			shot_start[j].r*2, 0,
			img_shot_start[shot_start[j].knd][shot_start[j].co[/url],TRUE);
    }
  }
}

描く頻度があやしいと思って数値を変えてみたのですが同じでした。
または、SHOT_STARTの数が足りてないのかなと思って2000とかにしても同じでした。
変数内を確認しても数は足りていました。

エラーばかりだしてるバカなので簡単な間違いをしていそうで怖いです。

ソースも・・・分かりにくいですね・・・(というか汚い;
すみません;

Re:画像の重なり

Posted: 2008年11月28日(金) 23:18
by Justy
 うーん、私にはあんまり意味がよくわからなかったです。

「小さくなっていくのがわかるときがあります」とありますが、
小さくしているのだから、わかって当然、と思ってしまいます。

 どういうことなのでしょうか?
 もうちょっと補足をお願いします。

Re:画像の重なり

Posted: 2008年11月29日(土) 00:12
by yu
あぁ!自分で自己解決しました!
Justy様の返信を考えていたらわかりました;
ありがとうございます。


そして、日本語不自由ですみません;
いまから質問内容の意味を再度書いてみます。

この記事で添付した画像の枠で囲ってあるところをみると
他の画像より前面にでてしまっているものがあります。
弾速が早いとあまり気にならないかもしれませんが
最初に添付したものをみるとかなり目立っています;

この弾の軌跡は弾の座標に画像を何回も描画し、小さくしていくことで表現しています。


ご理解頂けたでしょうか?・・・わかりませんよね・・・すみません


以下、原因を書いてみました。
int sertch_shot_start(){//空き番号から返す
	for(int i=0;i<SHOT_START;i++){
		if(shot_start.flag==0)
			return i;
	}
	return -1;
}

と

for(j=0;j<SHOT_START;j++){//弾発射時描画
    if(shot_start[j].flag>0){
	DrawRotaGraphFdF(shot_start[j].x, shot_start[j].y,
			shot_start[j].r*2, 0,
			img_shot_start[shot_start[j].knd][shot_start[j].co[/url],TRUE);
    }
  }

のところで
shot_start[0]~[50]内にそのデータが入ったとすると、
弾が小さくなって最初にshot_start[0]のflagが0になり
そして新しいデータがshot_start[0]に入るとshot_start[50]のほうが
後に描画されるのでshot_start[50]が前面に描画されてしまいました。

本当に説明が下手だ・・・orz



回避するため少し考えてみたのですが、
あまりいい策が思い浮かびません・・・。
上記のことが理解できないかもしれませんが、
もし分かった方がいたら
何か良い方法を教えていただけないでしょうか?

Re:画像の重なり

Posted: 2008年11月29日(土) 00:49
by Justy
 なるほど、理解しました。

 ようするに描画順がおかしいため、見た目がおかしくなるということですね。


>何か良い方法を教えていただけないでしょうか?

 あれ? 自己解決したんじゃ???


 単純に出現した順番(或いは時間とか出現した順を区別できる何か)も記録しておき、
描画するときに新たに出現した順にソートして描画すればいいわけですよね。

 一例を挙げると、描画時に int型のSHOT_START分の配列 order用意し、
shot_start[j].flag>0を満たす jの値を orderに片っ端から入れていきます。

 で、orderに入っている値の shot_start[j]の要素の出現順を比較して
orderの値をソート、最後に orderの値の順番…… shot_start[order[j]]な感じで描画すれば
うまくいくはずです。


 或いは shot_startのような配列ではなくリンクリストを使って管理すれば
追加はリストの先頭に、削除はリストの最後からとすれば
ソートの必要がなくなるので処理は楽になりますね。

Re:画像の重なり

Posted: 2008年11月29日(土) 00:56
by Justy
 ちなみにある程度の規模のゲームになると、描画オブジェクトには描画プライオリティを設けて
それを元にソートしてから表示したりすることがあります。

 3Dだとほぼ必須になりますし、2Dでも例えば自機の前後を動くようなものを
描画する場合、自機の奥にある場合(自機が上)と手前にある場合(自機が下)を表現するために
オブジェクトと自機をソートして描画する必要が出てきます。

 余力が有れば、そのあたりをシステマチックに処理できるように改良してみるのも
いいかと思います。

Re:画像の重なり

Posted: 2008年11月29日(土) 01:24
by yu
自己解決ではなく原因解明ですね・・・
すみません;

なるほど・・・
ソートすればいいのですね。

プログラミングを始めて2か月なので
まだまだ知識不足ですね・・・もっと勉強するようにします。


Justy様、本当にありがとうございました。
返信が早く、とても助かりました。