Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何将两种纹理组合为一种_Ios_Swift_Sprite Kit_Sktexture - Fatal编程技术网

Ios 如何将两种纹理组合为一种

Ios 如何将两种纹理组合为一种,ios,swift,sprite-kit,sktexture,Ios,Swift,Sprite Kit,Sktexture,我试图为一个游戏创建一个背景,并有两个背景图像。我可以使用两种不同的SKSpriteNode(),SKTexture,SKAction.sequence..等和一些数学来将它们缝合在一起,但结果有点不稳定,而且我似乎无法得到正确的数学结果。他们应该能够结合起来,使一个长期变化的背景,但它总是偏移 有人能告诉我如何将两种纹理组合成一种,这样我就不必在数学上伤脑筋了。或者如果有人发现我的数学错误,你能指出吗?两个背景的宽度相同,为1200像素 override func didMoveToView(

我试图为一个游戏创建一个背景,并有两个背景图像。我可以使用两种不同的SKSpriteNode(),SKTexture,SKAction.sequence..等和一些数学来将它们缝合在一起,但结果有点不稳定,而且我似乎无法得到正确的数学结果。他们应该能够结合起来,使一个长期变化的背景,但它总是偏移

有人能告诉我如何将两种纹理组合成一种,这样我就不必在数学上伤脑筋了。或者如果有人发现我的数学错误,你能指出吗?两个背景的宽度相同,为1200像素

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    var bgTexture = SKTexture(imageNamed: "bg_2_midground_1.png")
    var bgTexture2 = SKTexture(imageNamed: "bg_2_midground_2.png")

    var totalBG = bgTexture.size().width + bgTexture2.size().width

    var moveBG1 = SKAction.moveByX(-bgTexture.size().width, y: 0, duration: 12)
    //shift bg back to be able to repeat itself
    var replaceBG1 = SKAction.moveByX(bgTexture.size().width, y: 0, duration: 0.0) //move immediately back to replace self
    var moveBG1Forever = SKAction.repeatActionForever(SKAction.sequence([moveBG1,replaceBG1]))

    var moveBG2 = SKAction.moveByX(-bgTexture2.size().width, y: 0, duration: 12)
    //shift bg back to be able to repeat itself
    var replaceBG2 = SKAction.moveByX(bgTexture2.size().width, y: 0, duration: 0.0) //move immediately back to replace self
    var moveBG2Forever = SKAction.repeatActionForever(SKAction.sequence([moveBG2,replaceBG2]))

    for var i:CGFloat = 0; i<2; i++ {
        var bg = SKSpriteNode(texture: bgTexture)
        var bg2 = SKSpriteNode(texture: bgTexture2)

        bg.position = CGPointMake(bgTexture.size().width/2.0 + bgTexture.size().width * i + bgTexture2.size().width * i, CGRectGetMidY(self.frame))
        bg2.position = CGPointMake(bgTexture.size().width/2.0 + bgTexture2.size().width + bgTexture2.size().width * 2 * i, CGRectGetMidY(self.frame))

        bg.runAction(moveBG1Forever)
        bg2.runAction(moveBG2Forever)

        self.addChild(bg)
        self.addChild(bg2)

        println(bg.position)
        println(bgTexture.size().width)

        println(bg2.position)
        println(bgTexture2.size().width)
    }
覆盖func didMoveToView(视图:SKView){
/*在这里设置场景*/
var bgTexture=SKTexture(图像名为:“bg_2_middground_1.png”)
var bgTexture2=SKTexture(图像名为:“bg_2_middground_2.png”)
var totalBG=bgTexture.size().width+bgTexture2.size().width
var moveBG1=SKAction.moveByX(-bgTexture.size().width,y:0,持续时间:12)
//将bg移回,以便能够重复自身
var replaceBG1=SKAction.moveByX(bgTexture.size().width,y:0,duration:0.0)//立即移回以替换self
var moveBG1Forever=SKAction.repeatActionForever(SKAction.sequence([moveBG1,replaceBG1]))
var moveBG2=SKAction.moveByX(-bgture2.size().width,y:0,持续时间:12)
//将bg移回,以便能够重复自身
var replaceBG2=SKAction.moveByX(bgture2.size().width,y:0,duration:0.0)//立即移回替换self
var moveBG2Forever=SKAction.repeatActionForever(SKAction.sequence([moveBG2,replaceBG2]))

对于var i:CGFloat=0;i而不是使用SKActions,您可以使用
update
功能将所有背景节点移动到一起,在每个节点离开屏幕时将每个节点移动到末尾

为了使事情更易于管理,我们可以创建一个自定义的背景节点

class BackgroundNode : SKNode
{
    override init() {
        super.init()

        var bgTexture1 = SKTexture(imageNamed: "b1.jpg")
        var bgTexture2 = SKTexture(imageNamed: "b2.png")


        let totalBG = bgTexture1.size().width + bgTexture2.size().width

        for index in 0..<2
        {
            var bg1 = SKSpriteNode(texture: bgTexture1)
            var bg2 = SKSpriteNode(texture: bgTexture2)
            bg1.anchorPoint = CGPointMake(0, 0)
            bg2.anchorPoint = CGPointMake(0, 0)

            let i = CGFloat(index)

            bg1.position = CGPointMake(i * bgTexture1.size().width + i * bgTexture2.size().width, 0)
            bg2.position = CGPointMake((i+1) * bgTexture1.size().width + i * bgTexture2.size().width, 0)

            self.addChild(bg1)
            self.addChild(bg2)
            lastNode = bg2
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    var speedOfBackground : CGFloat = 300.0
    var previousTime : CFTimeInterval = -1
    var lastNode : SKSpriteNode!

    func update(currentTime: CFTimeInterval) {

        if previousTime != -1
        {
            var outOfBoundsSprite : SKSpriteNode? = nil
            let deltaX = speedOfBackground * CGFloat(currentTime - previousTime)
            for sknode in self.children
            {
                if let sprite = sknode as? SKSpriteNode
                {
                    sprite.position = CGPointMake(sprite.position.x - deltaX, sprite.position.y)
                    if (sprite.position.x < -sprite.size.width)
                    {
                        outOfBoundsSprite = sprite
                    }
                }
            }
            if (outOfBoundsSprite != nil)
            {
                outOfBoundsSprite?.position.x = lastNode.position.x + lastNode.size.width
                lastNode = outOfBoundsSprite!
            }
        }
        previousTime = currentTime
    }

}

@rakeshbs-你的答案很完美,我确实决定将其扩展一点。这将允许任何人在他们的项目中添加一个图集,并能够设置任意数量图像的滚动背景。但是,要注意一次加载多个资源,如果这样做,你需要将它们从游戏中删除,否则可能会发生不好的事情。=p

import SpriteKit

class BackgroundNode: SKNode {
    override init() {
        super.init()

        // create containers for all the Textures and Nodes
        var backgroundTextures = [SKTexture]()
        var backgroundSpriteNodes = [SKSpriteNode]()

        // load the TextureAtlas for the Background
        let backgroundAtlas : SKTextureAtlas = SKTextureAtlas(named: "BackgroundImages")
        let imagesCount:Int = backgroundAtlas.textureNames.count

        // fetch all of the image resources and store them as both textures and spriteNodes
        for var i = 1; i <= imagesCount; i++ {
            let imageTextureName = "background_\(i)"
            let imageTexture = backgroundAtlas.textureNamed(imageTextureName)

            let spriteNode = SKSpriteNode(texture: imageTexture)
            spriteNode.anchorPoint = CGPointMake(0, 0)

            backgroundTextures.append(imageTexture)
            backgroundSpriteNodes.append(spriteNode)
        }

        // for each image figure out what the x value of the location should be
        for var i = 0; i < imagesCount; i++ {
            var addtionalWidth:CGFloat = 0

            // add the x value of all the images before this image to come up with the latest x
            for var j = 0; j < i; j++ {
                addtionalWidth += backgroundTextures[j].size().width
            }

            // assign each SKNode a position
            backgroundSpriteNodes[i].position = CGPointMake(0 + addtionalWidth, 0)

            // add the Node to the scene
            self.addChild(backgroundSpriteNodes[i])
        }

        // keep track of where you are to reset scrolls images
        lastNode = backgroundSpriteNodes[imagesCount - 1]
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    var speedOfBackground : CGFloat = 300.0
    var previousTime : CFTimeInterval = -1
    var lastNode : SKSpriteNode!

    func update(currentTime: CFTimeInterval) {
        if previousTime != -1 {
            var outOfBoundsSprite : SKSpriteNode? = nil
            let deltaX = speedOfBackground * CGFloat(currentTime - previousTime)

            for sknode in self.children {
                if let sprite = sknode as? SKSpriteNode {
                    sprite.position = CGPointMake(sprite.position.x - deltaX, sprite.position.y)

                    if (sprite.position.x < -sprite.size.width) {
                        outOfBoundsSprite = sprite
                    }
                }
            }

            if (outOfBoundsSprite != nil) {
                outOfBoundsSprite?.position.x = lastNode.position.x + lastNode.size.width
                lastNode = outOfBoundsSprite!
            }
        }

        previousTime = currentTime
    }

}
导入SpriteKit
类背景节点:SKNode{
重写init(){
super.init()
//为所有纹理和节点创建容器
var backgroundTextures=[SKTexture]()
var backgroundSpriteNodes=[SKSpriteNode]()
//加载背景的TextureAtlas
let backgroundAtlas:SKTextureAtlas=SKTextureAtlas(命名为:“BackgroundImages”)
让ImageScont:Int=backgroundAtlas.textureNames.count
//获取所有图像资源并将其存储为纹理和spriteNodes

对于var i=1;i,那么你需要什么?你想在第一个背景开始移动后进入第二个背景?并永远像那样循环?完全正确…或者将两个纹理组合成一个,这样我就可以永远循环一个,它看起来是正确的。现在一些边不合适,因为我的数学显然是错误的这是一个好的解决方案@rakeshbs除非(sprite.position.x<-sprite.size.width){sprite.position.x=lastNode.position.x+lastNode.size.width lastNode=sprite}将在sprite.position.x<-sprite.size()时使位置偏移过多.width值中记录了一个偏移量。速度越高,偏移量越大,我就在我开始的位置。你的背景精灵有多大?你尝试过上面的代码吗?我在最后一个节点后添加一个离开屏幕的节点,并使其成为每次使用的最后一个节点是的,我使用了精确的代码,但始终存在一个间隙b在第一个精灵和新添加的精灵之间。当您增加/减少速度时,间距会增加/减少。我认为这是由于lastNode.position.x在传递到sprite.position.x=lastNode.position.x+lastNode.size.width时不是1200的精确倍数
import SpriteKit

class BackgroundNode: SKNode {
    override init() {
        super.init()

        // create containers for all the Textures and Nodes
        var backgroundTextures = [SKTexture]()
        var backgroundSpriteNodes = [SKSpriteNode]()

        // load the TextureAtlas for the Background
        let backgroundAtlas : SKTextureAtlas = SKTextureAtlas(named: "BackgroundImages")
        let imagesCount:Int = backgroundAtlas.textureNames.count

        // fetch all of the image resources and store them as both textures and spriteNodes
        for var i = 1; i <= imagesCount; i++ {
            let imageTextureName = "background_\(i)"
            let imageTexture = backgroundAtlas.textureNamed(imageTextureName)

            let spriteNode = SKSpriteNode(texture: imageTexture)
            spriteNode.anchorPoint = CGPointMake(0, 0)

            backgroundTextures.append(imageTexture)
            backgroundSpriteNodes.append(spriteNode)
        }

        // for each image figure out what the x value of the location should be
        for var i = 0; i < imagesCount; i++ {
            var addtionalWidth:CGFloat = 0

            // add the x value of all the images before this image to come up with the latest x
            for var j = 0; j < i; j++ {
                addtionalWidth += backgroundTextures[j].size().width
            }

            // assign each SKNode a position
            backgroundSpriteNodes[i].position = CGPointMake(0 + addtionalWidth, 0)

            // add the Node to the scene
            self.addChild(backgroundSpriteNodes[i])
        }

        // keep track of where you are to reset scrolls images
        lastNode = backgroundSpriteNodes[imagesCount - 1]
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    var speedOfBackground : CGFloat = 300.0
    var previousTime : CFTimeInterval = -1
    var lastNode : SKSpriteNode!

    func update(currentTime: CFTimeInterval) {
        if previousTime != -1 {
            var outOfBoundsSprite : SKSpriteNode? = nil
            let deltaX = speedOfBackground * CGFloat(currentTime - previousTime)

            for sknode in self.children {
                if let sprite = sknode as? SKSpriteNode {
                    sprite.position = CGPointMake(sprite.position.x - deltaX, sprite.position.y)

                    if (sprite.position.x < -sprite.size.width) {
                        outOfBoundsSprite = sprite
                    }
                }
            }

            if (outOfBoundsSprite != nil) {
                outOfBoundsSprite?.position.x = lastNode.position.x + lastNode.size.width
                lastNode = outOfBoundsSprite!
            }
        }

        previousTime = currentTime
    }

}