2015-10-14 3 views
7

В iOS 9 Apple представила collisionBoundsType до UIKit-Dynamics.Настройка ограничительного пути UIView в iOS 9

У меня нет проблем при установке этого UIDynamicItemCollisionBoundsTypeRectangle или когда я устанавливаю его на UIDynamicItemCollisionBoundsTypeEllipse.

скриншот ниже от игры я делаю, где collisionBoundsType игрока установлен в прямоугольник, и мяч устанавливается на эллипсу:

enter image description here

Однако, когда я установил игрока collisionBoundsType к путь я получаю странное поведение, как показано здесь:

enter image description here

мнение оказывается выше, чем это необходимо, и тело столкновения вправо где это должно быть.

В настоящее время у меня есть collisionBoundingPath набор для этого:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

Кроме того, моя функция DrawRect выглядит следующим образом:

- (void) drawRect:(CGRect)rect 
{ 
    if (!_color){ 
    [self returnDefualtColor]; 
    } 
    if (!maskPath) maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    [_color setFill]; 
    [maskPath fill]; 
} 

Почему это происходит? Как установить путь тела столкновения таким же, как рисунок в представлении?

Кроме того, красный цвет является только фоном вида (то есть view.backgroundColor = [UIColor redColor];).

+0

Не специалист по рисованию, но в документации предполагается, что путь должен быть многоугольником.Ваш код добавляет дугу, но не закрывает путь. Возможно, вы должны вызвать '[maskPath closePath]' для создания закрытого пути, который может иметь значение? –

+0

Он автоматически закрывается – WMios

+0

Для заполнения 'drawRect' это будет так. Вы уверены в своей 'collisionBoundingPath'? Где он говорит в документах, что он закрывает путь? –

ответ

2

Из документации на UIDynamicItem here следующее утверждение о системе координат для путей, кажется, представляют собой то, что это не так:

Объект путь создания должен представлять собой выпуклый многоугольник с счетчиком по часовой стрелке или по часовой стрелке, а путь не должен пересекаться. Точка (0, 0) пути должна быть расположена в центральной точке соответствующего динамического элемента. Если центральная точка не соответствует началу пути, поведение столкновений может не работать как ожидается .

Здесь указывается, что (0,0) для пути ДОЛЖЕН быть центральной точкой.

Я думаю, что центр вашей дуги должен быть (0,0), а не (SLIME_SIZE/2,SLIME_SIZE/2). Возможно, вы установили ширину и высоту кадра UIView для SLIME_SIZE, а не SLIME_SIZE*2?

SLIME_SIZE действительно определяет радиус, поэтому ширина рамки должна быть SLIME_SIZE*2. Если он установлен как SLIME_SIZE, то это объясняет, почему вам нужно перевести на SLIME_SIZE/2 в качестве коррекции.

+0

Отличный ответ, это действительно объясняло причины, почему мое исправление работало. – WMios

1

Я был в состоянии ответить на этот вопрос путем изменения:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

к:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE/2, SLIME_SIZE/2) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

Основное различие заключается в том, что я изменил центр дуги путем деления х и у значения на 2 .

1

Отладка физики - это вещь. Вероятно, это не то, что пользователи iOS, как правило, много думают, поскольку они обычно делали очень простые вещи с помощью UIKit Dynamics. Это немного позор, так как это один из лучших аспектов последних выпусков iOS, и он предлагает действительно интересный способ сделать впечатляющий опыт пользователей.

Итак ... как отлаживать физику?

Один из способов - мысленно представить, что происходит, а затем сопоставить это с тем, что происходит, и найти диссонанс между воображаемым и реальным, а затем решить проблему посредством сочетания процессов устранения, умственного или реального испытания & ошибки и дедукции, пока проблема не будет определена и решена.

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

С этой целью с момента их создания были созданы различные визуальные отладчики и строители физического моделирования.

К сожалению, у iOS нет такого редактора на основе экрана или «редактора сцен» для UIKit Dynamics, и то, что доступно для такого рода визуальной отладки в наборе спрайтов и наборе сцен, в лучшем случае является рудиментарным.

Однако существуют CALayers, которые присутствуют во всех UIKit Views, в которые CAShapeLayers могут быть созданы вручную и нарисованы для точного представления любых физических элементов, их границ и их привязок и отношений.

CAShapeLayers - это «контейнер» для CGPaths и может иметь разные цвета для контура и заливки и более одного элемента CGPath в пределах одного CAShapeLayer.

И процитировать великого Rob:.

«Если добавить CAShapeLayer в качестве слоя в целях, вы не должны реализовать любой рисунок кода самостоятельно Просто добавьте CAShapeLayer и вы, возможно, позже можете изменить путь, например, и будет автоматически перерисовывать его для вас. CAShapeLayer вытащит вас из сорняков , написав собственные процедуры drawRect или drawLayer ».

Если у вас есть огромное количество взаимодействующих элементов и хотят их отладку, вопросы производительности CAShapeLayer в могут вступить в игру, в какой момент вы можете использовать shouldRasterize для преобразования каждого в растровое изображение, и получить значительное улучшение производительности при достигнув ограничений, созданных «динамическими» возможностями CAShapeLayers.

Кроме того, для представления таких вещей, как ограничения и суставы, простой процесс создания пунктирных линий на CAShapeLayers путем простого задания свойств. Вот основные принципы настройки свойств CAShapeLayer и способ использования массива для создания 5-5-5 пунктирных контуров с шагом блока, шириной 3, без заполнения.

CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
[shapeLayer setBounds:self.bounds]; 
[shapeLayer setPosition:self.center]; 
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setLineWidth:3.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setLineDashPattern: 
[NSArray arrayWithObjects:[NSNumber numberWithInt:10], 
    [NSNumber numberWithInt:5],nil]];