xcode Spritekit 游戏中的无限滚动(重复)背景 - Swift

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26347559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:51:57  来源:igfitidea点击:

Endless scrolling (repeating) background in Spritekit game - Swift

iosiphonexcodeswiftsprite-kit

提问by Egghead

I want to Create a endless scrolling background for my spritekit game, iT should consist of one or two images probably, which repeat themselves? I found these oneand twoexamples, but they are in obj. C.

我想为我的 spritekit 游戏创建一个无尽的滚动背景,iT 应该由一两个图像组成,这些图像会重复吗?我找到了这一个两个例子,但它们在 obj. C。

I have no idea how I can achieve this in Swift. And is it possible to set the speed manually?

我不知道如何在 Swift 中实现这一点。是否可以手动设置速度?

Ps: I don't have the skill to convert obj. C into swift (newbie to Xcode dev.)

ps:我没有转换obj的技能。C 进入 swift(Xcode 开发新手。)

回答by Egghead

I found a way to do this, somehow i managed to convert thisobj. C to swift

我找到了一种方法来做到这一点,不知何故我设法转换了这个obj. C 快速

You have to declare the two node's publicly

你必须公开声明这两个节点的

let background1 = SKSpriteNode(imageNamed: "bg1")
let background2 = SKSpriteNode(imageNamed: "bg2") 

In the "didMoveToView" method

在“didMoveToView”方法中

background1.anchorPoint = CGPointZero
background1.position = CGPointMake(0, 0)
background1.zPosition = -15
self.addChild(background1)

background2.anchorPoint = CGPointZero
background2.position = CGPointMake(0, background1.size.height - 1)
background2.zPosition = -15
self.addChild(background2)

And in the "override func update(currentTime: CFTimeInterval)" method you add

并在“覆盖 func update(currentTime: CFTimeInterval)”方法中添加

background1.position = CGPointMake(background1.position.x, background1.position.y - 2)
background2.position = CGPointMake(background2.position.x, background2.position.y - 2)

            if(background1.position.y < -background1.size.height)
            {
                background1.position = CGPointMake(background2.position.x, background1.position.y + background2.size.height )
            }

            if(background2.position.y < -background2.size.height)
            {
                background2.position = CGPointMake(background1.position.x, background2.position.y + background1.size.height)

            }

i don't know if it's the most efficient way of doing this. The other questions mentioned a For loop. But this is easier in my opinion.

我不知道这是否是最有效的方法。其他问题提到了一个 For 循环。但在我看来,这更容易。

回答by Matthew Stromberg

I know this is late to the game, but I found how to do this horizontally as well!

我知道这已经迟到了,但我也找到了如何水平地做到这一点!

Starting off with Egghead's code (Excellent work!) I modified some things:

从 Egg​​head 的代码开始(出色的工作!)我修改了一些内容:

    let background1 = SKSpriteNode(imageNamed: "Street_Example")
    let background2 = SKSpriteNode(imageNamed: "Street_Example")

Also:

还:

    background1.position = CGPoint(x: frame.size.width / 2, y:frame.size.height / 2)
    background1.size = CGSize(width: frame.width, height: frame.height)
    background1.anchorPoint = CGPointZero
    background1.position = CGPointMake(0, 0)
    background1.zPosition = -15
    self.addChild(background1)

    background2.size = CGSize(width: frame.width, height: frame.height)
    background2.anchorPoint = CGPointZero
    background2.position = CGPointMake(background1.size.width - 1,0)
    background2.zPosition = -15
    self.addChild(background2)

And to update the position of the background:

并更新背景的位置:

    background1.position = CGPointMake(background1.position.x-2, background1.position.y)
    background2.position = CGPointMake(background2.position.x-2, background2.position.y)
    if(background1.position.x < -background1.size.width)
    {
      background1.position = CGPointMake(background1.position.x + background2.size.width , background2.position.y)
    }
    if(background2.position.x < -background2.size.width)
    {
      background2.position = CGPointMake(background2.position.x + background1.size.height, background1.position.y) 
    }

