Cómo escalar un juego correctamente en Android

En aras de la simplicidad supongamos que estoy haciendo un simple juego clon de Pong para Android. Supongamos que sólo sería jugable en el modo de paisaje. (Ignore los teléfonos cuadrados por ahora).

Me gustaría que el juego se vea en la misma escala en cada teléfono, en la medida en que si tomó una captura de pantalla del juego en el teléfono QVGA, y cambiar el tamaño de la captura de pantalla a tamaño WVGA, se vería casi igual que el juego Mirar en el teléfono WVGA. En otras palabras, el ancho de la paleta siempre debe ser 1/32 de la anchura de la pantalla, el diámetro de la bola siempre debe ser 1/16 de la anchura de la pantalla.

¿Cuál sería la forma correcta de pintar la aplicación? Funcionaría en SurfaceView estándar que se dibujaría sobre un Canvas .

Digamos que tengo un PNG de alta resolución para la paleta, bola y para la fuente del juego (marcador, menú principal).

¿Puedo averiguar la resolución física, a continuación, escalar el Canvas través de la scale(float sx, float sy) para hacer que todas mis imágenes (en QVGA y WVGA) tengan la misma resolución virtual , y luego dibujar exactamente las mismas primitivas en cada posición en cada ¿tamaño de pantalla?

¿O puedo utilizar píxeles independientes de la densidad (inmersión) de alguna manera en la lona?

Sólo he jugado una vez con las funciones de lienzo de dibujo y luego cambió todo a opengl pero la lógica sigue siendo el mismo (creo).

Primer problema que desea mantener una relación constante forma de un teléfono a otro. En mi aplicación agrego un efecto de "banda negra" en cada lado. En onSurfaceChanged, usted querrá calcular una relación, esta relación le permitirá determinar cuánto espacio tiene que quitar en cada lado para mantener un aspecto coherente a su dibujo. Esto le dará un delta X o Y para aplicar a todos sus dibujos el código siguiente es algo que adapté de la versión del ogl así que pudo necesitar ser tweeked un pedacito

 @Override public void onSurfaceChanged(int w, int h){ float ratioPhysicScreen = nativeScreenResoltionW/nativeScreenResoltionH; float ratioWanted = GameView.getWidth()/GameView.getHeight(); if(ratioWanted>ratioPhysicScreen){ newHeight = (int) (w*GameView.getHeight()/GameView.getWidth()); newWidth = w; deltaY = (int) ((h-newHeight)/2); deltaX = 0; }else{ newWidth = (int) (h/GameView.getHeight()*GameView.getWidth()); newHeight = h; deltaX = (int) ((w-newWidth)/2); deltaY = 0; } 

Entonces también querrá ser capaz de dibujar sus imágenes en el lienzo por saber que el tamaño también en el lienzo que hay tamaño real y que donde la diferencia entre image.getWidth () (tamaño real de la imagen) y un Image.getScaledWidth (lienzo) que le da el tamaño del elemento en dp lo que significa lo grande que aparecerá en la pantalla) es importante. Mira el ejemplo debajo.

 public class MainMenuView extends PixelRainView{ private Bitmap bmpPlay = null; private float playLeft = 0; private float playRight = 0; private float playBottom = 0; private float playTop = 0; public MainMenuView(Context context, AttributeSet attrs) { super(context,attrs); } @Override public void unLoadBitmaps() { super.unLoadBitmaps(); if(bmpPlay != null){ bmpPlay.recycle(); bmpPlay = null; } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(bmpPlay == null){ bmpPlay = getBitmapFromRessourceID(R.drawable.play_bt); playLeft = (this.getWidth()-bmpPlay.getScaledWidth(canvas))/2; playRight = playLeft + bmpPlay.getScaledWidth(canvas); playTop = (this.getHeight()-bmpPlay.getScaledHeight(canvas))/2; playBottom = playTop+bmpPlay.getScaledHeight(canvas); } canvas.drawBitmap(bmpPlay,playLeft, playTop, null); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN){ float x = event.getX(); float y = event.getY(); //test central button if(x>playLeft && x<playRight && y<playBottom && y>playTop){ Log.e("jason", "touched play"); PixelRainView.changeView(R.layout.composedlayoutgroup); } return super.onTouchEvent(event); } } 

Esto debería resolver todo su problema de relación cross plateforms Yo sugeriría opengl porque simplificará su necesidad de mantener un aspecto constante, pero supongo que no es una opción ^ ^

Espero que esto te ayude lo suficiente

Utilice las inmersiones y pinte las paletas en vez de usar PNGs

Pienso que hay solamente 3 resoluciones estándar disponibles (ldip, mdip, hdip) y usted debe tener una carpeta del recurso para cada uno de ellos.

http://developer.android.com/guide/practices/screens_support.html

Si escala manualmente los PNG para que se ajusten a cada una de las 3 resoluciones disponibles, el teléfono debe cargar la carpeta de recursos específica de forma transparente

  • Android diferentes resoluciones de pantalla dibujables
  • Mismo DPI pero tamaño de pulgada diferente
  • Lista de tamaños de imagen de cámara compatibles
  • Programación de Android - resolución de pantalla
  • Resolver la intención de URL a veces es nulo, lanza NullPointerException
  • Javascript para detectar el ancho de la pantalla del navegador móvil?
  • Android: ¿Por qué crear imágenes específicas para ldpi, mdpi y hdpi?
  • Múltiples imágenes de fondo extraíbles para adaptarse a las resoluciones de pantalla
  • Resolución de pantalla para Android y iPhone diseño en Photoshop
  • Android: Obtener la resolución de pantalla / píxeles como valores enteros
  • ¿Cómo funciona la carpeta mdpi, hdpi, xhdpi?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.