GoogleAdsence

DXライブラリとC#での音楽ゲームの作り方その2 BMSデータの記録方法

2020年2月24日

前回BMSの仕様についてお話ししました。今回はその続きになります。

BMSデータの記録方法

BMSデータの1つ分のデータを扱う情報をまとめて以下の様に定義します。

public struct TagBarInfo
{
    public bool Time;
    public int Data;
};

Timeとは先頭を0とした場合のカウント値、つまり譜面上での位置となります 。
そして、1小節あたり9600になります。

1小説あたり9600の理由

これは2分音符や4分音符、8分音符、16分音符といった一般的な音符の他に、
3分音符や12分音符(3連符)、20分音符(5連符)などの少し特殊な音符でも割り切れるためです。

例として以下のような譜面なら、たった2個分の構造体で定義できます。

TagBarInfo bar[2];
bar[0].Time = 2400;   // 1小節が9600だとすると2拍は2400となる
bar[0].Data = 0x01;  // 鳴らすデータ
bar[1].Time = 7200;   // 4拍目なので2400*3となる
bar[1].Data = 0x01;  // 鳴らすデータ

この方法では1小節あたり9600の分解能で表せるため、理論上9600分音符まで作ることが出来ます。
ただそこまで分解する作る必要はないと思いますので、この仕様で十分対応できます。

ファイルロード

C#でテキストファイルのロードをするには、 StreamReaderクラスを使います。

1行ずつ文字列を読み込む場合

using System;
using System.IO;
using System.Text;
 
namespace Sample
{
    class Sample
    {
        static void Main()
        {
        using (StreamReader sr = new StreamReader(
            file_name, Encoding.GetEncoding("Shift_JIS")))
        {
            string line = string.Empty;
                // 最後の行までループする
            while ((line = sr.ReadLine()) != null)
            {
                 // lineに一行分の文字列が入っているのでここで処理する
            }
            }
        }
    }
}

1度にすべての文字列を読み込む場合

using System;
using System.IO;
using System.Text;
 
namespace Sample
{
    class Sample
    {
        static void Main()
        {
       using (StreamReader sr = new StreamReader(
            file_name, Encoding.GetEncoding("Shift_JIS")))
        {
                // テキストファイルからすべての文字列を読み込む
            string line = sr.ReadToEnd();

            }
        }
    }
}

using文を使うとcloseで閉じる必要がないので、忘れそうな人はこの書き方をするのがおすすめです。
次回以降、ヘッダーとメインデータのロードについて説明します。