【问题标题】:SKTexture not updating properly in Swift/SpriteKitSKTexture 在 Swift/SpriteKit 中没有正确更新
【发布时间】:2015-08-28 02:04:26
【问题描述】:

我正在尝试根据手机的倾斜来更新精灵的图像。我的代码编译,打印倾斜,并说它正在加载图像但是,当我运行应用程序时,当我移动手机时图像不会改变或更新。有什么建议么?我只添加了我认为相关的内容。当我添加假图像文件时,出现错误(SKTexture:加载图像资源时出错:“FAKEIMAGE”)。这告诉我,当我有正确的图像名称时,它会在代码中更新,只是没有显示在我的屏幕上?

func createPlayer() -> SKNode {
    let playerNode = SKNode()
    playerNode.position = CGPoint(x: self.size.width / 2, y: 80.0)
    var playerSprite: SKSpriteNode = SKSpriteNode(imageNamed: "alienPink_swim1")


    playerNode.addChild(playerSprite)


    // 1
    playerNode.physicsBody = SKPhysicsBody(circleOfRadius: playerSprite.size.width / 2)
    // 2
    playerNode.physicsBody?.dynamic = false
    // 3
    playerNode.physicsBody?.allowsRotation = false
    // 4
    playerNode.physicsBody?.restitution = 1.0
    playerNode.physicsBody?.friction = 0.0
    playerNode.physicsBody?.angularDamping = 0.0
    playerNode.physicsBody?.linearDamping = 0.0

    // 1
    playerNode.physicsBody?.usesPreciseCollisionDetection = true
    // 2
    playerNode.physicsBody?.categoryBitMask = CollisionCategoryBitmask.Player
    // 3
    playerNode.physicsBody?.collisionBitMask = 0
    // 4
    playerNode.physicsBody?.contactTestBitMask = CollisionCategoryBitmask.Star | CollisionCategoryBitmask.Platform


    return playerNode
}

func changePlayerSprite() {

    let playerNode = SKNode()
    playerNode.position = CGPoint(x: self.size.width / 2, y: 80.0)
    var playerSprite: SKSpriteNode


    if self.xAcceleration > 0.3{
        playerSprite = SKSpriteNode(imageNamed: "alienPink_swim11")
        println("Right")
        playerNode.addChild(playerSprite)
    }
    else if self.xAcceleration < -0.3{
        playerSprite = SKSpriteNode(imageNamed: "alienPink_swim1")
        println("left")
        playerNode.addChild(playerSprite)
    }
    else {
        playerSprite = SKSpriteNode(imageNamed: "p3_front")
        println("middle")
        playerNode.addChild(playerSprite)
    }

}

覆盖函数更新(当前时间:NSTimeInterval){

        // CoreMotion
        // 1
        motionManager.accelerometerUpdateInterval = 0.2
        // 2
        motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: {
            (accelerometerData: CMAccelerometerData!, error: NSError!) in
            // 3
            let acceleration = accelerometerData.acceleration
            // 4
            self.xAcceleration = (CGFloat(acceleration.x) * 0.75) + (self.xAcceleration * 0.25)


        })


    changePlayerSprite()


}

【问题讨论】:

  • 我认为您可能想检查您尝试加载的图像,对我来说似乎不是与代码相关的问题
  • @MaxKargin - 我尝试更改图像,经过进一步检查,它似乎只会加载我为“中间”编码的图片。无论我使用什么图像文件,似乎都是这样。当我打印 xAcceleration + 图像文件时,它会打印预期的图像和加速度,但它仍然只显示中间图像,即使我向左或向右倾斜手机。
  • 奇怪,我从来没有遇到过这个,但这可能对你有帮助stackoverflow.com/questions/29431567/…

标签: ios swift sprite-kit


【解决方案1】:

GameScene 的更紧凑的实现...

class GameScene: SKScene {
    var node:SKNode!

