Я нахожусь на Yosemite 10.10.5 и Xcode 7, используя Swift, чтобы сделать игру с таргетингом на iOS 8 и выше.
РЕДАКТИРОВАТЬ: Более подробная информация, которая может быть полезна: это 2D-игра-головоломка/аркада, в которой игрок перемещает камни, чтобы соответствовать им. 3D-рендеринга вообще нет. Рисование уже слишком медленное, и я еще не дошел до взрывов с мусором. Существует также уровень затухания, очень важный. Но это все на симуляторе. У меня пока нет реального iPhone для тестирования, и я уверен, что фактическое устройство будет, по крайней мере, немного быстрее.
У меня есть собственный Draw2D-класс, который является типом UIView, настроенным как этот учебник. У меня есть один NSTimer, который инициирует следующую цепочку вызовов в Draw2D:
[setNeedsDisplay]; // which calls drawRect, which is the master draw function of Draw2D
drawRect(rect: CGRect)
{
scr_step(); // the master update function, which loops thru all objects and calls their individual update functions. I put it here so that updating and drawing are always in sync
CNT = UIGraphicsGetCurrentContext(); // get the curret drawing context
switch (Realm) // based on what realm im in, call the draw function for that realm
{
case rlm.intro: scr_draw_intro();
case rlm.mm: scr_draw_mm();
case rlm.level: scr_draw_level(); // this in particular loops thru all objects and calls their individual draw functions
default: return;
}
var i = AARR.count - 1; // loop thru my own animation objects and draw them too, note it iterating backwards because sometimes they destroy themselves
while (i >= 0)
{
let A = AARR[i];
A.scr_draw();
i -= 1;
}
}
И весь рисунок работает нормально, но медленно.
Проблема в том, что я хочу оптимизировать чертеж. Я хочу рисовать только в грязных прямоугольниках, требующих рисования, не весь экран, что и делает setNeedsDisplay
.
Я не мог найти для этого учебники или хороший пример кода. Самое близкое, что я нашел, это документация с документацией здесь, но она не объясняет, среди прочего, как получить список всех грязных прямоугольников. Он также явно не указывает , если список грязных прямоугольников автоматически очищается в конце каждого вызова drawRect?
Он также не объясняет, нужно ли вручную обрезать весь рисунок на основе прямоугольников. Я нашел противоречивую информацию об этом в Интернете, по-видимому, разные версии iOS делают это по-другому. В частности, если я собираюсь вручную закрепить вещи, я не вижу в первую очередь сути функции ядра яблока. Я мог бы просто сохранить свой собственный список прямоугольников и вручную сравнить каждый прямоугольник назначения чертежа с грязным прямоугольником, чтобы увидеть, нужно ли рисовать что угодно. Это было бы огромной болью, однако, потому что у меня есть фоновое изображение на каждом уровне, и я бы нарисовал часть его за каждым движущимся объектом. На самом деле я надеюсь, что это правильный способ использования setNeedsDisplayInRect, чтобы позволить основной структуре делать автоматическое отсечение для всего, что нарисовано в следующем цикле рисования, так что оно автоматически рисует только ту часть фон плюс движущийся объект сверху.
Итак, я попробовал несколько экспериментов: сначала в моем массиве камней:
func scr_draw_stone()
{
// the following 3 lines are new, I added them to try to draw in only dirty rectangles
if (xvp != xv || yvp != yv) // if the stone coordinates have changed from its previous coordinates
{
MyD.setNeedsDisplayInRect(CGRectMake(x, y, MyD.swc, MyD.shc)); // MyD.swc is Draw2D current square width in points, maintained to softcode things for different screen sizes.
}
MyD.img_stone?.drawInRect(CGRectMake(x, y, MyD.swc, MyD.shc)); // draw the plain stone
img?.drawInRect(CGRectMake(x, y, MyD.swc, MyD.shc)); // draw the stone icon
}
Это ничего не меняет. Все делалось так же медленно, как раньше. Итак, я положил его в скобки:
[MyD.setNeedsDisplayInRect(CGRectMake(x, y, MyD.swc, MyD.shc))];
Я понятия не имею, что делают скобки, но мой оригинальный setNeedsDisplay был в скобках точно так же, как они сказали сделать в учебнике. Поэтому я попробовал это в своем каменном объекте, но это тоже не повлияло.
Итак, что мне нужно сделать для правильной работы setNeedsDisplayInRect?
Прямо сейчас, я подозреваю, что мне нужна специальная проверка в моей мастер-схеме, например:
if (ListOfDirtyRectangles.count == 0)
{
[setNeedsDisplay]; // just redraw the whole view
}
else
{
[setNeedsDisplayInRect(ListOfDirtyRecangles)];
}
Однако я не знаю названия встроенного списка грязных прямоугольников. Я нашел этот, указав, что имя метода getRectsBeingDrawn
, но это для Mac OSX. Он не существует в iOS.
Может ли кто-нибудь помочь мне? Я на правильном пути с этим? Я до сих пор довольно новичок в Mac и iOS.