オプションについて

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

オプションについて

#1

投稿記事 by » 16年前

龍神録のcshot.cpp内でstate_optionが1のとき、
オプションが自機の周りに回るようにしてるのですが、
二つ固まって回ってしまい困ってます・・
添付したような形にしたいのですが、どこを修正したら
いいでしょうか?
また、オプション自体もstate_optionが1のときは
オプションの画像を変えたいのですが変わらなくて困ってます。
誰か助けてください><

ini.cpp内の一部
	option_bb[3].img=img_cshot[5];	//オプションボンボンの画像代入(49)
	option_bb[4].img=img_cshot[5];

cshot.cpp内
#include "../include/GV.h"

int cshot0num[2]  ={2,4};
//通常の自機ショットの1発目は(-10,-30)の位置、2発目は(10,-30)の位置、3発目は(-30,-10)・・・
int cshot0pos_x[4]={-10, 10,-30, 30};
int cshot0pos_y[4]={-30,-30,-10,-10};

#define OPTION_X 25
#define OPTION_Y 35
int    option0num[2]  ={2,4};
double option0ang[4] = {-PI/2,-PI/2,-PI/2-PI/4,-PI/2+PI/4};//オプションの発射角度(49)

//自機ショットの登録可能番号を返す
int search_cshot(){
	for(int i=0;i<CSHOT_MAX;i++){
		if(cshot.flag==0)
			return i;
	}
	return -1;
}

//通常ショット登録A
void ch0_shot_pattern(){
	int k;
	int n=cshot0num[ch.power<200?0:1];
	for(int i=0;i<n;i++){
		if((k=search_cshot())!=-1){
			cshot[k].flag=1;
			cshot[k].cnt=0;
			cshot[k].angle=-PI/2;
			cshot[k].spd=15;
			cshot[k].x=ch.x+cshot0pos_x;
			cshot[k].y=ch.y+cshot0pos_y;
			cshot[k].power= (n<2 ? 20 : 12) +ch.power/100;//2筋なら20,4筋なら12(50)
			cshot[k].knd=0;
			cshot[k].img=img_cshot[0];//画像番号代入(49)
		}
	}
	se_flag[2]=1;//発射音オン
	if(ch.power>=100){
		for(int i=0;i<(ch.power<300?2:4);i++){
			if((k=search_cshot())!=-1){
				cshot[k].flag=1;
				cshot[k].cnt=0;
				cshot[k].angle=option0ang;
				cshot[k].spd=8;
				cshot[k].x=option_bb[i%2].x;
				cshot[k].y=option_bb[i%2].y;
				cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
				cshot[k].knd=1;
				cshot[k].img=img_cshot[1];//画像番号代入(49)
			}
		}
	}
}

//低速通常ショット登録A
void ch1_shot_pattern(){
	int k;
	int n=cshot0num[ch.power<200?0:1];
	for(int i=0;i<n;i++){
		if((k=search_cshot())!=-1){
			cshot[k].flag=1;
			cshot[k].cnt=0;
			cshot[k].angle=-PI/2;
			cshot[k].spd=15;
			cshot[k].x=ch.x+cshot0pos_x/3;//低速中なら位置を中心側へ
			cshot[k].y=ch.y+cshot0pos_y/2;
			cshot[k].power= (n<2 ? 20 : 12) +ch.power/100;//2筋なら20,4筋なら12(50)
			cshot[k].knd=0;
			cshot[k].img=img_cshot[0];//画像番号代入(49)
		}
	}
	se_flag[2]=1;
	if(ch.power>=100){
		for(int i=0;i<(ch.power<300?2:4);i++){
			if((k=search_cshot())!=-1){
				cshot[k].flag=1;
				cshot[k].cnt=0;
				cshot[k].angle=option0ang;
				cshot[k].spd=8;
				cshot[k].x=option_bb[i%2].x;
				cshot[k].y=option_bb[i%2].y;
				cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
				cshot[k].knd=1;
				cshot[k].img=img_cshot[1];//画像番号代入(49)
			}
		}
	}
}

