1
/// <summary>
/// Simple UI TextBox Class. For displaying messages in 2D Games
/// </summary>
class TextBox
{
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="Text"> The text of the TextBox</param>
    public TextBox(string Text = "", int w = 400, int h = 200)
    {
        this.Text = Text;
        textNext = string.Empty;

        try { Surface = new Surface(w, h); }
        catch (NullReferenceException e)
        {
            MessageBox.Show(e.Message);
            Events.QuitApplication();
        }

        Offset = new System.Drawing.Point(30, 30);
        FontColor = System.Drawing.Color.White;
        BackColor = System.Drawing.Color.Black;
        Surface.Fill(BackColor);

        try { Font = new Font(@"data\font\AllerDisplay.ttf", 16); }
        catch (NullReferenceException e)
        {
            MessageBox.Show(e.Message);
            Events.QuitApplication();
        }

        Visible = true;
        MaxLines = 6;
        AcceptKey = Key.Return;
    }

    /// <summary>
    /// Locks and wraps up the text box.
    /// Text, Size and Font changes take effect
    /// </summary>
    public void Lock()
    {
        Surface.Fill(BackColor); // clear the surface
        DrawText(); // draw the text
    }

    public void Update()
    {
        if (Keyboard.IsKeyPressed(AcceptKey))
        {
            if (!String.IsNullOrEmpty(textNext))
            {
                Text = textNext;
                textNext = string.Empty;
                Lock();
            }
            else
            {
                Visible = false;
            }
        }
    }

    /// <summary>
    /// Wraps up and renders the text
    /// </summary>
    private void DrawText()
    {
        var x = 0;
        var y = 0;

        Console.WriteLine(Text.Length);

        // increment the size of each character
        for (var i = 0; i < Text.Length; i++)
        {
            x += Font.SizeText(Text[i].ToString()).Width;

            // if it exceeds the width of the box
            if (x > Surface.Width - Offset.X * 2)
            {
                Text = Text.Insert(i, "-\n");
                x = 0;
                y++;
            }

            // if the lines exceed the limit
            if (y > MaxLines)
            {
                // save the remaining lines for the next run
                var index = Text.LastIndexOf("-\n");
                textNext = Text.Substring(index);
                Text = Text.Substring(0, index);
                break;
            }
        }

        Console.WriteLine(Text);

        // render the string and blit it onto Surface
        var surf = Font.Render(Text, FontColor);
        Surface.Blit(surf, Offset);

    }

    /// <summary>
    /// The remaining text which is to be displayed 
    /// on the next run of the text box
    /// </summary>
    string textNext;

    /// <summary>
    /// The text of the text box
    /// </summary>
    public string Text
    {
        get;
        set;
    }

    /// <summary>
    /// The background surface of the text box
    /// </summary>
    public Surface Surface
    {
        get;
        set;
    }

    /// <summary>
    /// Maximum number of lines per text piece
    /// </summary>
    public int MaxLines
    {
        get;
        set;
    }

    // More irrelevant code...
}

现在该DrawText()方法基本上对文本进行了自动换行。如果文本太大而无法在单个框中显示,则将其部分存储并在重新运行时显示。现在的问题是,我第二次调用 Font.Render 时,出于某种原因,我得到了垂直显示的文本。例如:

            textBox = new TextBox(
@"Please note that this Tutorial is not for the absolute beginner. I assume that you already can code fluent in C# and that you are able to understand code when reading them. I will not explain every single line of code when it should be clear what it's doing. Also please note that i am not a native speaker, so there are for sure many grammatical errors in this text (which are maybe corrected in the future when i find them ;-)");

            textBox.Lock();

现在我得到的输出是: 输出 1 输出 2

那么为什么文本的第二部分是垂直显示的呢?我尝试检查我的自动换行功能是否正常工作,也许垂直方向是由 '\n' 插入引起的。但是,它运行良好。它只在正确的位置添加了一个 '\n'。所以字体渲染可能存在一些问题。

4

0 回答 0