回答by ThiagoAM

I've made a class for that. Currently it's written for Swift 5.0 or 4.2, and it supports top, bottom, left and right directions.

我为此做了一门课。目前它是为 Swift 5.0 或 4.2 编写的,它支持上、下、左、右方向。

Check it out and see if it helps you, it's called InfiniteScrollingBackground: https://github.com/ThiagoAM/InfiniteScrollingBackground

看看它是否对你有帮助,它叫做 InfiniteScrollingBackground:https: //github.com/ThiagoAM/InfiniteScrollingBackground

回答by Diogo Aleixo

You don′t need all that.

你不需要所有这些。

Just use this function with the vars that you declared and the attributes that you used in didMoveToView.

只需将此函数与您声明的变量和您在 didMoveToView 中使用的属性一起使用。

func backgroudScrollUpdate(){
    background1.position = CGPointMake(background1.position.x, background1.position.y - 1)
    background2.position = CGPointMake(background1.position.x, background2.position.y - 1)
    if background1.position.y == -UIScreen.mainScreen().bounds.height{
        background1.position = CGPointMake(0, 0)
        background2.position = CGPointMake(0, 0 + UIScreen.mainScreen().bounds.height)
    }
}

Then just call it in your update method.

然后只需在您的更新方法中调用它。

Of course, it is not the best way since it is readable for two images, when you have more go for a loop.

当然,这不是最好的方法,因为当你有更多的循环时,它对于两个图像是可读的。

回答by Cherpak Evgeny

Here what I came up with:

这是我想出的:

   func terrain() -> SKNode {
        let color = UIColor.init(red: randomColorChannel(), green: randomColorChannel(), blue: randomColorChannel(), alpha: 1.0)

        let scale: CGFloat = 1.0// UIScreen.mainScreen().scale
        let size = CGSizeMake(frame.size.width * scale, frame.size.height * scale)
        let node = SKSpriteNode.init(color: color, size: size)
        node.anchorPoint = CGPointZero
        node.position = CGPointMake(0, UIScreen.mainScreen().bounds.size.height)

        return node
    }

And in update do this:

并在更新中这样做:

override func update(currentTime: NSTimeInterval) {
        var newPosition1 = terrain1.position
        var newPosition2 = terrain2.position

        newPosition1.y -= terrainSpeed
        if newPosition1.y < 0 {
            newPosition2.y -= terrainSpeed
        }

        terrain1.position = newPosition1
        terrain2.position = newPosition2

        if terrain1.position.y <= -UIScreen.mainScreen().bounds.size.height {
            removeChildrenInArray([terrain1])
            terrain1 = terrain()
            addChild(terrain1)
        }

        if terrain2.position.y <= -UIScreen.mainScreen().bounds.size.height {
            removeChildrenInArray([terrain2])
            terrain2 = terrain()
            addChild(terrain2)
        }
    }

So basically, terrain is placed above the view, and then they start moving down, and replaced by new ones when needed, to repeat.

所以基本上,地形被放置在视图上方,然后它们开始向下移动,并在需要时替换为新的,重复。

回答by Anonymous

    func backgroudScrollUpdate(){
        BG .position = CGPoint(x: BG.position.x - 5, y: BG.position.y)
        BG2.position = CGPoint(x: BG2.position.x - 5, y: BG2.position.y)
        if BG2.position.x <= -self.frame.size.width {
            BG.position = CGPoint(x: self.frame.size.width, y: 0)
        }
        if BG.position.x <= -self.frame.size.width {
        BG2.position = CGPoint(x: self.frame.size.width, y: 0)
    }
}

-UPDATED FOR SWIFT 3.1-

-为 Swift 3.1 更新-

this is what I always use to make it work for the Y axis just switch all the extra stuff in the X positions to the Y positions

这就是我一直用来使它在 Y 轴上工作的方法,只需将 X 位置中的所有额外内容切换到 Y 位置