//通常ショット登録B
void ch2_shot_pattern(){
	int k;
	int n=cshot0num[ch.power<200?0:1];
	for(int i=0;i<n;i++){
		if((k=search_cshot())!=-1){
			cshot[k].flag=1;
			cshot[k].cnt=0;
			cshot[k].angle=-PI/2;
			cshot[k].spd=20;
			cshot[k].x=ch.x+cshot0pos_x;
			cshot[k].y=ch.y+cshot0pos_y;
			cshot[k].power= (n<2 ? 20 : 12) +ch.power/100;//2筋なら20,4筋なら12(50)
			cshot[k].knd=0;
			cshot[k].img=img_cshot[3];//画像番号代入(49)
		}
	}
	se_flag[2]=1;//発射音オン
	if(ch.power>=100){
		for(int i=0;i<(ch.power<300?2:4);i++){
			if((k=search_cshot())!=-1){
				cshot[k].flag=1;
				cshot[k].cnt=0;
				cshot[k].angle=option0ang;
				cshot[k].spd=8;
				cshot[k].x=option_bb[i%2].x;
				cshot[k].y=option_bb[i%2].y;
				cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
				cshot[k].knd=0;
				cshot[k].img=img_cshot[4];//画像番号代入(49)
			}
		}
	}
}

//低速通常ショット登録B
void ch3_shot_pattern(){
	int k;
	int n=cshot0num[ch.power<200?0:1];
	for(int i=0;i<n;i++){
		if((k=search_cshot())!=-1){
			cshot[k].flag=1;
			cshot[k].cnt=0;
			cshot[k].angle=-PI/2;
			cshot[k].spd=20;
			cshot[k].x=ch.x+cshot0pos_x[i]/3;//低速中なら位置を中心側へ
			cshot[k].y=ch.y+cshot0pos_y[i]/2;
			cshot[k].power= (n<2 ? 20 : 12) +ch.power/100;//2筋なら20,4筋なら12(50)
			cshot[k].knd=0;
			cshot[k].img=img_cshot[3];//画像番号代入(49)
		}
	}
	se_flag[2]=1;
	if(ch.power>=100){
		for(int i=0;i<(ch.power<300?2:4);i++){
			if((k=search_cshot())!=-1){
				cshot[k].flag=1;
				cshot[k].cnt=0;
				cshot[k].angle=option0ang[i];
				cshot[k].spd=8;
				cshot[k].x=option_bb[i%2].x;
				cshot[k].y=option_bb[i%2].y;
				cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
				cshot[k].knd=0;
				cshot[k].img=img_cshot[4];//画像番号代入(49)
			}
		}
	}
}

Re:オプションについて

#2

投稿記事 by » 16年前

続き
//オプションのぼんぼん計算
void calc_option_bb(){
	switch(state_option){
		case 0://選択
			if(ch.power>=100){//パワー100以上ならオプションをつける
				for(int i=0;i<5;i++){
					if(CheckStatePad(configpad.slow)==0){//低速移動中じゃないなら
						option_bb.x=ch.x+OPTION_X*(i==0 ? -1 : 1);
						option_bb.y=ch.y+OPTION_Y+sin(PI2/150*option_bb.cnt)*13;
					}
					else{
						option_bb.x=ch.x+OPTION_X/2*(i==0 ? -1 : 1);
						option_bb.y=ch.y+OPTION_Y/2;
					}
					option_bb.cnt++;
				}
				if(option_bb[0].flag==0)
					option_bb[0].flag = option_bb[1].flag = 1;
			}
			else{
				if(option_bb[0].flag==1)
					option_bb[0].flag = option_bb[1].flag = 0;
			}
			break;
		case 1:
			if(ch.power>=100){//パワー100以上ならオプションをつける
				for(int i=0;i<5;i++){
					//if(CheckStatePad(configpad.slow)==0){//低速移動中じゃないなら
					//	option_bb.x=ch.x0+sin(PI2/150*option_bb.cnt)*40;
					//	option_bb.y=ch.y0+OPTION_Y*(i==0 ? -1 : 1);
					//}
					//else{
					//	option_bb.x=ch.x0+OPTION_X/2*(i==0 ? -1 : 1);
					//	option_bb[i].y=ch.y0+OPTION_Y/2;
					//}
					if(CheckStatePad(configpad.slow)==0){//低速移動中じゃないなら
						ch.x0 = 60 * cos(2*PI*(count%50)/50) + ch.x;
						ch.y0 = 60 * sin(2*PI*(count%50)/50) + ch.y;
						option_bb[i].x=ch.x0+10*(i==0 ? -1 : 1);
						option_bb[i].y=ch.y0;
					}
					else{
						ch.x0 = 20 * cos(2*PI*(count%50)/50) + ch.x;
						ch.y0 = 20 * sin(2*PI*(count%50)/50) + ch.y;
						option_bb[i].x=ch.x0+10/2*(i==0 ? -1 : 1);
						option_bb[i].y=ch.y0+10/2;
					}
					option_bb[i].cnt++;
				}
				if(option_bb[0].flag==0)
					option_bb[3].flag = option_bb[4].flag = 1;
			}
			else{
				if(option_bb[0].flag==1)
					option_bb[3].flag = option_bb[4].flag = 0;
			}
			break;
		default:
			printfDx("不明なstate_option\n");
			break;
	}
}


