0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BVEのオリジナルの補助表示を作る

Last updated at Posted at 2024-12-09

 先日の第2回大糸線研究会総会にて、音声をオフにしてビューワーモードでプレイしている時にEB装置のブザーが鳴っていても気付けないというお話があり、BveEX経由で補助表示として表示する方法を取ることにしました。

おまじないの作成

 おーとま様の都市型ワンマンプラグインの左上に表示されているのがBveEXで追加した補助表示になります。そのソースを参考に、おまじないを作ってみます。

using BveTypes.ClassWrappers;

namespace AtsPlugin
{
    [Plugin(PluginType.VehiclePlugin)]
    internal class AtsMain : AssemblyPluginBase
    {
        // オリジナル補助表示
        private readonly AssistantText AssistantAtsText;

        // コンストラクタ
        public AtsMain(PluginBuilder services) : base(services)
        {
            AssistantAtsText = new AssistantText(new Mackoy.Bvets.AssistantSettings()
            {
                Name = "",
                AutoLocation = true,
                Anchor = AnchorStyles.Top | AnchorStyles.Left,
                Location = Point.Empty,
                Visible = true,
                Scale = 18
            });
            AssistantAtsText.Text = "補助表示だよ";
            AssistantAtsText.Color = System.Drawing.Color.White;
            AssistantAtsText.BackgroundColor = System.Drawing.Color.Red;
            // BVEの補助表示リストに追加
            BveHacker.MainForm.Assistants.Items.Add(AssistantAtsText);
        }

        public override void Dispose()
        {
            if (!(AssistantAtsText is null))
            {
                // お片付け
                BveHacker.MainForm.Assistants.Items.Remove(AssistantAtsText);
            }
        }
    }
}

これで、左上に赤い背景に白い文字で「補助表示だよ」と表示がされます。

設定

AssistantAtsText = new AssistantText(new Mackoy.Bvets.AssistantSettings()
{
    Name = "",
    AutoLocation = true,
    Anchor = AnchorStyles.Top | AnchorStyles.Left,
    Location = Point.Empty,
    Visible = true,
    Scale = 18
});

NameとAutoLocationはBVE標準の補助表示用の設定と思われます。(設定したところで何も起きませんでした)
Anchorは、補助表示のマージンの基準位置(AnchorStyles.Top | AnchorStyles.Left なら画面の左上が基準)、Locationは基準位置と補助表示のマージン。補助表示をマウスでドラッグすると、AnchorとLocationの値も変化します。
Visibleは補助表示の表示状態。
Scaleは補助表示のフォントサイズ。BVE標準の補助設定のScaleは、BVEの設定の補助表示タブの「大きさ」の値。

AssistantText変数にAssistantSettingsを持っていて、たとえば

AssistantAtsText.AssistantSettings.Visible = false;

とすると、補助表示が消えます。

Tickなどで変数の状態に合わせて表示を変えることができます。

public override void Tick(TimeSpan elapsed)
{
    if (!(AssistantAtsText is null))
    {
        if (EB == 0)
        {
            // EB装置は何も起きていない
            AssistantAtsText.AssistantSettings.Visible = false;
        }
        else if(EB == 1)
        {
            // EB装置ブザー鳴動
            AssistantEBText.Text = "EB装置が鳴動しています。リセットしてください。";
            AssistantEBText.Color = System.Drawing.Color.White;
            AssistantEBText.BackgroundColor = System.Drawing.Color.FromArgb(128, 0, 0, 0);
            AssistantEBText.AssistantSettings.Visible = true;
        }
        else
        {
            // EB装置ブザー動作
            AssistantEBText.Text = "EB装置が作動しました。ブレーキハンドルを非常位置に入れてください。";
            AssistantEBText.Color = System.Drawing.Color.White;
            AssistantEBText.BackgroundColor = System.Drawing.Color.Red;
            AssistantEBText.AssistantSettings.Visible = true;
        }
    }
}

実際に実装したものがこんな感じです。

設定値の保存

BVE本体の補助表示の設定は、ドキュメントフォルダのBveTs\Settings\Preferences.xmlに保存されています。
Preferences.xmlに手動で追記すればいいかと思いましたが、実際試すとダメでした。
というわけで、オリジナルの補助表示の設定を保存するには、自前で設定ファイルを作る必要があります。

設定値を格納するクラス

/// <summary>
/// 補助表示設定クラス
/// </summary>
public class ConfigAssistants
{
    /// <summary>
    /// 補助表示設定リスト
    /// </summary>
    public List<Assistant> Settings { get; set; }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public ConfigAssistants()
    {
        this.Settings = new List<Assistant>();
    }

    /// <summary>
    /// 補助表示設定スキーマ
    /// </summary>
    public class Assistant
    {
        /// <summary>
        /// 項目名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// フォントサイズ
        /// </summary>
        public int Size { get; set; }

        /// <summary>
        /// 座標基準
        /// </summary>
        public int Anchor { get; set; }

        /// <summary>
        /// 座標基準からのX座標
        /// </summary>
        public int X { get; set; }

        /// <summary>
        /// 座標基準からのY座標
        /// </summary>
        public int Y { get; set; }
    }
}

設定の読み書きを処理するクラス

/// <summary>
/// 設定処理クラス
/// </summary>
public class Config
{
    /// <summary>
    /// 補助表示設定
    /// </summary>
    public ConfigAssistants AssistantSettings { get; set; }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public Config()
    {
        this.AssistantSettings = new ConfigAssistants();
    }

