メニュー画面でのバグ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: メニュー画面でのバグ

Re: メニュー画面でのバグ

#16

by Math » 5年前

ようやく時間が取れたのでVS2017にファイルを転記してたら#3のevent.h と move.h のあいだのファイルの名前がない。
ミスが多過ぎる。時間を割くわけにわいかないので注意してください。
感覚的には質問者様のケアレスミスのきがしますよ。(^^;

Re: メニュー画面でのバグ

#15

by just_started_PG » 5年前

ご回答ありがとうございます。

「配列の範囲外へのアクセスなどの未定義動作が起こっている可能性」
これは変数定義時に初期化しておけば発生しないものですか?

Re: メニュー画面でのバグ

#14

by みけCAT » 5年前

変数の定義順の違いで動作が変わるということであれば、
配列の範囲外へのアクセスなどの未定義動作が起こっている可能性が考えられます。
Valgrindなどの自動検査ツールを使えればいいのですが、
Windowsに対応しているものはあったかなあ…?

Re: メニュー画面でのバグ

#13

by Math » 5年前

解決して良かったですね!
質問しているうちに自己解決されるかたが時々いますが 集中するからでしょうね。

>何が原因なんですかね。せっかくなので、聞いてもよろしいでしょうか。
順番はどちらでも いいはずだけど・・・わかりませんね・?・(^^;

Re: メニュー画面でのバグ

#12

by just_started_PG » 5年前

私の不手際が多く、信用しにくいかもしれませんが、
載せてあるサンプルソースコードは本物です。

後なぜクラスを使っていないかについてですが、
タイトルの本が「C言語ゲーム開発」なので、
C++から実装されているクラスというかオブジェクト指向の書き方は
その本では一切されていません。

C言語のみを学べば、作れるように書かれています。
なので、クラス内での関数定義はされていません。

Re: メニュー画面でのバグ

#11

by あたっしゅ » 5年前

これらのソースコードって、本当に「ライブラリではじめるC言語ゲーム開発」に掲載されているものですか ?
普通、宣言と実体定義は、.h と .cpp に、わけますよね。短い関数は、class 内部で定義しますが。

コード:

#pragma once
//
// irony.h
//
class TMain
{
public:
    TMain() {}
    void exec();
    ~TMain() {}
};


// end.

コード:

//
// irony.cpp
//
#include <stdlib.h>
#include "irony.h"

void
TMain::exec()
{
    puts(
        "2人のプレイヤーが3回勝つまでじゃんけんをして、勝負がついたならそれまでの勝負の履歴"
    );
}

int
main()
{
	TMain* app = new TMain();
	
	app->exec():
	delete app;
	return EXIT_SUCCESS;
}


// end.

Re: メニュー画面でのバグ

#10

by just_started_PG » 5年前

main.hにある

int use_item;//使用するアイテム番号を格納


どうやらこの変数より後にitem_step変数を定義しなければいけなかったようです。
何が原因なんですかね。せっかくなので、聞いてもよろしいでしょうか。

Re: メニュー画面でのバグ

#9

by just_started_PG » 5年前

自己解決しました。
サンプルコードは間違っているわけではありませんでした。
写経時の変数の順番が正しくありませんでした。item_step変数を後ろに定義したらバグが解消しました。

大変お騒がせしました。

Re: メニュー画面でのバグ

#8

by みけCAT » 5年前

一応ファイルの内容が揃って実行できるのかもしれないですが(確認してません)、
ファイルが多くてコピペの手間が大きそうですね。
本文で貼るのではなく、zip形式などでまとめて添付ファイルにしていただいた方がよかったと思います。

また、イベントやマップなどのコードもあるようですが、それは本当に「メニュー画面でのバグ」に関係あるのでしょうか?
関係ない部分は削っていただき、バグが再現可能な最小限のコードにしていただけるとわかりやすそうだと思います。

Re: メニュー画面でのバグ

#7

by just_started_PG » 5年前

これで一通りは掲載しました。
検証はこれで出来ると思われます。

お手数をおかけしますが
よろしくお願いします。

Re: メニュー画面でのバグ

#6

by just_started_PG » 5年前

fscanfで読み込んでいる.txtの中身についてです。

コード:

//chara.txt

主人公	
ゴブリン
親分達	
魔物
一般人	
一般人
ドラゴン
マリア
主人公?
魔王
覚醒魔王

コード:

//chara_ski.txt

1 2 3 4 5 6 7 8 0

コード:

//event.txt

0  4   5   3  1 -1  1 -1  0  1  0  1  3 -1	この世界は魔物に支配されて・・・	人に話しかけることで世界が	広がります・・・それが
1  4   5   3  1 -1  2 -1  1  1  1  1  2 -1	この世界の法則。	平和を取り戻すにはそれが・・・	あ
2  5   8   7  2 -1  6 -1  1  1  1  1  3  8	私達はあなたを応援しています。	魔王によって私達はすぐ消されてし	まう。でも、負けないで!
3  1  10  10  2  4  4 -1 -1  1  0  1  1 -1	引っかかったな!	あ	あ
4  1  10  10  2 -1  5 -1 -1  1  1  1  2  9	許してくれ!回復薬やるから!	覚えてろよ!お前なんて親分が!!	あ
5  2  11  11  1  5 -1 -1 -1  1  1  1  2 -1	よくもゴブリンを・・・	死ね!!	あ
6  4   0   0  1  6  7 -1  1  1  1  1  1 -1	きゃー!助けて!!	あ	あ
7  4   0   0  1 -1  8 -1  1  1  1  1  3  1	助けてくれてありがとう!	この武器を授けます。	装備メニューで装備してね!
8  6  13  13  1  7  9 -1 -1  1  1  1  3 -1	お前が最近ここらで仲間を	倒して回ってるやつか!	許さないぞ!
9  6  13  13  1 -1 10 -1 -1  1  1  1  3 -1	下のマップに・・・	召喚してやったわ!	これでこの世界も終わりに・・・・
10 7   8  14  2  8 11 -1 -1  1  1  1  2 -1	あなたは・・・	敵!	あ
11 8   8  14  2 -1 12 -1  7  1  1  1  2 10	みんな・・・・ごめん・・・・	みんな・・・・すまない・・・		あ
12 0   8  14  2 -1 13 -1  1  1  1  1  2 10	この人は僕?	一体なんなんだ・・・		あ
13 8   8  14  2 -1 14 -1  7  1  1  1  2 10	もし、叶うなら魔王を	倒して、皆に報いなければ・・・		あ
14 8   8  14  2 -1 15 -1  3  1  1  1  2 10	魔王は、このマップの2つ上に	存在している、		あ
15 8   8  14  2 -1 16 -1  7  1  1  1  3 10	マリアを倒した事により恐らく	その世界に到達できる。	もう一度生まれた僕、君なら・・・
16 8   8  14  2 -1 17 -1  7  1  1  1  3  3	この剣と鎧、薬を託そう。	僕はもう持っていても仕方ない。	頼んだよ。
17 0   8  14  2 -1 18 -1  1  1  1  1  3  7	魔王を倒せば・・・	この輪廻から解放されるのか。	やるしかないな・・・
18 8   8  14  2 -1 -1 -1  7  1  1  0  1 -1	また・・・みんなと・・・	あ	あ
19 9   9   0  3  9 20 -1  0  1  0  1  3 -1	また来たのか・・・	何度やっても結果は同じ。	まぁ・・・いい!こい!!
20 9   9   0  3 -1 21 -1  3  1  1  1  3 -1	やられたか。	なかなか今回の勇者は・・・	楽しませてくれるなぁ!!
21 10  9   0  3 10 22 -1  7  1  1  1  3 -1	来いよ!	今回は特別に本気でやってやる。	すぐに消滅するなよ?
22 0   9   0  3 -1 23 -1  3  1  1  1  2 -1	思い出したよね?	僕は・・・・・		あ

コード:

//group.txt

0 1 1 -1 -1  1	背景/草原.jpg
1 2 1  2 -1  1	背景/草原.jpg
2 3 1  2  3  1	背景/荒野.jpg
3 2 3  4 -1  1	背景/荒野.jpg
4 1 6 -1 -1	 6	背景/荒野.jpg
5 2 7  8 -1	 6	背景/草原.jpg
6 1 5 -1 -1	 8	背景/草原.jpg
7 1 9 -1 -1  9  背景/草原.jpg
8 1 10 -1 -1  9  背景/荒野.jpg
9 1 11 -1 -1  10  背景/ラスボス.jpg
10 1 12 -1 -1  11  背景/覚醒.jpg

コード:

//item.txt

0  1  5	木の剣 1	木でできた剣	あ	あ
1  1 20	鉄の剣 1	鉄でできた剣	あ	あ
2  1 50	銀の剣 1	銀でできた剣	あ	あ
3  1 100	勇者の剣 2	勇者にしか扱えない剣	最強の剣	あ
4  2  5	普通の服 1	一般人も着ている服	あ	あ
5  2 20	丈夫な服 1	普通の服より丈夫な服	あ	あ
6  2 50	豪華な服 2	豪華な修飾がなされた服	リッチな気分になれるかも?	あ
7  2 100	勇者の鎧 3	最強に硬い鎧	勇者専用	未知の物質でできている
8  3 50	薬草 1	一般的な回復薬	あ	あ
9  3 500	クスリ 1	傷などによく効く薬	あ	あ
10 3 1000 応急薬 3	緊急の際に用いられる薬	飲むとかなり回復する	持っていれば安心な薬

コード:

//map.txt

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
109 109 109 109 109 109 109 109 109 6 109 109 109 109 109 109 109 109 109 109
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

コード:

//pattern.txt

0 0 0 0 0 0 0 0
0 8 0 8 0 8 0 8
6 6 6 6 6 6 6 6
11 12 13 11 12 13 11 0
0 14 0 14 0 14 0 14
15 0 15 0 15 0 15 0
11 12 13 14 15 13 14 15
0 0 9 0 0 10 9 10

コード:

//skill.txt

0 0 0  0  9  2	斬撃
1 2 0 10 18  3	風剣
2 5 0 20 18  3	気弾剣
3 10 0 30 25  4	集気剣
4 20 0 40 15  10	葉剣
5 30 0 50 10  9	呪剣
6 40 0 60 10  3	投剣
7 50 0 70 10  6	光剣
8 100 0 100 5  11	煉獄剣
9 50 0 500 18  6	シャイン
10 50 0 1000 20  8	コスモ
11 50 0 50 10  9	ダークハンド
12 50 0 80 12  12	アシッドレイン
13 50 0 100 13  12	ダークスコール
14 50 0 200  8  11	ストーンウォール
15 50 0 400  5   6	ライトニング

コード:

//status.txt

0 30 10 10 10 10 -1	主人公	あ
1 10 10 18 10  3  0	タイタン	敵画像/タイタン.png
2 20 10 19  5  5  0	カオス	敵画像/カオス.png
3  5 10 17 15  2  0	シザーズ	敵画像/シザーズ.png
4 30 10 20 10  5  0	Dソルジャ	敵画像/ソルジャー.png
5 50 10 25  0  5  3	魔道士	敵画像/魔道士.png
6 100 10 30 20 25  1	ゴブリン	敵画像/ゴブリン.png
7 400 10 40 20 30  0	親分	敵画像/親分.png
8 450 10 20 40 30  2	傭兵	敵画像/傭兵.png
9 400 10 50 25 30  4	ドラゴン	敵画像/ドラゴン.png
10 450 10 60 50 40  5	マリア	敵画像/マリア.png
11 1 10 200 100 100  6	魔王	敵画像/魔王.png
12 2 10 300 200 200  7	覚醒魔王	敵画像/覚醒魔王.png

コード:

//save0.txt

50 10 13 10 10 
0 0 0 0 0 
0 0 0 0 0 

コード:

//save1.txt

1 0 0 1 1 5 0 0 4 
1 
0 
0 
0 
1 
0 
0 
0 
1 
0 
0 
0 
0 
0 
0 
0 
1 
1 
0 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
0 
1 
1 
1 
1 
0 
0 
0 
0 
0 
0 
0 
0 
50 10 50 10 13 10 10 0 5 0 

コード:

//save2.txt

1 0 0 1 1 5 0 0 4 
1 
0 
0 
0 
1 
0 
0 
0 
1 
0 
0 
0 
0 
0 
0 
0 
1 
1 
0 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
0 
1 
1 
1 
1 
0 
0 
0 
0 
0 
0 
0 
0 
500 100 500 100 30 40 30 6 798 0 

コード:

//save3.txt

1 0 0 1 1 5 0 0 4 
1 
0 
0 
0 
1 
0 
0 
0 
1 
0 
0 
0 
0 
0 
0 
0 
1 
1 
0 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
1 
0 
1 
1 
1 
1 
0 
0 
0 
0 
0 
0 
0 
0 
3000 1000 3000 1000 1000 1000 1000 0 10 0 

Re: メニュー画面でのバグ

#5

by just_started_PG » 5年前

サンプルコードの続きです。その2

コード:

//battle.h
void enemy_draw(void);//プロトタイプ関数
void hp_check(void);//プロトタイプ関数
void battle_top(void);//プロトタイプ関数
void battle_choose(void);//プロトタイプ関数
void battle_target(void);//プロトタイプ関数
void battle_atack(void);//プロトタイプ関数
void battle_skill_choose(void);//プロトタイプ関数
void battle_enemy_turn(void);//プロトタイプ関数
void battle_item(void);//プロトタイプ関数
void battle_escape(void);//プロトタイプ関数
void battle_over(void);//プロトタイプ関数
void battle_mode(void){
	char s_hp[5];//主人公の現在hp
	char s_tp[5];//主人公現在tp
	if(CheckSoundMem(bgm[group[now_group].bgm]) == 0 && CheckSoundMem(bgm[4]) == 0){//bgm再生
		StopSoundMem(bgm[now_bgm]);
		PlaySoundMem(bgm[group[now_group].bgm],DX_PLAYTYPE_LOOP);
		now_bgm = group[now_group].bgm;
	}
	DrawGraph(0,0,battle_back,FALSE);//背景描画
	enemy_draw();//敵の描画
	hp_check();//主人公の残りHPチェック
	DrawGraph(0,310,window[1],TRUE);//戦闘ウィンドウを表示
	DrawExtendGraph(10,30,100,120,chara[0].face[now_face],TRUE);//主人公描画

	sprintf(s_hp,"%d",battle[0].hp);//int型からchar型へ中身を変換
	sprintf(s_tp,"%d",battle[0].tp);//int型からchar型へ中身を変換
	DrawString(20,4,status[battle[0].enemy_no].name,color[now_color]);//名前表示
	DrawString(150,40,s_hp,color[now_color]);//hp表示
	DrawString(150,80,s_tp,color[now_color]);//tp表示
	DrawString(110,40,"HP",color[0]);//hp表示
	DrawString(110,80,"TP",color[0]);//tp表示
	
	if(battle_menu == 0){//初期画面
		battle_top();
	}
	else if(battle_menu == 1){//行動選択画面
		battle_choose();
	}
	else if(battle_menu == 2){//ターゲット画面
		battle_target();
	}
	else if(battle_menu == 3){//攻撃画面
		battle_atack();
	}
	else if(battle_menu == 4){//特技選択画面
		battle_skill_choose();
	}
	else if(battle_menu == 5){//敵行動選択
		battle_enemy_turn();
	}
	else if(battle_menu == 6){//アイテム選択
		battle_item();
	}
	else if(battle_menu == 7){//逃げる
		battle_escape();
	}
	else if(battle_menu == 8){//ゲームオーバー前の描画
		battle_over();
	}
}
void battle_change(void){//バトル前にこれからバトルするキャラ達のステータスを配列へ移動します
	//主人公ステータス初期化
	int spd_sum = 0;//敵のスピード合計
	battle[0].enemy_no = 0;//名前のため
	battle[0].atk = status[0].atk + item[s_equip[0]].point;//攻撃力
	battle[0].def = status[0].def + item[s_equip[1]].point;//防御力
	battle[0].spd = status[0].spd;//素早さ
	for(i = 1;i <= 3;i++){//初期化
		battle[i].enemy_no = 0;//名前のため
		battle[i].hp = 0;//HP
		battle[i].tp  = 0;//TP
		battle[i].atk = 0;//攻撃力
		battle[i].def  = 0;//防御力
		battle[i].spd  = 0;//素早さ
		battle[i].pattern  = 0;//敵の行動パターン
		battle[i].skin  = 0;//敵画像
	}
	if(event_b >= 0){//イベントバトルなら
		now_group = event_b;//イベントバトルグループ番号
		escape = 1;//逃げられないように
	}
	else{//イベントバトルでないのなら
		if(now_map == 1){//mapが1なら
			now_group = GetRand(1);//0~1
		}
		else if(now_map == 2){
			now_group =  GetRand(1) + 2;//2~3
		}
		escape = 0;//初期化
	}
	event_b = -1;//初期化
	battle_back = LoadGraph(group[now_group].back);//背景ロード
	for(i = 1;i <= group[now_group].enemy_count;i++){
		battle[i].enemy_no = status[group[now_group].enemy[i - 1]].no;//名前のため
		battle[i].hp =status[group[now_group].enemy[i - 1]].hp;//HP
		battle[i].tp =status[group[now_group].enemy[i - 1]].tp;//TP
		battle[i].atk =status[group[now_group].enemy[i - 1]].atk;//攻撃力
		battle[i].def =status[group[now_group].enemy[i - 1]].def;//防御力
		battle[i].spd =status[group[now_group].enemy[i - 1]].spd;//素早さ
		battle[i].pattern = status[group[now_group].enemy[i - 1]].pattern;//敵の行動パターン
		battle[i].skin = LoadGraph(status[group[now_group].enemy[i - 1]].skin);//敵画像
	}
	for(i = 1;i <= group[now_group].enemy_count;i++){
		spd_sum = spd_sum + battle[i].spd;
	}
	if(battle[0].spd >= spd_sum){//主人公スピードが敵合計より多いなら
		battle_menu = 0;//主人公から
		spd_sum = 0;//合計初期化
	}
	else{
		battle_menu = 5;//敵ターンから
		spd_sum = 0;//初期化
		LoadGraphScreen(0,0,"背景/ロード.jpg",FALSE);
		DrawGraph(0,310,window[1],TRUE);//会話ウィンドウを表示
		DrawString(210,375,"敵に先制された!!!",color[2]);
		DrawString(410,425,"PUSH ENTER KEY",color[2]);
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
	}
}
void enemy_draw(void){//敵の描画
int enemy_count = group[now_group].enemy_count;
	if(enemy_count == 1){//1匹の場合
		if(battle[1].hp > 0 && del_ef != 1){
			DrawGraph(200,140,battle[1].skin,TRUE);
		}
		else if(battle[1].hp > 0){
			del_ef = 0;//消去変数初期化
		}
	}
	else if(enemy_count == 2){//2匹の場合
		if(battle[1].hp > 0 && del_ef != 1){
			DrawGraph(60,140,battle[1].skin,TRUE);
		}
		else if(battle[1].hp > 0){
			del_ef = 0;//消去変数初期化
		}
		if(battle[2].hp > 0 && del_ef != 2){
			DrawGraph(340,140,battle[2].skin,TRUE);
		}
		else if(battle[2].hp > 0){
			del_ef = 0;//消去変数初期化
		}
	}
	else if(enemy_count == 3){//3匹の場合
		if(battle[1].hp > 0 && del_ef != 1){
			DrawGraph(200,140,battle[1].skin,TRUE);
		}
		else if(battle[1].hp > 0){
			del_ef = 0;//消去変数初期化
		}
		if(battle[2].hp > 0 && del_ef != 2){
			DrawGraph(10,140,battle[2].skin,TRUE);
		}
		else if(battle[2].hp > 0){
			del_ef = 0;//消去変数初期化
		}
		if(battle[3].hp > 0 && del_ef != 3){
			DrawGraph(390,140,battle[3].skin,TRUE);
		}
		else if(battle[3].hp > 0){
			del_ef = 0;//消去変数初期化
		}
	}
}
void hp_check(void){
	if(battle[0].hp <= 0){
		now_color = 2;//赤色へ
		now_face = 7;//死亡顔へ
	}
	else if(battle[0].hp <= status[0].hp/3){
		now_color = 1;//黄色へ
		now_face = 3;//苦しい顔へ
	}
	else{
		now_color = 0;//黒色へ
		now_face = 0;//健康顔へ
	}
}
void battle_top(void){
	play_skill = 0;//使用特技初期化
	ef_move = 0;//エフェクト初期化
	del_ef = 0;//消去変数初期化
	def_on = FALSE;//防御解除
	DrawString(60,365,"たたかう",color[0]);
	DrawString(60,415,"にげる",color[0]);
	DrawGraph(25, 360 + (50 * battle_cursor),chara[0].chip[1],TRUE);
	//カーソル描画		
	if(key[KEY_INPUT_UP] == 1){
		if(battle_cursor == 0){
			battle_cursor = 1;
		}else{
			battle_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(battle_cursor == 1){
			battle_cursor = 0;
		}else{
			battle_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		switch(battle_cursor){
			case 0:battle_menu = 1;//たたかう画面へ
				break;
			case 1:
				if(escape == 1){
				       DrawString(210,375,"この戦闘は回避できない!",color[2]);
					   WaitTimer(1000);
					   break;
				}
				else{
						battle_menu = 7;//逃げる画面へ
						break;	
				}
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		battle_cursor = 0;//バトルカーソル初期化
	}
}
void battle_choose(void){
	DrawString(60,350,"攻撃",color[0]);
	DrawString(60,375,"特技",color[0]);
	DrawString(60,400,"アイテム",color[0]);
	DrawString(60,425,"防御",color[0]);
	DrawGraph(25, 350 + (25 * battle_cursor),chara[0].chip[1],TRUE);
	switch(battle_cursor){
		case 0:DrawString(210,375,"目標を選び攻撃する",color[0]);
			break;
		case 1:DrawString(210,375,"特技を使用する",color[0]);
			break;
		case 2:DrawString(210,375,"所持しているアイテムを使用する",color[0]);
			break;
		case 3:DrawString(210,375,"敵の攻撃から身を守る",color[0]);
			break;
	}
	DrawString(290,430,"Bキーでトップへ戻る",color[0]);
	//カーソル描画		
	if(key[KEY_INPUT_UP] == 1){
		if(battle_cursor == 0){
			battle_cursor = 3;
		}else{
			battle_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(battle_cursor == 3){
			battle_cursor = 0;
		}else{
			battle_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		switch(battle_cursor){
			case 0:battle_menu = 2;//ターゲット選択画面へ
				play_skill = 0;//斬撃を格納
				if(battle[1].hp > 0){//いないはずの場所にカーソルがいかないようにするため
					battle_cursor = 0;
				}
				else if(battle[2].hp > 0){
					battle_cursor = 1;
				}
				else{
					battle_cursor = 2;
				}
				break;
			case 1:battle_menu =4;//スキル選択画面へ
				battle_cursor = 0;//初期化
				break;
			case 2:battle_menu =6;//アイテム選択画面へ
				battle_cursor = 0;//初期化
				break;
			case 3:battle_menu =5;//防御し、敵のターンへ
				battle_cursor = 0;//初期化
				def_on = TRUE;//防御on
				break;
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_B] == 1){//バトルトップへ戻る
		battle_menu = 0;
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
		battle_cursor = 0;//カーソル初期化
	}
}
void battle_target(void){
int enemy_count = group[now_group].enemy_count;
	DrawString(290,430,"Bキーで行動選択画面へ戻る",color[0]);
	DrawGraph(25, 350 + (40 * battle_cursor),chara[0].chip[1],TRUE);
	if(enemy_count == 2){
		DrawGraph(150 + (280 * battle_cursor), 140,chara[0].chip[1],TRUE);
	}
	else{
		if(battle_cursor == 2){
			DrawGraph(500,120,chara[0].chip[1],TRUE);
		}
		else if(battle_cursor == 1){
			DrawGraph(80,120,chara[0].chip[1],TRUE);
		}
		else{
			DrawGraph(290,120,chara[0].chip[1],TRUE);
		}
	}
	if(enemy_count == 1){//1匹の場合
		DrawString(60,360,status[battle[1].enemy_no].name,color[0]);
	}
	else if(enemy_count == 2){//2匹の場合
		if(battle[1].hp > 0){
			DrawString(60,350,status[battle[1].enemy_no].name,color[0]);
		}
		if(battle[2].hp > 0){
			DrawString(60,390,status[battle[2].enemy_no].name,color[0]);
		}
	}
	else if(enemy_count == 3){//3匹の場合
		if(battle[1].hp >  0){
			DrawString(60,350,status[battle[1].enemy_no].name,color[0]);
		}
		if(battle[2].hp >  0){
			DrawString(60,390,status[battle[2].enemy_no].name,color[0]);
		}
		if(battle[3].hp >  0){
			DrawString(60,430,status[battle[3].enemy_no].name,color[0]);
		}
	}
	if(enemy_count > 1){
		if(enemy_count == 2){
			if(key[KEY_INPUT_UP] == 1){
				if(battle_cursor == 0 && battle[2].hp > 0){//敵2が生きている
					battle_cursor = 1;
				}else if(battle_cursor == 1 && battle[1].hp > 0){//敵1が生きている
					battle_cursor = 0;
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
			}
			else if(key[KEY_INPUT_DOWN] == 1){
				if(battle_cursor == 1 && battle[1].hp > 0){//敵1が生きている
					battle_cursor = 0;
				}else if(battle_cursor == 0 && battle[2].hp > 0){
					battle_cursor = 1;
				}
				while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
			}
		}
		else if(enemy_count == 3){
			if(key[KEY_INPUT_UP] == 1){
				if(battle_cursor == 0){
					if(battle[3].hp > 0){//敵3が生きていれば
						battle_cursor = 2;
					}
					else if(battle[2].hp > 0){//敵3が居なくて2が生きていれば
						battle_cursor = 1;
					}
				}else if(battle_cursor == 1){
					if(battle[1].hp > 0){//敵1が生きていれば
						battle_cursor = 0;
					}
					else if(battle[3].hp > 0){//敵1が居なくて3が生きていれば
						battle_cursor = 2;
					}
				}
				else{//カーソルが2の場合
					if(battle[2].hp > 0){//敵2が生きていれば
						battle_cursor = 1;
					}
					else if(battle[1].hp > 0){//敵2が居なくて1が生きていれば
						battle_cursor = 0;
					}
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
			}
			else if(key[KEY_INPUT_DOWN] == 1){
				if(battle_cursor == 2){
					if(battle[1].hp > 0){//敵1が生きていれば
						battle_cursor = 0;
					}
					else if(battle[2].hp > 0){//敵1が居なくて2が生きていれば
						battle_cursor = 1;
					}
				}else if(battle_cursor == 1){
					if(battle[3].hp > 0){//敵3が生きていれば
						battle_cursor = 2;
					}
					else if(battle[1].hp > 0){//敵3が居なくて1が生きていれば
						battle_cursor = 0;
					}
				}
				else{//カーソルが0の場合
					if(battle[2].hp > 0){//敵2が生きていれば
						battle_cursor = 1;
					}
					else if(battle[3].hp > 0){//敵2が居なくて3が生きていれば
						battle_cursor = 2;
					}
				}
				while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
			}
		}
	}
	if(key[KEY_INPUT_B] == 1){//行動選択の画面へ戻る
		battle_menu = 1;
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
		battle_cursor = 0;//カーソル初期化
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		switch(battle_cursor){
			case 0:battle_menu = 3;//ターゲット選択画面へ
				target = 1;//敵1へ攻撃
				break;
			case 1:battle_menu = 3;//ターゲット選択画面へ
				target = 2;//敵2へ攻撃
				break;
			case 2:battle_menu = 3;//ターゲット選択画面へ
				target = 3;//敵3へ攻撃
				break;
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		battle[0].tp -= skill[play_skill].tp;//tp消費
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
		battle_cursor = 0;//カーソル初期化
	}
}
void battle_atack(void){
int enemy_count = group[now_group].enemy_count;
int da=0;//ダメージ計算用
int plus;//変動値+-判定用
int skill_x = 1;//もしスキルエフェクトが広範囲ならx座標を0にするための変数
int bp_max = 0;//bpの総和
char bp[5];//ボーナスポイント描画のための文字型
char da_moji[20];//ダメージをウィンドウに表示するため
	if(battle_cursor == 0){
		DrawString(200,355,"主人公の攻撃!",color[0]);
		DrawString(320,385,status[battle[target].enemy_no].name,color[0]);
		DrawString(440,415,"に",color[0]);
		if(play_skill == 0)//通常攻撃なら"攻撃"と描画違うなら技名を描画
			DrawString(480,415,"攻撃!",color[0]);
		else
			DrawString(465,415,skill[play_skill].name,color[0]);
		if(play_skill >= 6 && play_skill <= 10){
			skill_x = 0;//x座標を0にするため
		}
		if(enemy_count == 2){//敵が2体の場合
			DrawGraph((40 + (280 * (target - 1))) * skill_x , 130,skill[play_skill].effect[ef_move],TRUE);
		}
		else if(enemy_count == 3){//敵が3体の場合
			if(target == 1){
				DrawGraph(200 * skill_x,130,skill[play_skill].effect[ef_move],TRUE);
			}
			else if(target == 2){
				DrawGraph(10 * skill_x,130,skill[play_skill].effect[ef_move],TRUE);
			}
			else{
				DrawGraph(390 * skill_x,130,skill[play_skill].effect[ef_move],TRUE);
			}
		}
		else{//敵が1体の場合
			DrawGraph(200 * skill_x,130,skill[play_skill].effect[ef_move],TRUE);
		}
		WaitTimer(25);
		ef_move += 1;
		if(ef_move >= skill[play_skill].ef_count){
			battle_cursor += 1;
		}
		else if(ef_move >= skill[play_skill].ef_count - 1){
			del_ef = target;//消去ターゲットを格納
		}
	}
	else if(battle_cursor == 1){
		PlaySoundMem(se[skill[play_skill].se_no],DX_PLAYTYPE_BACK);//攻撃音
		battle_cursor = 2;
	}
	else if(battle_cursor == 2){
		DrawString(200,355,status[battle[target].enemy_no].name,color[0]);
		DrawString(340,355,"に",color[0]);
		plus = GetRand(1);//変動値が0なら+1なら-
		if(plus == 0)//変動値
			plus = 1;
		else
			plus = -1;
		if(battle[0].atk + skill[play_skill].point - battle[target].def > 0){
			da = (battle[0].atk + skill[play_skill].point - battle[target].def) + ((GetRand(battle[0].atk + skill[play_skill].point - battle[target].def) / 5) * plus);
		}
		else{//もし攻撃力ー防御力が0以下なら強制的に1ダメージとなる
			da = 1;
		}
		sprintf(da_moji,"%d",da);
		DrawString(360,385,da_moji,color[2]);
		DrawString(440,385,"のダメージ!",color[0]);
		DrawString(410,425,"PUSH ENTER KEY",color[0]);
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
		if(battle[target].hp - da <= 0){//ターゲットのhpが0以下になったら
			battle_cursor = 3;//敵が消滅したメッセージを描画するif文へ
			PlaySoundMem(se[4],DX_PLAYTYPE_BACK);//消滅音
		}
		else{
			battle_menu = 5;//敵のターンへ
			battle_cursor = 0;//バトルカーソル初期化
		}
		battle[target].hp = battle[target].hp - da;//ダメージを計算させ、格納
	}
	else if(battle_cursor == 3){
		DrawString(200,355,status[battle[target].enemy_no].name,color[0]);
		DrawString(410,425,"PUSH ENTER KEY",color[0]);
		DrawString(340,355,"は消滅した!",color[0]);
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
		if(battle[1].hp <= 0 && battle[2].hp <= 0 && battle[3].hp <= 0){
			battle_cursor = 4;//敵が全滅
		}
		else{
			battle_menu = 5;//敵のターンへ
			battle_cursor = 0;//バトルカーソル初期化
		}
	}
	else if(battle_cursor == 4){
		for(i = 1;i <= enemy_count;i++){
			bp_max += battle[i].enemy_no;//敵の番号 = ボーナス
		}
		DrawString(190,355,"敵は消え去った",color[0]);
		sprintf(bp,"%d",bp_max);
		DrawString(190,390,"主人公は",color[0]);
		DrawString(305,390,bp,color[0]);
		DrawString(330,390,"ボーナスポイントを得た",color[0]);
		//DrawString(410,425,"PUSH ENTER KEY",color[0]);
		bonus += bp_max;//実際に加算
		PlaySoundMem(se[7],DX_PLAYTYPE_BACK);//戦闘終了音
		WaitTimer(1200);
		DrawString(410,425,"PUSH ENTER KEY",color[0]);
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
		now_mode = 0;//マップへ
		battle_cursor = 0;
		battle_menu = 0;
	}
}
void battle_skill_choose(void){
	char d_tp[5];//消費tp描画のための文字変数
	sprintf(d_tp,"%d",skill[chara_skill[0].tokugi[battle_cursor]].tp);
	DrawString(35,350,"消費TP",color[0]);
	DrawString(140,350,d_tp,color[0]);
	DrawString(35,425,"B:前画面へ",color[0]);
	if(battle_cursor < 4){//特技左列の場合
		DrawGraph(185 , 340 + (30 * battle_cursor),chara[0].chip[1],TRUE);	
	}
	else{//特技右列の場合
		DrawGraph(385 , 340 + (30 *( battle_cursor - 4)),chara[0].chip[1],TRUE);	
	}
	for(i = 0;i < 2;i++){
		for(j = 0;j < 4;j++){ 
			if(chara_skill[0].flag  >= j+(i*4)){
				DrawString(220 + (i * 200),345 + (j * 30),skill[chara_skill[0].tokugi[j+(i*4)]].name,color[0]);
			}
		}
	}
	if(key[KEY_INPUT_UP] == 1 && chara_skill[0].flag != 0){//スキルを2つ以上覚えているなら
		if(battle_cursor == 0){
			battle_cursor = chara_skill[0].flag;
		}else{
			battle_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1 && chara_skill[0].flag != 0){//スキルを2つ以上覚えているなら
		if(battle_cursor == chara_skill[0].flag){
			battle_cursor = 0;
		}else{
			battle_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
	}
	else if(key[KEY_INPUT_B] == 1){//前画面へ戻る
		battle_menu = 1;
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
		battle_cursor = 0;//カーソル初期化
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		if(battle[0].tp >= skill[chara_skill[0].tokugi[battle_cursor]].tp){
			switch(battle_cursor){
				case 0:play_skill = chara_skill[0].tokugi[0];//主人公の特技[0]にあるスキルをplay_skillに格納
					break;
				case 1:play_skill = chara_skill[0].tokugi[1];//主人公の特技[1]にあるスキルをplay_skillに格納
					break;
				case 2:play_skill = chara_skill[0].tokugi[2];//主人公の特技[2]にあるスキルをplay_skillに格納
					break;
				case 3:play_skill = chara_skill[0].tokugi[3];//主人公の特技[3]にあるスキルをplay_skillに格納
					break;
				case 4:play_skill = chara_skill[0].tokugi[4];//主人公の特技[4]にあるスキルをplay_skillに格納
					break;
				case 5:play_skill = chara_skill[0].tokugi[5];//主人公の特技[5]にあるスキルをplay_skillに格納
					break;
				case 6:play_skill = chara_skill[0].tokugi[6];//主人公の特技[6]にあるスキルをplay_skillに格納
					break;
				case 7:play_skill = chara_skill[0].tokugi[7];//主人公の特技[7]にあるスキルをplay_skillに格納
					break;
			}
			if(battle[1].hp > 0){//いないはずの場所にカーソルがいかないようにするため
				battle_cursor = 0;
			}
			else if(battle[2].hp > 0){
				battle_cursor = 1;
			}
			else{
				battle_cursor = 2;
			}
			battle_menu = 2;//ターゲット選択へ
		}
		else{//tpが足りない場合
			DrawString(25,375,"TPが足りない",color[2]);
			WaitTimer(800);
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
	}
}
void battle_enemy_turn(void){
	int da=0;//ダメージ計算用
	int plus;//変動値+-判定用
	int enemy_skill;//敵が使うスキル用変数
	char da_moji[5];//ダメージをウィンドウに表示するため
	if(battle_cursor < group[now_group].enemy_count){//カーソルがグループ敵数より低いなら繰り返す
		DrawString(35,350,"敵のターン",color[0]);
		if(battle[battle_cursor + 1].hp > 0){//敵が生きているなら
			if(enemy_step == 0){//step = 0なら
				ef_move = 0;
				DrawString(200,355,status[battle[battle_cursor + 1].enemy_no].name,color[0]);
				DrawString(340,355,"の",color[0]);
				if(pat[battle[battle_cursor + 1].pattern][turn] == 0)//攻撃の場合
					DrawString(370,355,"攻撃!",color[0]);
				else//特技の場合
					DrawString(370,355,skill[pat[battle[battle_cursor + 1].pattern][turn]].name,color[0]);
				DrawString(410,425,"PUSH ENTER KEY",color[0]);
				while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
				while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
				enemy_step = 1;
			}
			else if(enemy_step == 1){
				if(pat[battle[battle_cursor + 1].pattern][turn] == 0){//敵の攻撃の時のエフェクトが主人公のとは違うため
					DrawGraph(0,0,enemy_atack_effect[ef_move],TRUE);
					ef_move += 1;
					WaitTimer(60);
					if(ef_move >= 6){
						PlaySoundMem(se[4],DX_PLAYTYPE_BACK);//攻撃音	
						enemy_step = 2;//次のステップへ
					}
				}
				else{//敵の行動パターンが特技の場合
					DrawGraph(0,0,skill[pat[battle[battle_cursor + 1].pattern][turn]].effect[ef_move],TRUE);
					ef_move += 1;	
					WaitTimer(40);
					if(ef_move >= skill[pat[battle[battle_cursor + 1].pattern][turn]].ef_count){
						PlaySoundMem(se[skill[pat[battle[battle_cursor + 1].pattern][turn]].se_no],DX_PLAYTYPE_BACK);//攻撃音
						enemy_step = 2;//次のステップへ
					}
				}
			}
			else if(enemy_step == 2){
				DrawString(200,355,status[battle[0].enemy_no].name,color[0]);
				DrawString(300,355,"に",color[0]);
				plus = GetRand(1);//変動値が0なら+1なら-
				if(plus == 0
					)//変動値
					plus = 1;
				else
					plus = -1;
				if(def_on == TRUE){//防御しているなら
					if(pat[battle[battle_cursor + 1].pattern][turn] == 0){//敵通常攻撃の場合
						if(battle[battle_cursor + 1].atk + skill[0].point - (battle[0].def * 2) > 0){
							da = (battle[battle_cursor + 1].atk + skill[0].point - (battle[0].def * 2)) + ((GetRand(battle[battle_cursor + 1].atk + skill[0].point - (battle[0].def * 2)) / 5) * plus);
						}
						else{//もし攻撃力ー防御力が0以下なら強制的に1ダメージとなる
							da = 1;
						}
					}
					else{//特技の場合
						if(battle[battle_cursor + 1].atk + skill[pat[battle[battle_cursor + 1].pattern][turn]].point - (battle[0].def * 2) > 0){
							da = (battle[battle_cursor + 1].atk + skill[pat[battle[battle_cursor + 1].pattern][turn]].point - (battle[0].def * 2)) + 
								((GetRand(battle[battle_cursor + 1].atk + skill[pat[battle[battle_cursor + 1].pattern][turn]].point - (battle[0].def * 2)) / 5) * plus);
						}
						else{//もし攻撃力ー防御力が0以下なら強制的に1ダメージとなる
							da = 1;
						}
					}
				}
				else{//主人公が防御していないなら
					if(pat[battle[battle_cursor + 1].pattern][turn] == 0){//敵通常攻撃の場合
						if(battle[battle_cursor + 1].atk + skill[0].point - battle[0].def > 0){
							da = (battle[battle_cursor + 1].atk + skill[0].point - battle[0].def) + ((GetRand(battle[battle_cursor + 1].atk + skill[0].point - battle[0].def) / 5) * plus);
						}
						else{//もし攻撃力ー防御力が0以下なら強制的に1ダメージとなる
							da = 1;
						}
					}
					else{//特技の場合
						if(battle[battle_cursor + 1].atk + skill[pat[battle[battle_cursor + 1].pattern][turn]].point - battle[0].def > 0){
							da = (battle[battle_cursor + 1].atk + skill[pat[battle[battle_cursor + 1].pattern][turn]].point - battle[0].def) + ((GetRand(battle[battle_cursor + 1].atk + skill[pat[battle[battle_cursor + 1].pattern][turn]].point - battle[0].def) / 5) * plus);
						}
						else{//もし攻撃力ー防御力が0以下なら強制的に1ダメージとなる
							da = 1;
						}
					}
				}
				sprintf(da_moji,"%d",da);
				DrawString(300,390,da_moji,color[2]);
				DrawString(360,390,"のダメージ!",color[0]);
				DrawString(410,425,"PUSH ENTER KEY",color[0]);
				while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
				while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
				if(battle[0].hp - da <= 0){//もし0よりも主人公のHPが低いなら
					battle[0].hp = 0;
					battle_cursor = 0;
					battle_menu = 8;//ゲームオーバー前の描画へ
				}
				else{
					battle[0].hp = battle[0].hp - da;//ダメージを計算させ、格納
					battle_cursor += 1;//次の敵行動へ
				}
				enemy_step = 0;//初期化
				ef_move = 0;//初期化
			}
		}
		else{
			battle_cursor += 1;//次の敵行動へ
		}
	}
	else{//抜けたら主人公の行動へ
		battle_cursor = 0;//バトルカーソル初期化
		battle_menu = 0;
		if(turn == 7){
			turn = 0;//初期化
		}
		else{
			turn += 1;//敵のターン追加
		}
	}
}
void battle_item(void){
char count[5];//個数描画のため
char heal_point[5];//回復量描画のため
int box[5];//アイテム欄の上から何が格納されているか
	int item_count = 0;
	int heal;//回復量計算のための変数
		if(item_step == 0){
		for(i = 0;i < item_all;i++){
			if(bag[i] > 0 && item[i].type == 3){//アイテム[i]がバッグに0より入っていて道具なら
				DrawGraph(220,345 + (30 * item_count),item[i].icon,TRUE);//アイコン描画
				DrawString(250,345 + (30 * item_count),item[i].name,color[0]);//名前表示
				sprintf(count,"%d",bag[i]);
				DrawString(400,345 + (30 * item_count),"×",color[0]);
				DrawString(440,345 + (30 * item_count),count,color[0]);

				box[item_count] = i;//boxにiを格納
				item_count += 1;
			}
		}
		DrawString(460,440,"戻る【B】",color[0]);//戻る表示
		if(battle_cursor == item_count){//最大の場合は戻るへ
			DrawGraph(420,440,chara[0].chip[1],TRUE);
			DrawString(35,350,"前画面へ",color[0]);//戻るボタン時
		}
		else{
			DrawGraph(190,343 + (30 * battle_cursor),chara[0].chip[1],TRUE);
			DrawString(35,350,"回復量",color[0]);//回復量
			sprintf(heal_point,"%d",item[box[battle_cursor]].point);
			DrawString(35,380,"HP",color[0]);
			DrawString(75,380,heal_point,color[0]);
		}
		if(key[KEY_INPUT_UP] == 1){
				if(battle_cursor == 0){//現在最小値なら最大値へ
					battle_cursor = item_count;
				}
				else{
					battle_cursor -= 1;
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
			}
			else if(key[KEY_INPUT_DOWN] == 1){
				if(battle_cursor == item_count){//現在最大値なら最小値へ
					battle_cursor = 0;
				}
				else{
					battle_cursor += 1;
				}
				while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
			}
			else if(key[KEY_INPUT_B] == 1){//前画面へ戻る
				battle_menu = 1;
				while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
				PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//カーソル移動音
				battle_cursor = 0;//カーソル初期化
			}
			else if(key[KEY_INPUT_RETURN] == 1){
				if(battle_cursor == item_count){
					battle_menu = 1;//行動選択画面へ
				}
				else if(battle_cursor == 0){
					use_item = box[0]; 
					item_step = 1;
				}
				else if(battle_cursor == 1){
					use_item = box[1]; 
					item_step = 1;
				}
				else if(battle_cursor == 2){
					use_item = box[2]; 
					item_step = 1;
				}
				else if(battle_cursor == 3){
					use_item = box[3]; 
					item_step = 1;
				}
				while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
				PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
				battle_cursor = 0;//初期化
			}
		}
		else if(item_step == 1){
			DrawString(220,355,"主人公のHPが",color[0]);//名前表示
			if(battle[0].hp + item[use_item].point > status[0].hp){//もし回復量が主人公ステータスを上回ったなら本来のMAXHPまで回復
				heal = status[0].hp - battle[0].hp;
				sprintf(heal_point,"%d",heal);
				battle[0].hp = status[0].hp;
				DrawString(400,355,heal_point,color[0]);//名前表示
				DrawString(440,355,"回復しました!",color[0]);//名前表示
			}
			else{
				sprintf(heal_point,"%d",item[use_item].point);
				DrawString(400,355,heal_point,color[0]);//名前表示
				DrawString(440,355,"回復しました!",color[0]);//名前表示
				battle[0].hp = battle[0].hp + item[use_item].point;
			}	
			DrawString(410,425,"PUSH ENTER KEY",color[0]);
			while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
			while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
			bag[use_item] -= 1;//使用したアイテムを-1する
			item_step = 0;//初期化
			use_item = 0;//初期化
			battle_menu = 5;//敵のターンへ
		}
}
void battle_escape(void){
	int escape;//逃げるときの判定に必要な変数
	DrawString(220,355,"主人公は逃げ出した!!",color[0]);
	PlaySoundMem(se[5],DX_PLAYTYPE_BACK);//カーソル移動音
	WaitTimer(1000);
	escape = GetRand(4);
	if(escape == 0){
		DrawString(220,385,"回り込まれて逃れられない!!",color[0]);
		DrawString(410,425,"PUSH ENTER KEY",color[0]);
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
		battle_cursor = 0;
		battle_menu = 5;
	}
	else{
		DrawString(220,385,"戦闘から離脱した!!",color[0]);
		DrawString(410,425,"PUSH ENTER KEY",color[0]);
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
		battle_cursor = 0;
		battle_menu = 0;
		now_mode = 0;
	}
}
void battle_over(void){
	DrawString(210,375,"主人公は死んでしまった・・・",color[2]);
	DrawString(410,425,"PUSH ENTER KEY",color[0]);
	if(CheckSoundMem(bgm[4]) == 0){//bgm再生
		StopSoundMem(bgm[now_bgm]);
		PlaySoundMem(bgm[4],DX_PLAYTYPE_LOOP);
		now_bgm = 4;
	}
	if(key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
		WaitTimer(1000);
		now_mode = 5;//ゲームオーバー画面へ
	}
}

Re: メニュー画面でのバグ

#4

by just_started_PG » 5年前

サンプルコードの続きです。

コード:

//menu.h
void menu_main(void);//メインメニュープロト
void menu_item(void);//アイテムプロト
void menu_sta(void);//ステータスプロト
void menu_skill(void);//特技プロト
void menu_equip(void);//装備プロト
void menu_save(void);//セーブプロト
void menu_title(void);//タイトルプロト
void menu_sta_draw(void);//描画関数プロト
void save_file(int a);//セーブ仕様関数プロト
void load_menu(void);//ロードメニュープロト
void load_file(int a);//ロード仕様関数プロト
void menu_mode(void){
	DrawGraph(0,0,window[3],FALSE);//メニュー背景
	if(menu == 0){//メイン
		menu_main();
	}
	else if(menu == 1){//アイテム
		menu_item();
	}
	else if(menu == 2){//ステータス
		menu_sta();
	}
	else if(menu == 3){//特技
		menu_skill();
	}
	else if(menu == 4){//装備
		menu_equip();
	}
	else if(menu == 5){//セーブ
		menu_save();
	}
	else if(menu == 6){//タイトル
		menu_title();
	}
}
void menu_main(void){//メインメニュー
	SetFontSize(30);//フォントサイズ変更
		DrawString(480,20,"アイテム",color[0]);
		DrawString(480,80,"ステータス",color[0]);
		DrawString(480,140,"特技",color[0]);
		DrawString(480,200,"装備",color[0]);
		DrawString(480,260,"セーブ",color[0]);
		DrawString(480,320,"タイトル",color[0]);
		SetFontSize(20);
		DrawString(410,440,"メニューを閉じる【M】",color[0]);
		SetFontSize(30);

		DrawGraph(440,20 + (60 * menu_cursor),chara[0].chip[1],TRUE);
		//カーソル描画

		if(key[KEY_INPUT_UP] == 1){
			if(menu_cursor == 0){//現在最小値なら最大値へ
				menu_cursor = 5;
			}
			else{
				menu_cursor -= 1;
			}
			while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_DOWN] == 1){
			if(menu_cursor == 5){//現在最大値なら最小値へ
				menu_cursor = 0;
			}
			else{
				menu_cursor += 1;
			}
			while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_M] == 1 || key[KEY_INPUT_B] == 1){
			now_mode = 0;//マップモードへ
			menu_cursor = 0;
			SetFontSize(24);//文字サイズを戻す
			while(CheckHitKey(KEY_INPUT_M) ==1);//連打抑制
			while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		}
		else if(key[KEY_INPUT_RETURN] == 1){
			switch(menu_cursor){
				case 0:menu = 1;//アイテム画面へ
					break;
				case 1:menu = 2;//ステータス画面へ
					break;
				case 2:menu = 3;//特技画面へ
					break;
				case 3:menu = 4;//装備画面へ
					break;
				case 4:menu = 5;//セーブ画面へ
					break;
				case 5:menu = 6;//タイトル画面へ
					break;
			}
			while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
		}

}
void menu_item(void){//アイテム
char count[5];//個数描画のため
char heal_point[5];//回復量描画のため
int heal;//回復量計算のための変数
int box[5];//アイテム欄の上から何が格納されているか
	int item_count = 0;
	for(i = 0;i < item_all;i++){
		if(bag[i] > 0 && item[i].type == 3){//アイテム[i]がバッグに0より入っていて道具なら
			DrawGraph(40,22 + (40 * item_count),item[i].icon,TRUE);//アイコン描画
			DrawString(70,20 + (40 * item_count),item[i].name,color[0]);//名前表示
			sprintf(count,"%d",bag[i]);
			DrawString(200,20 + (40 * item_count),"×",color[0]);
			DrawString(240,20 + (40 * item_count),count,color[0]);

			box[item_count] = i;//boxにiを格納
			item_count += 1;
		}
	}
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(500,280,"戻る",color[0]);//戻る表示
	if(item_step == 0){
		if(menu_cursor == item_count){//最大の場合は戻るへ
			DrawGraph(460,280,chara[0].chip[1],TRUE);
			DrawString(30,350,"メニュー画面へ戻ります",color[0]);//戻るボタン時
		}
		else{
			DrawGraph(10,20 + (40 * menu_cursor),chara[0].chip[1],TRUE);
			for(i = 0;i < item[box[menu_cursor]].text_count;i++){
				DrawString(30,350 + (35 * i),item[box[menu_cursor]].text[i],color[0]);
				//テキスト描画
			}
		}
		if(key[KEY_INPUT_UP] == 1){
				if(menu_cursor == 0){//現在最小値なら最大値へ
					menu_cursor = item_count;
				}
				else{
					menu_cursor -= 1;
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_DOWN] == 1){
			if(menu_cursor == item_count){//現在最大値なら最小値へ
				menu_cursor = 0;
			}
			else{
				menu_cursor += 1;
			}
			while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_RETURN] == 1){
			if(menu_cursor == item_count){
				menu = 0;//メインメニューへ
			}
			else{
				use_item = box[menu_cursor];
				menu_cursor = 0;//初期化
				item_step = 1;//次のステップへ
			}
			while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
		}
		else if(key[KEY_INPUT_B] == 1){
			while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
			menu = 0;//メインメニューへ
		}
	}
	else if(item_step == 1){
		DrawString(30,350 ,item[use_item].name,color[0]);
		DrawString(150,350 ,"を使用しますか?",color[0]);
		DrawString(80,385 ,"はい",color[0]);
		DrawString(80,420 ,"いいえ",color[0]);
		DrawGraph(42,380 + (35 * menu_cursor),chara[0].chip[1],TRUE);
		if(key[KEY_INPUT_UP] == 1){
				if(menu_cursor == 0){//現在最小値なら最大値へ
					menu_cursor = 1;
				}
				else{
					menu_cursor -= 1;
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_DOWN] == 1){
			if(menu_cursor == 1){//現在最大値なら最小値へ
				menu_cursor = 0;
			}
			else{
				menu_cursor += 1;
			}
			while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_RETURN] == 1){
			if(menu_cursor == 0){
				item_step = 2;//メインメニューへ
			}
			else{
				use_item = box[menu_cursor];
				menu_cursor = 0;//初期化
				item_step = 0;//次のステップへ
			}
			while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
		}
		else if(key[KEY_INPUT_B] == 1){
			while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
			item_step = 0;//戻る
		}


	}
	else if(item_step == 2){
		DrawString(30,350,"主人公のHPが",color[0]);
			if(battle[0].hp + item[use_item].point > status[0].hp){//もし回復量が主人公ステータスを上回ったなら本来のMAXHPまで回復
				heal = status[0].hp - battle[0].hp;
				sprintf(heal_point,"%d",heal);
				battle[0].hp = status[0].hp;
				DrawString(260,350,heal_point,color[0]);
				DrawString(340,350,"回復しました!",color[0]);
			}
			else{
				sprintf(heal_point,"%d",item[use_item].point);
				DrawString(260,350,heal_point,color[0]);
				DrawString(340,350,"回復しました!",color[0]);
				battle[0].hp = battle[0].hp + item[use_item].point;
			}	
			DrawString(380,425,"PUSH ENTER KEY",color[0]);
			while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
			while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
			bag[use_item] -= 1;//使用したアイテムを-1する
			item_step = 0;//初期化
			use_item = 0;//初期化
	}
}
void menu_sta(void){//ステータス
	menu_sta_draw();//sta描画関数
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 7;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor == 7){//現在最大値なら最小値へ
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_LEFT] == 1 && 
		bonus - (bonus_dumy[0] + bonus_dumy[1] + bonus_dumy[2] + bonus_dumy[3] + bonus_dumy[4] + bonus_dumy[5]) > 0 && menu_cursor < 6){
			if(menu_cursor != 5 || bonus_dumy[5] / (2 + (chara_skill[0].flag * chara_skill[0].flag) - skill_pt )< 1 && chara_skill[0].flag < 7){
			//割振り合計が所持BPを超えないように
				bonus_dumy[menu_cursor] += 1;
				while(CheckHitKey(KEY_INPUT_LEFT) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
			}
	}
	else if(key[KEY_INPUT_RIGHT] == 1 && bonus_dumy[menu_cursor] > 0 && menu_cursor < 6){//割振りが1以上あるなら
		bonus_dumy[menu_cursor] -= 1;
		while(CheckHitKey(KEY_INPUT_RIGHT) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 7 && key[KEY_INPUT_RETURN] == 1){
		for(i = 0;i < 6;i++){
			bonus_dumy[i] = 0;//初期化
			//戻った時に割振りが保存されているとまた入った時に振ったままになってしまうため
		}
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 1;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1 && menu_cursor == 6){
		if(bonus_dumy[0] > 0 || bonus_dumy[1] > 0 || bonus_dumy[2] > 0 ||
			bonus_dumy[3] > 0 || bonus_dumy[4] > 0 || bonus_dumy[5] > 0 ){ 
				DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
				DrawString(20,350,"ステータスが上昇しました!",color[0]);
				status[0].hp += bonus_dumy[0] * 10;//hpz
				battle[0].hp += bonus_dumy[0] * 10;//hpz(現在HPにも上昇値分のみプラス)
				status[0].tp += bonus_dumy[1] * 5;//tp
				battle[0].tp = status[0].tp;//tp(現在TPはステータスまで回復)
				status[0].atk += bonus_dumy[2];//atk
				status[0].def += bonus_dumy[3];//def
				status[0].spd += bonus_dumy[4];//spd
				skill_pt += bonus_dumy[5];//skillpt
				if(skill_pt >= 2 + (chara_skill[0].flag * chara_skill[0].flag)){//スキルレベルアップポイントまで振ったら
					skill_pt = 0;//初期化
					chara_skill[0].flag += 1;
					DrawString(20,380,"主人公は特技",color[0]);
					DrawString(250,380,skill[chara_skill[0].tokugi[chara_skill[0].flag]].name,color[0]);
					DrawString(390,380,"を習得した!",color[0]);
				}
				bonus = bonus - (bonus_dumy[0] + bonus_dumy[1] + bonus_dumy[2] + bonus_dumy[3] + bonus_dumy[4] + bonus_dumy[5]);
				//使用したボーナスを引く
				WaitTimer(1000);
				for(i = 0;i < 6;i++){
					bonus_dumy[i] = 0;//初期化
					//戻った時に割振りが保存されているとまた入った時に振ったままになってしまうため
				}
				while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
				PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
				menu_cursor = 0;//初期化(カーソルがステータスの上へ)
		}
	}
}
void menu_skill(void){//特技
	char atk_pt[5];//特技攻撃力
	char tp_pt[5];//消費tp
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(570,270,"戻る",color[0]);//戻る描画
	for(i = 0;i <= chara_skill[0].flag;i++){//スキルレベルが0からなのでレベル以下なら描画
		DrawString(60,10 +(40 * i),skill[chara_skill[0].tokugi[i]].name,color[0]);
	}
	if(menu_cursor <= chara_skill[0].flag){//スキルレベル以下ならカーソルを特技へ、違うなら戻るへカーソル
		DrawGraph(20,10 + (menu_cursor * 40),chara[0].chip[1],TRUE);
	}
	else{
		DrawGraph(530,270,chara[0].chip[1],TRUE);
	}
	if(menu_cursor <= chara_skill[0].flag){//特技にカーソルが乗っているなら情報を描画
		sprintf(atk_pt,"%d",skill[chara_skill[0].tokugi[menu_cursor]].point);
		sprintf(tp_pt,"%d",skill[chara_skill[0].tokugi[menu_cursor]].tp);
		DrawString(40,360,"特技攻撃力:",color[0]);
		DrawString(40,400,"消費TP:",color[0]);
		DrawString(260,360,atk_pt,color[0]);
		DrawString(260,400,tp_pt,color[0]);
	}
	else//違うなら戻るへ
		DrawString(40,360,"メニュートップへ戻る",color[0]);
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = chara_skill[0].flag + 1;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  chara_skill[0].flag + 1){//現在最大値なら最小値へ
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == chara_skill[0].flag + 1 && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 2;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
}
void menu_equip(void){//装備
int box[2][5];//アイテム欄の上から何が格納されているか
int item_count[2] = {0};
char e_point[5];//武器防具のパラメーター
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(570,270,"戻る",color[0]);//戻る描画
	for(i = 0;i < item_all;i++){
		if(bag[i] > 0 && item[i].type == 1 ){//アイテム[i]がバッグに0より入っていて武器なら
			DrawGraph(40,22 + (40 * item_count[0]),item[i].icon,TRUE);//アイコン描画
			DrawString(70,20 + (40 * item_count[0]),item[i].name,color[0]);//名前表示
			box[0][item_count[0]] = i;//boxにiを格納
			if(s_equip[0] == i){
				DrawString(240,20 + (40 * item_count[0]),"E",color[0]);//名前表示
			}
			item_count[0] += 1;
		}
		else if(bag[i] > 0 && item[i].type == 2 ){//アイテム[i]がバッグに0より入っていて防具なら
			DrawGraph(340,22 + (40 * item_count[1]),item[i].icon,TRUE);//アイコン描画
			DrawString(370,20 + (40 * item_count[1]),item[i].name,color[0]);//名前表示
			box[1][item_count[1]] = i;//boxにiを格納
			if(s_equip[1] == i){
				DrawString(540,20 + (40 * item_count[1]),"E",color[0]);//名前表示
			}
			item_count[1] += 1;
		}
	}

	if(menu_cursor < item_count[0]){//武器のカーソル
		sprintf(e_point,"%d",item[box[0][menu_cursor]].point);//武器の攻撃力変換
		DrawGraph(10,20 + (menu_cursor * 40),chara[0].chip[1],TRUE);
		DrawString(40,340,"武器攻撃力:",color[0]);
		DrawString(40,370,"説明:",color[0]);
		DrawString(240,340,e_point,color[0]);
		for(i = 0;i < item[box[0][menu_cursor]].text_count;i++){//テキストカウント分描画
			DrawString(160,370 +(i * 30),item[box[0][menu_cursor]].text[i],color[0]);//テキスト描画
		}
	}
	else if(menu_cursor < item_count[0] + item_count[1]){//防具のカーソル
		sprintf(e_point,"%d",item[box[1][menu_cursor - item_count[0]]].point);//防具の防御力変換
		DrawGraph(310,20 + ((menu_cursor - item_count[0]) * 40),chara[0].chip[1],TRUE);
		DrawString(40,340,"防具防御力:",color[0]);
		DrawString(40,370,"説明:",color[0]);
		DrawString(240,340,e_point,color[0]);
		for(i = 0;i < item[box[1][menu_cursor - item_count[0]]].text_count;i++){//テキストカウント分描画
			DrawString(160,370 +(i * 30),item[box[1][menu_cursor - item_count[0]]].text[i],color[0]);//テキスト描画
		}
	}
	else{//戻るの時
		DrawGraph(540,270,chara[0].chip[1],TRUE);
		DrawString(40,340,"トップメニューに戻る",color[0]);
	}
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = item_count[0] + item_count[1];//武器・防具の合計
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  item_count[0] + item_count[1]){//武器防具の合計が最大値なら最小値へ
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor ==  item_count[0] + item_count[1] && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 3;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		if(menu_cursor < item_count[0]){
			//選んでいるのが武器の場合
			s_equip[0] = box[0][menu_cursor];
		}
		else if(menu_cursor < item_count[0] + item_count[1]){
			//選んでいるのが防具の場合
			s_equip[1] = box[1][menu_cursor - item_count[0]];
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
	}
}
void menu_save(void){//セーブ
	static int a[3][5];//ステータスを画面で描画するために入れておく配列
	char b[5][20];//ステータス描画用
	FILE *fp;
	fp = fopen("save_0.txt","r");//セーブロード画面用要素テキストファイルオープン
	for(i = 0;i < 3;i++){
		fscanf(fp,"%d %d %d %d %d",&a[i][0],&a[i][1],&a[i][2],&a[i][3],&a[i][4]);//セーブデータのステータス読み込み
	}
	fclose(fp);
	LoadGraphScreen(0,0,"背景/ロード.jpg",FALSE);
	for(i = 0;i < 3;i++){//セーブ枠3つ描画
		DrawGraph(0,-20 +(160 * i),window[1],TRUE);
		if(a[i][0] <= 0){//セーブデータステータスHPが格納されていない(つまり0)なら
			DrawString(200,60 +(160 * i),"データがありません。",color[2]);
		}
		else{
			DrawGraph(50,30 + (160 * i),chara[0].face[0],TRUE);//主人公の顔画像描画
			sprintf(b[0],"%d",a[i][0]);//HP変換
			sprintf(b[1],"%d",a[i][1]);//TP変換
			sprintf(b[2],"%d",a[i][2]);//ATK変換
			sprintf(b[3],"%d",a[i][3]);//DEF変換
			sprintf(b[4],"%d",a[i][4]);//SPD変換
			DrawString(200,20 +(160 * i),"最大HP:",color[2]);//HP描画
			DrawString(310,20 +(160 * i),b[0],color[2]);//HP描画
			DrawString(400,20 +(160 * i),"最大TP:",color[2]);//TP描画
			DrawString(510,20 +(160 * i),b[1],color[2]);//TP描画
			DrawString(200,60 +(160 * i),"攻撃力:",color[2]);//ATK描画
			DrawString(310,60 +(160 * i),b[2],color[2]);//ATK描画
			DrawString(400,60 +(160 * i),"防御力:",color[2]);//DEF描画
			DrawString(510,60 +(160 * i),b[3],color[2]);//DEF描画
			DrawString(200,100 +(160 * i),"素早さ:",color[2]);//SPD描画
			DrawString(310,100 +(160 * i),b[4],color[2]);//SPD描画
		}
	}
	SetFontSize(16);
	DrawString(440,460,"メニューに戻る",color[2]);
	SetFontSize(30);
	if(menu_cursor == 3){
		DrawGraph(410,460,chara[0].chip[1],TRUE);
	}
	else{
		DrawGraph(0,60 +(160 * menu_cursor),chara[0].chip[1],TRUE);
	}
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 3;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  3){
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 3 && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 4;//初期化(カーソルがセーブの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1){ //決定
		save_file(menu_cursor);
		fp = fopen("save_0.txt","w");
		a[menu_cursor][0] = status[0].hp;//主人公のMAXHP
		a[menu_cursor][1] = status[0].tp;//主人公のMAXTP
		a[menu_cursor][2] = status[0].atk;//主人公のATK
		a[menu_cursor][3] = status[0].def;//主人公のDEF
		a[menu_cursor][4] = status[0].spd;//主人公のSPD
		for(i = 0;i < 3;i++){
			fprintf(fp,"%d %d %d %d %d \n",a[i][0],a[i][1],a[i][2],a[i][3],a[i][4]);
		}
		fclose(fp);
		LoadGraphScreen(0,0,"背景/セーブロード.jpg",FALSE);
		DrawString(160,240,"セーブしました",color[2]);
		WaitTimer(1000);
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
	}
}
void menu_title(void){//タイトル
	LoadGraphScreen(0,0,"背景/ロード.jpg",FALSE);
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(40,350,"本当にタイトルに戻りますか?",color[0]);
	DrawString(490,390,"はい",color[0]);
	DrawString(490,430,"いいえ",color[0]);
	DrawGraph(450,390 + (menu_cursor * 40),chara[0].chip[1],TRUE);
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 1;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  1){
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 1 && key[KEY_INPUT_RETURN] == 1){//いいえの場合
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 5;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		now_mode = 6;//トップ画面へ
		SetFontSize(24);//文字サイズを戻す
	}
}
void menu_sta_draw(void){//sta描画関数
	char st[2][11][20];//ステータス数値描画用
	char wari[7][20];//ボーナス割り振り描画用
	//ボーナス割り振り後の文字のために2列
	DrawGraph(20,20,chara[0].face[0],FALSE);//主人公の顔
	DrawString(140,20,chara[0].name,color[0]);//名前描画
	DrawString(520,0,"BP振り",color[0]);
	DrawString(540,40,"割振る",color[0]);//割振る描画
	DrawString(540,80,"戻る",color[0]);//戻る描画
	//カーソル画像描画
	if(menu_cursor > 5){
		DrawGraph(500,40 + ((menu_cursor - 6)* 40),chara[0].chip[1],TRUE);
	}
	else if(menu_cursor == 5){
		DrawGraph(540,360,chara[0].chip[1],TRUE);
	}
	else{
		DrawGraph(540,120 + (menu_cursor * 40),chara[0].chip[1],TRUE);
	}
	//int型からchar型へ変換
	sprintf(st[0][0],"%d",status[0].hp);
	sprintf(st[0][1],"%d",status[0].tp);
	sprintf(st[0][2],"%d",status[0].atk);
	sprintf(st[0][3],"%d",status[0].def);
	sprintf(st[0][4],"%d",status[0].spd);
	sprintf(st[0][5],"%d",chara_skill[0].flag);
	//hpとtpのみ現在数値も変換
	sprintf(st[0][6],"%d",battle[0].hp);
	sprintf(st[0][7],"%d",battle[0].tp);
	//bonusも変換
	sprintf(st[0][8],"%d",bonus);
	//特技ポイント
	sprintf(st[0][9],"%d",skill_pt);
	sprintf(st[0][10],"%d",2 + (chara_skill[0].flag * chara_skill[0].flag));//next(2 + レベルの2乗)
	//int型からchar型へ変換(bonus後)
	sprintf(st[1][0],"%d",status[0].hp + ( 10 * bonus_dumy[0]));
	sprintf(st[1][1],"%d",status[0].tp + ( 5 * bonus_dumy[1]));
	sprintf(st[1][2],"%d",status[0].atk + bonus_dumy[2]);
	sprintf(st[1][3],"%d",status[0].def + bonus_dumy[3]);
	sprintf(st[1][4],"%d",status[0].spd + bonus_dumy[4]);
	sprintf(st[1][5],"%d",chara_skill[0].flag + bonus_dumy[5] / (2 + (chara_skill[0].flag * chara_skill[0].flag) - skill_pt ));
	//hpとtpのみ現在数値も変換
	sprintf(st[1][6],"%d",battle[0].hp + ( 10 * bonus_dumy[0]));
	sprintf(st[1][7],"%d",status[0].tp + ( 5 * bonus_dumy[1]));
	//bonusも変換
	sprintf(st[1][8],"%d",bonus - (bonus_dumy[0] + bonus_dumy[1] + bonus_dumy[2] + bonus_dumy[3] + bonus_dumy[4] + bonus_dumy[5]));
	//特技ポイント
	sprintf(st[1][9],"%d",skill_pt + bonus_dumy[5]);
	sprintf(st[1][10],"%d",2 + (chara_skill[0].flag * chara_skill[0].flag));//next(2 + レベルの2乗)
	//文字を描画
	DrawString(120,120,"HP",color[0]);
	DrawString(120,160,"TP",color[0]);
	DrawString(120,200,"攻撃力",color[0]);
	DrawString(120,240,"防御力",color[0]);
	DrawString(120,280,"素早さ",color[0]);
	DrawString(120,320,"特技Lv.",color[0]);
	DrawString(120,360,"特技pt.",color[0]);
	DrawString(120,400,"BONUSpt.",color[0]);
	SetFontSize(12);
	DrawString(20,450,"←キー:BP振り →キー:BP戻し Bキーor戻るでENTER:前画面へ 割振るでENTER:割り振り確定",color[0]);
	SetFontSize(30);
	//実際の数値描画
	DrawString(310,120,st[0][0],color[0]);//hp
	DrawString(310,160,st[0][1],color[0]);//tp
	DrawString(240,200,st[0][2],color[0]);//atk
	DrawString(240,240,st[0][3],color[0]);//def
	DrawString(240,280,st[0][4],color[0]);//spd
	DrawString(240,320,st[0][5],color[0]);//特技レベル
	DrawString(240,120,st[0][6],color[0]);//hp2
	DrawString(240,160,st[0][7],color[0]);//tp2
	DrawString(295,120,"/",color[0]);
	DrawString(295,160,"/",color[0]);
	DrawString(240,400,st[0][8],color[0]);//bonus
	if(chara_skill[0].flag >= 7){
		DrawString(240,360,"MAX",color[0]);//skill_pt
		DrawString(310,360,"MAX",color[0]);//skill_pt
	}
	else{
		DrawString(240,360,st[0][9],color[0]);//skill_pt
		DrawString(310,360,st[0][10],color[0]);//skill_pt
	}
	DrawString(295,360,"/",color[0]);
	//カーソル
	DrawString(375,120,"→",color[2]);
	DrawString(375,160,"→",color[2]);
	DrawString(375,200,"→",color[2]);
	DrawString(375,240,"→",color[2]);
	DrawString(375,280,"→",color[2]);
	DrawString(375,320,"→",color[2]);
	DrawString(375,360,"→",color[2]);
	DrawString(375,400,"→",color[2]);
	//ステータス上昇後
	DrawString(480,120,st[1][0],color[2]);//hp
	DrawString(480,160,st[1][1],color[2]);//tp
	DrawString(410,200,st[1][2],color[2]);//atk
	DrawString(410,240,st[1][3],color[2]);//def
	DrawString(410,280,st[1][4],color[2]);//spd
	DrawString(410,320,st[1][5],color[2]);//特技レベル
	DrawString(410,120,st[1][6],color[2]);//hp2
	DrawString(410,160,st[1][7],color[2]);//tp2
	DrawString(470,120,"/",color[2]);
	DrawString(470,160,"/",color[2]);
	DrawString(410,400,st[1][8],color[2]);//bonus
	if(chara_skill[0].flag >= 7){
		DrawString(410,360,"MAX",color[2]);//skill_pt
		DrawString(480,360,"MAX",color[2]);//skill_pt
	}
	else{
		DrawString(410,360,st[1][9],color[2]);//skill_pt
		DrawString(480,360,st[1][10],color[2]);//skill_pt
	}
	DrawString(470,360,"/",color[2]);
	//ボーナス割り振り変換
	sprintf(wari[0],"%d",bonus_dumy[0]);
	sprintf(wari[1],"%d",bonus_dumy[1]);
	sprintf(wari[2],"%d",bonus_dumy[2]);
	sprintf(wari[3],"%d",bonus_dumy[3]);
	sprintf(wari[4],"%d",bonus_dumy[4]);
	sprintf(wari[5],"%d",bonus_dumy[5]);
	//ボーナス割り振り
	DrawString(580,120,wari[0],color[0]);//hp
	DrawString(580,160,wari[1],color[0]);//tp
	DrawString(580,200,wari[2],color[0]);//atk
	DrawString(580,240,wari[3],color[0]);//def
	DrawString(580,280,wari[4],color[0]);//spd
	DrawString(580,360,wari[5],color[0]);//特技pt
}
void save_file(int a){
	FILE *fp;
	char filename[3][255] = {"save_1.txt","save_2.txt","save_3.txt"};
	fp = fopen(filename[a],"w");
	fprintf(fp,"%d %d %d %d %d %d %d %d %d \n",now_map,s_pos_x,s_pos_y,s_vector,vector_check,now_bgm,en_count,s_equip[0],s_equip[1]);
	for(i=0;i < 15;i++){//バッグの中身
		fprintf(fp,"%d \n",bag[i]);
	}
	for(i=0;i < 32;i++){//イベントフラグ
		fprintf(fp,"%d \n",chara_eve[i].flag);
	}
	//主人公ステータス
	fprintf(fp,"%d %d %d %d %d %d %d %d %d %d \n",status[0].hp,status[0].tp,battle[0].hp,battle[0].tp,
		status[0].atk,status[0].def,status[0].spd,chara_skill[0].flag,bonus,skill_pt);
	fclose(fp);
}
void load_menu(void){
	SetFontSize(30);
	int a[3][5];//ステータスを画面で描画するために入れておく配列
	char b[5][5];//ステータス描画用
	FILE *fp;
	fp = fopen("save_0.txt","r");//セーブロード画面用要素テキストファイルオープン
	for(i = 0;i < 3;i++){
		fscanf(fp,"%d %d %d %d %d",&a[i][0],&a[i][1],&a[i][2],&a[i][3],&a[i][4]);//セーブデータのステータス読み込み
	}
	fclose(fp);
	LoadGraphScreen(0,0,"背景/ロード.jpg",FALSE);
	for(i = 0;i < 3;i++){//セーブ枠3つ描画
		DrawGraph(0,-20 +(160 * i),window[1],TRUE);
		if(a[i][0] <= 0){//セーブデータステータスHPが格納されていない(つまり0)なら
			DrawString(200,60 +(160 * i),"データがありません。",color[2]);
		}
		else{
			DrawGraph(50,30 + (160 * i),chara[0].face[0],TRUE);//主人公の顔画像描画
			sprintf(b[0],"%d",a[i][0]);//HP変換
			sprintf(b[1],"%d",a[i][1]);//TP変換
			sprintf(b[2],"%d",a[i][2]);//ATK変換
			sprintf(b[3],"%d",a[i][3]);//DEF変換
			sprintf(b[4],"%d",a[i][4]);//SPD変換
			DrawString(200,20 +(160 * i),"最大HP:",color[2]);//HP描画
			DrawString(310,20 +(160 * i),b[0],color[2]);//HP描画
			DrawString(400,20 +(160 * i),"最大TP:",color[2]);//TP描画
			DrawString(510,20 +(160 * i),b[1],color[2]);//TP描画
			DrawString(200,60 +(160 * i),"攻撃力:",color[2]);//ATK描画
			DrawString(310,60 +(160 * i),b[2],color[2]);//ATK描画
			DrawString(400,60 +(160 * i),"防御力:",color[2]);//DEF描画
			DrawString(510,60 +(160 * i),b[3],color[2]);//DEF描画
			DrawString(200,100 +(160 * i),"素早さ:",color[2]);//SPD描画
			DrawString(310,100 +(160 * i),b[4],color[2]);//SPD描画
		}
	}
	SetFontSize(16);
	DrawString(440,460,"トップ画面に戻る",color[2]);
	SetFontSize(30);
	if(menu_cursor == 3){
		DrawGraph(410,460,chara[0].chip[1],TRUE);
	}
	else{
		DrawGraph(0,60 +(160 * menu_cursor),chara[0].chip[1],TRUE);
	}
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 3;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  3){
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 3 && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 1;//初期化(カーソルがセーブの上へ)
		SetFontSize(24);//初期化
		now_mode = 6;//トップ画面へ
	}
	else if(key[KEY_INPUT_RETURN] == 1 && a[menu_cursor][0] > 0){ //データがない状態じゃない、つまりMAXHPが1以上あるデータなら
		load_file(menu_cursor);
		LoadGraphScreen(0,0,"背景/セーブロード.jpg",FALSE);
		DrawString(160,240,"ロードしました",color[2]);
		WaitTimer(1000);
		SetFontSize(24);//初期化
		now_mode = 0;//マップへ
		menu_cursor = 0;
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
	}
}
void load_file(int a){
	FILE *fp;
	char filename[3][255] = {"save_1.txt","save_2.txt","save_3.txt"};
	fp = fopen(filename[a],"r");
	fscanf(fp,"%d %d %d %d %d %d %d %d %d",&now_map,&s_pos_x,&s_pos_y,&s_vector,&vector_check,&now_bgm,&en_count,&s_equip[0],&s_equip[1]);
	for(i=0;i < 15;i++){//バッグの中身
		fscanf(fp,"%d",&bag[i]);
	}
	for(i=0;i < 32;i++){//イベントフラグ
		fscanf(fp,"%d",&chara_eve[i].flag);
	}
	//主人公ステータス
	fscanf(fp,"%d %d %d %d %d %d %d %d %d %d",&status[0].hp,&status[0].tp,&battle[0].hp,&battle[0].tp,
		&status[0].atk,&status[0].def,&status[0].spd,&chara_skill[0].flag,&bonus,&skill_pt);

	fclose(fp);
}

Re: メニュー画面でのバグ

#3

by just_started_PG » 5年前

至らない点が多々ありました、すみません。
サンプル丸ごとコピーすると、問題になりそうだと思ったのですが、

いろいろ誤っていて、動かないサンプルなら大丈夫ですよね。
問題がありそうなら、削除します。

後は、RPG sample.zip にはfileload.hで記載されている画像ファイルは一つも含まれているので
フリー素材を探して来て、適当に見繕うしかありません。

本のタイトルも間違っていましたね、すみません。
「ライブラリではじめるC言語開発」→「ライブラリではじめるC言語ゲーム開発」です。

後は、文字制限に引っかからないよう、
複数に分けてサンプルコードを掲載いたします。

コード:

//main.cpp

#include "DxLib.h"//DXライブラリ
#include "main.h"//変数、関数用ヘッダファイル
#include "map.h"//マップ用ヘッダファイル
#include "move.h"//移動用関数ヘッダファイル
#include "event.h"//イベント用ヘッダファイル
#include "menu.h"//メニュー用ヘッダファイル
#include "battle.h"//バトル用ヘッダファイル
#include "fileload.h"//ファイル読み込み関数ヘッダファイル
void open(void);//プロトタイプ関数
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){//メイン関数

		ChangeWindowMode(TRUE);
		SetDrawScreen(DX_SCREEN_BACK);//画面の裏に描写するように設定
		if(DxLib_Init() == -1){ //DXライブラリ初期化
			return -1; //エラーが起きたらすぐ終了
		}
		SetFontSize(24);//文字サイズ初期値
		ChangeFont( "HG明朝E" ) ;
		fileload(0);//ファイルロード関数を呼び出し

		//画像ファイル配列へ格納
		while(ScreenFlip() == 0 && ProcessMessage() == 0 &&
			GetHitKeyStateAll(key) == 0){//メインループの始まり
			ClearDrawScreen();//画面をクリア
			
			if(now_mode == 0){//マップ移動可能モード
				draw_map();//マップ描画
				DrawGraph(s_pos_x * 32,s_pos_y * 32,chara[0].chip[s_vector],TRUE);//主人公描画
				if(CheckSoundMem(bgm[0]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[0],DX_PLAYTYPE_LOOP);
					now_bgm = 0;
				}
				map_move();
			}
			else if(now_mode == 1){//イベントモード
				draw_map();//マップ描画
				DrawGraph(s_pos_x * 32,s_pos_y * 32,chara[0].chip[s_vector],TRUE);//主人公描画
				event_mode();
			}
			else if(now_mode == 2){//メニューモード
				if(CheckSoundMem(bgm[5]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[5],DX_PLAYTYPE_LOOP);
					now_bgm = 5;
				}
				menu_mode();
			}
			else if(now_mode == 3){//バトル準備
				battle_change();//バトルの準備をする関数
				turn = 0;//ターン初期化
				enemy_step = 0;//初期化
				now_mode = 4;//バトルへ
				battle_cursor = 0;//バトルカーソル初期化
			}
			else if(now_mode == 4){//バトル
				battle_mode();
			}
			else if(now_mode == 5){//ゲームオーバー
				LoadGraphScreen(0,0,"背景/ゲームオーバー.png",FALSE);
				if(CheckSoundMem(bgm[2]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[2],DX_PLAYTYPE_LOOP);
					now_bgm = 2;
				}
				DrawString(410,425,"PUSH ENY KEY",color[2]);	
				WaitKey();
				WaitTimer(1000);
				now_mode = 6;
			}
			else if(now_mode == 6){//トップ画面
				LoadGraphScreen(0,0,"背景/top.jpg",FALSE);
				DrawGraph(340,340 + (menu_cursor * 40),chara[0].chip[1],TRUE);//アイコン描画
				DrawString(400,340,"ゲームを始める",color[0]);//戻る表示
				DrawString(400,380,"続きから",color[0]);//戻る表示
				DrawString(400,420,"ゲームを終了する",color[0]);//ゲーム終了表示
				if(CheckSoundMem(bgm[3]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[3],DX_PLAYTYPE_LOOP);
					now_bgm = 3;
				}
				if(key[KEY_INPUT_UP] == 1){
						if(menu_cursor == 0){//現在最小値なら最大値へ
							menu_cursor = 2;
						}
						else{
							menu_cursor -= 1;
						}
						while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
						PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
				}
				else if(key[KEY_INPUT_DOWN] == 1){
					if(menu_cursor == 2){//現在最大値なら最小値へ
						menu_cursor = 0;
					}
					else{
						menu_cursor += 1;
					}
					while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
					PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
				}
				else if(key[KEY_INPUT_RETURN] == 1){
						if(menu_cursor == 0){
							fileload(1);//ステータスなど初期化
							now_mode = 8;//オープニングへ
							battle[0].hp = status[0].hp;//体力初期化
							battle[0].tp = status[0].tp;//tp初期化
							now_map = 1;//初期化
							en_count = 0;
							menu_cursor = 0;
							battle_cursor = 0;
							s_pos_x = 0;
							s_pos_y = 0;
							s_vector = 1;
							bag[0] = 1;//武器
							bag[4] = 1;//防具
							bag[8] = 1;//アイテム所持
							bonus = 10;//ボーナスポイント初期化
							s_equip[0] = 0;//木の剣装備
							s_equip[1] = 4;//普通の服装備
						}
						else if(menu_cursor == 1){//続きから
							now_mode = 7;//ロード画面へ
							menu_cursor = 0;//初期化
						}
						else if(menu_cursor == 2){//ゲーム終了
							DxLib_End();    // DXライブラリ終了処理
							return 0;
						}
						escape = 0;//初期化
						event_b = -1;//初期化
						while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
						PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
						menu_cursor = 0;//初期化
				}
			}
			else if(now_mode == 7){//ロード画面ーモード
				if(CheckSoundMem(bgm[5]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[5],DX_PLAYTYPE_LOOP);
					now_bgm = 5;
				}
				fileload(1);//ステータスなど初期化
				load_menu();//データロード画面へ
			}
			else if(now_mode == 8){//OP
				if(CheckSoundMem(bgm[7]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[7],DX_PLAYTYPE_LOOP);
					now_bgm = 7;
				}
				open();//オープニング画面へ
			}
		}
}
void open(void){
	DrawGraph(0,310,window[1],TRUE);//会話ウィンドウを表示
	DrawGraph(50,355,chara[0].face[op_eve[op_cnt].face_no],TRUE);
	//フェイス表示
	DrawString(200,350,chara[0].name,color[0]);
	//名前表示
	for(i = 0;i < op_eve[op_cnt].talk_count;i++){
		DrawString(195,375 +(27 * i),op_eve[op_cnt].kaiwa[i],color[0]);
	}
		DrawString(410,300,"PUSH ENTER KEY",color[2]);
		op_cnt += 1;
		if(op_cnt >= 30){
			op_cnt = 0;//初期化
			now_mode = 0;//マップへ
		}
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
}

コード:

//main.h
int map[10][15][20];//マップ画像番号格納用
int block[15][20];//侵入不可ゾーン格納配列

int now_map = 1;//現在表示マップ格納変数(セーブ)

int menu_cursor = 0;//メニューカーソル
int menu = 0;//現在メニュー判断

int item_all = 30;//アイテムの総数
int bag[15];//配列の数は総アイテムの数とします(セーブ2)

int window[4];//セリフなどの枠を格納
int color[3];//文字色格納配列

int now_mode = 6;//現在のモード変数(topが6になるため初期値は6)
int now_eve = 0;//実行するイベントを格納

int map_chip[2][152];//画像格納用配列(マップチップ用)
//マップ用の移動キャラ画像が12枚あるため12枚今は
//1キャラしかいないので左の配列は1とする。

int s_pos_x = 0;//主人公の現在地座標x(よこ)(セーブ)
int s_pos_y = 0;//主人公の現在地座標y(たて)(セーブ)

int s_vector = 1;//主人公の現在向き(セーブ)
//(今回、初期値はこちらを向いてる1としましょう)

int vector_check = 1;//0,1,2,1,0...にするための変数


int i,j;//for分用変数

char key[256];//GetHitKeyStateAllのための配列
int chara_all = 32;//ゲーム内のキャラクター数
struct chara1{//キャラクタイベントの構造体
	int no;//イベントno
	int chara_no;//どのキャラか
	int pos_x;//キャラの出現座標x
	int pos_y;//キャラの出現座標y
	int map;//キャラ出現マップ
	int battle;//戦闘があるかどうか
	int eve_flag;//他のイベのフラグを立たせるか
	int bgm;//bgmを変えるかどうか
	int face_no;//さらに何番目の画像か
	int chip_vector;//さらにそのチップの何番目の画像か、向き
	bool flag;//trueにすると消滅(セーブ2)
	int kihatu;//一回きりのイベントかどうか 
	int talk_count;//これにセリフが何行あるか格納する。
	int item;//アイテムが入手できるかどうか
	char kaiwa[3][40];//セリフ
};
static struct chara1 chara_eve[32]={-1};//構造体を配列に

struct op1{//オープニング用
	int no;//opのno
	int face_no;//顔画像ナンバー
	int talk_count;//何行会話か
	char kaiwa[3][40];//会話格納配列
};
static struct op1 op_eve[30];
static struct op1 ed_eve[30];
int op_cnt = 0;//オープニングカウント

//chara_allと同じ数値
struct chara2{//キャラクター情報
	char name[10];//名前
	int face[8];//キャラクターの顔画像格納ハンドル
	int chip[12];//キャラクターのチップ格納ハンドル
};
static struct chara2 chara[32] = {-1};//構造体を配列に
//chara_allと同じ数値

struct ite{//アイテム情報
	int no;//アイテム番号
	int type;//アイテムの種類
	int point;//上昇値
	int icon;//アイコン画像格納
	char name[10];//名前
	int text_count;//テキストを何行使うか
	char text[3][30];//アイテムの説明
};
static struct ite item[30] = {-1};//初期化

//ステータス
struct sta{//ステータス情報
	int no;//ステータス番号
	int hp;//HP(セーブ2)
	int tp;//TP(セーブ2)
	int atk;//攻撃力(セーブ2)
	int def;//防御力(セーブ2)
	int spd;//素早さ(セーブ2)
	int pattern;//敵の行動パターン
	int skill[8];//特技番号格納
	char name[20];//名前
	char skin[40];//敵画像
};
static struct sta status[32] = {0};//初期化

struct bat{//戦闘メンバーのための構造体、ほぼステータスと同じ
	int enemy_no;//敵の名前を描画するため
	int hp;//HP(セーブ2)
	int tp;//TP(セーブ2)
	int atk;//攻撃力
	int def;//防御力
	int spd;//素早さ
	int pattern;//敵の行動パターン
	int skin;//敵画像
};
static struct bat battle[4] = {0};//戦闘時用

struct en{//戦闘用のグループ格納構造体
	int no;//グループno
	int enemy_count;//敵の数
	int enemy[3];//どの敵か
	int bgm;//戦闘時流すbgmの配列番号を格納
	char back[30];//背景
};
static struct en group[30] = {0};

struct ef{//特技格納構造体
	int no;//特技no
	int tp;//消費tp
	int type;//特技の種類(攻撃か回復か、など)
	int point;//ダメージや回復量
	int ef_count;//エフェクトが何枚構成なのか
	int effect[25];//エフェクト
	int se_no;//発同時流すseの番号を格納
	char name[30];//特技名
};
static struct ef skill[30] = {0};

struct cha_ski{//キャラクター(主人公)別スキル習得構造体
	int tokugi[8];//キャラクターの覚える特技、今回最大8とする
	int flag;//スキルをどこまで習得しているか最大7(0を初期で覚えているため)(セーブ2)
};
static struct cha_ski chara_skill[10] = {0};//初期化

int battle_menu;//バトルの現在画面変数
int battle_cursor;//バトルカーソル
int bgm[13];//bgm格納ハンドル
int se[30];//効果音格納ハンドル
int now_group = 0;//どのグループと戦闘させるつもりなのか
int now_bgm;//現在どのbgmなのか(セーブ)
int battle_back;//戦闘背景
int now_face = 0;//残りHPにより顔を変える
int now_color = 0;//残りHPによりテキストカラーを変えるため

int target;//どの敵を攻撃するか

int play_skill;//どのスキルを使うのか

int ef_move;//アニメーションのように見せるための変数
int del_ef;//敵に攻撃を当てた時に消えるための変数

int enemy_atack_effect[6];//敵の攻撃エフェクト用配列

int turn = 0;//敵ターン格納変数

bool def_on = FALSE;//防御しているかしていないか

int enemy_step = 0;//敵ターンのステップ
int pat[10][8] = {0};//パターン格納配列

int item_step = 0;//アイテムのステップ管理変数
int use_item;//使用するアイテム番号を格納

int en_count;//敵との遭遇(20以上になったら)(セーブ)

int bonus = 0;//ボーナスポイント(セーブ2)
int skill_pt = 0;//特技ポイント(セーブ2)

int bonus_dumy[6];//一時的にボーナスポイントをふるため

int s_equip[2];//主人公の現在装備(0が武器1が防具)(セーブ)

int event_b;//イベントバトルかの判定変数
int escape = 0;//逃げられる戦いかどうかの判定

void event_check(void);//プロトタイプ関数

コード:

//fileload.h

void fileload(int x){//ファイルロード関数
	int f,g,h;//ファイルから読み込む用
	if(x == 0){
		LoadDivGraph("mapchip/map640,480/t_cave03.png",5,1,5,32,32,map_chip[1]);
		LoadDivGraph("mapchip/map640,480/村.png",152,8,19,32,32,map_chip[0]);
		LoadDivGraph("chara_chip/主人公.png",12,3,4,32,32,chara[0].chip);
		LoadDivGraph("chara_face/主人公.png",8,4,2,96,96,chara[0].face);
		LoadDivGraph("chara_chip/兵士.png",12,3,4,32,32,chara[1].chip);
		LoadDivGraph("chara_chip/敵.png",12,3,4,32,32,chara[2].chip);
		LoadDivGraph("chara_chip/敵.png",12,3,4,32,32,chara[6].chip);
		LoadDivGraph("chara_chip/敵.png",12,3,4,32,32,chara[7].chip);
		LoadDivGraph("chara_chip/村人A.png",12,3,4,32,32,chara[4].chip);
		LoadDivGraph("chara_face/村人A.png",8,4,2,96,96,chara[4].face);
		LoadDivGraph("chara_chip/村人B.png",12,3,4,32,32,chara[5].chip);
		LoadDivGraph("chara_face/村人B.png",8,4,2,96,96,chara[5].face);
		LoadDivGraph("chara_chip/主人公.png",12,3,4,32,32,chara[8].chip);
		LoadDivGraph("chara_face/主人公.png",8,4,2,96,96,chara[8].face);
		LoadDivGraph("chara_chip/魔王.png",12,3,4,32,32,chara[9].chip);
		LoadDivGraph("chara_face/魔王.jpg",8,4,2,96,96,chara[9].face);
		LoadDivGraph("chara_chip/魔王.png",12,3,4,32,32,chara[10].chip);
		LoadDivGraph("chara_face/覚醒魔王.jpg",8,4,2,96,96,chara[10].face);
		window[0]=LoadGraph("背景/セリフ枠.png");
		window[1]=LoadGraph("背景/セリフ枠2.png");
		window[2]=LoadGraph("背景/OP.jpg");
		window[3]=LoadGraph("背景/メニュー.jpg");
		bgm[0]=LoadSoundMem("BGM/イベント/マップ.mp3");
		bgm[1]=LoadSoundMem("BGM/戦闘/序盤.mp3");
		bgm[2]=LoadSoundMem("BGM/イベント/BAD.mp3");
		bgm[3]=LoadSoundMem("BGM/イベント/op.mp3");
		bgm[4]=LoadSoundMem("BGM/イベント/死.mp3");
		bgm[5]=LoadSoundMem("BGM/イベント/メニュー.mp3");
		bgm[6]=LoadSoundMem("BGM/戦闘/中ボス.mp3");
		bgm[7]=LoadSoundMem("BGM/イベント/オープニング.mp3");
		bgm[8]=LoadSoundMem("BGM/戦闘/イベント戦闘.mp3");
		bgm[9]=LoadSoundMem("BGM/戦闘/中盤戦闘.mp3");
		bgm[10]=LoadSoundMem("BGM/戦闘/ラスボス1.mp3");
		bgm[11]=LoadSoundMem("BGM/戦闘/ラスボス2.mp3");
		se[0]=LoadSoundMem("BGM/効果音/メニュー.mp3");
		se[1]=LoadSoundMem("BGM/効果音/決定.mp3");
		se[2]=LoadSoundMem("BGM/効果音/斬る.mp3");
		se[3]=LoadSoundMem("BGM/効果音/風.mp3");
		se[4]=LoadSoundMem("BGM/効果音/殴る.mp3");
		se[5]=LoadSoundMem("BGM/効果音/逃走.mp3");
		se[6]=LoadSoundMem("BGM/効果音/シャイン.mp3");
		se[7]=LoadSoundMem("BGM/効果音/レベルアップ.mp3");
		se[8]=LoadSoundMem("BGM/効果音/コスモ.mp3");
		se[9]=LoadSoundMem("BGM/効果音/ダーク.mp3");
		se[10]=LoadSoundMem("BGM/効果音/葉.mp3");
		se[11]=LoadSoundMem("BGM/効果音/爆発音中.mp3");
		se[12]=LoadSoundMem("BGM/効果音/雨.mp3");
		LoadDivGraph("エフェクト/切る.png",9,9,1,240,240,skill[0].effect);
		LoadDivGraph("エフェクト/風.png",18,5,4,256,256,skill[1].effect);
		LoadDivGraph("エフェクト/風2.png",18,5,4,256,256,skill[2].effect);
		LoadDivGraph("エフェクト/ライトニング.png",25,5,5,256,256,skill[3].effect);
		LoadDivGraph("エフェクト/葉っぱ.png",15,5,3,200,260,skill[4].effect);
		LoadDivGraph("エフェクト/迫る手.png",10,5,2,240,240,skill[5].effect);
		LoadDivGraph("エフェクト/ブーメラン.png",10,1,10,640,240,skill[6].effect);
		LoadDivGraph("エフェクト/ライトバースト.png",10,1,10,640,480,skill[7].effect);
		LoadDivGraph("エフェクト/全体ファイア.png",5,1,5,640,480,skill[8].effect);
		LoadDivGraph("エフェクト/究極魔法.png",6,1,6,640,480,skill[9].effect);
		LoadDivGraph("エフェクト/宇宙魔法.png",20,1,20,640,480,skill[10].effect);
		LoadDivGraph("エフェクト/ダークハンド.png",10,1,10,640,240,skill[11].effect);
		LoadDivGraph("エフェクト/雨.png",12,1,12,640,240,skill[12].effect);
		LoadDivGraph("エフェクト/スコール.png",13,1,13,640,240,skill[13].effect);
		LoadDivGraph("エフェクト/ストーン.png",8,1,8,640,240,skill[14].effect);
		LoadDivGraph("エフェクト/ライト.png",5,1,5,640,240,skill[15].effect);
		LoadDivGraph("エフェクト/敵攻撃.png",6,1,6,640,480,enemy_atack_effect);
		//char_chip[0]に12枚の画像を32x32のサイズで格納
		//1マス32で考えているため、それようの画像サイズ

		color[0] = GetColor(0,0,0);//黒
		color[1] = GetColor(200,160,20);//黄色
		color[2] = GetColor(255,0,0);//赤色
	}
	//ファイルからの読み出し
	//マップの画像番号を読み込みます
	FILE *fp;
		if((fp = fopen("map.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			f=0;
			g=0;
			while(fscanf(fp,"%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",&map[f][g][0],&map[f][g][1],
				&map[f][g][2],&map[f][g][3],&map[f][g][4],&map[f][g][5],&map[f][g][6],&map[f][g][7],&map[f][g][8],
				&map[f][g][9],&map[f][g][10],&map[f][g][11],&map[f][g][12],&map[f][g][13],&map[f][g][14],&map[f][g][15],
				&map[f][g][16],&map[f][g][17],&map[f][g][18],&map[f][g][19]) == 20){
					g++;
					if(g == 15){
						f = f+1;
						g = 0;
					}
			}
			fclose(fp);
		}
		if((fp = fopen("event.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%d%d%d%d%d%d%d%d%d%d%d%s%s%s",&chara_eve[h].no,&chara_eve[h].chara_no,
				&chara_eve[h].pos_x,&chara_eve[h].pos_y,&chara_eve[h].map,&chara_eve[h].battle,&chara_eve[h].eve_flag,
				&chara_eve[h].bgm,&chara_eve[h].face_no,&chara_eve[h].chip_vector,&chara_eve[h].flag,&chara_eve[h].kihatu,
				&chara_eve[h].talk_count,&chara_eve[h].item,chara_eve[h].kaiwa[0],chara_eve[h].kaiwa[1],chara_eve[h].kaiwa[2]) == 17){
					h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("chara.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%s",chara[h].name) == 1){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("item.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%s%d%s%s%s",&item[h].no,&item[h].type,&item[h].point,item[h].name,&item[h].text_count,item[h].text[0],
				item[h].text[1],item[h].text[2]) == 8){
				switch(item[h].type){
					case 1:item[h].icon = LoadGraph("アイコン/剣.png");
						break;
					case 2:item[h].icon = LoadGraph("アイコン/服.png");
						break;
					case 3:item[h].icon = LoadGraph("アイコン/道具.png");
						break;
				}
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("status.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%d%d%d%d%s%s",&status[h].no,&status[h].hp,&status[h].tp,&status[h].atk,
				&status[h].def,&status[h].spd,&status[h].pattern,status[h].name,status[h].skin) == 9){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("group.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%d%d%d%s",&group[h].no,&group[h].enemy_count,&group[h].enemy[0],
				&group[h].enemy[1],&group[h].enemy[2],&group[h].bgm,group[h].back) == 7){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("skill.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%d%d%d%s",&skill[h].no,&skill[h].tp,&skill[h].type,&skill[h].point,
				&skill[h].ef_count,&skill[h].se_no,skill[h].name) == 7){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("chara_ski.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%d%d%d%d%d%d",&chara_skill[h].tokugi[0],&chara_skill[h].tokugi[1],&chara_skill[h].tokugi[2],
				&chara_skill[h].tokugi[3],&chara_skill[h].tokugi[4],&chara_skill[h].tokugi[5],&chara_skill[h].tokugi[6],&chara_skill[h].tokugi[7],
				&chara_skill[h].flag) == 9){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("pattern.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%d%d%d%d%d",&pat[h][0],&pat[h][1],&pat[h][2],&pat[h][3],
				&pat[h][4],&pat[h][5],&pat[h][6],&pat[h][7]) == 8){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("op_t.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%s%s%s",&op_eve[h].no,&op_eve[h].face_no,&op_eve[h].talk_count,op_eve[h].kaiwa[0],op_eve[h].kaiwa[1],op_eve[h].kaiwa[2] ) == 6){
				h = h + 1;
			}
			fclose(fp);
		}
		if((fp = fopen("ed_t.txt","r")) == NULL )
			printf("ファイルをオープンできません。\n");
		else{
			h=0;
			while(fscanf(fp,"%d%d%d%s%s%s",&ed_eve[h].no,&ed_eve[h].face_no,&ed_eve[h].talk_count,ed_eve[h].kaiwa[0],ed_eve[h].kaiwa[1],ed_eve[h].kaiwa[2] ) == 6){
				h = h + 1;
			}
			fclose(fp);
		}
}

コード:

//event.h
int s_vector_check(int);//プロトタイプ関数
void event_check(void){//イベントがあるかチェックする関数
	int vector = s_vector_check(s_vector);
	for(i = 0;i < chara_all;i++){
		if(vector == 0){
			if(chara_eve[i].pos_x == s_pos_x && chara_eve[i].pos_y == s_pos_y + 1 && 
				chara_eve[i].map == now_map && chara_eve[i].flag == FALSE){
					now_mode = 1;//イベントモードへ
					now_eve = i;//実行するイベントを格納
					break;
			}
		}
		else if(vector == 1){
			if(chara_eve[i].pos_x == s_pos_x - 1 && chara_eve[i].pos_y == s_pos_y && 
				chara_eve[i].map == now_map && chara_eve[i].flag == FALSE){
					now_mode = 1;//イベントモードへ
					now_eve = i;//実行するイベントを格納
					break;
			}
		}
		else if(vector == 2){
			if(chara_eve[i].pos_x == s_pos_x + 1 && chara_eve[i].pos_y == s_pos_y && 
				chara_eve[i].map == now_map && chara_eve[i].flag == FALSE){
					now_mode = 1;//イベントモードへ
					now_eve = i;//実行するイベントを格納
					break;
			}
		}
		else if(vector == 3){
			if(chara_eve[i].pos_x == s_pos_x && chara_eve[i].pos_y == s_pos_y - 1 && 
				chara_eve[i].map == now_map && chara_eve[i].flag == FALSE){
					now_mode = 1;//イベントモードへ
					now_eve = i;//実行するイベントを格納
					break;
			}
		}
	}
		
}
int s_vector_check(int vector){//主人公の調べた時の向きチェック
	if(vector >= 0 && vector <= 2)
		return(0);//下向き
	else if(vector <= 5)
		return(1);//左向き
	else if(vector <= 8)
		return(2);//右向き
	else if(vector <= 11)
		return(3);//上向き
	else
		return(4);//エラー
}
void event_mode(void){
	int vector = s_vector_check(s_vector);
	int bef_eve = 0;//直前のイベント格納
	switch(vector){
		case 0:chara_eve[now_eve].chip_vector = 10; 
			break;
		case 1:chara_eve[now_eve].chip_vector = 7; 
			break;
		case 2:chara_eve[now_eve].chip_vector = 4; 
			break;
		case 3:chara_eve[now_eve].chip_vector = 1; 
			break;
	}
	DrawGraph(0,310,window[1],TRUE);//会話ウィンドウを表示
	DrawGraph(50,355,chara[chara_eve[now_eve].chara_no].face[chara_eve[now_eve].face_no],TRUE);
	//フェイス表示
	DrawString(200,350,chara[chara_eve[now_eve].chara_no].name,color[0]);
	//名前表示
	for(i = 0;i < chara_eve[now_eve].talk_count;i++){
		DrawString(195,375 +(27 * i),chara_eve[now_eve].kaiwa[i],color[0]);
	}
	if(CheckHitKey(KEY_INPUT_RETURN) == 1){
		if(chara_eve[now_eve].kihatu == 1){
				chara_eve[now_eve].flag = TRUE;//TRUEになる
		}
		if(chara_eve[now_eve].item >= 0){//もしchara_eve[now_eve].itemが0以上なら(何もない時は-1を格納しています)
			bag[chara_eve[now_eve].item] += 1;//bagに指定アイテムnoのアイテムを追加
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		if(chara_eve[now_eve].eve_flag != -1){//イベントフラグが-1じゃないなら発動
			bef_eve = now_eve;
			now_eve = chara_eve[now_eve].eve_flag;
			chara_eve[now_eve].flag = FALSE;
			if(chara_eve[now_eve].pos_x == chara_eve[bef_eve].pos_x &&
				chara_eve[now_eve].pos_y == chara_eve[bef_eve].pos_y &&
				chara_eve[now_eve].map == chara_eve[bef_eve].map  && chara_eve[bef_eve].battle == -1){
					//フラグを立たせたイベントが同マップ同座標そして、バトルがないならなら連続発動
					chara_eve[now_eve].chip_vector = chara_eve[bef_eve].chip_vector; 
			}
			else{
				if(chara_eve[bef_eve].battle >= 0){//バトルがあるなら(一個前のイベントのためbef_eve)
					now_mode = 3;//バトルへ
					event_b = chara_eve[bef_eve].battle;//一個前のイベントのためbef_eve
					now_eve = -1;
				}
				else
					now_mode = 0;//マップへ
				now_eve = -1;
			}

		}
		else{
			if(chara_eve[now_eve].battle >= 0){//バトルがあるなら
				now_mode = 3;
				event_b = chara_eve[now_eve].battle;
				now_eve = -1;
			}
			else{
				now_mode = 0;//マップへ
				now_eve = -1;
			}
		}
	}
}

コード:


void draw_map(void){//テキストから読み取ったマップ画像番号によりマップを描画
	for(i = 0;i < 15;i++){//縦の値
		for(j = 0;j < 20;j++){
			DrawGraph(j * 32,i * 32,map_chip[0][map[now_map-1][i][j]],FALSE);//5個目の画像
		//配列の中身をi×32で描画
			block[i][j] = 0;
			if(map[now_map-1][i][j] == 109){//侵入不可ブロック
				block[i][j] = 1;
			}
		}
	}
	for(i = 0;i < chara_all;i++){//イベントキャラ描画
		if(chara_eve[i].map == now_map && chara_eve[i].flag == FALSE){
			DrawGraph(chara_eve[i].pos_x * 32,chara_eve[i].pos_y * 32,chara[chara_eve[i].chara_no].chip[chara_eve[i].chip_vector],TRUE);
			block[chara_eve[i].pos_y][chara_eve[i].pos_x] = 1;
		}
	}
}
void map_check(void){//マップの移動座標等の判定
	if(now_map == 1){//現在マップが1そしてyも14なら
		if(s_pos_y == 14){//下端なら
			if(s_vector >= 0 && s_vector <=2){
				now_map = 2;//マップ2へ移動
				s_pos_y = 0;
			}
		}
		else if(s_pos_y == 0){//上端なら
			if(s_vector >= 9 && s_vector <= 11 && chara_eve[18].flag == FALSE){//フラグ18がたっているなら。
				now_map = 3;//マップ3へ移動
				s_pos_y = 14;
			}
		}
	}
	else if(now_map == 2){//現在マップが2そしてyも14なら
		if(s_pos_y == 0){//上端なら
			if(s_vector >= 9 && s_vector <= 11){
				now_map = 1;//マップ1へ移動
				s_pos_y = 14;
			}
		}
	}
	else if(now_map == 3){//現在マップが3そしてyも0なら
		if(s_pos_y == 14){//下端なら
			if(s_vector >= 0 && s_vector <= 2){
				now_map = 1;//マップ1へ移動
				s_pos_y = 0;
			}
		}
	}
}

コード:

//move.h
void map_encount(void){
	int ransu;//乱数取得のための数字
	ransu = GetRand(3) + 1;//0~3の数字に+1することで1~4の乱数に
	en_count += ransu;//乱数をエンカウントに足す
	if(en_count >= 30){
		now_mode = 3;//バトルモードへ
		en_count = 0;//エンカウント初期化
	}
}
void vector_up(void){//どの向きの画像を表示したらいいかチェックする関数(up)
	if(s_vector < 9 || s_vector > 11){//11~9でない場合
		s_vector = 9;
		vector_check = 1;
	}
	else{
		s_vector = s_vector + vector_check;
		if(s_vector == 11){
			vector_check = -1;
		}
		else if(s_vector == 9){
			vector_check = 1;
		}
	}
}
void vector_down(void){//どの向きの画像を表示したらいいかチェックする関数(down)
	if(s_vector < 0 || s_vector > 2){//0~2でない場合
		s_vector = 0;
		vector_check = 1;
	}
	else{
		s_vector = s_vector + vector_check;
		if(s_vector == 2){
			vector_check = -1;
		}
		else if(s_vector == 0){
			vector_check = 1;
		}
	}
}
void vector_right(void){//どの向きの画像を表示したらいいかチェックする関数(right)
	if(s_vector < 6 || s_vector > 8){//11~9でない場合
		s_vector = 6;
		vector_check = 1;
	}
	else{
		s_vector = s_vector + vector_check;
		if(s_vector == 8){
			vector_check = -1;
		}
		else if(s_vector == 6){
			vector_check = 1;
		}
	}
}
void vector_left(void){//どの向きの画像を表示したらいいかチェックする関数(left)
	if(s_vector < 3 || s_vector > 5){//11~9でない場合
		s_vector = 3;
		vector_check = 1;
	}
	else{
		s_vector = s_vector + vector_check;
		if(s_vector == 5){
			vector_check = -1;
		}
		else if(s_vector == 3){
			vector_check = 1;
		}
	}
}
void map_move(void){//マップ移動
	if(key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		event_check();//イベントが発生するかチェックする関数
	}
	else if(key[KEY_INPUT_M] == 1){
		now_mode = 2;//メニューモードへ
		menu = 0;//メニュー判断初期化
		while(CheckHitKey(KEY_INPUT_M) ==1);//連打抑制
	}
	else{
			if(key[KEY_INPUT_UP] == 1){//上移動
				if(s_pos_y > 0 && block[s_pos_y - 1][s_pos_x] != 1){
					s_pos_y -= 1;
					vector_up();//向きチェック関数
					map_encount();//エンカウントチェック
				}
				else{
					vector_up();//向きチェック関数
					map_check();//マップチェンジ関数
				}
			}
			if(key[KEY_INPUT_DOWN] == 1){//下移動
				if(s_pos_y < 14 && block[s_pos_y + 1][s_pos_x] != 1){
					s_pos_y += 1;
					vector_down();//向きチェック関数
					map_encount();//エンカウントチェック
				}
				else{
					vector_down();//向きチェック関数
					map_check();//マップチェンジ関数
				}
				
			}
			if(key[KEY_INPUT_RIGHT] == 1){//右移動
				if(s_pos_x < 19 && block[s_pos_y][s_pos_x + 1] != 1){
					s_pos_x += 1;
					vector_right();//向きチェック関数
					map_encount();//エンカウントチェック
				}
				else{
					vector_right();//向きチェック関数
					map_check();//マップチェンジ関数
				}
		}
		if(key[KEY_INPUT_LEFT] == 1){//左移動
			if(s_pos_x > 0 && block[s_pos_y][s_pos_x - 1] != 1){
				s_pos_x -= 1;
				vector_left();//向きチェック関数
				map_encount();//エンカウントチェック
			}
			else{
				vector_left();//向きチェック関数
				map_check();//マップチェンジ関数
				}
		}
			WaitTimer(50);
	}
}

Re: メニュー画面でのバグ

#2

by Math » 5年前

ライブラリではじめるC言語ゲーム開発 という本でありませんか。
RPG sample.zip は本に記載のパスワードがないと解凍できませんでしたね。

>下記にサンプルコードを掲載します。
>(文字制限があるので、関係ある部分だけ載せます)
複数ページで 最低限検証出来るようにして 提示いただかないと検討がつかないと思いますよ。

ここの https://dixq.net/g/ ににたような章がありませんか?

メニュー画面でのバグ

#1

by just_started_PG » 5年前

[1] メニュー画面でのバグを解消したいです。

「ライブラリではじめるC言語開発」という本の中のサンプルコードで
サンプルの通りコピペをすると、バグが発生します。何が原因になっているか知りたいです。

バグの内容はメニュー画面のカーソルが描画されないというものです。
item step変数が悪さをしているっぽいのを把握したのですが、
変数をいじってみると、メニューカーソルは表示されるようになりましたが、
そのあとの決定キーを押した以降の動作が上手く機能しません。

バグの原因が何なのか、ご教授いただければ助かります。
下記にサンプルコードを掲載します。
(文字制限があるので、関係ある部分だけ載せます)

[2] 環境  
 [2.1] OS : Windows10
 [2.2] コンパイラ名 : VisualStudio2017
 [2.3]ライブラリ:DXライブラリ

コード:

//main.cpp

#include "DxLib.h"//DXライブラリ
#include "main.h"//変数、関数用ヘッダファイル
#include "map.h"//マップ用ヘッダファイル
#include "move.h"//移動用関数ヘッダファイル
#include "event.h"//イベント用ヘッダファイル
#include "menu.h"//メニュー用ヘッダファイル
#include "battle.h"//バトル用ヘッダファイル
#include "fileload.h"//ファイル読み込み関数ヘッダファイル
void open(void);//プロトタイプ関数
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){//メイン関数

		ChangeWindowMode(TRUE);
		SetDrawScreen(DX_SCREEN_BACK);//画面の裏に描写するように設定
		if(DxLib_Init() == -1){ //DXライブラリ初期化
			return -1; //エラーが起きたらすぐ終了
		}
		SetFontSize(24);//文字サイズ初期値
		ChangeFont( "HG明朝E" ) ;
		fileload(0);//ファイルロード関数を呼び出し

		//画像ファイル配列へ格納
		while(ScreenFlip() == 0 && ProcessMessage() == 0 &&
			GetHitKeyStateAll(key) == 0){//メインループの始まり
			ClearDrawScreen();//画面をクリア
			
			if(now_mode == 0){//マップ移動可能モード
				draw_map();//マップ描画
				DrawGraph(s_pos_x * 32,s_pos_y * 32,chara[0].chip[s_vector],TRUE);//主人公描画
				if(CheckSoundMem(bgm[0]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[0],DX_PLAYTYPE_LOOP);
					now_bgm = 0;
				}
				map_move();
			}
			else if(now_mode == 1){//イベントモード
				draw_map();//マップ描画
				DrawGraph(s_pos_x * 32,s_pos_y * 32,chara[0].chip[s_vector],TRUE);//主人公描画
				event_mode();
			}
			else if(now_mode == 2){//メニューモード
				if(CheckSoundMem(bgm[5]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[5],DX_PLAYTYPE_LOOP);
					now_bgm = 5;
				}
				menu_mode();
			}
			else if(now_mode == 3){//バトル準備
				battle_change();//バトルの準備をする関数
				turn = 0;//ターン初期化
				enemy_step = 0;//初期化
				now_mode = 4;//バトルへ
				battle_cursor = 0;//バトルカーソル初期化
			}
			else if(now_mode == 4){//バトル
				battle_mode();
			}
			else if(now_mode == 5){//ゲームオーバー
				LoadGraphScreen(0,0,"背景/ゲームオーバー.png",FALSE);
				if(CheckSoundMem(bgm[2]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[2],DX_PLAYTYPE_LOOP);
					now_bgm = 2;
				}
				DrawString(410,425,"PUSH ENY KEY",color[2]);
				WaitKey();
				WaitTimer(1000);
				now_mode = 6;
			}
			else if(now_mode == 6){//トップ画面
				LoadGraphScreen(0,0,"背景/top.jpg",FALSE);
				DrawGraph(340,340 + (menu_cursor * 40),chara[0].chip[1],TRUE);//アイコン描画
				DrawString(400,340,"ゲームを始める",color[0]);//戻る表示
				DrawString(400,380,"続きから",color[0]);//戻る表示
				DrawString(400,420,"ゲームを終了する",color[0]);//ゲーム終了表示
				if(CheckSoundMem(bgm[3]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[3],DX_PLAYTYPE_LOOP);
					now_bgm = 3;
				}
				if(key[KEY_INPUT_UP] == 1){
						if(menu_cursor == 0){//現在最小値なら最大値へ
							menu_cursor = 2;
						}
						else{
							menu_cursor -= 1;
						}
						while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
						PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
				}
				else if(key[KEY_INPUT_DOWN] == 1){
					if(menu_cursor == 2){//現在最大値なら最小値へ
						menu_cursor = 0;
					}
					else{
						menu_cursor += 1;
					}
					while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
					PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//カーソル移動音
				}
				else if(key[KEY_INPUT_RETURN] == 1){
						if(menu_cursor == 0){
							fileload(1);//ステータスなど初期化
							now_mode = 8;//オープニングへ
							battle[0].hp = status[0].hp;//体力初期化
							battle[0].tp = status[0].tp;//tp初期化
							now_map = 1;//初期化
							en_count = 0;
							menu_cursor = 0;
							battle_cursor = 0;
							s_pos_x = 0;
							s_pos_y = 0;
							s_vector = 1;
							bag[0] = 1;//武器
							bag[4] = 1;//防具
							bag[8] = 1;//アイテム所持
							bonus = 10;//ボーナスポイント初期化
							s_equip[0] = 0;//木の剣装備
							s_equip[1] = 4;//普通の服装備
						}
						else if(menu_cursor == 1){//続きから
							now_mode = 7;//ロード画面へ
							menu_cursor = 0;//初期化
						}
						else if(menu_cursor == 2){//ゲーム終了
							DxLib_End();    // DXライブラリ終了処理
							return 0;
						}
						escape = 0;//初期化
						event_b = -1;//初期化
						while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
						PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
						menu_cursor = 0;//初期化
				}
			}
			else if(now_mode == 7){//ロード画面ーモード
				if(CheckSoundMem(bgm[5]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[5],DX_PLAYTYPE_LOOP);
					now_bgm = 5;
				}
				fileload(1);//ステータスなど初期化
				load_menu();//データロード画面へ
			}
			else if(now_mode == 8){//OP
				if(CheckSoundMem(bgm[7]) == 0){//bgm再生
					StopSoundMem(bgm[now_bgm]);
					PlaySoundMem(bgm[7],DX_PLAYTYPE_LOOP);
					now_bgm = 7;
				}
				open();//オープニング画面へ
			}
		}
}
void open(void){
	DrawGraph(0,310,window[1],TRUE);//会話ウィンドウを表示
	DrawGraph(50,355,chara[0].face[op_eve[op_cnt].face_no],TRUE);
	//フェイス表示
	DrawString(200,350,chara[0].name,color[0]);
	//名前表示
	for(i = 0;i < op_eve[op_cnt].talk_count;i++){
		DrawString(195,375 +(27 * i),op_eve[op_cnt].kaiwa[i],color[0]);
	}
		DrawString(410,300,"PUSH ENTER KEY",color[2]);
		op_cnt += 1;
		if(op_cnt >= 30){
			op_cnt = 0;//初期化
			now_mode = 0;//マップへ
		}
		while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
		while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
}

コード:

//main.h
int map[10][15][20];//マップ画像番号格納用
int block[15][20];//侵入不可ゾーン格納配列

int now_map = 1;//現在表示マップ格納変数(セーブ)

int menu_cursor = 0;//メニューカーソル
int menu = 0;//現在メニュー判断

int item_all = 30;//アイテムの総数
int bag[15];//配列の数は総アイテムの数とします(セーブ2)

int window[4];//セリフなどの枠を格納
int color[3];//文字色格納配列

int now_mode = 6;//現在のモード変数(topが6になるため初期値は6)
int now_eve = 0;//実行するイベントを格納

int map_chip[2][152];//画像格納用配列(マップチップ用)
//マップ用の移動キャラ画像が12枚あるため12枚今は
//1キャラしかいないので左の配列は1とする。

int s_pos_x = 0;//主人公の現在地座標x(よこ)(セーブ)
int s_pos_y = 0;//主人公の現在地座標y(たて)(セーブ)

int s_vector = 1;//主人公の現在向き(セーブ)
//(今回、初期値はこちらを向いてる1としましょう)

int vector_check = 1;//0,1,2,1,0...にするための変数


int i,j;//for分用変数

char key[256];//GetHitKeyStateAllのための配列
int chara_all = 32;//ゲーム内のキャラクター数
struct chara1{//キャラクタイベントの構造体
	int no;//イベントno
	int chara_no;//どのキャラか
	int pos_x;//キャラの出現座標x
	int pos_y;//キャラの出現座標y
	int map;//キャラ出現マップ
	int battle;//戦闘があるかどうか
	int eve_flag;//他のイベのフラグを立たせるか
	int bgm;//bgmを変えるかどうか
	int face_no;//さらに何番目の画像か
	int chip_vector;//さらにそのチップの何番目の画像か、向き
	bool flag;//trueにすると消滅(セーブ2)
	int kihatu;//一回きりのイベントかどうか 
	int talk_count;//これにセリフが何行あるか格納する。
	int item;//アイテムが入手できるかどうか
	char kaiwa[3][40];//セリフ
};
static struct chara1 chara_eve[32]={-1};//構造体を配列に

struct op1{//オープニング用
	int no;//opのno
	int face_no;//顔画像ナンバー
	int talk_count;//何行会話か
	char kaiwa[3][40];//会話格納配列
};
static struct op1 op_eve[30];
static struct op1 ed_eve[30];
int op_cnt = 0;//オープニングカウント

//chara_allと同じ数値
struct chara2{//キャラクター情報
	char name[10];//名前
	int face[8];//キャラクターの顔画像格納ハンドル
	int chip[12];//キャラクターのチップ格納ハンドル
};
static struct chara2 chara[32] = {-1};//構造体を配列に
//chara_allと同じ数値

struct ite{//アイテム情報
	int no;//アイテム番号
	int type;//アイテムの種類
	int point;//上昇値
	int icon;//アイコン画像格納
	char name[10];//名前
	int text_count;//テキストを何行使うか
	char text[3][30];//アイテムの説明
};
static struct ite item[30] = {-1};//初期化

//ステータス
struct sta{//ステータス情報
	int no;//ステータス番号
	int hp;//HP(セーブ2)
	int tp;//TP(セーブ2)
	int atk;//攻撃力(セーブ2)
	int def;//防御力(セーブ2)
	int spd;//素早さ(セーブ2)
	int pattern;//敵の行動パターン
	int skill[8];//特技番号格納
	char name[20];//名前
	char skin[40];//敵画像
};
static struct sta status[32] = {0};//初期化

struct bat{//戦闘メンバーのための構造体、ほぼステータスと同じ
	int enemy_no;//敵の名前を描画するため
	int hp;//HP(セーブ2)
	int tp;//TP(セーブ2)
	int atk;//攻撃力
	int def;//防御力
	int spd;//素早さ
	int pattern;//敵の行動パターン
	int skin;//敵画像
};
static struct bat battle[4] = {0};//戦闘時用

struct en{//戦闘用のグループ格納構造体
	int no;//グループno
	int enemy_count;//敵の数
	int enemy[3];//どの敵か
	int bgm;//戦闘時流すbgmの配列番号を格納
	char back[30];//背景
};
static struct en group[30] = {0};

struct ef{//特技格納構造体
	int no;//特技no
	int tp;//消費tp
	int type;//特技の種類(攻撃か回復か、など)
	int point;//ダメージや回復量
	int ef_count;//エフェクトが何枚構成なのか
	int effect[25];//エフェクト
	int se_no;//発同時流すseの番号を格納
	char name[30];//特技名
};
static struct ef skill[30] = {0};

struct cha_ski{//キャラクター(主人公)別スキル習得構造体
	int tokugi[8];//キャラクターの覚える特技、今回最大8とする
	int flag;//スキルをどこまで習得しているか最大7(0を初期で覚えているため)(セーブ2)
};
static struct cha_ski chara_skill[10] = {0};//初期化

int battle_menu;//バトルの現在画面変数
int battle_cursor;//バトルカーソル
int bgm[13];//bgm格納ハンドル
int se[30];//効果音格納ハンドル
int now_group = 0;//どのグループと戦闘させるつもりなのか
int now_bgm;//現在どのbgmなのか(セーブ)
int battle_back;//戦闘背景
int now_face = 0;//残りHPにより顔を変える
int now_color = 0;//残りHPによりテキストカラーを変えるため

int target;//どの敵を攻撃するか

int play_skill;//どのスキルを使うのか

int ef_move;//アニメーションのように見せるための変数
int del_ef;//敵に攻撃を当てた時に消えるための変数

int enemy_atack_effect[6];//敵の攻撃エフェクト用配列

int turn = 0;//敵ターン格納変数

bool def_on = FALSE;//防御しているかしていないか

int enemy_step = 0;//敵ターンのステップ
int pat[10][8] = {0};//パターン格納配列

int item_step = 0;//アイテムのステップ管理変数
int use_item;//使用するアイテム番号を格納

int en_count;//敵との遭遇(20以上になったら)(セーブ)

int bonus = 0;//ボーナスポイント(セーブ2)
int skill_pt = 0;//特技ポイント(セーブ2)

int bonus_dumy[6];//一時的にボーナスポイントをふるため

int s_equip[2];//主人公の現在装備(0が武器1が防具)(セーブ)

int event_b;//イベントバトルかの判定変数
int escape = 0;//逃げられる戦いかどうかの判定

void event_check(void);//プロトタイプ関数

コード:

//menu.h
void menu_main(void);//メインメニュープロト
void menu_item(void);//アイテムプロト
void menu_sta(void);//ステータスプロト
void menu_skill(void);//特技プロト
void menu_equip(void);//装備プロト
void menu_save(void);//セーブプロト
void menu_title(void);//タイトルプロト
void menu_sta_draw(void);//描画関数プロト
void save_file(int a);//セーブ仕様関数プロト
void load_menu(void);//ロードメニュープロト
void load_file(int a);//ロード仕様関数プロト

void menu_mode(void){
	DrawGraph(0,0,window[3],FALSE);//メニュー背景
	if(menu == 0){//メイン
		menu_main();
	}
	else if(menu == 1){//アイテム
		menu_item();
	}
	else if(menu == 2){//ステータス
		menu_sta();
	}
	else if(menu == 3){//特技
		menu_skill();
	}
	else if(menu == 4){//装備
		menu_equip();
	}
	else if(menu == 5){//セーブ
		menu_save();
	}
	else if(menu == 6){//タイトル
		menu_title();
	}
}
void menu_main(void){//メインメニュー
	SetFontSize(30);//フォントサイズ変更
		DrawString(480,20,"アイテム",color[0]);
		DrawString(480,80,"ステータス",color[0]);
		DrawString(480,140,"特技",color[0]);
		DrawString(480,200,"装備",color[0]);
		DrawString(480,260,"セーブ",color[0]);
		DrawString(480,320,"タイトル",color[0]);
		SetFontSize(20);
		DrawString(410,440,"メニューを閉じる【M】",color[0]);
		SetFontSize(30);

		DrawGraph(440,20 + (60 * menu_cursor),chara[0].chip[1],TRUE);
		//カーソル描画

		if(key[KEY_INPUT_UP] == 1){
			if(menu_cursor == 0){//現在最小値なら最大値へ
				menu_cursor = 5;
			}
			else{
				menu_cursor -= 1;
			}
			while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_DOWN] == 1){
			if(menu_cursor == 5){//現在最大値なら最小値へ
				menu_cursor = 0;
			}
			else{
				menu_cursor += 1;
			}
			while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_M] == 1 || key[KEY_INPUT_B] == 1){
			now_mode = 0;//マップモードへ
			menu_cursor = 0;
			SetFontSize(24);//文字サイズを戻す
			while(CheckHitKey(KEY_INPUT_M) ==1);//連打抑制
			while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		}
		else if(key[KEY_INPUT_RETURN] == 1){
			switch(menu_cursor){
				case 0:menu = 1;//アイテム画面へ
					break;
				case 1:menu = 2;//ステータス画面へ
					break;
				case 2:menu = 3;//特技画面へ
					break;
				case 3:menu = 4;//装備画面へ
					break;
				case 4:menu = 5;//セーブ画面へ
					break;
				case 5:menu = 6;//タイトル画面へ
					break;
			}
			while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
		}

}
[glow=red]void menu_item(void)[/glow]{//アイテム
char count[5];//個数描画のため
char heal_point[5];//回復量描画のため
int heal;//回復量計算のための変数
int box[5];//アイテム欄の上から何が格納されているか
	int item_count = 0;
	for(i = 0;i < item_all;i++){
		if(bag[i] > 0 && item[i].type == 3){//アイテム[i]がバッグに0より入っていて道具なら
			DrawGraph(40,22 + (40 * item_count),item[i].icon,TRUE);//アイコン描画
			DrawString(70,20 + (40 * item_count),item[i].name,color[0]);//名前表示
			sprintf(count,"%d",bag[i]);
			DrawString(200,20 + (40 * item_count),"×",color[0]);
			DrawString(240,20 + (40 * item_count),count,color[0]);

			box[item_count] = i;//boxにiを格納
			item_count += 1;
		}
	}
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(500,280,"戻る",color[0]);//戻る表示
	if(item_step == 0){
		if(menu_cursor == item_count){//最大の場合は戻るへ
			DrawGraph(460,280,chara[0].chip[1],TRUE);
			DrawString(30,350,"メニュー画面へ戻ります",color[0]);//戻るボタン時
		}
		else{
			DrawGraph(10,20 + (40 * menu_cursor),chara[0].chip[1],TRUE);
			for(i = 0;i < item[box[menu_cursor]].text_count;i++){
				DrawString(30,350 + (35 * i),item[box[menu_cursor]].text[i],color[0]);
				//テキスト描画
			}
		}
		if(key[KEY_INPUT_UP] == 1){
				if(menu_cursor == 0){//現在最小値なら最大値へ
					menu_cursor = item_count;
				}
				else{
					menu_cursor -= 1;
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_DOWN] == 1){
			if(menu_cursor == item_count){//現在最大値なら最小値へ
				menu_cursor = 0;
			}
			else{
				menu_cursor += 1;
			}
			while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_RETURN] == 1){
			if(menu_cursor == item_count){
				menu = 0;//メインメニューへ
			}
			else{
				use_item = box[menu_cursor];
				menu_cursor = 0;//初期化
				item_step = 1;//次のステップへ
			}
			while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
		}
		else if(key[KEY_INPUT_B] == 1){
			while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
			menu = 0;//メインメニューへ
		}
	}
	else if(item_step == 1){
		DrawString(30,350 ,item[use_item].name,color[0]);
		DrawString(150,350 ,"を使用しますか?",color[0]);
		DrawString(80,385 ,"はい",color[0]);
		DrawString(80,420 ,"いいえ",color[0]);
		DrawGraph(42,380 + (35 * menu_cursor),chara[0].chip[1],TRUE);
		if(key[KEY_INPUT_UP] == 1){
				if(menu_cursor == 0){//現在最小値なら最大値へ
					menu_cursor = 1;
				}
				else{
					menu_cursor -= 1;
				}
				while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_DOWN] == 1){
			if(menu_cursor == 1){//現在最大値なら最小値へ
				menu_cursor = 0;
			}
			else{
				menu_cursor += 1;
			}
			while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
			PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
		}
		else if(key[KEY_INPUT_RETURN] == 1){
			if(menu_cursor == 0){
				item_step = 2;//メインメニューへ
			}
			else{
				use_item = box[menu_cursor];
				menu_cursor = 0;//初期化
				item_step = 0;//次のステップへ
			}
			while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
		}
		else if(key[KEY_INPUT_B] == 1){
			while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
			PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
			menu_cursor = 0;//初期化
			item_step = 0;//戻る
		}


	}
	else if(item_step == 2){
		DrawString(30,350,"主人公のHPが",color[0]);
			if(battle[0].hp + item[use_item].point > status[0].hp){//もし回復量が主人公ステータスを上回ったなら本来のMAXHPまで回復
				heal = status[0].hp - battle[0].hp;
				sprintf(heal_point,"%d",heal);
				battle[0].hp = status[0].hp;
				DrawString(260,350,heal_point,color[0]);
				DrawString(340,350,"回復しました!",color[0]);
			}
			else{
				sprintf(heal_point,"%d",item[use_item].point);
				DrawString(260,350,heal_point,color[0]);
				DrawString(340,350,"回復しました!",color[0]);
				battle[0].hp = battle[0].hp + item[use_item].point;
			}
			DrawString(380,425,"PUSH ENTER KEY",color[0]);
			while(CheckHitKey(KEY_INPUT_RETURN) == 0);//エンターキー待ち
			while(CheckHitKey(KEY_INPUT_RETURN) == 1);//連打抑制
			bag[use_item] -= 1;//使用したアイテムを-1する
			item_step = 0;//初期化
			use_item = 0;//初期化
	}
}
void menu_sta(void){//ステータス
	menu_sta_draw();//sta描画関数
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 7;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor == 7){//現在最大値なら最小値へ
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_LEFT] == 1 && 
		bonus - (bonus_dumy[0] + bonus_dumy[1] + bonus_dumy[2] + bonus_dumy[3] + bonus_dumy[4] + bonus_dumy[5]) > 0 && menu_cursor < 6){
			if(menu_cursor != 5 || bonus_dumy[5] / (2 + (chara_skill[0].flag * chara_skill[0].flag) - skill_pt )< 1 && chara_skill[0].flag < 7){
			//割振り合計が所持BPを超えないように
				bonus_dumy[menu_cursor] += 1;
				while(CheckHitKey(KEY_INPUT_LEFT) ==1);//連打抑制
				PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
			}
	}
	else if(key[KEY_INPUT_RIGHT] == 1 && bonus_dumy[menu_cursor] > 0 && menu_cursor < 6){//割振りが1以上あるなら
		bonus_dumy[menu_cursor] -= 1;
		while(CheckHitKey(KEY_INPUT_RIGHT) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 7 && key[KEY_INPUT_RETURN] == 1){
		for(i = 0;i < 6;i++){
			bonus_dumy[i] = 0;//初期化
			//戻った時に割振りが保存されているとまた入った時に振ったままになってしまうため
		}
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 1;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1 && menu_cursor == 6){
		if(bonus_dumy[0] > 0 || bonus_dumy[1] > 0 || bonus_dumy[2] > 0 ||
			bonus_dumy[3] > 0 || bonus_dumy[4] > 0 || bonus_dumy[5] > 0 ){ 
				DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
				DrawString(20,350,"ステータスが上昇しました!",color[0]);
				status[0].hp += bonus_dumy[0] * 10;//hpz
				battle[0].hp += bonus_dumy[0] * 10;//hpz(現在HPにも上昇値分のみプラス)
				status[0].tp += bonus_dumy[1] * 5;//tp
				battle[0].tp = status[0].tp;//tp(現在TPはステータスまで回復)
				status[0].atk += bonus_dumy[2];//atk
				status[0].def += bonus_dumy[3];//def
				status[0].spd += bonus_dumy[4];//spd
				skill_pt += bonus_dumy[5];//skillpt
				if(skill_pt >= 2 + (chara_skill[0].flag * chara_skill[0].flag)){//スキルレベルアップポイントまで振ったら
					skill_pt = 0;//初期化
					chara_skill[0].flag += 1;
					DrawString(20,380,"主人公は特技",color[0]);
					DrawString(250,380,skill[chara_skill[0].tokugi[chara_skill[0].flag]].name,color[0]);
					DrawString(390,380,"を習得した!",color[0]);
				}
				bonus = bonus - (bonus_dumy[0] + bonus_dumy[1] + bonus_dumy[2] + bonus_dumy[3] + bonus_dumy[4] + bonus_dumy[5]);
				//使用したボーナスを引く
				WaitTimer(1000);
				for(i = 0;i < 6;i++){
					bonus_dumy[i] = 0;//初期化
					//戻った時に割振りが保存されているとまた入った時に振ったままになってしまうため
				}
				while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
				PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
				menu_cursor = 0;//初期化(カーソルがステータスの上へ)
		}
	}
}
void menu_skill(void){//特技
	char atk_pt[5];//特技攻撃力
	char tp_pt[5];//消費tp
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(570,270,"戻る",color[0]);//戻る描画
	for(i = 0;i <= chara_skill[0].flag;i++){//スキルレベルが0からなのでレベル以下なら描画
		DrawString(60,10 +(40 * i),skill[chara_skill[0].tokugi[i]].name,color[0]);
	}
	if(menu_cursor <= chara_skill[0].flag){//スキルレベル以下ならカーソルを特技へ、違うなら戻るへカーソル
		DrawGraph(20,10 + (menu_cursor * 40),chara[0].chip[1],TRUE);
	}
	else{
		DrawGraph(530,270,chara[0].chip[1],TRUE);
	}
	if(menu_cursor <= chara_skill[0].flag){//特技にカーソルが乗っているなら情報を描画
		sprintf(atk_pt,"%d",skill[chara_skill[0].tokugi[menu_cursor]].point);
		sprintf(tp_pt,"%d",skill[chara_skill[0].tokugi[menu_cursor]].tp);
		DrawString(40,360,"特技攻撃力:",color[0]);
		DrawString(40,400,"消費TP:",color[0]);
		DrawString(260,360,atk_pt,color[0]);
		DrawString(260,400,tp_pt,color[0]);
	}
	else//違うなら戻るへ
		DrawString(40,360,"メニュートップへ戻る",color[0]);
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = chara_skill[0].flag + 1;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  chara_skill[0].flag + 1){//現在最大値なら最小値へ
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == chara_skill[0].flag + 1 && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 2;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
}
void menu_equip(void){//装備
int box[2][5];//アイテム欄の上から何が格納されているか
int item_count[2] = {0};
char e_point[5];//武器防具のパラメーター
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(570,270,"戻る",color[0]);//戻る描画
	for(i = 0;i < item_all;i++){
		if(bag[i] > 0 && item[i].type == 1 ){//アイテム[i]がバッグに0より入っていて武器なら
			DrawGraph(40,22 + (40 * item_count[0]),item[i].icon,TRUE);//アイコン描画
			DrawString(70,20 + (40 * item_count[0]),item[i].name,color[0]);//名前表示
			box[0][item_count[0]] = i;//boxにiを格納
			if(s_equip[0] == i){
				DrawString(240,20 + (40 * item_count[0]),"E",color[0]);//名前表示
			}
			item_count[0] += 1;
		}
		else if(bag[i] > 0 && item[i].type == 2 ){//アイテム[i]がバッグに0より入っていて防具なら
			DrawGraph(340,22 + (40 * item_count[1]),item[i].icon,TRUE);//アイコン描画
			DrawString(370,20 + (40 * item_count[1]),item[i].name,color[0]);//名前表示
			box[1][item_count[1]] = i;//boxにiを格納
			if(s_equip[1] == i){
				DrawString(540,20 + (40 * item_count[1]),"E",color[0]);//名前表示
			}
			item_count[1] += 1;
		}
	}

	if(menu_cursor < item_count[0]){//武器のカーソル
		sprintf(e_point,"%d",item[box[0][menu_cursor]].point);//武器の攻撃力変換
		DrawGraph(10,20 + (menu_cursor * 40),chara[0].chip[1],TRUE);
		DrawString(40,340,"武器攻撃力:",color[0]);
		DrawString(40,370,"説明:",color[0]);
		DrawString(240,340,e_point,color[0]);
		for(i = 0;i < item[box[0][menu_cursor]].text_count;i++){//テキストカウント分描画
			DrawString(160,370 +(i * 30),item[box[0][menu_cursor]].text[i],color[0]);//テキスト描画
		}
	}
	else if(menu_cursor < item_count[0] + item_count[1]){//防具のカーソル
		sprintf(e_point,"%d",item[box[1][menu_cursor - item_count[0]]].point);//防具の防御力変換
		DrawGraph(310,20 + ((menu_cursor - item_count[0]) * 40),chara[0].chip[1],TRUE);
		DrawString(40,340,"防具防御力:",color[0]);
		DrawString(40,370,"説明:",color[0]);
		DrawString(240,340,e_point,color[0]);
		for(i = 0;i < item[box[1][menu_cursor - item_count[0]]].text_count;i++){//テキストカウント分描画
			DrawString(160,370 +(i * 30),item[box[1][menu_cursor - item_count[0]]].text[i],color[0]);//テキスト描画
		}
	}
	else{//戻るの時
		DrawGraph(540,270,chara[0].chip[1],TRUE);
		DrawString(40,340,"トップメニューに戻る",color[0]);
	}
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = item_count[0] + item_count[1];//武器・防具の合計
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  item_count[0] + item_count[1]){//武器防具の合計が最大値なら最小値へ
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor ==  item_count[0] + item_count[1] && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 3;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		if(menu_cursor < item_count[0]){
			//選んでいるのが武器の場合
			s_equip[0] = box[0][menu_cursor];
		}
		else if(menu_cursor < item_count[0] + item_count[1]){
			//選んでいるのが防具の場合
			s_equip[1] = box[1][menu_cursor - item_count[0]];
		}
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
	}
}
void menu_save(void){//セーブ
	static int a[3][5];//ステータスを画面で描画するために入れておく配列
	char b[5][20];//ステータス描画用
	FILE *fp;
	fp = fopen("save_0.txt","r");//セーブロード画面用要素テキストファイルオープン
	for(i = 0;i < 3;i++){
		fscanf(fp,"%d %d %d %d %d",&a[i][0],&a[i][1],&a[i][2],&a[i][3],&a[i][4]);//セーブデータのステータス読み込み
	}
	fclose(fp);
	LoadGraphScreen(0,0,"背景/ロード.jpg",FALSE);
	for(i = 0;i < 3;i++){//セーブ枠3つ描画
		DrawGraph(0,-20 +(160 * i),window[1],TRUE);
		if(a[i][0] <= 0){//セーブデータステータスHPが格納されていない(つまり0)なら
			DrawString(200,60 +(160 * i),"データがありません。",color[2]);
		}
		else{
			DrawGraph(50,30 + (160 * i),chara[0].face[0],TRUE);//主人公の顔画像描画
			sprintf(b[0],"%d",a[i][0]);//HP変換
			sprintf(b[1],"%d",a[i][1]);//TP変換
			sprintf(b[2],"%d",a[i][2]);//ATK変換
			sprintf(b[3],"%d",a[i][3]);//DEF変換
			sprintf(b[4],"%d",a[i][4]);//SPD変換
			DrawString(200,20 +(160 * i),"最大HP:",color[2]);//HP描画
			DrawString(310,20 +(160 * i),b[0],color[2]);//HP描画
			DrawString(400,20 +(160 * i),"最大TP:",color[2]);//TP描画
			DrawString(510,20 +(160 * i),b[1],color[2]);//TP描画
			DrawString(200,60 +(160 * i),"攻撃力:",color[2]);//ATK描画
			DrawString(310,60 +(160 * i),b[2],color[2]);//ATK描画
			DrawString(400,60 +(160 * i),"防御力:",color[2]);//DEF描画
			DrawString(510,60 +(160 * i),b[3],color[2]);//DEF描画
			DrawString(200,100 +(160 * i),"素早さ:",color[2]);//SPD描画
			DrawString(310,100 +(160 * i),b[4],color[2]);//SPD描画
		}
	}
	SetFontSize(16);
	DrawString(440,460,"メニューに戻る",color[2]);
	SetFontSize(30);
	if(menu_cursor == 3){
		DrawGraph(410,460,chara[0].chip[1],TRUE);
	}
	else{
		DrawGraph(0,60 +(160 * menu_cursor),chara[0].chip[1],TRUE);
	}
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 3;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  3){
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 3 && key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 4;//初期化(カーソルがセーブの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1){ //決定
		save_file(menu_cursor);
		fp = fopen("save_0.txt","w");
		a[menu_cursor][0] = status[0].hp;//主人公のMAXHP
		a[menu_cursor][1] = status[0].tp;//主人公のMAXTP
		a[menu_cursor][2] = status[0].atk;//主人公のATK
		a[menu_cursor][3] = status[0].def;//主人公のDEF
		a[menu_cursor][4] = status[0].spd;//主人公のSPD
		for(i = 0;i < 3;i++){
			fprintf(fp,"%d %d %d %d %d \n",a[i][0],a[i][1],a[i][2],a[i][3],a[i][4]);
		}
		fclose(fp);
		LoadGraphScreen(0,0,"背景/セーブロード.jpg",FALSE);
		DrawString(160,240,"セーブしました",color[2]);
		WaitTimer(1000);
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
	}
}
void menu_title(void){//タイトル
	LoadGraphScreen(0,0,"背景/ロード.jpg",FALSE);
	DrawGraph(0,0,window[0],TRUE);//テキストウィンドウ
	DrawString(40,350,"本当にタイトルに戻りますか?",color[0]);
	DrawString(490,390,"はい",color[0]);
	DrawString(490,430,"いいえ",color[0]);
	DrawGraph(450,390 + (menu_cursor * 40),chara[0].chip[1],TRUE);
	if(key[KEY_INPUT_UP] == 1){
		if(menu_cursor == 0){//現在最小値なら最大値へ
			menu_cursor = 1;
		}
		else{
			menu_cursor -= 1;
		}
		while(CheckHitKey(KEY_INPUT_UP) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_DOWN] == 1){
		if(menu_cursor ==  1){
			menu_cursor = 0;
		}
		else{
			menu_cursor += 1;
		}
		while(CheckHitKey(KEY_INPUT_DOWN) ==1);//連打抑制
		PlaySoundMem(se[0],DX_PLAYTYPE_BACK);//移動音
	}
	else if(key[KEY_INPUT_B] == 1 || menu_cursor == 1 && key[KEY_INPUT_RETURN] == 1){//いいえの場合
		while(CheckHitKey(KEY_INPUT_B) ==1);//連打抑制
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		menu_cursor = 5;//初期化(カーソルがステータスの上へ)
		menu = 0;//メインメニューへ
	}
	else if(key[KEY_INPUT_RETURN] == 1){
		while(CheckHitKey(KEY_INPUT_RETURN) ==1);//連打抑制
		PlaySoundMem(se[1],DX_PLAYTYPE_BACK);//決定音
		now_mode = 6;//トップ画面へ
		SetFontSize(24);//文字サイズを戻す
	}
}
[

ページトップ