//ショット登録部
void enter_shot(){
	//ショットボタンが押されていたら
	if(CheckStatePad(configpad.shot)>0){
		ch.shot_cnt++;
		switch(state_option){
			case 0://選択
				if(ch.shot_cnt%3==0){//3カウントに1回
					if(CheckStatePad(configpad.slow)>0)//低速移動中なら
						ch1_shot_pattern();
					else
						ch0_shot_pattern();
				}
				break;
			case 1:
				if(ch.shot_cnt%3==0){//3カウントに1回
					if(CheckStatePad(configpad.slow)>0)//低速移動中なら
						ch3_shot_pattern();
					else
						ch2_shot_pattern();
				}
				break;
			default:
				ch.shot_cnt=0;
				break;
		}
	}
	//else
	//	ch.shot_cnt=0;
}

//一番近い敵を探して角度をセットする
void calc_homing(int k){
	int i,d, num=-1, min=-1;
	double x,y;
	if(boss.flag==0){//ボスが居ない時
		for(i=0;i<ENEMY_MAX;i++){//敵の総数分
			if(enemy[i].flag==1){
				x=(enemy[i].x-cshot[k].x);
				y=(enemy[i].y-cshot[k].y);
				d=(int)(x*x+y*y);//ショットと敵の距離
				if(d<min || min==-1){//計算結果が最小値かまだ格納していないなら
					num=i;//番号記録
					min=d;//距離記録
				}
			}
		}
	}
	//近い敵が見つかったら、あるいはボスがいて、HPがあるときは角度をセット、かつ描画しないフラグがオフ
	if(num!=-1 || boss.flag==1 && boss.hp>0 && boss.graph_flag==0){
		if(boss.flag==0){
			x=enemy[num].x-cshot[k].x;
			y=enemy[num].y-cshot[k].y;
		}
		else{
			x=boss.x-cshot[k].x;
			y=boss.y-cshot[k].y;
		}
		cshot[k].angle=atan2(y,x);
	}
}

//ショットの移動計算
void calc_cshot(){
	for(int i=0;i<CSHOT_MAX;i++){
		if(cshot[i].flag==1){
			int dranx=(int)(cshot[i].spd+11/2),drany=(int)(cshot[i].spd+55/2);
			if(cshot[i].knd==1)
				calc_homing(i);
			cshot[i].x+=cos(cshot[i].angle)*cshot[i].spd;
			cshot[i].y+=sin(cshot[i].angle)*cshot[i].spd;
			cshot[i].cnt++;
			if(cshot[i].x<-dranx || cshot[i].x>FMX+dranx ||
				cshot[i].y<-drany || cshot[i].y>FMY+drany)//画面から外れたら
				cshot[i].flag=0;
		}
	}
}

//キャラクタショットに関する関数
void cshot_main(){
	calc_option_bb();//オプションのぼんぼん計算(49)
	calc_cshot();//ショットの起動計算
	if( func_state != 103){
		enter_shot();//ショット登録
	}
}

