Всплывающее текстовое диалоговое окно XNA - PullRequest
2 голосов
/ 16 мая 2010

Эй, ребята, я работаю над игрой и хотел добавить экран, который открывается, когда пользователь нажимает на определенные объекты. На экране будет размещено изображение слева, заголовок справа вверху и текст под заголовком.

У меня есть несколько проблем с этим, 1) Как бы я создал всплывающее окно? (желательно с закругленными краями) 2) Как бы я обернул текст (перед картинкой, но не снаружи всплывающего окна, мне могут даже понадобиться вертикальные полосы прокрутки) 3) Как бы я учел разные разрешения экрана (будут ли они вообще иметь значение?)

Спасибо за любую помощь, Max

Ответы [ 4 ]

4 голосов
/ 17 мая 2010

закругленные края и т. Д. Лучше всего обрабатывать, создавая изображение того, как вы хотите, чтобы всплывающее окно выглядело, и стилизуя его так, как вы хотите.

Допустим, вы сделали коробку, 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, и наиболее логично для сборки ПК. Хотя в окнах просмотра вы, вероятно, могли бы использовать ту же графику (возможно, стоит использовать изображения меньшего размера для гораздо меньшего экрана.

для разрешения вопросов типа вы, вероятно, захотите взглянуть на такие вещи, как безопасная область плитки и прочитать немного о viewports . Также предлагается установить для своей игры разрешение 1280 x 720, то есть собственное разрешение 720p, которое должно работать на всех телевизорах и которое дает вам представление о вашем искусстве.

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

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

    Content.RootDirectory = "Content";
}

Надеюсь, это хотя бы подтолкнет вас в правильном направлении.

2 голосов
/ 16 мая 2010

Я не касался XNA в течение многих лет, но я бы посоветовал вам взглянуть на пример состояния игры. Вероятно, он немного устарел, но даст вам хорошую отправную точку для управления состоянием вашей игры, всплывающих окон, меню и т. Д.

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

1 голос
/ 17 мая 2010

Для любого взгляда, вот полный код, над которым я работал, код - своего рода курица, но он делает свою работу ..

Обратите внимание, что я поместил загрузчик FillText внутри основной функции, вы должны переместить его наружу (чтобы он не вызывался повторно), если вы используете этот код

        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();
    }
0 голосов
/ 17 мая 2010

Вы должны просто взглянуть на объект спрайта, который обрабатывает пользовательский интерфейс в примере управления состоянием игры

...