[英]Setting collision bounding path of a UIView in iOS 9
在iOS 9中,Apple将collisionBoundsType
引入了UIKit-Dynamics
。
设置此UIDynamicItemCollisionBoundsTypeRectangle
或将其设置为UIDynamicItemCollisionBoundsTypeEllipse
时,我没有任何问题。
下面的截图来自我正在制作的游戏,其中玩家的collisionBoundsType
设置为矩形,并且球被设置为椭圆:
但是,当我将玩家的collisionBoundsType
设置为路径时,我会看到奇怪的行为,如下所示:
视图看起来比它应该高,碰撞体位于它应该的位置。
目前我将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];
)。
从这里的UIDynamicItem文档中,以下关于路径坐标系的声明似乎代表了错误:
您创建的路径对象必须表示逆时针或顺时针缠绕的凸多边形,并且路径不得与自身相交。 路径的(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
为校正。
我能够通过改变来回答这个问题:
- (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;
}
关键的区别在于我通过将x和y值除以2来修改弧的中心。
调试物理是一件事。 这可能不是iOS用户倾向于想的很多,因为他们通常使用UIKit Dynamics做了非常简单的事情。 这有点令人遗憾,因为它是最近版本iOS的最佳方面之一,并提供了一种真正有趣的方式来提供引人注目的用户体验。
那么...如何调试物理?
一种方法是在心理上想象正在发生的事情,然后将其与发生的事情联系起来,找到想象与真实之间的不和谐,然后通过消除,精神或真实的试验和错误以及演绎过程的混合来解决问题,直到问题得到确定和解决。
另一种方法是对所有创建和交互的视觉描述提供足够的反馈,以更快地确定元素的性质和范围,它们的关系和事件/事件,并用字面视觉解决问题。
为此,自引入以来,已经创建了各种视觉调试器和物理模拟的构建器。
不幸的是,iOS没有为UIKit Dynamics提供这样的基于屏幕的编辑器或“场景编辑器”,并且Sprite Kit和Scene Kit中可用于此类可视化调试的内容至多是基本的。
然而,所有UIKit视图中都存在CALayers,可以手动创建和绘制CAShapeLayers,以准确地表示任何和所有物理元素,它们的边界以及它们的锚点和关系。
CAShapeLayers是CGPaths的“容器”,可以在轮廓和填充中使用不同的颜色,在单个CAShapeLayer中可以有多个CGPath元素。
而且,引用伟大的罗布:
“如果将一个CAShapeLayer作为图层添加到视图中,则不必自己实现任何绘图代码。只需添加CAShapeLayer即可完成。例如,您甚至可以更改路径,它会自动生成为你重新绘制它.CAShapeLayer让你摆脱编写自己的drawRect或drawLayer例程的杂草。“
如果您有大量的交互元素并且想要调试它们,那么CAShapeLayer的性能问题可能会发挥作用,此时您可以使用shouldRasterize将每个元素转换为位图,并在达到“由”创建的限制时获得显着的性能提升。 CAShapeLayers的动态“功能。
此外,为了表示约束和关节之类的东西,只需设置属性,就可以在CAShapeLayers上创建一个简单的虚线过程。 以下是设置CAShapeLayer属性的基础知识,以及使用数组创建具有块笔划,宽度为3,无填充的5-5-5虚线轮廓的方法。
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]];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.