Un método más eficiente de dibujar miles de partículas (Java / Android)

Así que estoy escribiendo una especie de simulador de partículas, como un "juego de arena que cae" si sabes lo que es, y ahora he llegado a un obstáculo. La forma en que estoy haciendo esto es que tengo un objeto de partículas que, básicamente, a partir de ahora tiene una posición (int x, int y) y eso es todo. La forma en que estoy dibujar / moverlos, es con un hilo y el evento onDraw para un panel de android. Cada vez que se llama onDraw, hago un bucle a través de todas las partículas, las mueves hacia abajo un píxel a menos que golpeen el fondo y luego las dibuje, esto es bastante suave hasta llegar a unas 200 partículas, entonces el fps cae significativamente. Sé que esto es computación pesada de la manera que lo estoy haciendo, no hay ningún debate sobre ello, pero ¿hay alguna manera de hacer esto para permitir que se extraigan más partículas y con menos retraso?

Gracias por adelantado.

Supongo que está usando una función de dibujo de píxeles individuales para esto? Eso sería realmente lento.

Veo un par de maneras de mejorarlo. En primer lugar es poner los píxeles en un mapa de bits en memoria y luego dibujar el mapa de bits completo al mismo tiempo. En segundo lugar, ya que las partículas siempre están bajando un píxel, puede desplazarse parte del mapa de bits en lugar de replotar todo. Si Android no tiene un desplazamiento, simplemente dibuje el mapa de bits un píxel hacia abajo e inicie un nuevo mapa de bits para las partículas por encima del rollo. Tendrás que arreglar las partículas en la parte inferior, pero hay menos de ellas.

Nunca he hecho cosas como esta antes, pero he hecho algunos complejos de autómatas celulares . Lo siento si esto es demasiado vago.

La idea básica aquí es marcar todas las partículas que deben "seguir cayendo" o "no moverse" y excluirlos del procesamiento complejo (con un procesador especial corto / rápido para la lista "caída" – todo lo que necesita hacer es dejar caer cada uno Por un píxel).

  • La aceleración de las partículas que no se mueven – partículas estáticas (las llamaré partículas S), es que no se mueven. Marcarlo para todas las regiones que no se mueven (como una "pared" o "tazón" inmune a la gravedad que un usuario puede hacer Marca las partículas por encima de ella S si son estables, por ejemplo, para líquido, si tiene partículas S debajo, Y para ambos lados de sí misma, no se moverá.Para algo como la arena que forma pilas, si tiene un S en cada uno de los tres puntos debajo de él , que hace una pila, obtendrá agradable 45 grados pilas como este , Estoy seguro de que puede cambiarlo para que algunas cosas formen empinadas, o empalmes menos empinados. Do S mapping bottom-up.
  • La aceleración de partículas sin partículas debajo de ellas está disminuyendo – F partículas. Las partículas con una partícula F debajo de ellas son también partículas F. Marcar estos bottom-up también.
  • Las partículas sin marcar F o S son complejas , pueden empezar a caer, dejar de caer o rodar, utilizar el procesador lento, que ya tiene, para hacer frente a ellos, no debe haber muchos.

En el extremo lo que usted tendrá es muchas muchas partículas rápidas. Aquellos en una pila / lago y los que llueven. Las partículas sobrantes son las del borde de las laderas, en la parte superior de los lagos, o en otras posiciones complejas. No debería haber casi tantos como habrá partículas rápidas.

Marque visualmente cada tipo de partícula con un cierto color, partículas complejas que son rojo brillante. Encuentre los casos en los que sigue siendo lento, y vea qué otros tipos de procesadores rápidos debe hacer. Por ejemplo, puede encontrar que hacer un montón de montones de arena crea un montón de zonas rojas a lo largo de las laderas, es posible que desee invertir en la aceleración de "zonas de rodadura" a lo largo de las laderas de las pilas.

Espero que tenga sentido. No te olvides de volver y editar una vez que has calculado algo!

Es posible que desee examinar la aceleración de hardware de OpenGL ES y renderscript . No le da una solución más eficiente código sabio (ver las otras respuestas para eso). Se abre mucho más poder de procesamiento para que usted pueda utilizar sin embargo. Incluso puede ejecutar toda la simulación en la GPU (posiblemente, no conozca los detalles de implementación).

Editar
Además, si todavía decide realizar el procesamiento en java, debe consultar el perfil de métodos en DDMS . Esto le ayudará a visualizar dónde están sus cuellos de botella de rendimiento.

Si borras tu imagen un poco, entonces podrías mover la mitad de las partículas a la vez, tal vez sólo una cuarta parte e imprimirlas todas. Eso cortaría el cálculo y el usuario no lo vería, consiguiendo la sensación de que todas las partículas se mueven.

Pero lo que usted elija, creo que se debe poner un límite fuerte, no todos los usuarios tienen poderosos dispositivos Android.

Saludos, Stéphane

Creo que si las partículas están cerca uno del otro, puede crear objetos que representan 3 o más partículas.

Al exhibir varias partículas en la pantalla, los sistemas de granos pueden pasar inadvertidos.

  • Optimización: Acceso a campos y métodos
  • ¿Canvas.getClipBounds asigna un objeto Rect?
  • Ajustes de optimización de Proguard: Habilitar la combinación de clases, los modelos y el campo / * en versiones modernas de API y Proguard
  • Cómo reducir el tiempo de arranque en los sistemas operativos de Android.
  • Acelerando las operaciones de punto flotante (Android ARMv6)
  • Cómo optimizar las aplicaciones de Android para varios núcleos
  • Picasso "Cambiar tamaño y centerCrop" o ImageView "centerCrop"?
  • Creación de perfiles y optimización de un juego Android
  • ¿Algún consejo sobre cómo acelerar esto en Android?
  • Optimización del compilador de código Java en Android
  • Bucle eficiente a través de la lista de Java
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.