龍神録の支館にあったアシストの実装で

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
てんむすキツネ
記事: 88
登録日時: 9年前
住所: 岡山

龍神録の支館にあったアシストの実装で

#1

投稿記事 by てんむすキツネ » 8年前

タイトル通り、
だいぶ前に、支館にあった「アシスト」の作り方で、
アシストを実装したのですが、

最近になってアシストを使うとバグが発生するようになってしまいました。

どういうバグかというと、
一部のアシストが本来設定していたはずのspdよりも速いスピードで動いてしまうということです。

実際の動画↓


色々調べてみたのですが
とりあえずわかったのは
--------------------------------------------------------------------------------------------
・spd自体は本来あるべきspdと変わってない。(spdの値がおかしいわけではない)

・弾を登録する際、アシストでなく、普通の弾で(boss_shot.assistから→boss_shot.bullet)同じ内容で値を代入すると、
 バグは発生しない(アシストの時のみ発生するということ)

・きちんと指定していた座標に最初は描写されてる。(初期位置はおかしくない)((動画では画面外ですが・・・・

-------------------------------------------------------------------------------------------

いちおう支館のプログラムからいくつか変更した点を書いておきます。
-------------------------------------------------------------------------------------------
・当たり判定をつけた(bulletの処理をコピーして、bulletの部分をassistに変えて)

・↑の処理から、アシストに被弾したとき、自機にあたったアシストは消えないようにした。
 またボムでも消えないようにした(動画でなんとなく分かるかと)

・表示最大数を30から3000にした(bulletと同じ最大数にした)
-------------------------------------------------------------------------------------------

まだブレークポイントぐらいしかデバッグ機能を知らないので、原因がまったくわかりません。
なのでどこのコードを載せればいいのかわからないので、
とりあえず支館のプログラムで似たようなバグがなかったか教えて欲しいです。

ちなみにspdがはやいのは右上頂点から左下頂点にかけて伸びている直線の右上から4~8番目くらいの弾です。
MLP!MLP!

アバター
てんむすキツネ
記事: 88
登録日時: 9年前
住所: 岡山

Re: 龍神録の支館にあったアシストの実装で

#2

投稿記事 by てんむすキツネ » 8年前

原因はまだわかりませんが、
進展があったので載せときます。

登録番号が0~5で(初めてその番号に)登録されたアシストのみ、
処理がおかしいようです。
なので空き番号検索する関数を

コード:

//空き番号を返す
int search_boss_assist()
{
    for(int i=0;i<BOSS_ASSIST_MAX;i++)
    {
        if(boss_shot.assist[i].flag==0 && i>5)
            return i;
    }
    return -1;
}
とすると、問題無く出来ました。

しかし、無理やり直したように見せてるだけなのできちんと原因をさぐろうと思います。
まあ自己解決できそうです。
オフトピック
ここであまり質問したことないのでルールを完全には理解できていません。
もし自己解決できそうなときはどうすればいいのでしょうか?
更新履歴に(禁止行為「自分の勝手な都合で記事を削除する」)とありますが、
この場合は削除しないほうがいいのでしょうか?
MLP!MLP!

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 9年前
住所: 北海道札幌市
連絡を取る:

Re: 龍神録の支館にあったアシストの実装で

#3

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

支館はうちのHPではないので(SouthさんのHP)、プログラムコードは分かりませんが、
spdは適切な値なのに、早く動いてしまうということは、座標計算式がおかしいのでしょう。

特定部分だけ座標計算を1ループで2回なっているとか、特定の条件で計算式が変わっているとか、オーバーフローしているとか・・。
座標計算式の計算前と計算後で正しく計算されているか確認してはいかがでしょうか。

自己解決についてですが、
よろしければ、どうやって解決したのかをログに残して頂けると幸いです。
次に同じ問題で困った人が検索で月狐さんの情報を頼りに解決出来るかもしれません。

禁止行為については、学校の宿題などを質問して、
後から隠滅のために回答が得られたらトピックを消して去っていく人が過去に何人かいたので、作ったものです。

アバター
てんむすキツネ
記事: 88
登録日時: 9年前
住所: 岡山

Re: 龍神録の支館にあったアシストの実装で

#4

投稿記事 by てんむすキツネ » 8年前

<Dixq様

ご親切にありがとうございます!

解決しました!
この処理で、弾幕の座標を計算していたのですが、

コード:

--boss.cpp--
//ボスの弾幕を計算する
void boss_shot_calc(){
	int i;
	boss.endtime[boss.knd]--;
	for(i=0;i<BOSS_BULLET_MAX;i++){
		if(boss_shot.bullet[i].flag>0 && boss_shot.bullet[i].yotyou>9){
			boss_shot.bullet[i].x+=cos(boss_shot.bullet[i].angle)*boss_shot.bullet[i].spd;
			boss_shot.bullet[i].y+=sin(boss_shot.bullet[i].angle)*boss_shot.bullet[i].spd;
			boss_shot.bullet[i].cnt++;
			if(boss_shot.bullet[i].cnt>boss_shot.bullet[i].till){
				if(boss_shot.bullet[i].x<-50 || boss_shot.bullet[i].x>FMX+50 ||
					boss_shot.bullet[i].y<-50 || boss_shot.bullet[i].y>FMY+50)
					boss_shot.bullet[i].flag=0;
			}
		}
	}
	 for( i = 0; i < BOSS_ASSIST_MAX; i++ )
    {
        if( boss_shot.assist[i].flag > 0 )
        {
            boss_shot.assist[i].x += cos(boss_shot.assist[i].angle)*boss_shot.assist[i].spd;
            boss_shot.assist[i].y += sin(boss_shot.assist[i].angle)*boss_shot.assist[i].spd;
            boss_shot.assist[i].cnt++;
            if( boss_shot.assist[i].cnt > boss_shot.assist[i].till )
            {
                if( boss_shot.assist[i].x < -50 || boss_shot.assist[i].x > FMX+50 ||
                    boss_shot.assist[i].y < -50 || boss_shot.assist[i].y > FMY+50 )
                {
                    boss_shot.assist[i].flag=0;
                }
            }
        }
    }
	boss_shot.cnt++;
}
ここでこんな処理をしていました。

コード:

void boss_assist_img(){

	int j,eff;
	double disp_angle;

	if(boss_shot.flag > 0){//弾幕データがオンなら
		for(j=0; j < 5; j++){//その弾幕が持つ弾の最大数分ループ
			if(boss_shot.assist[j].flag != 0){//弾データがオンなら
				//計算部//
				boss_shot.assist[j].x += cos(boss_shot.assist[j].angle) * boss_shot.assist[j].spd;
				boss_shot.assist[j].y += sin(boss_shot.assist[j].angle) * boss_shot.assist[j].spd;
				boss_shot.assist[j].cnt ++;
				//ここまで//
				eff = 0;
				if(boss_shot.assist[j].kaiten==1)
					disp_angle = PI2*(boss_shot.assist[j].cnt%120)/120;
				else
					disp_angle = boss_shot.assist[j].angle+PI/2;
				if(boss_shot.assist[j].eff == 1)
					SetDrawBlendMode(DX_BLENDMODE_ADD, 255),eff = 1;
				if(boss_shot.assist[j].eff == 2)
					SetDrawBlendMode(DX_BLENDMODE_ADD, 255+GetRand(100)),eff = 1 ;
				if(boss_shot.assist[j].c_flag == 0)
					DrawRotaGraphFdF((float)boss_shot.assist[j].x, (float)boss_shot.assist[j].y, 1.0, disp_angle, img_bullet[boss_shot.assist[j].knd][boss_shot.assist[j].col], TRUE);
				else
					DrawRotaGraph2F((float)boss_shot.assist[j].x, (float)boss_shot.assist[j].y, (float)boss_shot.assist[j].cx, (float)boss_shot.assist[j].cy, 1.0, disp_angle, img_bullet[boss_shot.assist[j].knd][boss_shot.assist[j].col], TRUE);

				if(eff == 1)
					SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
			}
		}
	}

	return;
}
なぜこんな処理をかいたかは覚えてないのですが・・・・

あと、描画も2回されていたようです。
弾丸を描画する関数内にもこんな処理が

コード:

for(j=0;j<BOSS_ASSIST_MAX;j++)
        {
            //アシストデータがオンなら
            if(boss_shot.assist[j].flag!=0)
            {
                if(boss_shot.assist[j].eff==1)
                    SetDrawBlendMode( DX_BLENDMODE_ADD, 255) ;
                if(boss_shot.assist[j].kaiten==1)
                    disp_angle=PI2*(boss_shot.assist[j].cnt%120)/120;
                else
                    disp_angle=boss_shot.assist[j].angle+PI/2;
                    DrawRotaGraphF(
                    boss_shot.assist[j].x+FX+dn.x, boss_shot.assist[j].y+FY+dn.y,
                    1.0, disp_angle,
                    img_bullet[boss_shot.assist[j].knd][boss_shot.assist[j].col],TRUE);

                if(boss_shot.assist[j].eff==1)
                    SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0) ;
            }
        }
いらない方を消して、
使いやすい方を残そうと思います。

あと、DrawRotaGraph2Fって関数は、グラフィックの回転描画2とDxLibに書いてありましたが、
詳しい使い方がわかりません。
DxLibリファレンスページにのってない関数の使い方ってどうやったらわかるのでしょうか?
MLP!MLP!

閉鎖

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