代码之家  ›  专栏  ›  技术社区  ›  Jack Richards

Sprite套件Swift中的碰撞检测

  •  2
  • Jack Richards  · 技术社区  · 7 年前

    这是我第一次用iOS制作游戏,所以很自然地我遇到了几个问题。我已经设法解决了这些问题,但现在说到马里奥和管道之间的碰撞部分,我遇到了一些麻烦:

    实际发生的情况:

    未检测到任何碰撞。

    import SpriteKit
    import GameplayKit
    
    class GameScene: SKScene, SKPhysicsContactDelegate {
    
        var mario = SKSpriteNode()
    
        enum ColliderType: UInt32 {
    
            case Mario = 1
            case Object = 2
        }
    
        func addPipes() {
    
            let pipetexture = SKTexture(imageNamed: "pipes")
    
            let pipes = SKSpriteNode(texture: pipetexture)
    
            let setScale = CGFloat(arc4random_uniform(19) + 15)
    
            pipes.setScale(setScale) //min 15, max 19
    
            pipes.position = CGPoint(x: self.frame.maxX, y: self.frame.minY)
    
            let movePipes = SKAction.move(by: CGVector(dx: -5 * self.frame.width, dy: 0), duration: TimeInterval(self.frame.width/100))
    
            let removePipes = SKAction.removeFromParent()
    
            let moveAndRemovePipes = SKAction.sequence([movePipes, removePipes])
    
            pipes.zPosition = +1
    
            pipes.physicsBody = SKPhysicsBody(rectangleOf: pipes.size)
    
            pipes.physicsBody!.isDynamic = false
    
            pipes.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue
            pipes.physicsBody!.categoryBitMask = ColliderType.Object.rawValue
            pipes.physicsBody!.collisionBitMask = ColliderType.Mario.rawValue
    
            self.addChild(pipes)
    
            pipes.run(moveAndRemovePipes)
    
        }
    
        func didBegin(_ contact: SKPhysicsContact) {
            print("contact")
        }
    
        override func didMove(to view: SKView) {
    
            self.physicsWorld.contactDelegate = self
    
            _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.addPipes), userInfo: nil, repeats: true)
    
            let marioTexture = SKTexture(imageNamed: "mariorun0.png")
            let marioTexture2 = SKTexture(imageNamed: "mariorun1.png")
            let marioTexture3 = SKTexture(imageNamed: "mariorun2.png")
    
            let animation = SKAction.animate(with: [marioTexture, marioTexture2, marioTexture3], timePerFrame: 0.1)
    
            let makeMarioRun = SKAction.repeatForever(animation)
    
            mario = SKSpriteNode(texture: marioTexture)
    
            mario.setScale(10)
    
            mario.position = CGPoint(x: -(self.frame.size.width/3.5), y: -(self.frame.size.height/2.8))
    
            mario.run(makeMarioRun)
    
            mario.physicsBody = SKPhysicsBody(rectangleOf: mario.size)
    
            mario.physicsBody!.isDynamic = false
    
            mario.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue
            mario.physicsBody!.categoryBitMask = ColliderType.Mario.rawValue
            mario.physicsBody!.collisionBitMask = ColliderType.Object.rawValue
    
            self.addChild(mario)
    
    
            addPipes()
    
            mario.zPosition = +2
    
        }
    
    }
    

    我已经尝试将两个精灵的z位置设置为相同的值,但没有任何运气。

    我最初担心的是图像太小,因此碰撞几乎无法检测到。但是,由于我正在放大两个节点,并使用放大图像的物理体,因此不会出现问题,但这也没有帮助。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Knight0fDragon    7 年前

    physicsBody!.isDynamic = false

    这对于管道来说是有意义的,因为管道从不移动,所以没有理由是动态的。(如果你在玩flappy bird esc游戏,你的世界应该在移动,而不是管道)

    现在对于马里奥来说,这是没有意义的。马里奥是一个移动的实体,因此他将与世界各地的物理世界互动。为了解决你的问题,你需要让他充满活力 mario.physicsBody!.isDynamic = true