    override func didMoveToView(view: SKView) {
        var xAcceleration:CGFloat = 0.0
        node = createPlayer()
        // CoreMotion
        if let playerSprite = node.childNodeWithName("playerSprite") as? SKSpriteNode {
            let motionManager = CMMotionManager()
            motionManager.accelerometerUpdateInterval = 0.2
            motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue()) {
                [weak self] accelerometerData, error in

                var acceleration = accelerometerData.acceleration
                xAcceleration = (CGFloat(acceleration.x) * 0.75) + (xAcceleration * 0.25)
                self!.node.position = CGPoint(x: self!.size.width / 2, y: 80.0)
                var texture:SKTexture!
                switch (xAcceleration) {
                case let x where x > 0.3:
                    texture = SKTexture(imageNamed: "alienPink_swim11")
                case let x where x < -0.3:
                    texture = SKTexture(imageNamed: "alienPink_swim1")
                default:
                    texture = SKTexture(imageNamed: "p3_front")
                }
                playerSprite.texture = texture
            }
        }
    }

    func createPlayer() -> SKNode {
        let playerNode = SKNode()
        playerNode.position = CGPoint(x: self.size.width / 2, y: 80.0)
        var playerSprite: SKSpriteNode = SKSpriteNode(imageNamed: "alienPink_swim1")

        playerSprite.name = "playerSprite"
        playerNode.addChild(playerSprite)


        // 1
        playerNode.physicsBody = SKPhysicsBody(circleOfRadius: playerSprite.size.width / 2)
        // 2
        playerNode.physicsBody?.dynamic = false
        // 3
        playerNode.physicsBody?.allowsRotation = false
        // 4
        playerNode.physicsBody?.restitution = 1.0
        playerNode.physicsBody?.friction = 0.0
        playerNode.physicsBody?.angularDamping = 0.0
        playerNode.physicsBody?.linearDamping = 0.0

        // 1
        playerNode.physicsBody?.usesPreciseCollisionDetection = true
        // 2
        playerNode.physicsBody?.categoryBitMask = 1
        // 3
        playerNode.physicsBody?.collisionBitMask = 0
        // 4
        playerNode.physicsBody?.contactTestBitMask = 2


        return playerNode
    }
}

【讨论】:

    【解决方案2】:

    您应该使用 SKAction 方法来更改纹理。它是更清洁的方式。

    https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKAction_Ref/#//apple_ref/occ/clm/SKAction/setTexture:

    类似这样的:

        var node: SKSpriteNode = SKSpriteNode(imageNamed: "imageassetname")
    
        func doMagic() {
            let texture = SKTexture(imageNamed: "p3_front")
            var action:SKAction = SKAction.setTexture(texture)
    
            node.runAction(action)
        }
    

    通过这种方式,您可以在函数中定义角色节点的动作。示例:

     enum pos {
            case top
            case bot
            case left
            case right
        }
    
        var node: SKSpriteNode = SKSpriteNode(imageNamed: "imageassetname")
    
        func doMagic(direction: pos) -> SKAction {
            var texture: SKTexture = SKTexture()
    
            switch direction {
            case .bot:
                texture = SKTexture(imageNamed: "p3_front")
            case .left: let texture = SKTexture(imageNamed: "leftimage")
            default:
                texture = SKTexture(imageNamed: "rightimage")
            }
    
            var action:SKAction = SKAction.setTexture(texture)
    
            return action
        }
    
    
        func change() {
            node.runAction(doMagic(pos.bot))
        }
    

    【讨论】:

    • 这成功了!非常感谢,我真的很感激。你会建议在覆盖函数更新(currentTime:NSTimeInterval)中调用doMagic吗?这就是我现在所说的,但是,似乎有一些滞后(尤其是在我的水平结束时)
    • 你在update每秒60次初始化Core Motion。它不属于那里。这就是为什么您看到延迟而不是此答案中的代码。
    • 感谢您的回复。我将核心运动代码移到了我的 init 方法中,但它仍然给我带来了延迟。
    • 另一个问题是您每秒更改纹理 60 次,但每秒读取加速度计 5 次。
    • @0x141E ,你建议我只在加速度计更新时更改纹理还是反过来做?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多