XNA弹出文本对话框

时间:2010-05-16 19:17:10

标签: c# popup xna textwrapping

嘿伙计们,我正在开发一款游戏,并希望添加一个在用户点击某些对象时打开的屏幕。屏幕布局为左侧有图像,右上角有标题,标题下方有文字。

我有一些问题, 1)我如何创建弹出框? (最好有圆边) 2)我如何包装文本(在图片前面,但不在弹出框之外,我甚至可能需要垂直滚动条) 3)我如何考虑不同的屏幕分辨率(他们甚至会有所作为?)

感谢您的帮助, 最大

4 个答案:

答案 0 :(得分:4)

圆形边缘等可以通过制作您想要弹出窗口的图像并根据需要设置样式来最好地处理。

假设你制作了一个300px×300px的盒子

然后从那里你想要将你的文本包装好,并且可能让它滚动,或者你想通过检查文本的高度和宽度来处理它,以找到包装文本的位置......

例如,你可以创建一个这样的函数,它将获取你的全文并根据一些测量值进行包装。

private string WrapText(string text)
{
  string[] words = text.Split(' ');
  StringBuilder sb = new StringBuilder();
  float linewidth = 0f;
  float maxLine = 250f; //a bit smaller than the box so you can have some padding...etc
  float spaceWidth = spriteFont.MeasureString(" ").X;

  foreach (string word in words)
  {
    Vector2 size = spriteFont.MeasureString(word);
    if (linewidth + size.X < 250)
    {
      sb.Append(word + " ");
      linewidth += size.X + spaceWidth;
    } 
    else
    {
      sb.Append("\n" + word + " ");
      linewidth = size.X + spaceWidth;
    }
  }
  return sb.ToString();
}

如果您的文字对于从上到下的视图很多 - 您必须提出某种滚动文本,或按“继续”按钮按下以加载下一页文本。

最后,就分辨率而言,它取决于平台,你想要建立你的游戏和艺术平台,例如300x300图像的对话框可能不会工作那么好,如果这是你在XNA建立的东西4用于手机,但对于xbox构建来说很好,而且大多数逻辑上都是pc构建。虽然使用视口你可能会使用相同的艺术(可能值得使用较小的图像用于更小的屏幕。

解决您可能希望查看tile safe area等问题的问题,并阅读一些关于viewports的内容。它还建议您将游戏设置为1280 x 720,这是一个720p原始分辨率,适用于所有电视,并为您的艺术提供参考。

public Game1()
{
    graphics = new GraphicsDeviceManager(this);

    this.graphics.PreferredBackBufferWidth = 1280;
    this.graphics.PreferredBackBufferHeight = 720;

    Content.RootDirectory = "Content";
}

希望至少能帮助你朝着正确的方向前进。

答案 1 :(得分:2)

我多年没有触及XNA,但我建议你看看Game状态样本。它现在可能有点过时了,但它会给你一个很好的起点来管理你的游戏状态和'弹出窗口',菜单等。

http://creators.xna.com/en-US/samples/gamestatemanagement

答案 2 :(得分:1)

对于任何寻找,这里是我编写的完整代码,代码有点像鸡肉划痕,但它确实有效...

请注意我将FillText加载器放在main函数中,如果使用此代码,则应将其移到外部(因此不会重复调用)

        public void DisplayPopup (string Title, string Text, string AssetPicturePath, SpriteBatch batch)
    {
        FillText = new Texture2D(game.GraphicsDevice, 1, 1);
        FillText.SetData(new Color[] { Color.White });
        //Draw rectangle, center screen,
        Rectangle MainBox;
        MainBox.Width = 700;
        MainBox.Height = 400;
        MainBox.X = game.Window.ClientBounds.Width / 2 - MainBox.Width / 2;
        MainBox.Y = game.Window.ClientBounds.Height / 2 - MainBox.Height / 2;

        //Draw Title
        Rectangle TitleBox;
        TitleBox.Width = 650;
        TitleBox.Height = (int)ArialFont.MeasureString(Title).Y;
        Padding = MainBox.Width / 2 - TitleBox.Width / 2;
        TitleBox.X = (int)Padding + MainBox.X;
        TitleBox.Y = (int)Padding + MainBox.Y;

        //Draw Line Between Title and TextBox
        Rectangle TextSeperator;
        TextSeperator.Width = MainBox.Width - (int)Padding * 2;
        TextSeperator.Height = 1;
        TextSeperator.X = MainBox.X + (int)Padding;
        TextSeperator.Y = TitleBox.Y + (int)(Padding * 1.2);

        //Draw PictureBox
        Rectangle PictureBox;
        if (AssetPicturePath != string.Empty)
            PictureBox.Width = 200;
        else
            PictureBox.Width = 0;

        PictureBox.Height = 250;
        PictureBox.X = MainBox.X + (int)Padding;
        PictureBox.Y = MainBox.Y + TitleBox.Height + (int)Padding * 2;

        MainBox.Height = PictureBox.Y - MainBox.Y + PictureBox.Height + (int)Padding;

        //Draw TextBody
        Rectangle TextBody;
        if (AssetPicturePath == string.Empty)
            TextBody.Width = MainBox.Width - ((int)Padding * 2);
        else
            TextBody.Width = MainBox.Width - ((int)Padding * 3) - PictureBox.Width;
        TextBody.Height = MainBox.Height - ((int)Padding * 3) - TitleBox.Height;
        if (AssetPicturePath == string.Empty)
            TextBody.X = PictureBox.X;
        else
            TextBody.X = PictureBox.X + PictureBox.Width + (int)Padding;
        TextBody.Y = TitleBox.Y + TitleBox.Height + (int)Padding;

        //Draw MainBox
        batch.Draw(FillText, MainBox, Color.Wheat);
        //Draw PictureBox
        //batch.Draw(FillText, PictureBox, Color.Green);
        if (AssetPicturePath != string.Empty)
            batch.Draw(game.Content.Load<Texture2D>(AssetPath + AssetPicturePath.TrimStart(new char[] { '/' })), PictureBox, Color.White);
        //Draw TitleBox
        //batch.Draw(FillText, TitleBox, Color.BlueViolet);
        batch.DrawString(ArialFont, Title, new Vector2(TitleBox.X, TitleBox.Y),Color.Blue);
        //Draw Line Between Title And TextBody
        batch.Draw(FillText, TextSeperator, Color.Gray);
        //Draw TextBody
        //batch.Draw(FillText, TextBody, Color.Indigo);
        int LineNumber = 0;
        foreach (string Line in WrapText(Text, TextBody.Width))
        {
            batch.DrawString(ArialFont, Line, new Vector2(TextBody.X, TextBody.Y + (LineNumber * ArialFont.MeasureString(Line).Y)), Color.Black);
            LineNumber++;
        }

    }
    private object[] WrapText(string text, float Length)
    {
        string[] words = text.Split(' ');
        ArrayList Lines = new ArrayList();
        float linewidth = 0f;
        float spaceWidth = ArialFont.MeasureString(" ").X;
        int CurLine = 0;
        Lines.Add(string.Empty);
        foreach (string word in words)
        {
            Vector2 size = ArialFont.MeasureString(word);
            if (linewidth + size.X < Length)
            {
                Lines[CurLine] += word + " ";
                linewidth += size.X + spaceWidth;
            }
            else
            {
                Lines.Add(word + " ");
                linewidth = size.X + spaceWidth;
                CurLine++;
            }
        }
        return Lines.ToArray();
    }

答案 3 :(得分:0)

您应该查看sprite批处理对象,该对象在游戏状态管理示例中处理ui