在SpriteKit中无尽滚动背景 [英] Endless Scrolling Background in SpriteKit

查看:142
本文介绍了在SpriteKit中无尽滚动背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用苹果的SpriteKit进行侧滚动游戏。当想要做无尽的滚动背景时,我遇到了这个回答



实施解决方案后,它似乎工作虽然它显着降低我的FPS。这可能是因为图片位置正在每一帧重新计算。



我觉得如果我可以使用一个或多个 SKAction 调用为我照顾这个动画,但我不知道如何实现它。



想法?



到目前为止,我在场景类中的代码(这只是动画屏幕一次)

   - (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];
}


解决方案

SKScrollingNode 对于我最后一个开放源代码项目中的特定需求: SprityBird 。 / p>

即使使用3或4层(视差),FPS也不是问题,但您可能需要自己尝试。



要使用它,你只需像任何其他节点一样添加它,并给它 scrollingSpeed likeso:

  back = [SKScrollingNode scrollingNodeWithImageNamed:@backinContainerWidth: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


I am attempting to make a side scrolling game using Apple's SpriteKit. When wanting to make a endless scrolling background I came across this answer.

After implementing the solution it does appear to work although it drops my FPS significantly. This is probably due to the fact that the images positions are being recalculated on every frame.

I feel like it would be much better if I could use one or more SKAction calls to take care of this animation for me but I'm not certain how to implement it.

Thoughts?

The code I have so far in my scene class (this only animates the background across the screen once though)

- (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];
}

解决方案

I did a small component called SKScrollingNode for that particular need in my last open source project : SprityBird.

FPS was not an issue even with 3 or 4 layers (for parallax), but you may need to try it yourself.

To use it you just have to add it like any other node and giving it a scrollingSpeed likeso :

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

这篇关于在SpriteKit中无尽滚动背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