Базовая анимация с содержимым - PullRequest
2 голосов
/ 28 мая 2009

в моей (головоломке) игре части нарисованы на экране, используя CALayer для каждой части. Есть 48 частей (в сетке 8x6), каждый из которых 48x48 пикселей. Я не уверен, что это слишком много слоев, но если это не лучшее решение, я не знаю, что именно, потому что перерисовка всего дисплея с использованием Quartz2D, каждый кадр не выглядит так, как будто это будет быстрее.

В любом случае, изображения для кусочков приходят из одного большого файла PNG, который имеет 24 кадра анимации для 10 различных состояний (таким образом, имеет размер 1152 x 480 пикселей), и анимация выполняется путем установки свойства contentsRect каждого * 1005. * как я двигаю это.

На самом деле, кажется, что это работает довольно хорошо: до 7 частей отслеживают точку касания в окне, но странная вещь в том, что когда я первоначально начинаю перемещать части, в течение первых 0,5 секунды или около того, это очень резко процессор делает что-то еще, но после этого он будет отслеживать и обновлять экран со скоростью 40+ FPS (в соответствии с инструментами).

Так есть ли у кого-нибудь идеи, что может объяснить эту начальную вялость?

Единственная теория, которую я мог придумать, - это распаковывать биты файла PNG во временную папку и затем отбрасывать их после остановки анимации. В таком случае есть ли способ остановить Core Animation, выполняющую это?

Я, очевидно, мог бы разбить файл PNG на 10 частей, но я не уверен, что это поможет, поскольку все они (потенциально) все еще должны быть в памяти сразу.

РЕДАКТИРОВАТЬ: ОК, как описано в комментарии к первому ответу, я разделил изображение на десять частей, которые теперь имеют размер 576 x 96, чтобы соответствовать ограничениям аппаратное обеспечение. Это все еще не так гладко, как должно быть, поэтому я положил награду за это.

EDIT2: Я связал одно из изображений ниже. По сути, отслеживается касание пользователя, вычисляется смещение от начала отслеживания (они могут перемещаться по горизонтали или вертикали и только в одно место за раз). Затем в качестве содержимого слоя выбирается одно из изображений (в зависимости от того, к какому типу элемента он относится и движется ли он горизонтально или вертикально). Затем для свойства contentsRect выбирается один кадр 48x48 из более крупного изображения с чем-то вроде этого: -

layer.position = newPos;
layer.contents = (id)BallImg[imgNum];
layer.contentsRect = CGRectMake((1.0/12.0)*(float)(frame % 12), 
                                0.5 * (float)(frame / 12), 
                                1.0/12.0, 0.5); 

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

Следующая вещь, которую я попробую, - это скопировать каждый кадр в отдельный CGImage, что избавит, по крайней мере, от уродливого вычисления contentsRect.

Sample image

EDIT3: Дальнейшие исследования показывают, что это проблема отслеживания касаний, а не Core Core Animation. Я нашел базовый пример приложения, которое отслеживает прикосновения и закомментировал код, который фактически вызывает перерисовку экрана, и NSLog() показывает точно такую ​​же проблему, с которой я столкнулся: длительная задержка между touchesBegin и первым touchesMoved событий.

2009-06-05 01:22:37.209 TouchDemo[234:207] Begin Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.432 TouchDemo[234:207] Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.448 TouchDemo[234:207] Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.464 TouchDemo[234:207] Touch ID 0 Tracking with image 2
2009-06-05 01:22:37.480 TouchDemo[234:207] Touch ID 0 Tracking with image 2

Типичный интервал между touchesMoved событиями составляет 20 мс. Разрыв между touchesBegin и первым touchesMoved в десять раз больше. И это без каких-либо вычислений или обновления экрана вообще, только вызов NSLog. Вздох. Я думаю, я открою это отдельным вопросом.

Ответы [ 3 ]

3 голосов
/ 28 мая 2009

Я не думаю, что это проблема с памятью; Я думаю, что это связано с неэффективностью наличия такого большого изображения с точки зрения базовой анимации.

Core Animation не может использовать его изначально, так как он превышает максимальный размер текстуры на графическом процессоре (1024x1024). Я бы разбил его немного ; отдельные изображения могут дать вам лучшую производительность, но вам придется проверить, чтобы выяснить.

IIRC, UIImageView выполняет анимацию, устанавливая последовательные отдельные изображения, поэтому, если этого достаточно для Apple….

1 голос
/ 04 июня 2009

Когда речь идет о производительности, я определенно рекомендую использовать Shark (также поверх Instruments). В «Time Profile» вы можете увидеть узкие места в вашем приложении, даже если это что-то в коде Apple. Я много использовал его при разработке приложения для iPhone, которое использует OpenGL и Core Animation.

0 голосов
/ 03 июня 2009

Вы уже пробовали использовать CATiledLayer?

Оптимизирован для этого вида работ.

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