2014-08-31 33 views
0

我正在研究在每個SKSpriteNodes背景中有3個雲的遊戲。爲了創建視差效果,我會在角色向上移動時將它們向下移動(屏幕也向上移動)。刪除後將SKSpriteNode兒童添加回父項

我將它們在更新方法中刪除後,他們到達屏幕的底部。我想將它們添加回可見場景上方20px的Y位置,以便iPhone 4可以使用500x,使用iPhone 5可以使用588px。然後重複一遍又一遍。

那麼只有這樣,我可以想到做到這一點是鏈接SKActions並運行一個序列,但我不認爲這是最好的方法。我試圖找到一種在更新方法中刪除它們之後將它們添加回來的方法。

-(id)initWithSize:(CGSize)size { 

     ... 

     //Moving Clouds 
    [self performSelector:@selector(createClouds) withObject:nil afterDelay:.2]; 

    } 

-(void)createClouds { 

    SKSpriteNode *cloud1 = [SKSpriteNode spriteNodeWithImageNamed:@"cloud1"]; 
    cloud1.position = CGPointMake(40, 200); 
    cloud1.xScale = .5; 
    cloud1.yScale = .5; 
    cloud1.name = @"Cloud1"; 
    cloud1.zPosition = 0; 

    SKAction *moveCloud1 = [SKAction moveToY:-20 duration:15]; 
    [cloud1 runAction:[SKAction repeatActionForever:moveCloud1]]; 

    [self addChild:cloud1]; 

    SKSpriteNode *cloud2 = [SKSpriteNode spriteNodeWithImageNamed:@"cloud2"]; 
    cloud2.position = CGPointMake(300, 320); 
    cloud2.xScale = .5; 
    cloud2.yScale = .5; 
    cloud2.name = @"Cloud2"; 
    cloud2.zPosition = 0; 

    SKAction *moveCloud2 = [SKAction moveToY:-40 duration:15]; 
    [cloud2 runAction:[SKAction repeatActionForever:moveCloud2]]; 

    [self addChild:cloud2]; 

    SKSpriteNode *cloud3 = [SKSpriteNode spriteNodeWithImageNamed:@"cloud3"]; 
    cloud3.position = CGPointMake(200, 450); 
    cloud3.xScale = .5; 
    cloud3.yScale = .5; 
    cloud3.name = @"Cloud3"; 
    cloud3.zPosition = 0; 

    SKAction *moveCloud3 = [SKAction moveToY:-200 duration:20]; 
    [cloud3 runAction:[SKAction repeatActionForever:moveCloud3]]; 

    [self addChild:cloud3]; 

} 

-(void)update:(CFTimeInterval)currentTime { 
    .... 
    // Remove Cloud from parent 
     [self enumerateChildNodesWithName:@"Cloud1" usingBlock:^(SKNode *node, BOOL *stop) { 
      if (node.position.x < 0 || node.position.y < 0) { 
       [node removeFromParent]; 
       //Add node back to the scene at a Y position above the screen then move 
       // the cloud downwards again. Repeat Forever. 
       // Exp: Move Cloud 1 to X position 40, Y position 500 (20 pixels above the top of the screen for an iPhone 4s) 
      } 
      else { 
       // Do something? 
      } 
     }]; 

回答

2

您可以添加SKAction移動你的雲回到頂端:

SKSpriteNode *cloud1 = [SKSpriteNode spriteNodeWithImageNamed:@"cloud1"]; 
    cloud1.position = CGPointMake(40, 200); 
    cloud1.xScale = .5; 
    cloud1.yScale = .5; 
    cloud1.name = @"Cloud1"; 
    cloud1.zPosition = 0; 

    SKAction *moveCloud1 = [SKAction moveToY:-20 duration:15]; 
    // SKAction to move cloud back to top of screen 
    SKAction *moveToTop = [SKAction moveToY:CGRectGetHeight(self.frame)+20 duration:0]; 
    SKAction *cloud1Action = [SKAction sequence:@[moveCloud1, moveToTop]]; 
    [cloud1 runAction:[SKAction repeatActionForever:cloud1Action]]; 

您不需要在更新方法的代碼。

+0

這結束了很好的工作!我不知道爲什麼我反對這樣做。 – Paul 2014-09-01 16:39:32

1

我想你可以簡單地改變位置

此外,使用CGRectGetMinY使用相對定位,更易於管理不同的屏幕尺寸。

並且只檢查Y位置,因爲如果垂直移動,X不會改變。

這是我的想法:

-(void)update:(NSTimeInterval)currentTime { 

    for(int i = 1; i<=3; i++){ 
     NSString* cloud = [NSString stringWithFormat:@"Cloud%d",i]; 
     [self enumerateChildNodesWithName:cloud usingBlock:^(SKNode *node, BOOL *stop) { 
      if (node.position.y < 0) { 
       node.position = CGPointMake(node.position.x,CGRectGetMaxY(self.frame)+20); 
      } 
     }]; 
    } 
} 
+0

你的答案好像會起作用,但事實並非如此。我在node.position = CGPointMake(node.position.x,CGRectGetMaxY(self.frame)+20)之後添加了一個NSLog語句;',它不在控制檯中觸發。 – Paul 2014-09-01 01:53:07

+0

,如果你在更新方法的開頭放置一個NSLog,它會被調用? – Draelach 2014-09-01 12:07:37

+0

是的,我把NSLog放在更新方法的開頭,它被調用,但是雲沒有移動。無論如何,感謝您的幫助。 – Paul 2014-09-02 22:57:25