Ajustando o jogo Android em diferentes tamanhos de tela

11

Estou criando um jogo para Android apenas na orientação retrato na tela. Funciona muito bem quando executo no meu telefone, mas quando executo em um tablet, mesmo que o tamanho da tela seja maior, todos os bitmaps têm o mesmo tamanho. Existe alguma maneira de fazer com que os bitmaps permaneçam na mesma proporção, mesmo em telas de tamanhos diferentes?

user1404512
fonte

Respostas:

11

A menos que você esteja usando o AbsoluteLayout (geralmente é uma péssima idéia, ao projetar seu layout usando coordenadas x / y, que só se adequam ao dispositivo em que foi desenvolvido), isso não deve acontecer - os aplicativos Android se ajustam automaticamente ao tamanho da tela do dispositivo . No entanto, pelo que você descreve (o layout não se ajusta à tela da tabela), parece que o AbsoluteLayout pode ser o problema aqui.

Certifique-se de que, nos arquivos XML do layout, NÃO use layouts absolutos (isso inclui definir coordenadas / larguras / alturas explícitas em qualquer tipo de visualização). Em vez disso, considere usar:

  • LinearLayout - empilha várias visualizações horizontal ou verticalmente
  • FrameLayout - geralmente contém um filho
  • RelativeLayout - Alinhar filhos em relação um ao outro
  • TableLayout - Um layout baseado em tabela
  • ScrollView - pode conter um item filho (como um LinearLayout) e permite rolar o conteúdo

... o que melhor se adequa ao seu propósito.

Se você é novo no Android , o Google oferece um bom tutorial que apresenta os diferentes tipos de layout mencionados acima. Mais tutoriais podem ser encontrados aqui .

Além disso, seu nível de API seria relevante (para saber se você está usando o Android 2.x ou 4.x - não assumo o 3.x, pois não está disponível para smartphones) para descobrir a causa do seu problema.

Você está forçando seu aplicativo no modo retrato, definindo:

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

... na sua Atividade que exibe as visualizações do jogo?

Forneça mais informações sobre como você está projetando suas visualizações (você está usando XML para o layout que mais tarde inflará em sua Atividade, ou você está usando layout em código em sua Atividade, etc ...)? Além disso: você tentou executar seu aplicativo em um emulador do tamanho de um smartphone e um tablet? Se sim, o problema persiste?


ATUALIZAÇÃO: COMO ESCALAR BITMAPS

O OP perguntou como ele pode escalar o bitmap que ele está usando em seu jogo. Uma opção (pelo que sei sobre a configuração do OP): o SurfaceHolder.Callback que você está substituindo para exibir seu jogo e no qual renderiza todos os Bitmaps etc ... tem um método chamado:

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

Esse método fornece a largura / altura da sua superfície, para que você possa agora usar:

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

da classe Bitmap . Para redimensionar suas imagens proporcionalmente ao tamanho da superfície em que você está desenhando.

O que você precisa fazer é o seguinte: se você conhece as dimensões do seu bitmap em relação a um determinado tamanho de tela, por exemplo, o tamanho da tela do seu smartphone. Em seguida, você pode calcular as dimensões de destino dos bitmaps dimensionados. Aqui está a matemática (envolvida em um exemplo):

Digamos que você tenha um Bitmap A com as dimensões 25x50 (largura x altura) que é exibido em uma tela com as dimensões 100x200 (largura x altura). Para esse tamanho de tela (100x200), o bitmap possui as dimensões corretas - agora, se você deseja exibir o bitmap em uma tela maior, é necessário:

  • Calcular o fator de escala para o tamanho do bitmap
  • Manter a proporção do bitmap (para que ele não fique distorcido)

Digamos que a tela maior tenha 200 x 300 (largura x altura), o fator de escala da largura é:

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

Então 2 é o nosso fator de escala para o valor da largura e altura do bitmap, já que precisamos manter a proporção do bitmap, podemos simplesmente multiplicar o fator de escala pela largura e altura do bitmap:

bitmapWidth * 2 = scaledBitmapWidth
bitmapHeight * 2 = scaledBitmapHeight

Portanto, usando nosso exemplo de bitmap A de cima e a fórmula mencionada, as novas dimensões do bitmap seriam: 50x100 (widthxheight) porque:

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

Então agora que sabemos o novo tamanho do nosso bitmap, simplesmente usamos a chamada de API que mencionei acima e preenchemos os espaços em branco:

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

myBitmap no exemplo acima é o bitmap original A que tinha as dimensões 25x50 e é dimensionado para 50x100 usando o snippet de código acima.


No entanto, isso não resolveria o problema original do aplicativo, ocupando apenas o canto superior direito de um dispositivo do tamanho de um tablet. Para responder a essa pergunta, precisaríamos de respostas para as perguntas que fizemos sobre sua configuração. Vou resumir rapidamente aqui:

  • Você está usando um mecanismo de jogo como o AndEngine ou o Unity ?
  • Você está escrevendo seu layout em xml? Se sim, qual é o seu layout raiz para renderizar o conteúdo do seu jogo?
  • Você mencionou que está implementando o SurfaceHolder.Callback? A largura / altura fornecida na chamada de método surfaceChanged fornece o tamanho da superfície - é do mesmo tamanho quando o aplicativo é executado em um smartphone ou tablet?
  • Você tem acesso ao SurfaceView (ou o que estiver vinculado a esse SurfaceHolder.Callback que você está implementando), para que possamos determinar se esse é o que define rigidamente o tamanho do aplicativo para o tamanho do smartphone.
  • Os mesmos problemas de redimensionamento ocorrem no emulador com diferentes resoluções de tela?

