Как эффективно показать много изображений? (программирование iPhone) - PullRequest
9 голосов
/ 24 марта 2010

В моем приложении мне нужно было что-то вроде системы частиц, поэтому я сделал следующее:

Пока приложение инициализируется, я загружаю UIImage

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

UIImage * laserImage объявляется в интерфейсе моего контроллера. Теперь каждый раз, когда мне нужна новая частица, этот код создает:

// 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];

Обратите внимание, что изображения имеют размер только 17px * 1px, а model.lasers - это внутренний массив для выполнения всех расчетов, отделенных от графического вывода. Поэтому в моем основном цикле рисования я установил все позиции UIImageView в вычисленные позиции в моем массиве model.lasers:

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

Я увеличил теги на 10, потому что по умолчанию это 0, и я не хочу перемещать все представления с тегом по умолчанию.

Таким образом, анимация выглядит хорошо с примерно 10 - 20 изображениями, но на самом деле становится медленной при работе с примерно 60 изображениями. Итак, мой вопрос: есть ли способ оптимизировать это без перезапуска в OpenGl ES?

Ответы [ 4 ]

8 голосов
/ 06 апреля 2010

Как сказали jeff7 и FenderMostro, вы используете высокоуровневый API (UIKit), и у вас будет лучшая производительность при использовании более низких API, CoreAnimation или OpenGL. (cocos2d построен поверх OpenGL)

  • Лучшим вариантом будет использование CALayers вместо UIImageViews, получение CGImageRef из вашего UIImage и установка его в качестве содержимого для этих слоев.

  • Кроме того, вы можете сохранить пул CALayers и повторно использовать их, скрывая / отображая по мере необходимости. 60 CALayers 17 * 1 пикселей не много, я делал это с сотнями из них без дополнительной оптимизации.

Таким образом, изображения уже будут распакованы и доступны в видеопамяти. При использовании UIKit все проходит через ЦП, не говоря уже о создании UIViews, которые являются довольно тяжелыми объектами.

3 голосов
/ 30 марта 2010

Похоже, вы пытаетесь закодировать игру с помощью UIKit API, который на самом деле не очень подходит для такого рода целей. Вы тратите ресурсы устройства всякий раз, когда выделяете UIView, что приводит к замедлению, потому что создание объекта стоит дорого. Вы можете получить желаемую производительность, перейдя в CoreAnimation, которая действительно хороша для рисования сотен изображений за ограниченный промежуток времени, хотя было бы намного лучше, если бы вы использовали OpenGL или движок, такой как Cocos2d. *

1 голос
/ 24 марта 2010

UIImageView предназначен для отображения одного или нескольких изображений. Таким образом, вместо того, чтобы каждый раз создавать UIImageView, вам следует подумать о создании нового изображения и вместо этого добавить его в UIImageView.

См. здесь .

0 голосов
/ 24 марта 2010

Я бы рекомендовал начать заново с использованием OpenGL ES, есть отличная платформа под названием cocos2d для iPhone , которая может сделать этот тип программирования очень простым и быстрым. При быстром взгляде на ваш код, ваши лазеры могут быть переоборудованы в CCSprite, что является простым способом перемещения изображений по сцене среди многих других вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...