    /// <summary>
    /// 補助表示設定の読み込み
    /// </summary>
    /// <returns></returns>
    public bool LoadAssistant()
    {
        try
        {
            string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData) +      "\\hamatetsu\\AssistantSettings.json"; // C:\Users\(  )\AppData\Local\hamatetsu\AssistantSettings.json
            if (System.IO.File.Exists(path) == true)
            {
                string jsonText = File.ReadAllText(path);
                AssistantSettings = JsonSerializer.Deserialize<ConfigAssistants>(jsonText);
                if (AssistantSettings == null) AssistantSettings= new ConfigAssistants();
                return true;
            }
            else
            {
                AssistantSettings = new ConfigAssistants();
                return false;
            }
        }
        catch (Exception ex)
        {
            AssistantSettings = new ConfigAssistants();
            MessageBox.Show(path + "\n" + ex.Message, "補助表示設定読込(LoadAssistant)");
            return false;
        }
    }

    /// <summary>
    /// 補助表示設定の保存
    /// </summary>
    /// <returns></returns>
    public bool SaveAssistant()
    {
        try
        {
            string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData) + "\\hamatetsu\\";
            if (System.IO.Directory.Exists(path) == false)
            {
                System.IO.Directory.CreateDirectory(path);
            }

            var options = new JsonSerializerOptions
            {
                Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
                WriteIndented = true
            };
            string jsonString = JsonSerializer.Serialize(AssistantSettings, options);
            File.WriteAllText(path, jsonString);
        }
        catch (Exception ex)
        {
            MessageBox.Show(path + "\n" + ex.Message, "補助表示設定保存(SaveAssistant)");
            return false;
        }
    }

    /// <summary>
    /// 補助表示設定リストから指定名称の設定を取得(見つからなかった場合は新規追加)
    /// </summary>
    /// <param name="name">名称</param>
    /// <param name="size">フォントサイズ</param>
    /// <returns></returns>
    public ConfigAssistants.Assistant GetAssistant(string name, int size = 18)
    {
        ConfigAssistants.Assistant retval = null;
        try
        {
            foreach (ConfigAssistants.Assistant AS in this.AssistantSettings.Settings)
            {
                if (AS.Name == name)
                {
                    retval = AS;
                    break;
                }
            }
            if(retval == null)
            {
                // 新規追加
                retval = new ConfigAssistants.Assistant();
                retval.Name = name;
                retval.Size = size;
                retval.Anchor = (int)(AnchorStyles.Top | AnchorStyles.Left);
                retval.X = 0;
                retval.Y = 0;
                this.AssistantSettings.Settings.Add(retval);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(name + "\n" + ex.Message, "GetAssistant");
        }
        return retval;
    }
}

おまじないを改造

using BveTypes.ClassWrappers;

namespace AtsPlugin
{
    [Plugin(PluginType.VehiclePlugin)]
    internal class AtsMain : AssemblyPluginBase
    {
        // 設定
        private Config CFG;

        // 変数
        private readonly AssistantText AssistantAtsText;

        // コンストラクタ
        public AtsMain(PluginBuilder services) : base(services)
        {
            try
            {
                // 設定初期化
                this.CFG = new Config();
                // 設定読込
                if(this.CFG.LoadAssistant() == false) MessageBox.Show("設定読込失敗");
    
                // BVE標準の補助表示設定のフォントサイズ
                int sz = 18;
                if (BveHacker.MainForm.AssistantDrawer.Items.Count > 0)
                {
                    sz = BveHacker.MainForm.Assistants.Items[0].AssistantSettings.Scale;
                }
                // 補助表示設定取得
                ConfigAssistants.Assistant AS1 = this.CFG.GetAssistant("hojo", sz);
                // 補助表示初期化
                AssistantAtsText = new AssistantText(new Mackoy.Bvets.AssistantSettings()
                {
                    Name = AS1.Name,
                    AutoLocation = true,
                    Anchor = (AnchorStyles)AS1.Anchor,
                    Location = new System.Drawing.Point(AS1.X, AS1.Y),
                    Visible = true,
                    Scale = AS1.Size
                });
                AssistantAtsText.Text = "補助表示だよ";
                AssistantAtsText.Color = System.Drawing.Color.White;
                AssistantAtsText.BackgroundColor = System.Drawing.Color.Red;
                // 補助表示リストに追加
                BveHacker.MainForm.AssistantDrawer.Items.Add(AssistantAtsText);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public override void Dispose()
        {
            if (!(AssistantAtsText is null))
            {
                // 補助表示設定保存
                ConfigAssistants.Assistant AS1 = this.CFG.GetAssistant("hojo");
                AS1.Anchor = (int)AssistantAtsText.AssistantSettings.Anchor;
                AS1.X = AssistantAtsText.AssistantSettings.Location.X;
                AS1.Y = AssistantAtsText.AssistantSettings.Location.Y;
                this.CFG.SaveAssistant();
                // お片付け
                BveHacker.MainForm.Assistants.Items.Remove(AssistantAtsText);
            }
        }
    }
}

※フォントサイズの初期値はBVEの設定の補助表示のフォントサイズになります。設定ファイルに保存されたScaleの値を書き換えてやれば、以降のフォントサイズが変わります。

※2024.12.22 BveEXリリースに伴いコードを修正しました。
BveHacker.MainForm.AssistantDrawer → BveHacker.MainForm.Assistants

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?