2010-03-24 22 views
9

En mi aplicación necesita algo así como un sistema de partículas, así que hizo lo siguiente:¿Cómo mostrar eficientemente muchas imágenes? (IPhone de programación)

Si bien la aplicación inicializa cargo un UIImage

laserImage = [UIImage imageNamed:@"laser.png"]; 

UIImage * laserImage se declara en la interfaz de mi controlador Ahora cada vez que necesita una nueva partícula este código hace que uno:

// add new Laserimage 
UIImageView *newLaser = [[UIImageView alloc] initWithImage:laserImage]; 
[newLaser setTag:[model.lasers count]-9]; 
[newLaser setBounds:CGRectMake(0, 0, 17, 1)]; 
[newLaser setOpaque:YES]; 
[self.view addSubview:newLaser]; 
[newLaser release]; 

Por favor, observe que las imágenes sólo son 17px * 1px pequeña y model.lasers es una matriz interna que hacer todo el cálculo de separado de la salida gráfica. Así que en mi bucle principal dibujo que puse todas las posiciones de la UIImageView a las posiciones calculadas en mi model.lasers matriz:

for (int i = 0; i < [model.lasers count]; i++) { 
    [[self.view viewWithTag:i+10] setCenter:[[model.lasers objectAtIndex:i] pos]]; 
} 

que incrementa las etiquetas en un 10 porque el valor predeterminado es 0 y no quiero mover todos las vistas con la etiqueta predeterminada.

Así que la animación se ve bien con alrededor de 10 - 20 imágenes, pero realmente se vuelve lenta cuando se trabaja con cerca de 60 imágenes. Entonces mi pregunta es: ¿hay alguna forma de optimizar esto sin comenzar de nuevo en OpenGl ES?

Respuesta

8

Como dijo jeff7 y FenderMostro, está utilizando la API de alto nivel (UIKit), y tendría un mejor rendimiento con las API más bajas, CoreAnimation u OpenGL. (Cocos2d se construye en la parte superior de OpenGL)

  • Su mejor opción sería utilizar CALayers en lugar de UIImageViews, conseguir un CGImageRef de su UIImage y configurarlo como el contenido de estas capas.

  • Además, es posible que desee mantener un grupo de CALayers y reutilizarlos ocultándolos/mostrándolos según sea necesario. 60 CALayers de 17 * 1 píxeles no es mucho, lo he estado haciendo con cientos de ellos sin necesitar una optimización adicional.

De esta manera, las imágenes ya estarán descomprimidas y disponibles en la memoria de video. Al usar UIKit, todo pasa por la CPU, sin mencionar la creación de UIViews, que son objetos bastante pesados.

+0

Esta es la respuesta correcta. Su código funcionará bien siempre y cuando use CALayers y tenga cada uno de ellos el mismo layer.contents configurado en la misma imagen CG. Volver a cablear toda su juego en OpenGL pueden ser excesivos, sólo tiene que no asignar toneladas de UIImageView, que es la raíz de su problema de implementación. ver http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CoreAnimation_guide/SettingUpLayerObjects/SettingUpLayerObjects.html#//apple_ref/doc/uid/TP40004514-CH13-SW12 – MoDJ

0

Recomiendo comenzar a utilizar OpenGL ES, existe un excelente marco llamado cocos2d for iPhone que puede hacer que este tipo de programación sea muy fácil y rápida. Desde un vistazo rápido a su código, sus rayos láser pueden ser remodelados como CCSprite, que es una manera fácil de mover imágenes alrededor de una escena, entre muchas otras cosas.

+0

Me tomó un vistazo rápido a cocos2d y parecía muy capaz pero casi terminado mi aplicación y una reescritura no sería más costará demasiado tiempo. ¿Tienes alguna otra idea? – Thomas

1

El UIImageView está hecho para mostrar imágenes individuales O múltiples. Entonces, en lugar de crear cada vez un UIImageView, deberías considerar crear una nueva imagen y agregarla al UIImageView.

Ver here.

+0

La documentación de Apple dice que UIImageView es para mostrar una sola imagen o animar una serie de imágenes. Como necesito que todas las imágenes se muestren a la vez, no puedo usar esta funcionalidad ... ¿Otras ideas? – Thomas

+0

ohh, lo siento Thomas, no sé por dónde proceder. Esperemos si hay otras respuestas de la comunidad. –

+0

Hola Thomas, el problema podría ser que no has borrado el contexto del dibujo. ¿Puedes verificarlo dos veces? –

3

Parece que estás tratando de codificar un juego utilizando la API de UIKit, que no es muy adecuada para este tipo de propósitos. Está gastando los recursos del dispositivo cada vez que asigna un UIView, que incurre en ralentizaciones porque la creación de objetos es costosa. Sin embargo, es posible que puedas obtener el rendimiento que deseas si bajas a CoreAnimation, que es realmente bueno para dibujar cientos de imágenes en un marco de tiempo limitado, aunque sería mucho mejor si utilizas OpenGL o un motor como Cocos2d.

Cuestiones relacionadas