Могу ли я ускорить использование Core Graphics для рисования движущихся треугольников каждые 1/10 секунды?

Я недавно добавил в свое приложение несколько элементов Core Graphics, и оно резко замедлилось, сделав его практически бесполезным. Я не уверен, что я просто не использую Core Graphics эффективно (как мне сделать это быстрее?) Или эта проблема связана с использованием Core Graphics. Мой код ниже, после этого описания:

По экрану движутся пузыри речи (по осям x и y). У каждого пузыря есть соответствующее изображение внизу экрана, которое также перемещается по осям x и y. Я использую Core Graphics, чтобы нарисовать треугольник из пузырей речи, заканчивающийся нижними изображениями. На экране одновременно может быть более 10 таких треугольников, и все они движутся. Каждую 1/10 секунды срабатывает таймер, вычисляет положение всего и вызывает setNeedsDisplay в построенном мною треугольном объекте.

Код для объекта треугольник:

- (void)drawRect:(CGRect)rect {
    // Drawing code
 // Drawing code
 CGContextRef ctx = UIGraphicsGetCurrentContext(); //get the graphics context
 CGContextSetRGBStrokeColor(ctx, 1.0, 0, 0, 1); //there are two relevant color states, "Stroke" -- used in Stroke drawing functions and "Fill" - used in fill drawing functions

 //Create an array of points for triangle  
 CGPoint leftTrianglePoint;
 CGPoint rightTrianglePoint;
 rightTrianglePoint = CGPointMake(pointBlob.x, (pointBlob.y + 10.0));
 leftTrianglePoint = CGPointMake(pointBlob.x, (pointBlob.y - 10.0));

 CGPoint triangleArray [] =
 {
  pointGrid,
  rightTrianglePoint,
  leftTrianglePoint,
 pointGrid,};

 //Add lines to the context
 CGContextAddLines( ctx, triangleArray, 4);
 //draw the path

 //color the context - using a function for gray, to matche the saved blobs
 CGContextSetGrayFillColor(ctx, 0.0, .7);

 //Now fill the path 
 CGContextFillPath(ctx);
}

Как я могу ускорить это / повысить эффективность, чтобы моя графика снова двигалась плавно?


person KLC    schedule 29.01.2010    source источник


Ответы (3)


Ненавижу это говорить, но откажитесь от Core Graphics и сделайте это с помощью OpenGL. OpenGL любит треугольники. На большой скорости он будет мигать тысячами в секунду. Многие думают, что OpenGL предназначен только для работы с 3D, но то, что вы делаете в 2D, также отлично с ним работает.

person Stefan Arentz    schedule 29.01.2010
comment
Фу. Ваш ответ пугающий, хотя он совпадает с некоторыми другими найденными мною ресурсами. Спасибо за быстрый ответ (даже если это не та волшебная таблетка, которую я хотел) - person KLC; 29.01.2010
comment
Это не так уж и сложно. Учебники Google для OpenGL 2D для iPhone. Есть много хороших. Извините, у меня нет ссылки под рукой. - person Stefan Arentz; 29.01.2010

Как предлагает Кендалл, если вам просто нужно переместить треугольники, нарисуйте их один раз в UIView или CALayer и анимируйте положения и / или вращения этих элементов. Перерисовка треугольников в каждом кадре с использованием Core Graphics будет ужасно медленной, потому что для этого потребуется обновлять слой или слой представления каждый раз, когда вы рисуете.

Однако похоже, что вам нужно оживить фактическую форму треугольника. Для этого я рекомендую взглянуть на недавно добавленный (в iPhone OS 3.0 и Snow Leopard) класс CAShapeLayer. Вы можете задать путь (с заливкой и обводкой), который будет рисоваться этим слоем, а затем плавно анимировать его на другой путь (с тем же количеством контрольных точек) с помощью CABasicAnimation. Примеры этого приведены здесь и здесь.

person Brad Larson    schedule 29.01.2010
comment
Спасибо, Брэд. Это то, что я начал делать, пытаясь избежать добавления OpenGL в нашу архитектуру - теперь у меня небольшие трудности с CABasicAnimation. См. Здесь: stackoverflow.com/questions/2233601/ - person KLC; 10.02.2010

Если вы хотите упростить порт OpenGL, попробуйте использовать библиотеку OpenGL, например Cocos2D.

Однако мне кажется, что вы могли бы значительно ускорить свой код, нарисовав отдельные CALayers только один раз и просто перемещая их (поскольку все ваши треугольники кажутся фиксированными по размеру, просто меняясь по размещению). Я очень рекомендую вам заглянуть в книгу Core Graphics.

person Kendall Helmstetter Gelner    schedule 29.01.2010
comment
Таким образом, треугольники не имеют фиксированного размера - я должен был прояснить это - pointGrid, leftTrianglePoint и rightTrianglePoint всегда постоянно меняются. Размер и углы всегда меняются - person KLC; 29.01.2010
comment
Еще одна вещь, о которой нужно подумать, - у вас есть десять разных UIView с drawRect? Если бы вы могли рисовать их все в одном представлении, это было бы более эффективно. Просто не похоже, что это слишком много для рисования. Кроме того, вы уверены, что ваше время срабатывает только раз в 1/10 секунды, а не намного чаще ... - person Kendall Helmstetter Gelner; 29.01.2010