2014-09-28 3 views
0

내 응용 프로그램에는 바닥으로 작동하고 아래쪽으로 스크롤되는 이미지가 있습니다.SpriteKit Scrolling Bottom에는 루프가 틈이 있습니다.

-(void)initalizingScrollingBackground 
    { 
     for (int i = 0; i < 2; i++) 
     { 
      SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"Bottom_Scroller"]; 
      bg.zPosition = BOTTOM_BACKGROUND_Z_POSITION; 
      bottomScrollerHeight = bg.size.height; 
      bg.position = CGPointMake((i * bg.size.width) + (bg.size.width * 0.5f) - 1, bg.size.height * 0.5f); 
      bg.name = @"bg"; 
      bg.physicsBody = [SKPhysicsBody bodyWithTexture:bg.texture size:bg.texture.size]; 


      bg.physicsBody.categoryBitMask = bottomBackgroundCategory; 


      bg.physicsBody.contactTestBitMask = flappyBirdCategory; 


      bg.physicsBody.collisionBitMask = 0; 


      bg.physicsBody.affectedByGravity = NO; 
      [self addChild:bg]; 
     } 
    } 

- (void)moveBottomScroller 
{ 
    [self enumerateChildNodesWithName:@"bg" usingBlock: ^(SKNode *node, BOOL *stop) 
    { 
     SKSpriteNode * bg = (SKSpriteNode *) node; 
     CGPoint bgVelocity = CGPointMake(-BG_VELOCITY, 0); 
     CGPoint amtToMove = CGPointMultiplyScalar(bgVelocity,_dt); 
     bg.position = CGPointAdd(bg.position, amtToMove); 

     //Checks if bg node is completely scrolled of the screen, if yes then put it at the end of the other node 
     if (bg.position.x + bg.size.width * 0.5f <= 0) 
     { 
      bg.position = CGPointMake(bg.size.width*2 - (bg.size.width * 0.5f) - 2, 
             bg.position.y); 
     } 
    }]; 
} 

그러나 너무 오랫동안 스크롤 한 후에는 다음과 같이 간격을 표시합니다. 이 문제를 어떻게 해결할 수 있습니까?

enter image description here

+0

같은 루프에서 노드가 화면 밖으로 나가는 것을 감안할 때, 두 번째 노드가 움직이기 전에 첫 번째 노드의 위치가 변경되면 (화면이 보이지 않기 때문에) 어떻게 될까요? 디버거를 사용하여 단계별로 진행하고 위치를 "예상"한 것으로 확인하면 문제가 나타납니다. – prototypical

+0

프로토 타입에 동의합니다. 일반적으로 모든 배경 위치를 업데이트 한 다음 화면에서 요소를 확인합니다. 같은 루프에서 하나 이상의 배경 화면을 벗어나지 않을 것입니다. 더 정확하게하려면 절대 위치 대신 다른 Bg의 위치를 ​​사용하여 배경의 위치를 ​​다시 지정할 수 있습니다. – gzafra

+0

지금 SpriteKit을 배우고 있습니다. 그래서 당신이 말한 내용 중 일부는 내 머리 위로하고, 이것은 자습서에서 나온 것입니다. 그래서 어디로 가야할 지 모르겠습니다. – user717452

답변

2

내가 할 줄 것은 :

// This would go in the init or didMoveToView method of your scene 
const NSUInteger numBgs = 3; 
for (NSUInteger i = 0; i < numBgs; i++) { 
    CGFloat color = 0.2f * i; 
    SKSpriteNode *bg = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:color green:color blue:color alpha:1.0] size:CGSizeMake(512, 300)]; 
    bg.anchorPoint = CGPointMake(0.5, 0); 
    bg.position = CGPointMake((i * bg.size.width) + (bg.size.width * 0.5f), CGRectGetMinY(self.frame)); 
    bg.name = @"bg"; 
    [self addChild:bg]; 

    if (i == numBgs-1) { // Means it's last bg on the right 
     lastBg = bg; 
    } 
} 

[self enumerateChildNodesWithName:@"bg" usingBlock:^(SKNode *node, BOOL *stop) { 
    SKSpriteNode * bg = (SKSpriteNode *) node; 

    //Checks if bg node is completely scrolled of the screen, if yes then put it at the end of the other node 
    if (bg.position.x + bg.size.width * 0.5f <= 0) 
    { 
     bg.position = CGPointMake(lastBg.position.x + bg.frame.size.width, 
            bg.position.y); 
     lastBg = bg; 
    } 


    CGPoint bgVelocity = CGPointMake(-BG_VELOCITY, 0); 
    CGPoint amtToMove = CGPointMultiplyScalar(bgVelocity,_dt); 
    bg.position = CGPointAdd(bg.position, amtToMove); 

}]; 
lastBg 상단 가장 잘 그래서 다시 위치에있는 BG를 가리키는 인스턴스 변수입니다

항상 될 것입니다 이 스프라이트에 비례하여.

다른 방법을 시도해 볼 수 있습니다. 다시 배치하기 전에 위치 확인을 전환하고 (예에서와 같이) 열거 블록에서 체크를 제거하고 다시 위치 지정과 독립적으로 수행 할 수 있습니다.

나는 예에서와 같이하는 데 익숙했지만 잘 작동했습니다. 어떻게되는지 알려주세요.

+0

고마워요. 내가 방금 Sprite Kit을 배우면서 방금 전에 좌절 했었던 것처럼 말했듯이이 튜토리얼은 이와 비슷했기 때문에 모든 도움을 주셔서 감사 드리며 배우는 중 누군가가 대답을 해주지 않도록하기 위해서입니다. – user717452

+0

좋아, 어디 lastBg 처음에 설정해야합니까? 내가 한 모든 것은 그것을위한 ivar를 추가하는 것이었고, 그 차이는 이제 화면의 너비입니다. – user717452

+0

장면을 설정할 때 lastBg를 설정해야합니다. 설정을 할 때 lastBg ivar가 오른쪽의 마지막 bg를 가리키는 지 확인하십시오. 또한 포지셔닝은 모든 BG가 동일한 너비를 갖는다 고 가정합니다. – gzafra