Spritekit - 使用手势同时用多个手指绘制多条线

时间:2015-12-06 00:38:36

标签: ios objective-c sprite-kit

使用下面的代码,我可以使用1个手指使用平移手势绘制一条线。然而,我试图做的是1个手指绘制1条线,另一个手指同时绘制第二条线。我已经阅读过使用字典存储触摸但不知道如何在代码中编写它的地方。任何人都可以帮忙吗?

-(void)didMoveToView:(SKView *)view {

    UIPanGestureRecognizer *gestureRecognizerPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
    [[self view] addGestureRecognizer:gestureRecognizerPan];

}

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
    if (recognizer.state == UIGestureRecognizerStateBegan) {

        CGPoint touchLocation = [recognizer locationInView:recognizer.view];
        touchLocation = [self convertPointFromView:touchLocation];

        pathToDraw = CGPathCreateMutable();
        CGPathMoveToPoint(pathToDraw, NULL, touchLocation.x, touchLocation.y);
        lineNode = [[SKShapeNode alloc] init];
        lineNode.path = pathToDraw;
        lineNode.name = lineNodeCategoryName;
        [_gameLineNode addChild:lineNode];

    } else if (recognizer.state == UIGestureRecognizerStateChanged) {

        CGPoint touchLocation = [recognizer locationInView:recognizer.view];
        touchLocation = [self convertPointFromView:touchLocation];

        CGPathAddLineToPoint(pathToDraw, NULL, touchLocation.x, touchLocation.y);
        lineNode.path = pathToDraw;
        lineNode.name = lineNodeCategoryName;
        lineNode.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:pathToDraw];
        lineNode.physicsBody.dynamic = YES;
        lineNode.strokeColor = [SKColor blackColor];
        lineNode.glowWidth = 3.0;

    } else if (recognizer.state == UIGestureRecognizerStateEnded) {

        CGPathRelease(pathToDraw);

    }
}

1 个答案:

答案 0 :(得分:2)

同时绘制多行非常简单。关键是要独立跟踪每个触摸事件。一种方法是维护一个字典,该字典使用触摸事件作为键,形状节点(用于绘制线条)作为值。

@implementation GameScene {
    NSMutableDictionary *lines;
}

-(void)didMoveToView:(SKView *)view {
    self.scaleMode = SKSceneScaleModeResizeFill;
    // Create a mutable dictionary
    lines = [NSMutableDictionary dictionaryWithCapacity:10];
}

// Add each line node to the dictionary with the touch event as the key
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];
        // Create a mutable path
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:location];
        // Create a shape node using the path
        SKShapeNode *lineNode = [SKShapeNode shapeNodeWithPath:path.CGPath];
        lineNode.strokeColor = [SKColor blackColor];
        [self addChild:lineNode];
        // Use touch pointer as the dictionary key. Since the dictionary key must conform to
        // NSCopying, box the touch pointer in an NSValue
        NSValue *key = [NSValue valueWithPointer:(void *)touch];
        [lines setObject:lineNode forKey:key];
    }
}

// Update the lines as needed
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];
        // Retrieve the shape node that corresponds to touch
        NSValue *key = [NSValue valueWithPointer:(void *)touch];
        SKShapeNode *lineNode = [lines objectForKey:key];
        if (lineNode != NULL) {
            // Create and initialize a mutable path with the lineNode's current path
            UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:lineNode.path];
            // Add a line to the current touch point
            [path addLineToPoint:location];
            // Update lineNode
            lineNode.path = path.CGPath;
        }
    }
}

// Remove the line nodes from the dictionary when the touch ends
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *touch in touches) {
        NSValue *key = [NSValue valueWithPointer:(void *)touch];
        [lines removeObjectForKey:key];
    }
}

@end