チルチル

Re:オプションについて

#3

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

プログラムを読み解くのは苦手なので確信はありませんが

2つ固まってしまうなら片方の角度に+PIすれば反対側に行くんじゃないでしょうか?

画像を変えるのはstate_optionを配列の要素番号指定に使うか直接分岐すれば良いんじゃないでしょうか?

Re:オプションについて

#4

投稿記事 by » 16年前

>>チルチルさん
片方の角度とはプログラムでいうと、どこを指しているのでしょうか?

チルチル

Re:オプションについて

#5

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

オプションの座標を計算する三角関数の引数です

プログラムで言うと(多分)ここです

ch.x0 = 60 * cos(2*PI*(count%50)/50) + ch.x;

ch.y0 = 60 * sin(2*PI*(count%50)/50) + ch.y;

Re:オプションについて

#6

投稿記事 by » 16年前

ch.x0 = 60 * cos(2*PI*(count%50)/50) + ch.x+PI;
ch.y0 = 60 * sin(2*PI*(count%50)/50) + ch.y+PI;
こうってことですか?
特に変わりませんでした。
というか、どれが一つのオプションを表していて、
もう一つのオプションがどれを表してるとうのがよく分かりません。

それに
option_bb.x=ch.x0+10*(i==0 ? -1 : 1);
等の()内のプログラムが何を言ってるのかが分からないのですが、
解説お願いしてもらえませんでしょうか?

conio

Re:オプションについて

#7

投稿記事 by conio » 16年前

①「角度を足す」のと、
②「足す角度の値を足す」のは 全然意味が違ってしまいますよ。

------------------------------------------
①x = sin(90゜+ 90゜);  //x = sin(180)、 x = 0
②x = sin(90゜) + 90;  //x = 1 + 90、   x = 91
------------------------------------------

☆さんのは、①ではなく、②を実行してます。


>>というか、どれが一つのオプションを表していて、 
>>もう一つのオプションがどれを表してるとうのがよく分かりません。 
プログラムはコピーペーストなのですか?
自分で書いたわけでは無いのですか?
質問内容を見ると、オプションの部分は自分で実装させようとしているように感じました。


>>option_bb.x=ch.x0+10*(i==0 ? -1 : 1); 
>>等の()内のプログラムが何を言ってるのかが分からないのですが、 
()内は条件演算子です。

iが0なら-1、そうでないなら1となります。
下記のif文と同じ動作です。
---------------------------------------
if(i==0){
  option_bb.x=ch.x0+10*-1; 
}else if(i != 0){
  option_bb.x=ch.x0+10*1; 
}
---------------------------------------

チルチル

Re:オプションについて

#8

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

確信はありませんがfor(int i=0;i<5;i++)から察するに
オプションを5個まで出現させれるようですね
つまりi=0が1個目でi=1が2個目だと思います

ch.x0とch.y0は自機の座標から求めた原点のようですが
今回は自機が回転軸なので必要ない気がします

option_bb.xとoption_bb.yがオプションの座標のようなので


ch.x0 = 60 * cos(2*PI*(count%50)/50) + ch.x;

ch.y0 = 60 * sin(2*PI*(count%50)/50) + ch.y;

option_bb.x=ch.x0+10*(i==0 ? -1 : 1);

option_bb.y=ch.y0;


の部分を


option_bb.x=60*cos(PI/30*count+PI*i)+ch.x;

option_bb.y=60*sin(PI/30*count+PI*i)+ch.y;


に変えれば行けるかもしれません


option_bb.x=ch.x0+10*(i==0 ? -1 : 1);

これは多分オプションを右と左にずらしているんだと思います

Re:オプションについて

#9

投稿記事 by » 16年前

>>conioさん
解説ありがとうございます。
なるほど、条件演算子でしたか。
最近まったく使ったことなかったのですっかり忘れてましたorz

角度を足すとはこういうことでいいでしょうか?
ch.x0 = 20 * cos(2*PI*(count%50)/50+PI) + ch.x;
ただ、これでも画像のように二つ一緒に回ってしまうのですが・

Re:オプションについて

#10

