如何使2D游戏分辨率独立?


10

我正在开发一个简单的2D游戏。我已经完成了手机版本。

但是,我的老板希望游戏能够在他的RT上运行。我正在执行“转换”,但是我的按钮放在错误的位置,因为我对屏幕尺寸进行了硬编码,如下所示:

 texture = game.Content.Load<Texture2D>("StartScreen");
 mainFrame = new Rectangle(0, 0, game.GraphicsDevice.Viewport.Width, game.GraphicsDevice.Viewport.Height);

 // button definitions
 startbrect = new Rectangle(300, 258, 88, 88);
 startbtext = game.Content.Load<Texture2D>("bplay");

在此示例中,mainframe可以,但startbrect不是,因为我定义了与Windows Phone屏幕匹配的尺寸。当所有Windows 8手机的屏幕都不同时,如何处理响应式设计?是否有公式或宏可以计算出每次合适的尺寸?


您可以检查使用的按钮在Windows Phone屏幕大小中所占的百分比,然后使用该百分比来计算其他分辨率下的正确屏幕大小。但是我敢肯定,还有比这更优雅的方法。
基督教徒

我正在寻找一种更优雅的方式,但目前我将尝试使用百分比。
加布森

2
您应该可以通过操作相机来做到这一点。
ashes999

我的解决方案是处理找不到的百分比。
加布森

Answers:


17

我使用参考屏幕尺寸,并根据它缩放所有内容,同时保持所有内容的比例相同。

private static float CalcRatio(Vector2 Sizes)
{
    return Sizes.y/Sizes.x;
}

public static Vector2 CalculateNewPos(Vector2 RefPos, Vector2 RefScreenSize, 
                                      Vector2 CurrentScreenSize)
{       
    return new Vector2((RefPos.x/RefScreenSize.x) * CurrentScreenSize.x, 
                       (RefPos.y/RefScreenSize.y) * CurrentScreenSize.y);
}

public static Vector2 CalculateNewSize(Vector2 RefSize, Vector2 RefScreenSize,
                                       Vector2 CurrentScreenSize)
{       
    float origRatio = CalcRatio(RefSize);
    float perW = RefSize.x * 100f / RefScreenSize.x;    
    float newW = perW / 100f * CurrentScreenSize.x;
    float newH = newW * origRatio;
    return new Vector2(newW, newH);
}

为确保游戏在分辨率上与参考分辨率大不相同的分辨率上表现良好,请定义一个“可玩区域”,以适合任何类型的屏幕,并在其中放置所有重要的游戏视觉效果。用背景填充其中所有内容。通常,我的参考可播放区域与参考屏幕尺寸一样大。

在纵向方向上,我计算(新的)可播放区域,以使屏幕垂直填充,水平放置的空间与保持该比例所需的空间一样大。在横向方向上,我水平填充屏幕,并在设置垂直大小时保持比例。

有关更多信息,请参见http://en.wikipedia.org/wiki/Safe_area_(television),因为它是类似的概念,即使不是完全相同。


0

我认为与分辨率无关的布局最简单,最自然的方法是相对(百分比)方案。因此,从一开始就不以实际分辨率工作,而是尽可能以统一的[0,1] x [0,1]正方形工作。

这意味着对于给定的screen_size和给定的object_size以及给定的相对位置(px, py)(例如,屏幕中心为(0.5,0.5)),对象的左上角的计算公式为:

x = px * screen_size.width - 0.5 * object_size.width
y = py * screen_size.height - 0.5 * object_size.height

这个想法应该很清楚。一个现成的抽象将是

x = cx1 * screen_size.width + cx2 * object_size.width + cx3
y = cy1 * screen_size.height + cy2 * object_size.height + cy3

然后由定义每个位置(cxi, cyi)。通过这种方式,可以将物体放置在有或没有边界的角落等。

请确保单个元素的大小(按钮,标签等)也已缩放。


-2

特别是对于MonoGame,我有针对该问题的平台独立解决方案,称为IRR(独立分辨率渲染器)。它的用法非常简单:

  1. Initialize()方法中创建IRR

    _irr =新的ResolutionRenderer(this,VirtualResolutionWidth,VirtualResolutionHeight,_gfx.PreferredBackBufferWidth,_gfx.PreferredBackBufferHeight);

  2. Draw()调用的每个循环中调用_irr.Draw()
  3. 在要使用IRR的任何SpriteBatch.Begin()调用中提供_irr.GetTransformationMatrix()

描述在这里:http : //panthernet.ru/forum/index.php?/topic/17-monogamexna-examples-v14/?p=44

代码在这里:https : //github.com/panthernet/Monogame-Examples

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.