【问题标题】:sprite kit collision not working精灵套件碰撞不起作用
【发布时间】:2018-05-01 00:03:23
【问题描述】:

这是我一直在开发的游戏。总之,有一个名为敌人的移动块,我希望它与一个名为 invisibleGround2 的不可见静态块发生碰撞。当它们应该碰撞但它们没有碰撞时,我会打印它。我已经通过 apply 和其他人阅读了所有快速碰撞文档,但我不知道出了什么问题。任何帮助将不胜感激!

import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    var orb = SKSpriteNode(imageNamed: "orb")
    var scrollingG:scrollingGround?
    var invisibleGround = SKSpriteNode(imageNamed: "invisible")
    var invisibleGround2 = SKSpriteNode(imageNamed: "invisible")

    let enemies = [SKSpriteNode(imageNamed: "blueE.png"), SKSpriteNode(imageNamed: "redE.png")]
    let enemyCategory : UInt32 = 1
    let jumperCategory : UInt32 = 1
    let rotateDuration = 2
    let enemyMoveSpeed = 5
    let groundScrollingSpeed = 5

    func createOrb(){
        let orbConst = frame.size.width/2
         let xConstraint = SKConstraint.positionX(SKRange(constantValue: orbConst))
        orb.position = CGPoint(x: frame.size.width/2, y: 480)
        orb.physicsBody = SKPhysicsBody(texture: orb.texture!, size: orb.texture!.size())
        orb.constraints = [xConstraint]

        self.addChild(orb)
        }

    func createScrollingGround () {
        scrollingG = scrollingGround.scrollingNodeWithImage(imageName: "ground", containerWidth: self.size.width)
        scrollingG?.scrollingSpeed = CGFloat(groundScrollingSpeed)
        scrollingG?.anchorPoint = .zero
        self.addChild(scrollingG!)
    }

    func createGround(){
        invisibleGround2.size.width = 1
        invisibleGround2.size.height = 1
        invisibleGround2.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width:1, height: 100))
        invisibleGround2.physicsBody?.isDynamic = false
        invisibleGround2.position = CGPoint(x: 530, y: 191)
        invisibleGround2.physicsBody?.categoryBitMask = jumperCategory
        invisibleGround2.physicsBody?.collisionBitMask = enemyCategory
        invisibleGround2.physicsBody?.contactTestBitMask = enemyCategory

        invisibleGround2.name = "jumper"
        invisibleGround.position = CGPoint(x: 0, y: 190)
        invisibleGround.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.size.width * 3, height: 10))
        invisibleGround.physicsBody?.isDynamic = false
        self.addChild(invisibleGround2)
        self.addChild(invisibleGround)
    }

    func getRandomEnemy(fromArray array:[SKSpriteNode])->SKSpriteNode{
        return array[Int(arc4random_uniform(UInt32(array.count)))]
    }

    func spawnEnemy() {
        if let enemy = getRandomEnemy(fromArray: enemies).copy() as? SKSpriteNode {
            enemy.position = CGPoint(x: frame.size.width + frame.size.width/3, y: 440)
            enemy.physicsBody = SKPhysicsBody(texture: enemy.texture!, size: enemy.texture!.size())
            if enemy.size.width < 95 {
                 enemy.physicsBody?.categoryBitMask = enemyCategory
               enemy.physicsBody?.collisionBitMask = jumperCategory
                enemy.physicsBody?.contactTestBitMask = jumperCategory
            }
            enemy.name = "enemy"
            self.addChild(enemy)
            let moveLeft = SKAction.moveBy(x: -1500, y: 0, duration: TimeInterval(enemyMoveSpeed))
            enemy.run(moveLeft)
        }
    }

    func addEnemies () {
        self.run(SKAction.repeatForever(SKAction.sequence([SKAction.run {
            self.spawnEnemy()
        }, SKAction.wait(forDuration: 4)])))
    }

    func jump() {
        orb.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 335))
    }

    func rotate() {
        let rotate = SKAction.rotate(byAngle: CGFloat(M_PI * -2.55), duration: TimeInterval(rotateDuration))
        let repeatAction = SKAction.repeatForever(rotate)
        orb.run(repeatAction)
    }

    override func didMove(to view: SKView) {
        createScrollingGround()
        createOrb()
        createGround()
        rotate()
        addEnemies()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        jump()
    }

    override func update(_ currentTime: TimeInterval) {
        if self.scrollingG != nil {
            scrollingG?.update(currentTime: currentTime)

            func didBegin(_ contact: SKPhysicsContact) {
                let bodyA = contact.bodyA.categoryBitMask
                let bodyB = contact.bodyB.categoryBitMask

                if bodyA == jumperCategory && bodyB == enemyCategory {

                    print("hit")
                } else if  bodyA == enemyCategory && bodyB == jumperCategory {
                    print("hit 2")
                }
            }
        }
    }
}

【问题讨论】:

  • 为什么didBegin函数在update函数里面?
  • 以便它始终在测试联系。我已经在它之外尝试过,它没有任何区别。
  • 首先,您似乎不是 SKPhysaicsContact 代表,而且 - 正如 maddy 指出的那样 - didBegin 永远不会在 update 旁边工作。

标签: swift sprite-kit collision


【解决方案1】:

不是一个答案,而是一些需要检查的东西:

  • 您是否将场景的物理世界delegate 属性设置为 self?
  • didBegin 移出update
  • “敌人”精灵的宽度是否
  • 添加一个print("Contact detected") 作为您重新定位的didBegin 的第一行,这样您至少知道已检测到一些 联系人。

在这里查看我的回答https://stackoverflow.com/a/43605825/1430420 以获得一个简单的 SK 碰撞演示,这可能会有所帮助 - 我认为它需要更新到 Swift 4,我会尝试这样做。

【讨论】:

  • 具体来说,他可能是在场景呈现时在ViewController中设置物理世界,所以应该是scene.delegate = scene(场景中的场景变量相当于self)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 2012-03-04
相关资源
最近更新 更多