Android: FPS bajo que dibuja muchos mapas de bits en una vista de superficie

Estoy tratando de crear un juego Bullethell y he tenido un poco de problemas. No puedo conseguir más de 17 fps después de unas 500 balas. El código de la lógica de la actualización tarda alrededor de 1-4ms para todos ellos mientras que el código de la toma toma alrededor de 40ms

Por ahora mi código es

private void drawEntities(Canvas canvas) { for (HashMap<UUID, Spatial> h: spatialList) { for (Spatial spatial: h.values()) { spatial.render(canvas); if(spatial.life > 0) spatial.life--; else if (spatial.life == 0) engine.deleteEntity(spatial.owner); } } } 

spatialList es un arrayList donde cada índice es un zLevel

El espacial que muestra la bala real es

 public void render(Canvas canvas) { float angle = (float) (vel.getAngle() * (180 / Math.PI)); matrix.reset(); matrix.setTranslate(pos.x - bullet.getWidth() / 2, pos.y - bullet.getHeight() / 2); matrix.postRotate(angle + 90, pos.x, pos.y); canvas.drawBitmap(bullet, matrix, paint); canvas.drawCircle(pos.x, pos.y, col.getRadius(), paint); } 

Puedo proporcionar más código, pero estos parecen ser el principal problema. He intentado todo lo que puedo pensar y no puedo encontrar mucho más en línea. Lo único que puedo pensar en arreglar esto es cambiar de una superficie a una GLSurfaceview, pero realmente creo que hay una mejor manera y sólo estoy usando código malo.

Edit: Me di cuenta de mi temporizador estaba apagado y eliminado el drawcircle y después de ejecutarlo de nuevo me sale 40ms ~ alrededor de 500, que sigue siendo un poco demasiado bajo para un rendimiento razonable.

TLDR; 500 entidades = 17 fps.

Puede estar limitado por la tasa de relleno de píxeles. ¿Qué tamaño (en píxeles) tiene la pantalla en su dispositivo de prueba?

Una cosa simple para jugar es usar setFixedSize() para reducir el tamaño de SurfaceViewView. Eso reducirá el número de píxeles que estás tocando. Ejemplo aquí , video aquí , post de blog aquí .

Por lo general, es una buena idea hacer esto, ya que los dispositivos más nuevos parecen competir hacia absurdos conteos de píxeles. Un juego de pantalla completa que realiza toda la representación en software va a luchar en una pantalla de 2560×1440, y flail mal en 4K. "Limitar" el juego a 1080p y dejar que el escalador de pantalla haga el trabajo pesado debería ayudar. Dependiendo de la naturaleza del juego, podría establecer la resolución incluso más baja sin pérdida aparente de calidad.

Otra cosa a intentar es eliminar la llamada de drawBitmap() , comprobar sus horarios, después restaurarla y eliminar la llamada de drawCircle() , para ver si uno o el otro está mascando para arriba la mayor parte del tiempo.

Puede que el cambio a OpenGL ES no sea tan malo. La actividad de "hardware scaler exerciser" en Grafika (del video adjunto) muestra un renderizado de mapa de bits simple. Reemplace drawCircle() con un mapa de bits a escala y es posible que la mayoría de la forma realizada. (Tenga en cuenta que utiliza SurfaceView, no GLSurfaceView, para GLES en esa actividad.)

Tuve el mismo problema. El problema se resolverá en gran medida si haces todo el dibujo en un framebuffer de mapa de bits y luego dibujar el framebuffer al lienzo. Si usted está dibujando directamente en el lienzo, entonces hay varios gastos generales. Miré alrededor y encontré este tutorial " http://www.kilobolt.com/day-6-the-android-game-framework-part-ii.html "

Mire la implementación de AndroidGraphics y AndroidFastRenderView y vea cómo usa AndroidGraphics para hacer todo el dibujo real en un búfer y pinta ese búfer al lienzo en AndroidFastRenderView.

Pruebe el rendimiento al quitar las partes rotación y / o drawCircle del método render (). Ambos pueden ser bastante tiempo como probablemente contienen sin () / cos () cálculos.

Si eso ayuda, usted tendrá que averiguar cómo reemplazarlos con algo más rápido, si no, bueno …

  • End SurfaceView y GameThread al salir de la aplicación
  • ¿Por qué el bucle de mi SurfaceView no funciona con un FPS decente?
  • Cómo reproducir varios archivos de video simultáneamente en un diseño lado a lado en diferentes vistas en Android
  • Dibujar SurfaceView desde el diseño xml
  • Vista superficial en capas en un FrameLayout en Android
  • Android SurfaceView no muestra onDraw
  • Android SurfaceView onDraw Pregunta
  • ¿Mejora el rendimiento de la vista personalizada SurfaceView-dervied?
  • Ajuste de una vista previa de la cámara a un SurfaceView más grande que la pantalla
  • Android dibuja usando SurfaceView y el hilo
  • Android SurfaceView causando parpadeo de la pantalla
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.