简体   繁体   English

围绕一个圆圈移动一个 SKNode

[英]Move a SKNode around a circle

i am moving my sknode around a circle created with this code:我正在围绕使用此代码创建的圆圈移动我的 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"];

And everything is working.一切正常。 Now i want that when an user tap on the screen to revert the direction and move the node in counterClockwise.现在我希望当用户点击屏幕以反转方向并逆时针移动节点时。 I did that by running the same action with .reversedAction command.我通过使用 .reversedAction 命令运行相同的操作来做到这一点。

But the action always restart from the start point.但动作总是从起点重新开始。

I want to know if there is some kind of method to make start the animation from the point where the old animation is when the user tap on the screen?我想知道是否有某种方法可以从用户点击屏幕时旧动画所在的点开始动画?

A UIBezierPath is composed by path Elements where the first is moveToPoint that , as explained in the official document , starts a new subpath at a specified location in a mutable graphics path . UIBezierPath由路径Elements组成,其中第一个是moveToPoint ,如官方文档中所述,它在可变图形路径中的指定位置开始一个新的子路径

So, unfortunately is not enough doing:因此,不幸的是,这样做还不够:

UIBezierPath *circlePathReversed = [circlePath bezierPathByReversingPath];

because when you stop your circle from following the path, the actual position of the circle is not the same of the moveToPoint point (coordinates x and y).因为当你阻止你的圆圈跟随路径时,圆圈的实际位置与moveToPoint点(坐标 x 和 y)不同。

However you could rebuild your path retrieving all elements and re-starting from the actual circle position.但是,您可以重建路径以检索所有元素并从实际圆位置重新开始。

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;
    }
}

Usage :用法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM