发布
社区首页 >问答首页 >SpriteKit中具有深度的背景动画

SpriteKit中具有深度的背景动画
EN

Stack Overflow用户
提问于 2016-09-02 18:04:14
回答 3查看 2.1K关注 0票数 7

我正在构建我的第一个游戏使用Swift和SpriteKit,并希望添加一个背景。游戏在太空中进行,所以我想让背景中的星星以不同的速度运动。目前,我将通过使较大的恒星在屏幕上的移动速度比小的恒星更快的速度来实现3D的外观。是否有一种有效的方法来做到这一点,而不是像这样创建一个SKNode子类,并在DidMoveToView开始时将它作为子类添加?这个方法似乎相当密集,但我想在重复使用相同的图像之前,我应该尝试一下。

代码语言:javascript
代码运行次数:0
复制
class BackGroundAnimation:SKNode{

let theView:SKView
init(aView:SKView){

    theView = aView

    super.init()

    animate()
}


func animate(){


    for _ in 1...200{

        let randomSize = random(1, max: 3)
        var randomPosx = random(1,max: 1000)
        randomPosx = randomPosx/1000.0
        var randomPosy = random(1,max: 1000)
        randomPosy = randomPosy/1000.0

        let star:SKSpriteNode = SKSpriteNode(texture:starTexture)
        star.setScale(randomSize/60.0)



        star.position = CGPoint(x:(theView.scene?.size.width)! * randomPosx,y:(theView.scene?.size.width)! * randomPosy)//    (self.scene.size.width)*randomPosx, y:(self.scene.size.height) * randomPosy)

        //star.position = CGPoint(x: 200,y: 200)

        star.physicsBody = SKPhysicsBody(circleOfRadius: star.size.width/2 )
        star.physicsBody?.collisionBitMask = 0
        star.physicsBody?.categoryBitMask = 0
        star.physicsBody?.contactTestBitMask = 0

        star.physicsBody?.linearDamping = 0
        star.physicsBody?.velocity = CGVector(dx:1 * randomSize, dy:0)
        star.name = "star"

        //addChild(star)
        self.addChild(star)
        self.moveToParent(self.scene!)


    }


}




required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

}

任何帮助都会很好。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-03 00:23:14

正如我在评论中提到的,您可以使用粒子创建一个美丽的视差背景。

在类中的任何位置添加此函数。

代码语言:javascript
代码运行次数:0
复制
//Creates a new star field
func starfieldEmitterNode(speed speed: CGFloat, lifetime: CGFloat, scale: CGFloat, birthRate: CGFloat, color: SKColor) -> SKEmitterNode {
    let star = SKLabelNode(fontNamed: "Helvetica")
    star.fontSize = 80.0
    star.text = "✦"
    let textureView = SKView()
    let texture = textureView.textureFromNode(star)
    texture!.filteringMode = .Nearest

    let emitterNode = SKEmitterNode()
    emitterNode.particleTexture = texture
    emitterNode.particleBirthRate = birthRate
    emitterNode.particleColor = color
    emitterNode.particleLifetime = lifetime
    emitterNode.particleSpeed = speed
    emitterNode.particleScale = scale
    emitterNode.particleColorBlendFactor = 1
    emitterNode.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMaxY(frame))
    emitterNode.particlePositionRange = CGVector(dx: CGRectGetMaxX(frame), dy: 0)
    emitterNode.particleSpeedRange = 16.0

    //Rotates the stars
    emitterNode.particleAction = SKAction.repeatActionForever(SKAction.sequence([
        SKAction.rotateByAngle(CGFloat(-M_PI_4), duration: 1),
        SKAction.rotateByAngle(CGFloat(M_PI_4), duration: 1)]))

    //Causes the stars to twinkle
    let twinkles = 20
    let colorSequence = SKKeyframeSequence(capacity: twinkles*2)
    let twinkleTime = 1.0 / CGFloat(twinkles)
    for i in 0..<twinkles {
        colorSequence.addKeyframeValue(SKColor.whiteColor(),time: CGFloat(i) * 2 * twinkleTime / 2)
        colorSequence.addKeyframeValue(SKColor.yellowColor(), time: (CGFloat(i) * 2 + 1) * twinkleTime / 2)
    }
    emitterNode.particleColorSequence = colorSequence

    emitterNode.advanceSimulationTime(NSTimeInterval(lifetime))
    return emitterNode
}

然后再添加这个函数。这就是创造恒星层的功能。只需调用此函数,如在didMoveToView中。

