撃ち返しについて【龍神録プログラミングの館 改変】

アバター
Tatu
記事: 445
登録日時: 14年前
住所: 北海道

撃ち返しについて【龍神録プログラミングの館 改変】

投稿記事 by Tatu » 12年前

http://dixq.net/forum/viewtopic.php?f=3&t=13573を見て
龍神録プログラミングの館の改変について書いてみました。
前に書いたのいつだっけ。

今回のテーマは撃ち返しです。
ザコの撃ち返しのみ扱います。
既に改変したものに手を加えているため、
全く同じことをしてもうまくいかないかもしれません。


1.撃ち返しってなに?
2.実装の方法
3.コードなどの変更


1.撃ち返しってなに?
シューティングゲームにおいて敵を倒すと発生する攻撃のことです。
英語ではsuicide bullet,return bullet,revenge bulletなどと呼ばれるそうです。

2.実装の方法
龍神録プログラミングの館ではshot構造体によってザコの弾幕を制御しています。
shot構造体のフラグは敵が出現してからその敵に設定された弾幕の開始時間がたったら立てられます。
そこで、撃ち返しの場合は敵が倒された時に撃ち返し用の弾幕のフラグを立てるようにします。
撃ち返し用の弾幕関数は敵が死んでいても弾が出る以外は通常の弾幕関数と同じです。
よって今回は通常の弾幕関数と同じファイルに書くことにします。


3.コードなどの変更

struct.h
enemy_tとenemy_order_tのメンバに

CODE:

	//撃ち返し弾幕の種類 -1ならば撃たない
	int reblknd;
を追加。
この変数が-1ならば撃ち返しをしないようにし、
0以上ならば撃破された時に対応した弾幕を登録するようにします。


load.cpp
load_story()を書き換え、
撃ち返し弾幕の番号を読み込めるようにします。

CODE:

case 18:enemy_order[n].reblknd	=atoi(inputc);break;
を追加し、

CODE:

if(num==18){

CODE:

if(num==19){
に変更します。

エクセルファイルに撃ち返し弾幕情報の追加をします。

右端の行に
撃ち返し弾幕
reblknd
数字(対応した弾幕の番号、撃たない場合は-1)
を入れる。上の二つはコメント。

撃ち返し確認用の弾幕関数を作成します。
名前は普段通りshot_bullet_H***とします。

弾幕関数に関するshotH.cppとshot.cppの変更については省略します。
敵がすでに死んだ状態であるため、弾登録時の判定にshot[n].flag!=2をつけていると弾が出ないことに注意してください。

shot.cpp
shot_calc()の

CODE:

	//現在表示中の弾が一つでもあるかどうか調べる
	for(i=0;i0)
			return;
	//現在表示中の弾が一つもなければ
	if(enemy[shot[n].num].flag!=1){
		enemy[shot[n].num].flag=0;
		shot[n].flag=0;//終了
	}

CODE:

	if(shot[n].cnt>180){
		//現在表示中の弾が一つでもあるかどうか調べる
		for(i=0;i0)
				return;
		//現在表示中の弾が一つもなければ
		if(enemy[shot[n].num].flag!=1){
			shot[n].flag=0;//終了
		}
	}
に変更。

弾幕開始から3秒たたないと弾幕が終了しないようにしています。
これは敵が死んでいるため、このようにしないと0カウント目で撃つようにしなければならず
やられてから少ししてから撃ち始めるという事が出来ないからです。
また、enemy[shot[n].num].flag=0;
を削除して通常の弾幕が終了した時に敵のフラグが0にならないようにしています。
これは撃ち返し弾幕の発射に倒された敵の座標を使っている場合に
後に出てくる敵に同じ番号のenemy構造体を使用されないようにするためです。
このようにしないと後に出てくる敵の座標が使われる可能性があります。

enemy.cpp

読み込んだ撃ち返し弾幕の種類を敵のデータに渡せるようにするため
enemy_enter()に

CODE:

				enemy[i].reblknd=enemy_order[t].reblknd;//撃ち返す弾幕の種類
を追加します。

enter_shot()の変更

CODE:

void enter_shot(int i,int blknd)
引数blkndを追加。
通常の弾幕を撃つときはenemy.blknd
撃ち返し弾幕を撃つときはenemu.reblkndとする。

enter_shot()の

CODE:

			shot[j].knd=enemy[i].blknd;//弾の種類

CODE:

			shot[j].knd=blknd;//弾の種類
に変更します。


out.cpp

CODE:

void enter_shot(int i,int blknd);
を追加。
敵がやられた時に撃ち返し弾幕を登録できるように
enemy_death_judge()の敵のHPが0未満になったら
の部分に

CODE:

		if(enemy[s].reblknd!=-1){
			enter_shot(s,enemy[s].reblknd);
		}
を追加します。
また、

CODE:

        enemy[s].flag=0;//敵を消滅させる

CODE:

        enemy[s].flag=2;//敵をやられた状態にする
に変更します。
enemy.flagが2の時は敵はやられたがその敵の弾幕が残っている状態を意味しています。

やられた敵に当たり判定はないので

cshot_and_enemy()の

CODE:

                if(enemy[s].flag>0){

CODE:

                if(enemy[s].flag==1){
にします。

enemy.cpp
enemy_act()に

CODE:

	int j;
	int flag;
を追加。
この二つの変数はenemy.flagが2の時に使用します。
jはenemyが撃った弾幕が残っていないかを調べるためのカウンタ変数です。
flagはenemy.flagを0にするかを判定するためのものです。

enter_shot()に引数を追加したので

CODE:

					enter_shot(i);

CODE:

					enter_shot(i,enemy[i].blknd);
に変更。

敵がやられているが弾幕が残っている状態の処理を追加します。

CODE:

		if(enemy[i].flag==2){//敵がやられた状態だったら
			flag=0;
			//iの敵が撃ったショットが存在しないならば敵のフラグを0にする
			for(j=0;j<SHOT_MAX;++j){
				if(shot[j].flag!=0 && shot[j].num==i){
					flag=1;
				}
			}
			if(flag==0){
				enemy[i].flag=0;
			}
		}
を追加。


このようにすれば撃ち返しが実装できるはずです。
非表示エリア
この非表示エリアを表示するには、登録し、ログインする必要があります。
最後に編集したユーザー Tatu on 2013年8月03日(土) 17:47 [ 編集 1 回目 ]

コメントはまだありません。