в моей (головоломке) игре части нарисованы на экране, используя 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
.
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
. Вздох. Я думаю, я открою это отдельным вопросом.