【问题标题】:Swift spritekit didbegincontact being called with delaySwift spritekit didbegincontact 被延迟调用
【发布时间】:2019-02-27 11:54:17
【问题描述】:

这是我的GameScene 代码。

class GameScene: SKScene, SKPhysicsContactDelegate {

    let orcWidth = UIScreen.main.bounds.width / 5

    var orcCategory:UInt32 = 0x1 << 0
    var knightCategory:UInt32 = 0x1 << 1

    private var orc = SKSpriteNode()
    private var  knight = SKSpriteNode()
    private var orcWalkingFrames: [SKTexture] = []
    private var knightIdleFrames: [SKTexture] = []
    private var knightAttackFrame: [SKTexture] = []
    var background = SKSpriteNode(imageNamed: "game_background1")

    override func didMove(to view: SKView) {
        physicsWorld.contactDelegate = self
        physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        setupbackground()
        startGame()
    }

    func setupbackground() {
        background.zPosition = 0
        background.size = self.frame.size
        background.position = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
        addChild(background)
    }

    func startGame() {
        buildRandomOrcs()
        buildKnight()
    }

    func stopGame() {
    }

    func buildOrc(yposition: CGFloat) {
        var orcWalkFrames: [SKTexture] = []
        let orcAnimatedAtlas = SKTextureAtlas(named: "OrcWalking")

        let numImages = orcAnimatedAtlas.textureNames.count
        for i in 0...numImages - 1 {
            let orcTextureName = "0_Orc_Walking_\(i)"
            orcWalkFrames.append(orcAnimatedAtlas.textureNamed(orcTextureName))
        }
        self.orcWalkingFrames = orcWalkFrames

        let firstFrameTexture = orcWalkingFrames[0]
        orc = SKSpriteNode(texture: firstFrameTexture)
        orc.name = "orc"
        orc.position = CGPoint(x: frame.minX-orcWidth/2, y: yposition)
        self.orc.zPosition = CGFloat(self.children.count)
        orc.scale(to: CGSize(width: orcWidth, height: orcWidth))
        orc.physicsBody = SKPhysicsBody(rectangleOf: orc.size, center: orc.position)
        orc.physicsBody?.affectedByGravity = false
        orc.physicsBody?.isDynamic = true
        orc.physicsBody?.categoryBitMask = orcCategory
        orc.physicsBody?.contactTestBitMask = knightCategory
        orc.physicsBody?.collisionBitMask = knightCategory
        addChild(orc)
        walkOrc()
        moveOrcForward()
    }

    func buildKnight() {
        var knightIdleFrames: [SKTexture] = []
        let knightIdleAtlas = SKTextureAtlas(named: "KnightIdle")

        let numImages = knightIdleAtlas.textureNames.count
        for i in 0...numImages - 1 {
            let orcTextureName = "_IDLE_00\(i)"
            knightIdleFrames.append(knightIdleAtlas.textureNamed(orcTextureName))
        }
        self.knightIdleFrames = knightIdleFrames

        let firstFrameTexture = knightIdleFrames[0]
        knight = SKSpriteNode(texture: firstFrameTexture)
        knight.name = "knight"
        knight.position = CGPoint(x: frame.maxX-orcWidth/2, y: frame.midY)
        self.knight.zPosition = 1
        knight.scale(to: CGSize(width: -orcWidth, height: orcWidth))
        knight.physicsBody = SKPhysicsBody(rectangleOf: knight.size, center: knight.position)
        knight.physicsBody?.affectedByGravity = false
        knight.physicsBody?.isDynamic = false
        knight.physicsBody?.categoryBitMask     = knightCategory
        knight.physicsBody?.contactTestBitMask = orcCategory
        knight.physicsBody?.collisionBitMask     = orcCategory
        addChild(knight)
        idleKnight()
    }

    func idleKnight() {
        knight.run(SKAction.repeatForever(SKAction.animate(with: knightIdleFrames, timePerFrame: 0.1)))
    }

    func walkOrc() {
        orc.run(SKAction.repeatForever(SKAction.animate(with: orcWalkingFrames,timePerFrame: 0.025)))
    }

    func moveOrcForward() {
        orc.run(SKAction.repeatForever(SKAction.moveBy(x: 55, y: 0, duration: 0.25)))
    }

    func buildRandomOrcs () {
        let wait = SKAction.wait(forDuration: TimeInterval(makeRandomNumberBetween(min: 0, max: 0)))
        let spawn = SKAction.run {
            self.buildOrc(yposition: self.makeRandomCGFloatNumber())
        }

        let spawning = SKAction.sequence([spawn,wait])

        self.run(SKAction.repeat(spawning, count: 10))
    }

    func makeRandomCGFloatNumber() -> CGFloat {
        let randomNumber = arc4random_uniform(UInt32((frame.maxY-orcWidth/2) - (frame.minY+orcWidth/2))) + UInt32(frame.minY+orcWidth/2)
        return CGFloat(randomNumber)

    }

    func makeRandomNumberBetween (min: Int, max: Int) -> Int{
        let randomNumber = arc4random_uniform(UInt32(max - min)) + UInt32(min)
        return Int(randomNumber)
    }


    func didBegin(_ contact: SKPhysicsContact) {
        let collision:UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
        if collision == orcCategory | knightCategory {
            self.scene?.view?.isPaused = true
            print("COLLIDED")
        }
    }
}

问题是场景在碰撞后几乎暂停了 2-3 秒。 我更改了knightposition,延迟时间也更改了。

例如,如果我将位置设置为frame.minX+orcWidth/2,则没有延迟。

我的代码有什么问题?

【问题讨论】:

    标签: swift sprite-kit skspritenode


    【解决方案1】:

    您的问题不是事情被延迟了,您的问题是您的边界框不在您认为的位置

    使用view.showPhysics = true 确定您的箱子在哪里

    一旦你意识到他们在错误的位置,就去这一行

    knight.physicsBody = SKPhysicsBody(rectangleOf: knight.size, center: knight.position)
    

    并修复它

    knight.physicsBody = SKPhysicsBody(rectangleOf: knight.size)
    

    对你身体的其余部分这样做

    【讨论】:

      【解决方案2】:

      我的猜测是SKView 属性的操作必须发生在主线程上,即

      DispatchQueue.main.async { [unowned self] in
          self.scene?.view?.isPaused = true
          print("COLLIDED")
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多