ページ 1 / 1
オプションについて
Posted: 2009年9月06日(日) 05:12
by ☆
龍神録の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:オプションについて
Posted: 2009年9月06日(日) 05:13
by ☆
続き
//オプションのぼんぼん計算
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:オプションについて
Posted: 2009年9月06日(日) 12:21
by チルチル
プログラムを読み解くのは苦手なので確信はありませんが
2つ固まってしまうなら片方の角度に+PIすれば反対側に行くんじゃないでしょうか?
画像を変えるのはstate_optionを配列の要素番号指定に使うか直接分岐すれば良いんじゃないでしょうか?
Re:オプションについて
Posted: 2009年9月06日(日) 13:31
by ☆
>>チルチルさん
片方の角度とはプログラムでいうと、どこを指しているのでしょうか?
Re:オプションについて
Posted: 2009年9月06日(日) 14:18
by チルチル
オプションの座標を計算する三角関数の引数です
プログラムで言うと(多分)ここです
ch.x0 = 60 * cos(2*PI*(count%50)/50) + ch.x;
ch.y0 = 60 * sin(2*PI*(count%50)/50) + ch.y;
Re:オプションについて
Posted: 2009年9月06日(日) 14:52
by ☆
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);
等の()内のプログラムが何を言ってるのかが分からないのですが、
解説お願いしてもらえませんでしょうか?
Re:オプションについて
Posted: 2009年9月06日(日) 15:21
by conio
①「角度を足す」のと、
②「足す角度の値を足す」のは 全然意味が違ってしまいますよ。
------------------------------------------
①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:オプションについて
Posted: 2009年9月06日(日) 15:35
by チルチル
確信はありませんが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:オプションについて
Posted: 2009年9月06日(日) 15:39
by ☆
>>conioさん
解説ありがとうございます。
なるほど、条件演算子でしたか。
最近まったく使ったことなかったのですっかり忘れてましたorz
角度を足すとはこういうことでいいでしょうか?
ch.x0 = 20 * cos(2*PI*(count%50)/50+PI) + ch.x;
ただ、これでも画像のように二つ一緒に回ってしまうのですが・
Re:オプションについて
Posted: 2009年9月06日(日) 15:47
by ☆
>>チルチルさん
おお!動きました!ありがとうございます!
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;
このへんがおかしいと思ってるのですが、どこが間違ってるのでしょうか?
Re:オプションについて
Posted: 2009年9月06日(日) 16:05
by conio
---------------------------------------------------------------------------------
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:オプションについて
Posted: 2009年9月06日(日) 17:05
by ☆
>>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:オプションについて
Posted: 2009年9月06日(日) 17:17
by ☆
すみません。質問を間違えてました。
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;
だけ表示するようにしたいです
Re:オプションについて
Posted: 2009年9月06日(日) 18:39
by conio
まず、"オプション"のシステムが曖昧なので確認してみます。
"オプション"というのは
-----------------------
① 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:オプションについて
Posted: 2009年9月07日(月) 22:44
by ☆
>>conioさん
>状態遷移する際は現在描画されているオプションの描画フラグを0に戻して下さい
これを見事に初期化するのを忘れていたために発生したバグであることが分かりました。
助かりました。ありがとうございました。
それと、もうちょっと聞きたいことがあるのですが
パワーが300~400のときに添付した画像のように
三角の形でまわしたいのですが、三角の形がどうしてもできません。
どのようにしたらいいのでしょうか?
Re:オプションについて
Posted: 2009年9月07日(月) 23:01
by チルチル
三角関数は早くマスターした方が良いですよ
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:オプションについて
Posted: 2009年9月08日(火) 00:42
by ☆
あの、オプション自体を一つ増やすにはどこのプログラムが関係して
どの部分を変更すればいいのでしょうか?
Re:オプションについて
Posted: 2009年9月08日(火) 02:06
by conio
"option_bb"を増やせば良いのではないでしょうか。
何処にあるのかは知りませんが、恐らくoption_bb[5];みたいになっていると思います。
(for文の繰り返し回数から判断。)
そのオプションの配列を増やせば良いのではないのかと。
あと、プログラムを把握できていないままどんどん開発を進めようとすると、
どんどんゴチャゴチャになって訳が分からなくなる可能性が高いですので、
一旦、プログラムがどういう構造になっているのか、どの変数が何を定義しているのか
などを確実に理解してから 進める事をお勧めします。
Re:オプションについて
Posted: 2009年9月08日(火) 14:23
by チルチル
現時点でも5個用意してあるようなので
option_bb[2].flag=1;
で3個目が使えるんじゃないでしょうか?
0番と1番のフラグを立てている所に追加するのが一番ですが・・