投稿記事 by » 16年前

>>チルチルさん
おお!動きました!ありがとうございます!
ch.x0とch.y0はオプションが自機の周りをまわりながら
オプション自体も回るようにしようとしたのですが・・

あとは
オプション自体もstate_optionが1のときは
オプションの画像を変えたいのですが
多分、
if(option_bb[0].flag==0)
option_bb[3].flag = option_bb[4].flag = 1;

else{
if(option_bb[0].flag==1)
option_bb[3].flag = option_bb[4].flag = 0;

このへんがおかしいと思ってるのですが、どこが間違ってるのでしょうか?

conio

Re:オプションについて

#11

投稿記事 by conio » 16年前

---------------------------------------------------------------------------------
ini.cpp内の一部
	option_bb[3].img=img_cshot[5];	//オプションボンボンの画像代入(49)
	option_bb[4].img=img_cshot[5];
---------------------------------------------------------------------------------
上記のプログラムを見た限り、"img"というメンバで画像の種類を選択しているっぽいので、
とりあえず、下記の赤字の部分のようにしてみてはどうでしょうか。


------------------------------------------------------------------------------------------------
		case 1:
                           for(int i = 0; i < 5; i++)
                              option_bb.img = //任意の画像番号を指定
			if(ch.power>=100){//パワー100以上ならオプションをつける
				for(int i=0;i<5;i++){
					//if(CheckStatePad(configpad.slow)==0){//低速移動中じゃないなら
					//	option_bb.x=ch.x0+sin(PI2/150*option_bb.cnt)*40;
					//	option_bb.y=ch.y0+OPTION_Y*(i==0 ? -1 : 1);
					//}
					//else{
					//	option_bb.x=ch.x0+OPTION_X/2*(i==0 ? -1 : 1);
					//	option_bb.y=ch.y0+OPTION_Y/2;
					//}
					if(CheckStatePad(configpad.slow)==0){//低速移動中じゃないなら
						ch.x0 = 60 * cos(2*PI*(count%50)/50) + ch.x;
						ch.y0 = 60 * sin(2*PI*(count%50)/50) + ch.y;
						option_bb.x=ch.x0+10*(i==0 ? -1 : 1);
						option_bb.y=ch.y0;
					}
					else{
						ch.x0 = 20 * cos(2*PI*(count%50)/50) + ch.x;
						ch.y0 = 20 * sin(2*PI*(count%50)/50) + ch.y;
						option_bb.x=ch.x0+10/2*(i==0 ? -1 : 1);
						option_bb.y=ch.y0+10/2;
					}
					option_bb[i].cnt++;
				}
				if(option_bb[0].flag==0)
					option_bb[3].flag = option_bb[4].flag = 1;
			}
			else{
				if(option_bb[0].flag==1)
					option_bb[3].flag = option_bb[4].flag = 0;
			}
			break;
------------------------------------------------------------------------------------------------

Re:オプションについて

#12

投稿記事 by » 16年前

>>conioさん
あの・・
graph.cpp内はこうなってるのですが・・

//自機ショット描画
void graph_cshot(){
	for(int i=0;i<CSHOT_MAX;i++){
		if(cshot.flag>0){
			DrawRotaGraphFdF(cshot.x,cshot.y,1,cshot.angle+PI/2,cshot.img,TRUE);
		}
	}
	for(int i=0;i<5;i++){//オプション(49)
		if(option_bb.flag>0){
			DrawRotaGraphFdF(option_bb.x,option_bb.y,1.0,2.0*PI*(count%120)/120,option_bb.img,TRUE);
		}
	}
}


ここの部分は
if(option_bb[0].flag==0)
	option_bb[3].flag = option_bb[4].flag = 1;
}
else{
if(option_bb[0].flag==1)
	option_bb[3].flag = option_bb[4].flag = 0;
コメントアウトするということでしょうか?

Re:オプションについて

#13

投稿記事 by » 16年前

すみません。質問を間違えてました。
if(option_bb[0].flag==0)
	option_bb[3].flag = option_bb[4].flag = 1;
}
else{
if(option_bb[0].flag==1)
	option_bb[3].flag = option_bb[4].flag = 0;
にしたら
state_option=1のときはちゃんとオプションが描画されてるのですが
state_option=0のときにもstate_option=1と同じオプションが一緒に描画されてしまうバグが
起こってしまいます。state_option=0は
if(option_bb[0].flag==0)
	option_bb[0].flag = option_bb[1].flag = 1;
}
else{
if(option_bb[0].flag==1)
	option_bb[0].flag = option_bb[1].flag = 0;
だけ表示するようにしたいです

conio

Re:オプションについて

#14

投稿記事 by conio » 16年前

まず、"オプション"のシステムが曖昧なので確認してみます。

"オプション"というのは
-----------------------
① 0番と1番と2番を描画
②  3番と4番と2番を描画
-----------------------
の2種類があり、それらは排他的と言うことでしょうか?
(①と②、どちらか一方しか描画しない。case 0,case 1で分岐させる事により実装。)


それともう一つ。
①と②の状態遷移は複数回起こるものなのですか?
(①→②→①→②→①・・・)


とりあえず、
【1】オプションは2種類あり、排他的。
【2】オプション①になったり、オプション②になったりする
という条件で考えると、下記の様にすればよいと思います。
--------------------------------------------------------
switch(state_option){
    case 0:
           if(攻撃力 >= 100){
             if(オプション0番が付いていなければ)
                オプション0番と1番を描画するフラグを立てる。
           }else{
             if(オプション0番が付いていれば)
                オプション0番と1番を描画フラグを消す。
           }
           break;
    case 1:
           if(攻撃力 >= 100){
             if(オプション3番が付いていなければ)
                オプション3番と4番を描画するフラグを立てる。
           }else{
             if(オプション3番が付いていれば)
                オプション3番と4番を描画フラグを消す。
           }
           break;
}
--------------------------------------------------------
※状態遷移する際は現在描画されているオプションの描画フラグを0に戻して下さい。


で、オプション①とオプション②で画像を変えたいのであれば、
下記の様に初期化しておけば良いと思います。
-------------------------------------
option_bb[0].img = //任意の画像番号A
option_bb[1].img = //任意の画像番号A

option_bb[3].img = //任意の画像番号B
option_bb[4].img = //任意の画像番号B
-------------------------------------

Re:オプションについて

#15

投稿記事 by » 16年前

>>conioさん
>状態遷移する際は現在描画されているオプションの描画フラグを0に戻して下さい
これを見事に初期化するのを忘れていたために発生したバグであることが分かりました。
助かりました。ありがとうございました。

それと、もうちょっと聞きたいことがあるのですが
パワーが300~400のときに添付した画像のように
三角の形でまわしたいのですが、三角の形がどうしてもできません。
どのようにしたらいいのでしょうか?

チルチル

Re:オプションについて

#16

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

三角関数は早くマスターした方が良いですよ

option_bb.x=60*cos(PI/30*count+PI2/3*i)+ch.x;

option_bb.y=60*sin(PI/30*count+PI2/3*i)+ch.y;

で行けると思います、全方位ショットと同じような感じです

Re:オプションについて

#17

投稿記事 by » 16年前

あの、オプション自体を一つ増やすにはどこのプログラムが関係して
どの部分を変更すればいいのでしょうか?

conio

Re:オプションについて

#18

投稿記事 by conio » 16年前

"option_bb"を増やせば良いのではないでしょうか。
何処にあるのかは知りませんが、恐らくoption_bb[5];みたいになっていると思います。
(for文の繰り返し回数から判断。)

そのオプションの配列を増やせば良いのではないのかと。


あと、プログラムを把握できていないままどんどん開発を進めようとすると、
どんどんゴチャゴチャになって訳が分からなくなる可能性が高いですので、
一旦、プログラムがどういう構造になっているのか、どの変数が何を定義しているのか
などを確実に理解してから 進める事をお勧めします。

チルチル

Re:オプションについて

#19

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

現時点でも5個用意してあるようなので
option_bb[2].flag=1;
で3個目が使えるんじゃないでしょうか?
0番と1番のフラグを立てている所に追加するのが一番ですが・・

閉鎖

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