代码语言:javascript
代码运行次数:0
复制
func createStarLayers() {
    //A layer of a star field
    let starfieldNode = SKNode()
    starfieldNode.name = "starfieldNode"
    starfieldNode.addChild(starfieldEmitterNode(speed: -48, lifetime: size.height / 23, scale: 0.2, birthRate: 1, color: SKColor.lightGrayColor()))
    addChild(starfieldNode)

    //A second layer of stars
    var emitterNode = starfieldEmitterNode(speed: -32, lifetime: size.height / 10, scale: 0.14, birthRate: 2, color: SKColor.grayColor())
    emitterNode.zPosition = -10
    starfieldNode.addChild(emitterNode)

    //A third layer
    emitterNode = starfieldEmitterNode(speed: -20, lifetime: size.height / 5, scale: 0.1, birthRate: 5, color: SKColor.darkGrayColor())
    starfieldNode.addChild(emitterNode)
}

这就是它的样子。

票数 9
EN

Stack Overflow用户

发布于 2017-11-04 06:20:33

Swift 4 / iOS 11更新@JozemiteApps解决方案

在类中的任何位置添加此函数。

代码语言:javascript
代码运行次数:0
复制
//Creates a new star field
func starfieldEmitterNode(speed speed: CGFloat, lifetime: CGFloat, scale: CGFloat, birthRate: CGFloat, color: SKColor) -> SKEmitterNode {
    let star = SKLabelNode(fontNamed: "Helvetica")
    star.fontSize = 80.0
    star.text = "✦"
    let textureView = SKView()
    let texture = textureView.texture(from: star)
    texture!.filteringMode = .nearest

    let emitterNode = SKEmitterNode()
    emitterNode.particleTexture = texture
    emitterNode.particleBirthRate = birthRate
    emitterNode.particleColor = color
    emitterNode.particleLifetime = lifetime
    emitterNode.particleSpeed = speed
    emitterNode.particleScale = scale
    emitterNode.particleColorBlendFactor = 1
    emitterNode.position = CGPoint(x: frame.midX, y: frame.maxY)
    emitterNode.particlePositionRange = CGVector(dx: frame.maxX, dy: 0)
    emitterNode.particleSpeedRange = 16.0

    //Rotates the stars
    emitterNode.particleAction = SKAction.repeatForever(SKAction.sequence([
        SKAction.rotate(byAngle: CGFloat(-Double.pi/4), duration: 1),
        SKAction.rotate(byAngle: CGFloat(Double.pi/4), duration: 1)]))

    //Causes the stars to twinkle
    let twinkles = 20
    let colorSequence = SKKeyframeSequence(capacity: twinkles*2)
    let twinkleTime = 1.0 / CGFloat(twinkles)
    for i in 0..<twinkles {
        colorSequence.addKeyframeValue(SKColor.white,time: CGFloat(i) * 2 * twinkleTime / 2)
        colorSequence.addKeyframeValue(SKColor.yellow, time: (CGFloat(i) * 2 + 1) * twinkleTime / 2)
    }
    emitterNode.particleColorSequence = colorSequence

    emitterNode.advanceSimulationTime(TimeInterval(lifetime))
    return emitterNode
}

然后再添加这个函数。这就是创造恒星层的功能。只需调用此函数,如在didMoveToView中。

代码语言:javascript
代码运行次数:0
复制
func createStarLayers() {
        //A layer of a star field
        let starfieldNode = SKNode()
        starfieldNode.name = "starfieldNode"
        starfieldNode.addChild(starfieldEmitterNode(speed: -48, lifetime: size.height / 23, scale: 0.2, birthRate: 1, color: SKColor.lightGray))
        addChild(starfieldNode)

        //A second layer of stars
        var emitterNode = starfieldEmitterNode(speed: -32, lifetime: size.height / 10, scale: 0.14, birthRate: 2, color: SKColor.gray)
        emitterNode.zPosition = -10
        starfieldNode.addChild(emitterNode)

        //A third layer
        emitterNode = starfieldEmitterNode(speed: -20, lifetime: size.height / 5, scale: 0.1, birthRate: 5, color: SKColor.darkGray)
        starfieldNode.addChild(emitterNode)
    }
票数 3
EN

Stack Overflow用户

发布于 2016-09-04 12:56:27

要做到这一点,没有粒子,你可以创建层,只需移动各个层。

所以创建一个背景SKNode,用你的背景精灵填充它

创建一个前台SKNode,用前景精灵填充它。

添加背景作为前景的子元素,给它至少-1的zPosition。

然后你移动前景,无论你移动前景,你移动的背景向相反的方向,通常以较小的百分比(我喜欢使用一半)。如果前景向左移动10个像素,则向右移动背景5个像素。

因为您的所有节点都在这些层中,所以当您移动该层时,所有节点都会移动。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39298383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档