SpriteKit 背景图像滚动在接缝处闪烁

SpriteKit background image scrolling flickers at seam line

我正在使用 SpriteKit 创建一个 2D macOS 游戏,我想要一个从左到右连续滚动的背景。

我有一张与我的相框大小相同的背景图片。图像并排复制:最初左边的居中,右边的在屏幕外。两张图片 (SKSpriteNode) 都设置了动画以在屏幕上滑动,然后在移动了整个帧宽后重置它们的位置。

相关代码如下:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

    private var background = SKSpriteNode()

    func makeBackground() {
        let texture = SKTexture(imageNamed: "bg-empty")
        let scroll = SKAction.move(by: CGVector(dx: -texture.size().width, dy: 0), duration: 30)
        let reset = SKAction.move(by: CGVector(dx: texture.size().width, dy: 0), duration: 0)
        let animation = SKAction.repeatForever(SKAction.sequence([scroll, reset]))

        for idx in 0...1 {
            background = SKSpriteNode(texture: texture)
            background.position = CGPoint(x: CGFloat(idx)*texture.size().width, y: self.frame.midY)
            background.zPosition = -1
            background.run(animation)
            self.addChild(background)
        }
    }

    override func didMove(to view: SKView) {        
        makeBackground()
    }    
}

虽然这有效,但我注意到在连接接缝处出现了一个特殊的黑色(约 1 像素垂直条带)闪烁。

是什么导致了这种闪烁,我该如何消除它?

您遇到了浮点舍入错误。这将导致您的第一个 BG 向下舍入,而第二个 BG 向上舍入,给您一个 1 像素的差距。

改为尝试以下代码

class GameScene: SKScene {

    private var background = SKNode()

    func makeBackground() {
        let texture = SKTexture(imageNamed: "bg-empty")
        let scroll = SKAction.move(by: CGVector(dx: -texture.size().width, dy: 0), duration: 30)
        let reset = SKAction.move(by: CGVector(dx: texture.size().width, dy: 0), duration: 0)
        let animation = SKAction.repeatForever(SKAction.sequence([scroll, reset]))

        for idx in 0...1 {
            let subNode = SKSpriteNode(texture: texture)
            subNode.position = CGPoint(x: CGFloat(idx)*texture.size().width, y: self.frame.midY)

            background.addChild(subNode)
        }
        background.zPosition = -1
        background.run(animation)
        self.addChild(background)
    }

    override func didMove(to view: SKView) {        
        makeBackground()
    }    
}

现在你可以避免差距,因为你不是运行 2个不同的动作。

如果您希望能够双向滚动。然后在背景的左边放置一个纹理。

这将在主背景之前和之后放置一个背景节点,实际上将其变成 1 个大节点,只完整显示中间纹理。

如果您有多个背景图片,则只需将背景的最后一帧也放在左侧