7

在 iOS 9 中,Apple 引入collisionBoundsTypeUIKit-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];)。

4

3 回答 3

2

从这里关于 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,那么这将解释为什么您需要将 by 翻译SLIME_SIZE/2为更正。

于 2015-10-22T10:53:13.643 回答
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;
}

主要区别在于我通过将 x 和 y 值除以 2 来修改弧的中心。

于 2015-10-22T04:52:17.070 回答
1

调试物理是一回事。这可能不是 iOS 用户经常考虑的事情,因为他们通常使用 UIKit Dynamics 做了非常简单的事情。这有点可惜,因为它是最新版本 iOS 的最佳方面之一,并提供了一种真正有趣的方式来打造引人入胜的用户体验。

那么......如何调试物理?

一种方法是在精神上想象正在发生的事情,然后将其与正在发生的事情联系起来,找到想象与现实之间的不协调,然后通过消除、心理或真实试错和演绎的混合过程来解决问题,直到问题确定并解决。

另一种方法是对所有创建和交互的内容进行可视化描述,提供足够的反馈,以更快地确定元素的性质和范围、它们的关系和事件/事件,并用文字解决问题。

为此,自推出以来,已经创建了各种可视化调试器和物理模拟构建器。

不幸的是,iOS 没有这样的基于屏幕的编辑器或 UIKit Dynamics 的“场景编辑器”,而在 Sprite Kit 和 Scene Kit 中可用于这种可视化调试的东西充其量只是初级的。

然而,所有 UIKit 视图中都存在 CALayers,可以手动创建和绘制 CAShapeLayers 以准确表示任何和所有物理元素、它们的边界以及它们的锚点和关系。

CAShapeLayers 是 CGPaths 的“容器”,可以有不同的轮廓和填充颜色,以及单个 CAShapeLayer 中的多个 CGPath 元素。

而且,引用伟大的 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]];
于 2015-10-22T07:58:58.520 回答