Uma suspeita geral: nem todo smartphone tem o mesmo tamanho de tela, na verdade, há uma ampla variedade de tamanhos de tela, o que me faz pensar: você já testou seu aplicativo em um smartphone com um tamanho de tela diferente do da sua tela? Porque - o fato de caber na tela, mas não em um tablet, me faz pensar em quem define essas dimensões e quando. Como duvido que um aplicativo possa se ajustar a todos os tamanhos de tela de smartphones, mas não aos tamanhos de tablets - não fará muito sentido (porque eles têm mais ou menos o mesmo núcleo Android em execução neles, algumas diferenças entre sx, 3. x e 4.x à parte) A menos que você esteja usando uma estrutura que não suporte (por qualquer motivo - talvez você precise comprar suporte para tablet extra ou o que for) tamanhos de tela do tamanho de um tablet. É por isso que é realmente importante saber se o aplicativo é redimensionado corretamente apenas no seu telefone, ou em outros smartphones também. A única maneira de saber como um aplicativo pode ser limitado ao tamanho da tela de um telefone específico é usando AbsoluteLayout e dimensões geralmente absolutas para widgets etc.


UPDATE: Dimensionando coordenadas x / y

Para ajustar a localização do seu bitmap ao tamanho da tela, algo como o seguinte deve fazer o trabalho:

  • Dimensões da tela: 100/200 (largura / altura)
  • Localização do bitmap: x = 50 / y = 100

Agora, se você aumentar o tamanho da tela, precisará escalar esses valores x / y:

  • Dimensões da tela: 200/400 (largura / altura)

O fator de escala seria 2, porque a largura e a altura aumentaram igualmente em dois. Portanto, as dimensões seriam ...

  • Localização do bitmap: x = 100 / y = 200

Outra tentativa - desta vez com diferentes fatores de escala para largura / altura

  • Dimensões da tela: 100/150 (largura / altura)
  • Localização do bitmap: x = 50 / y = 50

Se a nova tela de destino for 150/250, os cálculos serão:

  • Fator de escala para largura = targetWidth / originalWidth = 1.5
  • Fator de escala para altura = targetHeight / originalHeight = 1.666 ... (Período)

Agora precisamos escalar as coordenadas x / y, x é escalado usando a escala de largura e a altura é escalada usando a escala de altura, eis o resultado:

  • x = originalX * 1,5 = 75
  • y = originalY * 1.666 .. (Período) = 83.333 ... (Período)

Portanto, as novas dimensões da tela e as coordenadas x / y em escala são:

  • width = 150
  • height = 250
  • x = 75
  • y = 83.333 ... (Período)

Para resumir uma longa história, o algoritmo para dimensionar bitmaps é:

X = (targetScreenWidth / defaultScreenWidth) * defaultXCoordinate
Y = (targetScreenHeight / defaultScreenHeight) * defaultYCoordinate
Zainodis
fonte
Meu jogo usa um painel de jogo que estende o SurfaceHolder.Callback (está em um arquivo XML chamado por uma Atividade). Isto poderia ser parte do problema?
User1404512
@ user1404512 Um SurfaceHolder.Callback geralmente está vinculado a um SurfaceView - e também depende de como o SurfaceView é configurado (largura / altura) se for incorporado em outro Layout (como FrameLayout etc.) ... no seu A SurfaceHolder.Callback. deve ser um método: public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) a largura e a altura devem ser o tamanho do que está sendo desenhado na tela - que no seu caso seria o mesmo em tablets e smartphones - pode você verifica isso?
AgentKnopf
Sim, acho que devo dizer o seguinte: quando o executo no tablet, mesmo que o tamanho da tela seja maior, todos os bitmaps têm o mesmo tamanho. Existe alguma maneira de fazer com que os bitmaps permaneçam na mesma proporção, mesmo em telas de tamanhos diferentes?
User1404512
@ user1404512 É realmente importante que você responda a todas as perguntas que fizemos, pois ainda estamos no escuro sobre como o layout é projetado, o que dificulta a resposta a qualquer pergunta específica. Quanto aos seus bitmaps: atualizei minha resposta para responder da melhor forma possível à pergunta sobre escala de bitmap, já que pouco se sabe sobre sua configuração.
AgentKnopf
Não, não estou usando um mecanismo de jogo. Eu tenho meu layout em xml e, no meu arquivo xml, tenho um SurfaceHolder.Callback que é a tela inteira. A largura e a altura do suporte mudam de tela para tela. Penso que meu problema é que estou desenhando os bitmaps com as coordenadas X e Y, mas a escala dos bitmaps permanece a mesma de tela para tela. Existe alguma maneira de corrigir isso? Muito obrigado antecipadamente!
user1404512
3

Há um artigo bom e relevante no Android.com: http://developer.android.com/guide/practices/screens_support.html

Esta referência ajuda a classificar o tamanho, a densidade e a resolução da tela. O objetivo é usar as APIs do Android para obter "independência de densidade", para que os componentes e gráficos da interface do usuário possam ficar bem em vários dispositivos.

Lembre-se de que você também pode criar configurações diferentes de dispositivos virtuais Android para o emulador enquanto estiver testando o layout e a aparência: http://developer.android.com/guide/developing/devices/emulator.html

amb
fonte
0

Apenas um tiro no escuro aqui. Você definiu o layout principal para preencher o pai na vertical e na horizontal?

Derek
fonte