【发布时间】:2010-05-16 19:17:10
【问题描述】:
大家好,我正在开发一款游戏,并且想添加一个屏幕,当用户单击某些对象时会打开该屏幕。屏幕的布局将在左侧显示图像,在右上角显示标题,在标题下方显示文本。
我对此有一些问题, 1)我将如何创建弹出框? (最好有圆边) 2)我将如何包装文本(在图片前面,但不在弹出框之外,我什至可能需要垂直滚动条) 3) 我将如何考虑不同的屏幕分辨率(它们甚至会有所不同吗?)
感谢您的任何帮助, 最大
【问题讨论】:
大家好,我正在开发一款游戏,并且想添加一个屏幕,当用户单击某些对象时会打开该屏幕。屏幕的布局将在左侧显示图像,在右上角显示标题,在标题下方显示文本。
我对此有一些问题, 1)我将如何创建弹出框? (最好有圆边) 2)我将如何包装文本(在图片前面,但不在弹出框之外,我什至可能需要垂直滚动条) 3) 我将如何考虑不同的屏幕分辨率(它们甚至会有所不同吗?)
感谢您的任何帮助, 最大
【问题讨论】:
通过制作您希望弹出窗口的外观并按照您的需要设置样式,可以最好地处理圆形边缘等。
假设你制作了一个 300 x 300 像素的盒子
然后从那里你会想要在其中包装你的文本,并可能让它滚动,或者你想通过检查文本的高度和宽度来找到在哪里包装文本来处理它......
例如,您可以创建一个这样的函数,它将获取您的全文并根据一些测量值对其进行包装。
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();
}
如果您的文本对于从上到下的视图来说太多了 - 您将不得不想出某种滚动文本,或者按下“继续”按钮来加载下一页文本。
最后,就分辨率而言,它取决于平台,您想针对平台构建游戏和艺术,例如,如果这是您在 XNA 中构建的东西,对话框的 300x300 图像可能不会那么好用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";
}
希望至少能将你推向正确的方向。
【讨论】:
我已经很多年没有接触过 XNA,但我建议您看一下游戏状态示例。现在可能有点过时了,但会给你一个很好的起点来管理你的游戏状态和“弹出窗口”、菜单等。
http://creators.xna.com/en-US/samples/gamestatemanagement
【讨论】:
对于任何人来说,这里是我编写的完整代码,代码有点鸡肋,但它确实可以完成工作..
请注意我将 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();
}
【讨论】:
您应该只查看精灵批处理对象,它在游戏状态管理示例中处理用户界面
【讨论】: