【问题标题】:Swift Spritekit Scrolling BackgroundSwift Spritekit 滚动背景
【发布时间】:2014-11-27 13:39:56
【问题描述】:

我正在尝试找到在 Swift 中进行垂直滚动背景的最佳方法, 不使用更新方法。背景是 1 个应该无限循环的图像。 图像应位于屏幕中间(全尺寸),向下移动,并且在该图像之上应始终生成另一个图像。

但是,我的工作不太正常,它会生成 2 张图像,然后在延迟之后它们会弹出并再次启动动作。 此外,它有时会从 30 FPS 降至 26 FPS,这是我想避免的。 我希望更喜欢 Swift 的人可以帮助我。

let Background = SKTexture(imageNamed: "Background.png")
    Background.filteringMode = .Nearest

    let BackgroundMove = SKAction.moveByX(0, y: -self.frame.size.height, duration: 10)
    let BackgroundReset = SKAction.moveByX(0, y: self.frame.size.height, duration: 0.0)
    let BackgroundMoveAndResetForever = SKAction.repeatActionForever(SKAction.sequence([BackgroundMove,BackgroundReset]))

    for var i:CGFloat = 0; i < 2.0 + self.frame.size.height / (Background.size().height * 2); ++i {
        let sprite = SKSpriteNode(texture: Background)
        sprite.size = CGSize(width: self.frame.size.width / 2, height: self.frame.size.height)
        sprite.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2 * i)
        sprite.zPosition = 1
        sprite.runAction(BackgroundMoveAndResetForever)
        self.addChild(sprite)
    }

【问题讨论】:

    标签: ios swift scroll sprite-kit


    【解决方案1】:

    这是我用来制作在屏幕上从右向左移动的背景的代码。它使用一个循环来生成三个背景,所有这些背景都形成一条线,穿过屏幕并在完成后返回到它们的原始位置。要将其转换为从上到下移动的屏幕,您必须将moveByXSKActions 替换为moveToY,并将更改的 x 值与更改的 y 值交换。希望这会有所帮助!

    func makeBackground() {
    
        var backgroundTexture = SKTexture(imageNamed: "img/bg.png")
    
        //move background right to left; replace
        var shiftBackground = SKAction.moveByX(-backgroundTexture.size().width, y: 0, duration: 9)
        var replaceBackground = SKAction.moveByX(backgroundTexture.size().width, y:0, duration: 0)
        var movingAndReplacingBackground = SKAction.repeatActionForever(SKAction.sequence([shiftBackground,replaceBackground]))
    
        for var i:CGFloat = 0; i<3; i++ {
            //defining background; giving it height and moving width
            background=SKSpriteNode(texture:backgroundTexture)
            background.position = CGPoint(x: backgroundTexture.size().width/2 + (backgroundTexture.size().width * i), y: CGRectGetMidY(self.frame))
            background.size.height = self.frame.height
            background.runAction(movingAndReplacingBackground)
    
            self.addChild(background)
        }
    }
    

    【讨论】:

    • 你会从哪里调用这个函数?
    • @RubenMartinezJr。一旦游戏开始,这将在 SKGameScene 中调用。祝你好运!
    【解决方案2】:

    我写了这个...它可能没有尽可能短,但它只使用了 2 个图像副本,与上面发布的最佳答案不同。它还允许您指定方向(true 向右滚动,false 向左滚动)和速度(指示图像在屏幕上滚动所需的秒数,数字越小 = 越快)。它还需要您指定视图,并且我没有使用与所需输出大小不同的图像对其进行测试(尽管我包括了缩放,所以它可能有效)

    func scrollingBackground (view: SKView, rightward: Bool, speed: CGFloat) {
    
        let background = SKSpriteNode(imageNamed: "space")
        let background2 = SKSpriteNode(imageNamed: "space")
    
        // variables to manage x position, will be set based on which
        // direction this will be moving
        var b1startX, b2startX, destination, resetPos: CGFloat
    
        // Set values based on desired direction
        if(rightward){
            b1startX = frame.size.width * -0.5      // value to start offscreen
            b2startX = frame.size.width * 0.5       // value to start on screen
            destination = frame.size.width * 1.5    // position where image will disappear
            resetPos = frame.size.width * -0.5      // position where image will reappear
        }
        else{
            b1startX = frame.size.width * 1.5
            b2startX = frame.size.width * 0.5
            destination = frame.size.width * -0.5
            resetPos = frame.size.width * 1.5
        }
    
        background.position = CGPoint(x: b1startX, y: frame.size.height / 2)
        background.scale(to: view.bounds.size)
        background.zPosition = -1
    
        background2.position = CGPoint(x: b2startX, y: frame.size.height / 2)
        background2.scale(to: view.bounds.size)
        background2.zPosition = -1
    
        // Define actions based on desired direction
        let scrollFromMid = SKAction.moveTo(x: destination, duration: TimeInterval(speed))
        let scrollFromLeft = SKAction.moveTo(x: destination, duration: TimeInterval(speed * 2.0))
        let resetPosition = SKAction.moveTo(x: resetPos, duration: 0)
    
        //background starts in the default starting position, totally offscreen
        background.run(SKAction.repeatForever(SKAction.sequence([scrollFromLeft, resetPosition])))
    
        // background2 starts fully displayed, moves offscreen, then into default loop
        background2.run(SKAction.sequence([scrollFromMid, resetPosition,
                        SKAction.repeatForever(
                            SKAction.sequence([scrollFromLeft, resetPosition]))
                        ]))
    
        addChild(background)
        addChild(background2)
    
    }
    

    【讨论】:

      【解决方案3】:

      当您创建 BackgroundReset 操作时,您将 y 更改设置为负值,这会将背景移到屏幕下方。删除减号可将背景移回屏幕。

      let BackgroundReset = 
      SKAction.moveByX(0, y: /* removed minus sign here */ self.frame.size.height * 2, duration: 0.0)
      

      【讨论】:

      • 谢谢!现在它无限生成,它们之间有延迟。如何消除延迟?
      • 将 BackgroundMove 和 BackgroundReset 中的 self.frame.size.height * 2 更改为 self.frame.size.height?
      • 我觉得我表达的不对。我在 OP 中添加了信息。
      • @Nima FYI,OP 代表原始海报,一个人。对于这个问题,你是 OP。
      猜你喜欢
      • 1970-01-01
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      相关资源
      最近更新 更多