2014-02-11 11 views
8

Ich versuche, ein Side-Scrolling-Spiel mit Apple SpriteKit zu machen. Wenn ich einen endlosen Scroll-Hintergrund machen wollte, stieß ich auf diese answer.Endless Scrolling Hintergrund in SpriteKit

Nach der Implementierung der Lösung scheint es zu funktionieren obwohl es fällt meine FPS deutlich. Dies liegt wahrscheinlich daran, dass die Bildpositionen in jedem Bild neu berechnet werden.

Ich fühle mich wie es wäre viel besser, wenn ich einen oder mehrere SKAction Anrufe verwenden könnte, um diese Animation für mich zu kümmern, aber ich bin mir nicht sicher, wie man es implementiert.

Gedanken?

Der Code, den ich bisher in meiner Szene Klasse

- (void)addBackgroundTileAtPoint:(CGPoint)point { 

    SKSpriteNode *bg = [SKSpriteNode spriteNodeWithImageNamed:@"background"]; 
    bg.anchorPoint = CGPointZero; 
    bg.position = point; 
    bg.name = @"background"; 
    bg.zPosition = -99; 
    [self addChild:bg]; 

    SKAction *sequence = [SKAction sequence:@[ 
     [SKAction moveByX:-(bg.size.width * 2) y:0 duration:10], 
     [SKAction removeFromParent] 
    ]]; 
    [bg runAction: sequence]; 
} 
+0

Aktionen werden Ihnen nichts nützen, wenn das Scrollen nicht konstant ist: gleiche Richtung bei gleicher Geschwindigkeit. Selbst dann bezweifle ich, dass Aktionen deutlich schneller sein werden als die Implementierung der Antwort. Obwohl es möglicherweise schneller ist, wenn Sie anstelle von enumerateByName nur Referenzen auf die beiden Hintergrund-Sprites haben, damit SK das Knotendiagramm nicht nach Namen durchsuchen muss. – LearnCocos2D

+0

Sie benötigen einen rekursiven Aufruf hier innerhalb * Sequenz. zB nach [SKAction removeFromParent], fügen Sie [self addBackgroundTileAtPoint:]; hinzu, oder verwenden Sie repeat action, ohne den Hintergrund aus der Superansicht zu entfernen. –

+0

@ LearnCocos2D Wenn Aktionen nicht der richtige Weg sind, haben Sie Vorschläge zur Optimierung der anderen Antworten Lösung oder hatten Sie eine andere Lösung. Wenn die Lösung dieser Antwort auf dem Emulator ausgeführt wird, fällt der FPS sofort von 60 auf ~ 30 ab. –

Antwort

12

(dies nur den Hintergrund über den Bildschirm, obwohl einmal beseelt) habe ich eine kleine Komponente SKScrollingNode für diesen speziellen Bedarf in meinem letzten Open-Source-Projekt mit dem Namen : SprityBird.

FPS war kein Problem, auch mit 3 oder 4 Schichten (für Parallaxe), aber Sie müssen es möglicherweise selbst versuchen.

Um es zu nutzen, nur um es zu fügen haben wie jeder andere Knoten und eine scrollingSpeed likeso geben:

back = [SKScrollingNode scrollingNodeWithImageNamed:@"back" inContainerWidth:WIDTH(self)]; 
[back setScrollingSpeed:BACK_SCROLLING_SPEED]; 
[self addChild:back]; 

SKScrollingNode.h

@interface SKScrollingNode : SKSpriteNode 

@property (nonatomic) CGFloat scrollingSpeed; 

+ (id) scrollingNodeWithImageNamed:(NSString *)name inContainerWidth:(float) width; 
- (void) update:(NSTimeInterval)currentTime; 

@end 

SKScrollingNode.m

@implementation SKScrollingNode 

+ (id) scrollingNodeWithImageNamed:(NSString *)name inContainerWidth:(float) width 
{ 
    UIImage * image = [UIImage imageNamed:name]; 

    SKScrollingNode * realNode = [SKScrollingNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(width, image.size.height)]; 
    realNode.scrollingSpeed = 1; 

    float total = 0; 
    while(total<(width + image.size.width)){ 
     SKSpriteNode * child = [SKSpriteNode spriteNodeWithImageNamed:name ]; 
     [child setAnchorPoint:CGPointZero]; 
     [child setPosition:CGPointMake(total, 0)]; 
     [realNode addChild:child]; 
     total+=child.size.width; 
    } 

    return realNode; 
} 

- (void) update:(NSTimeInterval)currentTime 
{ 
    [self.children enumerateObjectsUsingBlock:^(SKSpriteNode * child, NSUInteger idx, BOOL *stop) { 
     child.position = CGPointMake(child.position.x-self.scrollingSpeed, child.position.y); 
     if (child.position.x <= -child.size.width){ 
      float delta = child.position.x+child.size.width; 
      child.position = CGPointMake(child.size.width*(self.children.count-1)+delta, child.position.y); 
     } 
    }]; 
} 
@end 
+1

Super Arbeit, aber mit der Veröffentlichung von iOS 9 enumerateObjectsUsingBlock löst einen inkompatiblen Blockzeiger Fehler bei der Verwendung und SKSpriteNode. Nachdem ich ein Spiel gemacht und dann noch etwas gesucht habe, habe ich den folgenden Post gefunden, der das Problem löst. http://stackoverflow.com/questions/33584180/incompatible-block-pointer-skspritenode/33584230#33584230 – Grenter

1

Ich habe an einer Bibliothek für eine unendliche Kachel Scroller gearbeitet, Sie können es leicht verwenden, um eine sc zu erstellen rollender Hintergrund. Werfen Sie einen Blick auf sie:

RPTileScroller

ich die Mühe gemacht, um es am effizientesten möglich, aber ich bin kein Spielentwickler. Ich habe es mit meinem iPhone 5 mit zufälligen Farben Kacheln von 10x10 Pixeln versucht, und läuft auf einem soliden 60 fps.