スペルプラクティス実装

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

スペルプラクティス実装

投稿記事 by Tatu » 14年前

今回は「スペルプラクティスが実装さえできればよい」という感じで内容がまとまっていないため
「ふーん、これでできるんだ」程度で見てください。
できたサンプルはこちら。これまでに作成した200と少しの弾幕も入っています。

[拡張子 zip は無効化されているため、表示できません]

Microsoft Visual C++ 2010 Express で作成しています。
素材などが入っていないので「サンプル」フォルダを
龍神録プログラミングの館からダウンロードしてできた「龍神録project」フォルダに入れてください。
実行時にはコンパイルを行ってください。






以下はサンプル作成時に行った手順です。

プラクティスの場合、基本的には通常のSTGと同じ処理をしますが
所々で異なる処理があるのでプラクティスモードかどうかを判断するための変数を用意しました。

GV.hに以下を追加

CODE:

GLOBAL int practice;//プラクティスモードか否か
プラクティスのほか、
ステージセレクト(四聖龍神録では通常の1面かEXかPHのどれを始めるかを選択する)もあるので
ボスの情報はそれぞれを選んだ時に設定されるようにしました。

game_ini()から
stage
boss.knd
boss.boss_num
に関する処理を消去しました。

タイトルでしか使わない変数を使うので
graph_title()をtitle.cppに移動。
graph.cppではextern宣言のみにしました。

title.cppにメニューの処理と描画処理を書きました。
► スポイラーを表示
プラクティスでは
ステージ開始時にボスが登場し、
ステージ最後のボスを倒してもクリア状態にはならないようにしたいので
boss.cppのboss_shot_mainの以下の部分を変更しました。

CODE:

boss_shot_main(){}
	if(boss.flag==0 && ((practice==0 && stage_count==boss.appear_count[boss.boss_num]) 
	|| (practice==1 && stage_count==1))){//開始時間なら

CODE:

		if(practice==1 || boss.knd==boss.danmaku_num[boss.boss_num]){//出すべき弾幕をだしきったら
			boss.flag=0;//消す
			enter_dn(10,40);//(45)
			se_flag[9]=1;//ボスが死んだ音
			if(practice==0 && boss.boss_num==stage_boss_num[stage]){//最後のボスを倒したらクリア状態にする
				for(int i=0;i<CSHOT_MAX;i++){//自機ショット消去
					cshot[i].flag=0;
				}
				func_state=CLEAR;
			}
			boss.boss_num++;
			return ;
		}
ボスが倒れて3秒後に終了したいので
main.cppのcase GAME_STGに以下を追加しました。

CODE:

			if(practice==1 && stage_count==180){
				StopSoundMem(area.bgm.handle);
				delete_bgm();
				func_state=TITLE;
			}
道中の雑魚が出てこないようにするため、プラクティスモードの時は
ステージデータを読み込まないようにしました。

ini.cppのstage_iniの以下を変更

CODE:

	if(practice==0) load_story();//ステージデータ読み込み
スペルプラクティス用の音楽処理をstage_ini()に追加しました。

ini.cppの以下を変更

CODE:

	if(practice==0){
		area.bgm.flag=0;//音楽再生フラグを初期化(48)
		area.bgm.knd[0]=0;//通常BGMをどういうタイミングで再生するか、取り決めはmusic.cpp(48)
		area.bgm.knd[1]=0;//ボスBGMをどういうタイミングで再生するか、取り決めはmusic.cpp(48)
		area.bgm.loop_pos[0]=26672;//通常BGMのループ位置(48)
		area.bgm.loop_pos[1]=27010;//ボスBGMのループ位置(48)
	}
	else{
		if(boss.boss_num < stage_boss_num[stage]){
			area.bgm.handle=LoadSoundMem("../dat/music/0_0.ogg");
			area.bgm.loop_pos[0]=26672;//通常BGMのループ位置(48)
			SetLoopPosSoundMem( area.bgm.loop_pos[0], area.bgm.handle );//ループ位置セット
		}
		else{
			area.bgm.handle=LoadSoundMem("../dat/music/0_1.ogg");
			area.bgm.loop_pos[1]=27010;//ボスBGMのループ位置(48)
			SetLoopPosSoundMem( area.bgm.loop_pos[1], area.bgm.handle );//ループ位置セット
		}
		PlaySoundMem(area.bgm.handle,DX_PLAYTYPE_LOOP);
	}
通常時の音楽処理を行わないので

main.cppの以下を変更

CODE:

if(practice==0) bgm_main();
プラクティス時は進行度を表示しないようにしたいのでgraph_developを以下のようにしました。

graph.cppを変更

CODE:

void graph_develop(){
	//デバッグ用に数字を表示、公開時はコメントアウトする
	DrawFormatString(0,0,GetColor(255,255,255),"%d",stage_count);
	if(practice == 0 && boss.flag==0){//ボスがいないときのみ表示
		//虹色の線を表示
		DrawRotaGraphF(16.0,FMY/2,1.0,0,img_develop,FALSE);
		//自機画像を表示
		DrawRotaGraphF(16.0,FMY/2+200-400.0*stage_count/boss.appear_count[1],0.5,0,img_ch[0][(stage_count/30)%4],TRUE);
	}
}
ステージタイトルが出ないような処理を付けました。

calc_main()の以下を変更。

CODE:

	if(practice==0) calc_stage_title();
以上に示した作業と
ini.cppにある弾幕やボスに関する情報と
func.hにある弾幕関数ポインタの変更により
スペルプラクティスを実装することができました。

アバター
SAI
記事: 115
登録日時: 14年前

Re: スペルプラクティス実装

投稿記事 by SAI » 14年前

少しづつ龍神録に近づきつつありますね!
これはアレですか?
四聖龍(たつ)神録の前身でしょうか?(オイ