围绕圆圈移动SKNode

时间:2016-10-07 20:57:48

标签: objective-c xcode sprite-kit uibezierpath sknode

我正在使用此代码创建的圆圈移动我的sknode:

    circleDiameter = 300;
    pathCenterPoint = CGPointMake(self.position.x - circleDiameter/2, self.position.y - circleDiameter/2);

    UIBezierPath *circlePath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(pathCenterPoint.x, pathCenterPoint.y, circleDiameter, circleDiameter) cornerRadius:circleDiameter/2];
    self.actionClockwise = [SKAction followPath:circlePath.CGPath asOffset:false orientToPath:true duration:2];
    self.circleActionForever = [SKAction repeatActionForever:self.actionClockwise];
    [self runAction:self.actionCounterClockwise withKey:@"circleActionForever"];

一切正常。现在我希望当用户点击屏幕以恢复方向并以counterClockwise方式移动节点时。我通过使用.reversedAction命令运行相同的操作来做到这一点。

但是行动总是从起点重新开始。

我想知道是否有某种方法可以在用户点击屏幕时从旧动画的位置开始动画?

1 个答案:

答案 0 :(得分:1)

UIBezierPath由路径Elements组成,其中第一个moveToPoint,如official document中所述, 启动新的子路径可变图形路径中的指定位置

所以,遗憾的是还不够:

UIBezierPath *circlePathReversed = [circlePath bezierPathByReversingPath];

因为当您阻止圆圈跟随路径时,圆圈的实际位置与moveToPoint点(坐标x和y)不同。

但是,您可以重建路径,检索所有元素并从实际圆圈位置重新开始。

void MyCGPathApplierFunc (void *info, const CGPathElement *element) {
    NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;

    CGPoint *points = element->points;
    CGPathElementType type = element->type;

    switch(type) {
        case kCGPathElementMoveToPoint: // contains 1 point
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];
            break;

        case kCGPathElementAddLineToPoint: // contains 1 point
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];
            break;

        case kCGPathElementAddQuadCurveToPoint: // contains 2 points
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[1]]];
            break;

        case kCGPathElementAddCurveToPoint: // contains 3 points
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[1]]];
            [bezierPoints addObject:[NSValue valueWithCGPoint:points[2]]];
            break;

        case kCGPathElementCloseSubpath: // contains no point
            break;
    }
}

<强>用法

NSMutableArray *bezierPoints = [NSMutableArray array];
CGPathApply(circlePath.CGPath, bezierPoints, MyCGPathApplierFunc);