龍神録プログラミングの館の改変について書いてみました。
前に書いたのいつだっけ。
今回のテーマは撃ち返しです。
ザコの撃ち返しのみ扱います。
既に改変したものに手を加えているため、
全く同じことをしてもうまくいかないかもしれません。
1.撃ち返しってなに?
2.実装の方法
3.コードなどの変更
1.撃ち返しってなに?
シューティングゲームにおいて敵を倒すと発生する攻撃のことです。
英語ではsuicide bullet,return bullet,revenge bulletなどと呼ばれるそうです。
2.実装の方法
龍神録プログラミングの館ではshot構造体によってザコの弾幕を制御しています。
shot構造体のフラグは敵が出現してからその敵に設定された弾幕の開始時間がたったら立てられます。
そこで、撃ち返しの場合は敵が倒された時に撃ち返し用の弾幕のフラグを立てるようにします。
撃ち返し用の弾幕関数は敵が死んでいても弾が出る以外は通常の弾幕関数と同じです。
よって今回は通常の弾幕関数と同じファイルに書くことにします。
3.コードなどの変更
struct.h
enemy_tとenemy_order_tのメンバに を追加。
この変数が-1ならば撃ち返しをしないようにし、
0以上ならば撃破された時に対応した弾幕を登録するようにします。
load.cpp
load_story()を書き換え、
撃ち返し弾幕の番号を読み込めるようにします。
を追加し、 を に変更します。
エクセルファイルに撃ち返し弾幕情報の追加をします。
右端の行に
撃ち返し弾幕
reblknd
数字(対応した弾幕の番号、撃たない場合は-1)
を入れる。上の二つはコメント。
撃ち返し確認用の弾幕関数を作成します。
名前は普段通りshot_bullet_H***とします。
弾幕関数に関するshotH.cppとshot.cppの変更については省略します。
敵がすでに死んだ状態であるため、弾登録時の判定にshot[n].flag!=2をつけていると弾が出ないことに注意してください。
shot.cpp
shot_calc()の
//現在表示中の弾が一つでもあるかどうか調べる
for(i=0;i0)
return;
//現在表示中の弾が一つもなければ
if(enemy[shot[n].num].flag!=1){
enemy[shot[n].num].flag=0;
shot[n].flag=0;//終了
}
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()に を追加します。
enter_shot()の変更 引数blkndを追加。
通常の弾幕を撃つときはenemy.blknd
撃ち返し弾幕を撃つときはenemu.reblkndとする。
enter_shot()の を に変更します。
out.cpp を追加。
敵がやられた時に撃ち返し弾幕を登録できるように
enemy_death_judge()の敵のHPが0未満になったら
の部分に を追加します。
また、 を に変更します。
enemy.flagが2の時は敵はやられたがその敵の弾幕が残っている状態を意味しています。
やられた敵に当たり判定はないので
cshot_and_enemy()の を にします。
enemy.cpp
enemy_act()に を追加。
この二つの変数はenemy.flagが2の時に使用します。
jはenemyが撃った弾幕が残っていないかを調べるためのカウンタ変数です。
flagはenemy.flagを0にするかを判定するためのものです。
enter_shot()に引数を追加したので を に変更。
敵がやられているが弾幕が残っている状態の処理を追加します。
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;
}
}
このようにすれば撃ち返しが実装できるはずです。