使Android游戏适应不同的屏幕尺寸


11

我正在制作仅纵向屏幕方向的Android游戏。当我在手机上运行它时效果很好,但是当我在平板电脑上运行它时,即使屏幕尺寸更大,所有位图的大小都相同。有什么方法可以使位图即使在不同尺寸的屏幕上也保持相同的比例?

Answers:


11

除非您使用AbsoluteLayout(通常是一个非常糟糕的主意,因为您使用x / y坐标设计布局,而该坐标仅适合被设计的设备),否则就不会发生-Android应用程序会自动调整为设备的屏幕尺寸。但是,从您的描述(布局无法适应表格屏幕)看来,AbsoluteLayout可能是这里的问题。

确保在布局XML文件中没有使用绝对布局(这包括在任何类型的视图上设置显式坐标/宽度/高度)。而是考虑使用:

...最适合您的目的。

如果您是Android的新手,那么Google提供了一个不错的教程,其中介绍了上述不同的Layout Types。更多的教程可以在这里找到。

此外,您的API级别也很重要(要知道您使用的是Android 2.x还是4.x-我不认为3.x,因为它不适用于智能手机)才能找出问题的原因。

您是否通过设置以下方式将应用程序强制设为纵向模式:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set screen orientation for this dialog to portrait
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

...在您的显示游戏视图的活动中?

请提供有关您如何布局视图的更多信息(您是将XML用于以后要在Activity中填充的布局,还是在Activity中使用代码内布局等。)?此外:您是否尝试过在智能手机和平板电脑大小的模拟器中运行应用程序?如果是,该问题是否仍然存在?


更新:如何缩放位图

OP询问他如何缩放他在游戏中使用的位图。一个选项(据我所知,关于OP的设置):您要覆盖此SurfaceHolder.Callback以显示游戏,并在其上渲染所有Bitmap等...具有一种称为:

surfaceChanged(SurfaceHolder holder, int format, int width, int height)

该方法为您提供了表面的宽度/高度,因此您现在可以使用:

Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)

来自Bitmap类。要根据要绘制的表面的大小调整图像的大小。

您需要做的是:如果您知道位图的尺寸相对于给定的屏幕尺寸,例如智能手机的屏幕尺寸。然后,您可以计算缩放位图的目标尺寸。这是数学(在示例中包装):

假设您有一个尺寸为25x50(宽x高)位图A,它会在尺寸为100x200(宽x高)的屏幕上显示。对于该屏幕尺寸(100x200),位图具有正确的尺寸-现在,如果要在更大的屏幕上显示位图,则需要:

  • 计算位图大小的比例因子
  • 保持位图的高宽比(这样它就不会失真)

假设较大的屏幕为200x300(widthxheight),则宽度的比例因子为:

200(target screen width)/100(default screen width) = 2

所以2是位图的宽度和高度值的比例因子,因为我们需要保持位图的长宽比,所以我们可以简单地将比例因子乘以位图的宽度和高度:

bitmapWidth * 2 = scaledBitmapWidth
bitmapHeight * 2 = scaledBitmapHeight

因此,使用上面的示例位图A和提到的公式,位图的新尺寸为:50x100(宽度x高),因为:

 2*25(width) = 50 height
 2*50(height) = 100 height

现在,我们知道位图的新大小,我们只需使用我上面提到的API调用并填写空白即可:

   Bitmap.createScaledBitmap (myBitmap, 50, 100, false)

上面示例中的myBitmap是原始位图A,其尺寸为25x50,并使用上述代码段缩放为50x100。


但是,这无法解决您原来只占用平板电脑大小的设备右上角的应用程序问题。要回答这个问题,我们需要回答我们询问您有关设置的问题。我会在这里快速总结一下:

  • 您是否正在使用AndEngineUnity之类的游戏引擎?
  • 您正在用xml编写布局吗?如果可以,呈现游戏内容的根布局是什么?
  • 您提到要实现SurfaceHolder.Callback?surfaceChanged方法调用中提供的宽度/高度为您提供了表面的大小-当您的应用程序在智能手机或平板电脑上运行时,它的大小是否相同?
  • 您是否有权访问SurfaceView(或正在实现的与该SurfaceHolder.Callback链接的任何链接),因此我们可以确定是否将应用程序大小严格设置为智能手机大小。
  • 在具有不同屏幕分辨率的模拟器中是否发生相同的调整大小问题?

