Sprite套件中的碰撞检测Swift

问题描述:

这是我第一次在iOS上制作游戏,所以我自然遇到了一些问题。我已经成功地解决这些问题,但现在,它来到马里奥,我遇到了一些麻烦的管之间的碰撞部:Sprite套件中的碰撞检测Swift

我想这样做:

当马里奥与管道碰撞,他将不得不跳过他们去对方。如果他不这样做,那么管道将继续“推”他到游戏结束的屏幕边缘。

实际发生了什么:

没有发现任何碰撞。

这里是下面的代码:

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位置设置为相同的值,但没有任何运气。

我最初的担心是图像很小,因此几乎不可能检测到碰撞。但是,由于我扩大了两个节点,并使用放大图像的物理体,所以不存在问题,但这也没有帮助。

感谢您的帮助提前。

+0

这行代码是不必要的:'pipes.physicsBody!.contactTestBitMask = ColliderType .Object.rawValue'。首先,这意味着管道在与自己联系时通知管道,但是如果您已正确设置Mario与管道接触,则可以删除此管道,因此没有必要让管道与Mario联系。您已正确设置了碰撞。 –

physicsBody!.isDynamic = false表示该物体不会发生任何物理活动。其他机构可以与它互动,但它不会与任何事物互动。

这对管道来说是有意义的,因为管道永远不会移动,所以没有理由是动态的。 (如果你正在做一个flappy bird-esc游戏,你的世界应该移动,而不是管道)

现在对于马里奥来说,这没有任何意义。马里奥是一个移动的实体,所以他将与周围的物理世界进行交互。要解决你的问题,你需要让他动态mario.physicsBody!.isDynamic = true

+0

这就是我需要的,谢谢! –