在iOS 9中设置UIView的碰撞边界路径

在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中可用于这种可视化调试的内容是最基本的。

然而,CALayers存在于所有的UIKit视图中,可以手动创建和绘制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]];
链接地址: http://www.djcxy.com/p/88203.html

上一篇: Setting collision bounding path of a UIView in iOS 9

下一篇: New Android Studio Activity Design Pattern content