一个普遍的怀疑:并不是每个智能手机都具有相同的屏幕尺寸,实际上屏幕尺寸范围很广,这使我感到奇怪:您是否曾经在与屏幕尺寸不同的智能手机上测试过您的应用程序吗?因为-它适合您的屏幕,但不适合平板电脑,这一事实使我想知道是由谁来设置这些尺寸以及何时设置。因为我怀疑某个应用程序可以适应所有智能手机的屏幕尺寸,而不能适应平板电脑的尺寸-这样做没有多大意义(因为它们或多或少都具有相同的android内核,因此sx,3之间有些区别)。除x和4.x之外),除非您使用的框架不支持(无论出于何种原因-也许您必须购买额外的或更多的平板电脑支持)平板电脑大小的屏幕尺寸。这就是为什么真正重要的是要知道应用程序是否仅在手机上调整大小,或其他智能手机上。我知道如何将应用程序限制为一部特定手机的屏幕尺寸的唯一方法是使用AbsoluteLayout和小部件等的绝对尺寸...


更新:缩放x / y坐标

为了将位图的位置调整为屏幕大小,应执行以下操作:

  • 屏幕尺寸:100/200(宽度/高度)
  • 位图位置:x = 50 / y = 100

现在,如果您增加屏幕尺寸,则必须沿以下比例缩放这些x / y值:

  • 屏幕尺寸:200/400(宽度/高度)

比例因子将为2,因为宽度和高度平均增加了2。因此,尺寸将是...

  • 位图位置:x = 100 / y = 200

另一种尝试-这次使用不同的宽度/高度比例因子

  • 屏幕尺寸:100/150(宽度/高度)
  • 位图位置:x = 50 / y = 50

如果新的目标屏幕为150/250,则计算为:

  • 宽度的比例因子= targetWidth / originalWidth = 1.5
  • 高度的比例因子= targetHeight / originalHeight = 1.666 ...(Period)

现在我们需要缩放x / y坐标,使用宽度比例缩放x,使用高度比例缩放高度,结果如下:

  • x =原始X * 1.5 = 75
  • y =原始Y * 1.666 ..(句点)= 83.333 ...(句点)

因此,新的屏幕尺寸和缩放的x / y坐标为:

  • 宽度= 150
  • 高度= 250
  • x = 75
  • y = 83,333 ...(句号)

长话短说,缩放位图的算法是:

X = (targetScreenWidth / defaultScreenWidth) * defaultXCoordinate
Y = (targetScreenHeight / defaultScreenHeight) * defaultYCoordinate

我的游戏使用扩展了SurfaceHolder.Callback的游戏面板(它在一个Activity调用的XML文件中)。这可能是问题的一部分吗?
user1404512

@ user1404512一个SurfaceHolder.Callback通常链接到一个SurfaceView-并且还取决于如果SurfaceView嵌入到另一个Surface布局(如FrameLayout等)中的SurfaceView的配置方式(宽度/高度)...在您的SurfaceHolder.Callback中应该是一种方法:public void surfaceChanged(SurfaceHolderholder,int format,int width,int height)的宽度和高度应该是屏幕上绘制的大小-在您的情况下,平板电脑和智能手机上的大小相同-可以你确认吗?
AgentKnopf 2012年

是的,我想我应该这样说:当我在平板电脑上运行它时,即使屏幕尺寸更大,所有位图的大小也相同。有什么方法可以使位图即使在不同尺寸的屏幕上也保持相同的比例?
user1404512 2012年

@ user1404512非常重要,您要回答我们问过的所有这些问题,因为关于布局的设计方式我们还是一无所知,这使得很难回答任何特定的问题。至于您的位图:考虑到您的设置知之甚少,我更新了我的答案以尽可能地回答位图缩放问题。
AgentKnopf

不,我没有使用游戏引擎。我的确在xml中有布局,在我的xml文件中有一个SurfaceHolder.Callback,即整个屏幕。支架的宽度和高度因屏幕而异。我认为我的问题是我在绘制带有X和Y坐标的位图,但是位图的比例在屏幕之间保持不变。有没有什么办法解决这一问题?在此先多谢!
user1404512 2012年

3

Android.com上有一篇不错且相关的文章:http : //developer.android.com/guide/practices/screens_support.html

此参考可帮助您对屏幕尺寸,屏幕密度和分辨率进行分类。目标是使用Android API来实现“密度独立性”,以便您的用户界面组件和图形在各种设备上看起来都不错。

请记住,在测试布局和外观时,您还可以为模拟器创建不同的Android虚拟设备配置:http : //developer.android.com/guide/developing/devices/emulator.html


0

这里只是黑暗中的一枪。您是否设置了任何主布局以垂直和水平填充父级?

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.