|
Май
24
|
Правильный выбор анимации/трансформации — ключ к повышению уровня приложения и один из важнейших аспектов при разработке игр.
На выбор предлагается три базовых типа трансформации, которые можно задействовать или изобрести собственные. Вот они:
- вращение;
- масштабирование;
- сдвиг;

Анимация применима практически ко всему — изображениям (”UIImageView“), кнопкам (”UIButton“), панелям инструментов, меткам, представлениям…
Вращение.
Предположим, имеется изображение (”UIImageView *myImage“) и желание что-то с ним сделать. Для вращения на 45 градусов вправо введите:
1 | myImage.transform = CGAffineTransformMakeRotation(M_PI*0.25); |
Ниже приведен список типовых величин с соответствующими значениями в градусах:
- M_PI * 0.00 = 0° (исходное состояние)
- M_PI * 0.25 = 45°
- M_PI * 0.50 = 90°
- M_PI * 0.75 = 135°
- M_PI * 1.00 = 180°
- M_PI * -0.75 = 225°
- M_PI * -0.50 = 270°
- M_PI * -0.25 = 315°
Если необходимо значение в градусах вместо интервала <-1 ; 1>, умноженного на M_PI, задайте постоянное значение в заголовочном файле класса: “#define radianConst M_PI/180.0” (прямо под строками “#import“). Чтобы повернуть изображение на 63 градуса, ориентируйтесь на приведенный ниже код:
1 | myImage.transform = CGAffineTransformMakeRotation(63.0*radianConst); |
Масштабирование.
При масштабировании, изображение увеличивается/уменьшается. Можно сделать изменение непропорциональным, задав разные параметры для высоты и ширины. Чтобы изображение стало в 2 раза шире в 1,5 раза выше, воспользуйтесь следующим кодом:
1 | myImage.transform = CGAffineTransformMakeScale(2.0,1.5); |
Не удивляйтесь, если в результате картинка “побьется” отдельными пикселями. Для таких операций необходимы исходники высокого разрешения, которые делаются меньше при загрузке (например, “CGAffineTransformMakeScale(0.5,0.5)“), а потом при необходимости отображаются в оригинале посредством “CGAffineTransformMakeScale(1.0,1.0)“.
У масштабирования есть еще одна интересная возможность. Если в качестве параметров задать отрицательные значения, изображение после трансформации перевернется горизонтально или вертикально. Примеры:
- CGAffineTransformMakeScale(-1.0,2.0) — изображение переворачивается горизонтально и становится в два раза выше
- CGAffineTransformMakeScale(1.5,-3.0) — изображение в 1,5 раза шире, в 3 раза выше и перевернуто вертикально
- CGAffineTransformMakeScale(-2.0,-2.0) — изображение в два раза больше, перевернуто по горизонтали и вертикали
Сдвиг.
Эффект при сдвиге практически аналогичен смене значения для центра объекта — изображение перемещается вдоль осей X и Y. Возможности здесь крайне скудны, поэтому ограничусь одним примером:
- CGAffineTransformMakeTranslation(50.0,20.0) — изображение сместилось на 50 пикселей вправо и на 20 вниз
Такой же результат, как уже упоминалось выше, даст корректировка значения “centre” — “myImage.center = CGPointMake(140.0,90.0)“. У каждого из способов свои преимущества и недостатки, но мы переходим к более интересным моментам.
Анимация.
Вы уже знаете, как повернуть изображение (или любой другой элемент), задав угол, масштаб, поворот или перемещение. А как насчет плавной анимации? Все достаточно просто:
1 2 3 4 5 6 | UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:1.5]; // здесь другая анимация myImage.transform = CGAffineTransformMakeRotation(M_PI*0.5); // здесь другая анимация [UIView commitAnimations]; |
Приведенный ниже код плавно повернет объект на 45 градусов за 1,5 секунды. Обратите внимание: параллельно с анимацией приложение выполняет следующие задачи, не дожидаясь окончания процесса. Чтобы последующие действия происходили только по окончании анимации, воспользуйтесь “NSTimer“:
1 | [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(nextMethodName) userInfo:nil repeats:NO]; |
или дополните код анимации делегатом и селектором:
1 2 3 4 5 6 7 | [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:1.5]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(nextMethodName)]; myImage.transform = CGAffineTransformMakeRotation(M_PI*0.5); // здесь другая анимация [UIView commitAnimations]; |
Второй пример значительно эффективнее, но в таком случае метод “nextMethodName” (в зависимости от присвоенного имени) должен возвращать “boolean YES” вместо “void“, вообще не возвращающего значений. Пример:
1 2 3 4 5 | -(BOOL)nextMethodName { // некие задачи return YES; } |
Анимация отлично подходит для переходов между двумя представлениями, но об этом в другой раз.
Две трансформации за раз.
Любая из описанных выше трансформаций редактирует только одно свойство конкретного объекта — “transform“. Так, например, приведенный ниже код поворачивает изображение на 180 градусов без масштабирования — оно отменяется после вращения.
1 2 | myImage.transform = CGAffineTransformMakeScale(2.0,1.5); myImage.transform = CGAffineTransformMakeRotation(M_PI*1.0); |
Чтобы объединить две трансформации, воспользуйтесь приведенным ниже кодом:
1 | animateLabel.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(2.0, 1.5), CGAffineTransformMakeRotation(M_PI*1.0)); |
Лично мне такой подход не по душе. На уроках математики мне никогда не нравились матрицы. Любая трансформация создает матрицу, а “CGAffineTransformConcat” их перемножает — для поддержания порядка. Для объединения трех трансформаций придется использовать “CGAffineTransformConcat” со слиянием двух трансформаций в аргумент перед объединением с третьей. Звучит запутанно? Согласны?
Исходное состояние.
В заключение приведу простой способ отмены любых трансформаций с помощью “CGAffineTransformIdentity” в качестве свойства “transform” для любого объекта.
1 | myImage.transform = CGAffineTransformIdentity; |
Думаю, на этот раз информации об анимации и трансформациях достаточно. При желании загрузите проект, где можно вращать, масштабировать, смещать объекты при помощи бегунков, наблюдая за плавной трансформацией.


Октябрь 10th, 2011 at 09:53
Хороший урок, выглядит почти так же просто, как и в cocos 2D, приду домой, попробую.
Март 22nd, 2012 at 12:40
Спасибо - помогло