2015-05-22 63 views
0

我在做什麼:使一個SKSpriteNode跟隨一個UIBezierPath,其中端點是用戶觸摸的位置。SKSpriteNode遵循bezier路徑旋轉

問題:當用戶觸摸我時,將位置發送給播放器節點,播放器節點會自行移動它。然而,這隻有在玩家節點向上「指向」時才起作用,例如在第一次觸摸時。其他的觸動會讓玩家誤入歧途。

圖片說明問題:http://i.stack.imgur.com/nleXj.png
我在Photoshop中增加了一些解釋的事情所以這裏是一個解釋:
- 厚>是我在移動SKSpriteNode。
- 紫色正方形是觸摸的確切位置,按順序編號(實際上爲調試目的添加了SKSpriteNodes)
- 細箭頭是觸摸發生時玩家的位置。

我相信這個問題是在玩家節點座標系和場景座標系之間轉換的地方。
例如:第一次觸摸(當玩家zRotation沒有改變時)將玩家移動到正確的位置。然而,第二次觸摸是在玩家節點座標系中的左側,但是它基本上在場景座標系中左側,如果觸摸與節點一起旋轉,如果它被旋轉指向上。

的代碼:
GameScene.m:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    /* Called when a touch begins */ 
    for (UITouch *touch in touches) { 
     [self playRiddle]; 

     CGPoint touchPoint = [touch locationInNode:_player]; 
     [_player moveTo:touchPoint]; 

     SKSpriteNode *n = [SKSpriteNode spriteNodeWithColor:[UIColor purpleColor] size:CGSizeMake(10, 10)]; 
     n.position = [self convertPoint:touchPoint fromNode:_player]; 
     [_worldNode addChild:n]; 
    } 
} 

Player.m:

- (void)moveTo:(CGPoint)point { 
    _moving = YES; 
    [self removeActionForKey:@"move"]; 

    CGVector vector = [self convertAngleToVector:[self shipOrientation]]; 
    CGPoint controlPoint = CGPointMake(vector.dx, vector.dy); 

    UIBezierPath *path = [self createPathWindEndPoint:point controlPoint:controlPoint]; 
    SKAction *move = [SKAction followPath:[path CGPath] asOffset:YES orientToPath:YES speed:15]; 
    SKAction *done = [SKAction runBlock:^{ 
     _moving = NO; 
    }]; 
    [self runAction:[SKAction sequence:@[move, done]] withKey:@"move"]; 
} 

- (UIBezierPath *)createPathWindEndPoint:(CGPoint)endpoint controlPoint:(CGPoint)cp {  
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    [path moveToPoint:CGPointZero]; 

    [path addQuadCurveToPoint:endpoint controlPoint:cp]; 

    //Draw path 
    SKShapeNode *line = [SKShapeNode node]; 
    line.path = [path CGPath]; 
    [line setStrokeColor:[UIColor darkGrayColor]]; 
    line.position = self.position; 
    [self.parent addChild:line]; 

    return path; 
} 

- (CGVector)convertAngleToVector:(CGFloat)radians { 
    CGVector vector; 
    vector.dx = cos(radians) * 25; 
    vector.dy = sin(radians) * 25; 
    return vector; 
} 

- (CGFloat)shipOrientation { 
    return self.zRotation + M_PI_2; 
} 

的_player父節點是被添加到GameScene一個SKNode。 我嘗試了很多東西[節點convertPoint:..]但沒有成功。會喜歡一些指向正確方向的指針。

謝謝!

回答

1

我建議您使用絕對場景座標而不是相對節點座標來創建要遵循的路徑。下面是如何做到這一點的例子:)

GameScene

1在touchesBegan,進行以下更改到觸摸位置轉換爲座標現場

CGPoint touchPoint = [touch locationInNode:self]; 

球員。米

; 2)將下列創建場景座標路徑(見註釋)

- (void)moveTo:(CGPoint)point { 
    _moving = YES; 
    [self removeActionForKey:@"move"]; 

    CGVector vector = [self convertAngleToVector:[self shipOrientation]]; 
    // Offset the control point by the node's position 
    CGPoint controlPoint = CGPointMake(vector.dx+self.position.x, vector.dy+self.position.y); 

    UIBezierPath *path = [self createPathWindEndPoint:point controlPoint:controlPoint]; 
    // Use absolute path 
    SKAction *move = [SKAction followPath:[path CGPath] asOffset:NO orientToPath:YES speed:15]; 

    SKAction *done = [SKAction runBlock:^{ 
     _moving = NO; 
    }]; 
    [self runAction:[SKAction sequence:@[move, done]] withKey:@"move"]; 
} 

- (UIBezierPath *)createPathWindEndPoint:(CGPoint)endpoint controlPoint:(CGPoint)cp { 
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    // Use scene coordinates 
    [path moveToPoint:self.position]; 

    [path addQuadCurveToPoint:endpoint controlPoint:cp]; 

    //Draw path 
    SKShapeNode *line = [SKShapeNode node]; 
    line.path = [path CGPath]; 
    [line setStrokeColor:[UIColor darkGrayColor]]; 
    // Line relative to the origin 
    line.position = CGPointZero; 
    [self.parent addChild:line]; 

    return path; 
}