「ライブラリではじめる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);//文字サイズを戻す
}
}