前回の反省を踏まえて作り直してきました。
#define _CRT_SECURE_NO_WARNINGS 1
#include "DxLib.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "main.h"
static int Key[ 256 ];
static music_t music[ MUSIC_NUM ];
int gpUpdateKey()
{
char tmpKey[ 256 ]; // 現在のキーの入力状態を格納する
GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
for( int i=0; i<256; i++ ){
if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
Key[i]++; // 加算
} else { // 押されていなければ
Key[i] = 0; // 0にする
}
}
return 0;
}
int ProcessLoop() // 毎ループ必要な事
{
if( ProcessMessage() != 0 ) return 1;
if( ClearDrawScreen() != 0 ) return 1;
if( gpUpdateKey() != 0 ) return 1;
return 0;
}
void Music_Draw::Init()
{
m_Font[0] = CreateFontToHandle( "MSPゴシック", 16, 16, DX_FONTTYPE_ANTIALIASING_EDGE_8X8, -1, 1, 0, -1 ); // フォント1
m_Font[1] = CreateFontToHandle( "MSPゴシック", 14, 10, DX_FONTTYPE_ANTIALIASING_EDGE_8X8, -1, 1, 0, -1 ); // フォント2
m_SelectNum = 0;
m_SelectedMusicNo = 0;
}
void Music_Draw::Load()
{
m_img_back[0] = LoadGraph( "dat/img/title03a.png" ); // 背景画像を読み込む
m_img_back[1] = LoadGraph( "dat/img/title03b.png" ); // 背景画像を読み込む
}
void Music_Draw::Load_Script()
{
char FileName[] = "dat/bgm/musiccmt.txt"; // ファイルの名前
int i,num=0,n=0,line=0; // n曲目の判断やfor文関係
int input[128]; // 一文字読み込むのに必要
char inputc[128]; // 上に同じ
FILE* fp = fopen( FileName , "r" ); // ファイルを開く
if( fp == NULL ){ // ファイルが無い時の処理
MSG( "No Script File !" );
exit(1);
}
for(i=0 ; i<4 ; i++ ) // 最初の4行はコメントなので読み飛ばす
while( fgetc( fp ) != '\n' );
while( 1 ){
for(i=0 ; i<128 ; i++ ){ // 横64文字まで読み込んで
input[i] = inputc[i] = fgetc( fp );
if( input[i] == '#' ){ // コメント記号ならば
while( fgetc( fp ) != '\n' ); // その行の終わりまでループして
i = -1; // カウンタを戻して
continue;
}
if( input[i] == '\n' ){ // 改行記号なら(独自フォーマットのファイルだから改行で区切る)
inputc[i] = '\0'; // そこまでを文字列にして
break;
}
if( input[i] == EOF ){ // EOFなら(ここは、charで判断はしないほうが良い)
goto EXFILE; // ファイルクローズタグにジャンプ( でいいのかな? )
}
}
switch( num ){ // 読み込んだファイルから構造体にコピーする
case 0: strcpy( music[n].path , inputc ); break; // 音楽再生の為のパス
case 1: strcpy( music[n].name[0], inputc ); break; // 名前1 : No.~
case 2: strcpy( music[n].name[1], inputc ); break; // 名前2 : ♪~
// -----------------以下、コメント読み込み----------------- //
case 3: strcpy( music[n].comme[ line ] , inputc );break;
case 4: strcpy( music[n].comme[ line + 1 ], inputc );break;
case 5: strcpy( music[n].comme[ line + 2 ], inputc );break;
case 6: strcpy( music[n].comme[ line + 3 ], inputc );break;
case 7: strcpy( music[n].comme[ line + 4 ], inputc );break;
case 8: strcpy( music[n].comme[ line + 5 ], inputc );break;
case 9: strcpy( music[n].comme[ line + 6 ], inputc );break;
// -------------------------------------------------------- //
}
num++; // num加算
if( num == 10 ){ // numの値が9(1曲分のファイル読み込みが終わったら)なら
num = 0; // numを加算
n++; // nも加算
}
}
EXFILE: // ファイルクローズ
fclose( fp );
}
void Music_Draw::Load_LoopFile()
{
char FileName[] = "dat/bgm/loop.txt"; // ファイル名( path )
int input[32]; // 一文字読み込み
char inputc[32]; // 一文字読み込み
int i,n=0;
FILE* fp = fopen( FileName, "r" ); // ファイルをリード形式で展開
if( fp == NULL ){ // ファイルが無い時の処理
MSG( "No Loop File !" );
exit(1);
}
for(i=0 ; i<4 ; i++ ) // 最初の4行はコメントなので飛ばす
while( fgetc( fp ) != '\n' );
while( 1 ){
for(i=0 ; i<32 ; i++ ){
input[i] = inputc[i] = fgetc( fp );
if( input[i] == '#' ){ // コメント記号なら
while( fgetc( fp ) != '\n' ); // 改行までループして
i = -1; // カウンタを戻して
continue;
}
if( input[i] == ';' ){ // 終了記号なら
inputc[i] = '\0'; // そこまでを文字列として
break;
}
if( input[i] == EOF ){ // ファイルの終わりなら
goto EXFILE;
}
}
music[n].loop = atoi( inputc ); // 読みとったループ位置を構造体のloopに代入
n++; // 曲加算
}
EXFILE:
fclose( fp );
}
void Music_Draw::DrawBack()
{
DrawGraph( 0, 0, m_img_back[0], TRUE); // 画像を描写
DrawGraph( 512, 0, m_img_back[1], TRUE); // 同上
}
void Music_Draw::DrawComment()
{
int i;
for(i=0 ; i<7 ; i++ ){// コメントの行数
DrawFormatStringToHandle( 80, 340+16*i, GetColor(240,210,210), m_Font[1], "%s", music[ m_SelectedMusicNo ].comme[ i ] );
}
}
void Music_Draw::DrawName()
{
int i,j;
for(i=0 , j=0 ; i<MUSIC_NUM ; j++ , i++ ){ // No.~の部分
if( i == m_SelectNum ) // もし選択中なら
DrawFormatStringToHandle( 60, 130+18*j, GetColor(240,210,210), m_Font[0], "%s", music[i].name[0] );
else // そうで無ければ
DrawFormatStringToHandle( 65, 130+18*j, GetColor(130,105,105), m_Font[0], "%s", music[i].name[0] );
}
for(i=0 ; i<MUSIC_NUM ; i++ ){ // 曲名を表示
DrawFormatStringToHandle( 60, 320, GetColor(240,210,210), m_Font[1], "%s", music[ m_SelectedMusicNo ].name[1] );
}
}
void Music_Draw::Fin()
{
InitGraph();
InitFontToHandle();
}
void Music_SE::Load()
{
m_se_select = LoadSoundMem( "dat/se/se_select00.wav" ); // seを読み込む
}
void Music_SE::Fin()
{
InitSoundMem(); // 音声ハンドルを消す
}
void Music_SE::PlaySE()
{
if( CheckSoundMem( m_se_select ) == 0 ){
PlaySoundMem( m_se_select, DX_PLAYTYPE_BACK );
}
}
void Music_BGM::Load_BGM()
{
int i;
for(i=0 ; i<MUSIC_NUM ; i++ ){
m_BGM[i] = LoadBGM( music[i].path ); // BGMを流し込む
if( m_BGM[i] == NULL ){
MSG( "Waveファイルがないぞぅ" ) ;
exit(1);
}
}
SetLoopTimePosSoundMem( music[ 0 ].loop, m_BGM[ 0 ] ); // 0番目の曲( =タイトル曲 )曲のループ位置
PlaySoundMem( m_BGM[ 0 ], DX_PLAYTYPE_BACK ); // 0番目の曲( =タイトル曲 )を再生
}
void Music_BGM::PlayBGMFile( int SelectNum )
{
int i;
for(i=0 ; i<MUSIC_NUM+1 ; i++ ){
if( CheckSoundMem( m_BGM[i] ) == 1 ){ // 再生中なら
StopSoundMem( m_BGM[i] ); // サウンドファイルを停止する
} else {
SetLoopTimePosSoundMem( music[ SelectNum ].loop, m_BGM[ SelectNum ] ); // 選択された曲のループ位置
PlaySoundMem( m_BGM[ SelectNum ], DX_PLAYTYPE_BACK ); // 音楽を再生
}
}
}
void Music_Main::Init()
{
m_Draw.Init(); // フォントの初期化
}
void Music_Main::Load()
{
//---------画像読み込み------------//
m_Draw.Load();
m_Draw.Load_LoopFile();
m_Draw.Load_Script();
//----------SE読み込み----------//
m_SE.Load();
//----------BGM読み込み--------//
m_Bgm.Load_BGM();
}
void Music_Main::Draw()
{
m_Draw.DrawBack() ; // 背景描写
m_Draw.DrawComment() ; // コメント描写
m_Draw.DrawName() ; // 名前描写
}
void Music_Main::Update()
{
if( Key[ KEY_INPUT_DOWN ] == 1 || ( Key[ KEY_INPUT_DOWN ] % 5 == 0 && Key[ KEY_INPUT_DOWN ] > 30 ) ){ // ↓キーが押されたら
m_Draw.m_SelectNum = ( m_Draw.m_SelectNum + 1 ) % MUSIC_NUM;
}
if( Key[ KEY_INPUT_UP ] == 1 || ( Key[ KEY_INPUT_UP ] % 5== 0 && Key[ KEY_INPUT_UP ]> 30 ) ){ // ↑キーが押されたら
m_Draw.m_SelectNum = ( m_Draw.m_SelectNum + ( MUSIC_NUM - 1 ) ) % MUSIC_NUM;
}
if( Key[ KEY_INPUT_DOWN ] == 1 || Key[ KEY_INPUT_UP ] == 1 || ( Key[ KEY_INPUT_DOWN ] % 5 == 0 && Key[ KEY_INPUT_DOWN ] > 30 )||
( Key[ KEY_INPUT_UP ] % 5 == 0 && Key[ KEY_INPUT_UP ] > 30 ) ){ // 上下どちらかのキーが押されたら
m_SE.PlaySE(); // 選択音を再生
}
if( Key[ KEY_INPUT_Z ] == 1 || Key[ KEY_INPUT_RETURN ] == 1 ){ // Z Key と Enter Key が押されたら
m_Draw.m_SelectedMusicNo = m_Draw.m_SelectNum; // 選択された項目を更新する
m_Bgm.PlayBGMFile( m_Draw.m_SelectedMusicNo ); // 選択されたBGMを再生
}
}
void Music_Main::Fin()
{
m_Draw.Fin() ; // 全ての画像とフォントハンドルを削除
m_SE.Fin() ; // メモリに読み込んだ音声ハンドルを削除
}
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int)
{
ChangeWindowMode( TRUE ), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );
Music_Main Music; // インスタンス化
Music.Init();
Music.Load();
while( !ProcessLoop() ){
Music.Update();
Music.Draw();
ScreenFlip();
}
Music.Fin();
DxLib_End();
return 0;
}
#pragma once
#define MUSIC_NUM 6
#define MSG(message) {MessageBox( NULL, _T( message ), _T( "Message" ), MB_OK );} // エラーメッセージ
#include "DxLib.h"
typedef struct{ // 曲の構造体
int loop ; // 曲のループ位置
char path[ 256 ] ; // 曲のコメント(パス)
char name[2][ 256 ] ; // [0] = (名前1),[1] = (名前2)
char comme[7][ 256 ] ; // (コメント)
} music_t;
class Music_Draw // 描写クラス
{
private:
int m_Font[2] ; // フォントを設定する
int m_img_back[2] ; // 背景画像を読み込む
public:
int m_SelectNum ; // 現在選択中 この変数はclass Music_BGMでも使う
int m_SelectedMusicNo ; // コメントを表示する曲の番号を保持
void Init() ; // フォントとかの初期化
void Load() ; // 画像とかの読み込み
void Load_Script() ; // スクリプトファイルを読み込む
void Load_LoopFile() ; // ループファイルを読み込む
void DrawComment() ; // コメント描写関数
void DrawName() ; // 曲名[0]と[1]描写関数
void DrawBack() ; // 背景描写
void Fin() ; // 終了処理
};
class Music_SE // SEクラス
{
private:
int m_se_select ; // seを読み込む
public:
void Load() ; // seの読み込み
void Fin() ; // 終了処理。たぶん,InitSoundMem()呼び出すからBGMも一緒に削除されると思われ
void PlaySE() ; // seを再生する
};
class Music_BGM // BGMクラス
{
private:
int m_BGM[ MUSIC_NUM ]; // BGMをメモリに読み込む為の変数
public:
void Load_BGM(); // BGMをメモリに読み込む為の関数
void PlayBGMFile( int SelectNum ); // 選択中( エンターキー or Zキーが押された時 )のBGMを再生
};
class Music_Main // 総括クラス
{
private:
Music_Draw m_Draw ; // インスタンス化( ここでインスタンス化していいのか? )
Music_SE m_SE ; // 同上
Music_BGM m_Bgm ; // 同上
public:
void Init();
void Load();
void Update();
void Draw();
void Fin();
};
#追記 URLの貼り忘れていました