【问题标题】:Why does UIBezierPath behave like this?为什么 UIBezierPath 会这样?
【发布时间】:2014-09-08 17:20:59
【问题描述】:

我制作了一个小 SpriteKit 游戏,其中敌人正在跟随 UIBezierPath。 (顺便说一句,还有其他方法可以做到这一点吗?这似乎很没有生产力)

反正我的敌人表现得很奇怪。这是一个直径为 300 的简单圆的代码:

    enemy.position = CGPointMake(0, 0);

    UIBezierPath* circlePath = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0, 0, 300, 300)];

    CGPathRef pathRef = [cicrlePath CGPath];


    SKAction *followPath = [SKAction followPath:pathRef
                                       asOffset:NO
                                   orientToPath:NO
                                       duration: pathSpeed];




    SKAction *forever = [SKAction repeatActionForever:followPath];


    [enemy runAction:forever];

现在看看我是如何在 (0,0) 指定敌人位置和 circlePath 位置的?

不知何故,它给了我这个结果:http://www.gfycat.com/DistinctSnarlingAracari

我认为这不太合理,因为它不合时宜?还是我错过了什么?

哦,就像我之前提到的,我怎样才能以最有效/最高效的方式为我的游戏进行敌人移动?我目前正在使用带有 UIBeziers 的 PaintCode,但它总是给我一个奇怪的结果。我真的很期待你的回答..

【问题讨论】:

  • 您的 GIF 到底有什么问题?如果您认为“1”图标放错了位置,您希望它在哪里?
  • 好吧,因为 Sprite Kit 场景的默认锚点位于左下角(如此处所示:developer.apple.com/library/ios/documentation/GraphicsAnimation/…)我希望 1 仅在左下角可见编辑:我刚刚意识到我的错:我认为它会使用 BezierPath 的中心来定位它的路径..

标签: objective-c sprite-kit nodes uibezierpath cgpath


【解决方案1】:

我想你不明白-[UIBezierPath bezierPathWithOvalInRect:] 或者CGRectMake。您的0, 0 是椭圆形边界框的左上角,而不是中心,300, 300 是该边界框的宽度和高度。如果您希望椭圆以 0, 0 为中心,请尝试以下操作:

UIBezierPath* circlePath = [UIBezierPath bezierPathWithOvalInRect:
    CGRectMake(-150, -150, 300, 300)];

【讨论】:

  • 是的,现在说得通了。但是,您知道为我的游戏创建敌人路径的更好方法吗?我现在这样做似乎有点麻烦
  • 我对游戏开发工具的经验很少。
  • 无论如何,“麻烦”是什么意思?这只是一个模糊的、敏感的、毫无意义的意见。
【解决方案2】:

UIBezier 椭圆路径的中心位于 (x + width/2, y + height/2)。从角度 = 0(椭圆上最右边的点,即 (x+width,y+height/2))开始,椭圆在场景坐标中逆时针绘制。因此,精灵会沿着逆时针方向的椭圆形路径移动,因为它会沿着绘制路径的方向移动。

以下代码可能对您有用:

此方法创建一个以指定 CGRect 的位置(原点)为中心的椭圆路径。

- (CGPathRef) ovalInRect:(CGRect)rect
{
    CGFloat width = rect.size.width;
    CGFloat height = rect.size.height;
    CGFloat x = rect.origin.x-rect.size.width/2;
    CGFloat y = rect.origin.y-rect.size.height/2;

    return[UIBezierPath bezierPathWithOvalInRect: CGRectMake(x, y, width, height)].CGPath;
}

此方法创建一个沿圆形路径移动节点的 SKAction。参数 指定路径的中心、半径和方向(YES = 顺时针,NO = 逆时针)。

- (SKAction *) createCircularPathActionAtLocation:(CGPoint)center
                                       withRadius:(CGFloat)radius
                                  andDirectionCW:(BOOL)directionCW

{
    CGRect rect = CGRectMake(center.x, center.y, radius*2, radius*2);
    CGPathRef ovalPath = [self ovalInRect:rect];
    SKAction *circlePathAction = [SKAction followPath:ovalPath asOffset:NO orientToPath:YES duration:5];
    SKAction *action;

    if (directionCW) {
        // Reverse the action to follow the path in the opposite direction
        action = [SKAction repeatActionForever:[circlePathAction reversedAction]];
    }
    else {
        action = [SKAction repeatActionForever:circlePathAction];
    }
    return action;
}

旁注:如果您使用的是 PaintCode 2,则可以通过使用变量而不是绝对值来概括它生成的代码。

【讨论】:

  • 感谢您的解释!您提到 PaintCode 2 可以通过使用变量来概括代码,这有什么不同(与使用绝对值)以及我在哪里可以找到这个选项?
  • 这是左侧面板中图像下方的最后一项。
猜你喜欢
  • 2018-10-15
  • 2011-06-03
  • 2018-06-08
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多