GoogleAdsence

DXライブラリとC#での音楽ゲームの作り方その10 選択画面の作り方

2020年2月26日

音ゲーの内部の説明はすべて終わったので、最後に簡単な曲の選択画面を作ります。

選択画面

初期化

  1. GetCurrentDirectoryでカレントディレクトリを取得する
  2. Directory.GetDirectoriesでカレントディレクトリ+\Res\Bmsフォルダの中にあるすべてのフォルダを列挙する
  3. FolderNamesに列挙したフォルダ名を追加
  4. FileNamesの中身をすべて消去する
  5. Directory.EnumerateFilesでFolderNamesのVertical番目のフォルダ名を指定し、その中のファイルをPatternsの中に入っている拡張子を含むファイル(.bms.bme)のみ取り出す
  6. 5で取得したフルパスのファイル名をGetFileNameでファイル名のみ取り出してFileNamesに追加

計算

上を押した場合

  1. Horizontal(水平)を0にし、Vertical(垂直)を-1する、この時にVertical < 0ならVerticalを一番下の数字を代入する
  2. FileNamesの中身をすべて消去する
  3. Directory.EnumerateFilesでFolderNamesのVertical番目のフォルダ名を指定し、その中のファイルをPatternsの中に入っている拡張子を含むファイル(.bms.bme)のみ取り出す
  4. 5で取得したフルパスのファイル名をGetFileNameでファイル名のみ取り出してFileNamesに追加

下を押した場合

  1. Horizontal(水平)を0にし、Vertical(垂直)を+1する、この時にVertical < 0ならVerticalを一番下の数字を代入する。さらに一番下で下を選択したら一番上にカーソルを合わせる(Verticalを0にする)
  2. FileNamesの中身をすべて消去する
  3. Directory.EnumerateFilesでFolderNamesのVertical番目のフォルダ名を指定し、その中のファイルをPatternsの中に入っている拡張子を含むファイル(.bms.bme)のみ取り出す
  4. 5で取得したフルパスのファイル名をGetFileNameでファイル名のみ取り出してFileNamesに追加

左右を押した場合

左を押した場合は、Horizontalが0より多い場合には、-1して左に移動して、右を押した場合には、ファイルの数(FileNames.Count() – 1)より小さい時には、Horizontalを+1して右にを移動する。

スペースキーを押した場合

  1. ステージクラスの引数にフルパスのフォルダ名+ファイル名を渡してStageを追加
  2. 自クラス(CTitle)のLifeを0にしてSceneリストから消去する
MG.SceneBuf.Add(new CStage(FolderNames[Vertical]+"\\"+FileNames[Horizontal]));
Life = 0;

描画

FolderNamesに入っているすべてのフォルダの文字列×3の数だけ描画フォルダ名をGetFileNameでフルパスからフォルダ名のみを取り出してDrawStringで描画して、この時選択されてるフォルダ名は青(MG.Color[4])にする。さらにFileNamesに入ってるファイル名をすべて列挙して描画して、 この時選択されてるフォルダ名は青(MG.Color[4])にする。

public class CTitle : CScene
{
    int State = 0;
    int Horizontal = 0;
    int Vertical = 0;
    int gOffsetY = 0;

    List<string> FolderNames = new List<string>();
    List<string> FileNames = new List<string>();
    const int POS_INTERVAL = 30;    // メニュー項目の間隔
    const int FIRST_POS = 220;	// カーソルの初期位置
    string[] Patterns = { ".bms", ".bme" };
    public CTitle()
    {
        string cur_dir = Directory.GetCurrentDirectory();

        string[] folders = Directory.GetDirectories(cur_dir + "\\Res\\Bms\\", "*.*", SearchOption.AllDirectories);
        foreach (string file in folders)
        {
            FolderNames.Add(file);
        }

        FileNames.Clear();
        var files = Directory.EnumerateFiles(FolderNames[Vertical] +"\\", "*.*", SearchOption.AllDirectories).Where(file => Patterns.Any(pattern => .ToLower().EndsWith(pattern)));
        foreach (string file in files)
        {
            string fn = Path.GetFileName(file);
            FileNames.Add(fn);
        }
    }
    public override void Move()
    {
        switch (State)
        {
            case 0:
                // メニュー項目の選択
                if (GetPadKey("Up") == 1)
                {
                    Horizontal = 0;
                    Vertical--;
                    gOffsetY += POS_INTERVAL;
                    // 一番上でさらに上を選択したら一番下にカーソルを合わせる
                    if (Vertical < 0)
                    {
                        Vertical = FolderNames.Count - 1;
                        gOffsetY = -POS_INTERVAL * (FolderNames.Count - 1);
                    }
                    FileNames.Clear();
                    var files = Directory.EnumerateFiles(FolderNames[Vertical] + "\\", "*.*", SearchOption.AllDirectories).Where(file => Patterns.Anttern => file.ToLower().EndsWith(pattern)));
                    foreach (string file in files)
                    {
                        string fn = Path.GetFileName(file);
                        FileNames.Add(fn);
                    }
                }
                if (GetPadKey("Down") == 1)
                {
                    Horizontal = 0;
                    Vertical++;
                    gOffsetY -= POS_INTERVAL;
                    // 一番下でさらに下を選択したら一番上にカーソルを合わせる
                    if (Vertical > FolderNames.Count - 1)
                    {
                        Vertical = 0;
                        gOffsetY = 0;
                    }
                    FileNames.Clear();
                    var files = Directory.EnumerateFiles(FolderNames[Vertical] + "\\", "*.*", SearchOption.AllDirectories).Where(file => Patterns.Anttern => file.ToLower().EndsWith(pattern)));
                    foreach (string file in files)
                    {
                        string fn = Path.GetFileName(file);
                        FileNames.Add(fn);
                    }
                }            
                
                if (GetPadKey("Left") == 1)
                {
                    if (Horizontal > 0)
                        Horizontal--;
                }
                if (GetPadKey("Right") == 1)
                {
                    if (Horizontal < FileNames.Count() - 1)
                        Horizontal++;
                }
                if(GetPadKey("Start") == 1)
                {
                    MG.SceneBuf.Add(new CStage(FolderNames[Vertical]+"\\"+FileNames[Horizontal]));
                    Life = 0;
                }
                break;
        }
    }
    public override void Draw()
    {
        switch (State)
        {
            case 0:
                // フォルダの文字列の描画
                for (int j = -1; j < 2; j++)
                {
                    for (int i = 0; i < FolderNames.Count; i++)
                    {
                        string fn = Path.GetFileName(FolderNames[i]);
                        DX.DrawString(20,
                            i * POS_INTERVAL + FIRST_POS + gOffsetY + (FolderNames.Count * POS_INTERVAL * j),
                            fn, Vertical == i ? MG.Color[4] : MG.Color[0]);
                    }
                }
                // ファイル内の文字列の描画
                for (int i = 0; i < FileNames.Count; i++)
                {
                    DX.DrawString(300, FIRST_POS + i * 25, FileNames[i], Horizontal == i ? MG.Color[4] : MG.Color[0]);
                }
                break;
        }
    }
}

実行結果