2017-08-21 53 views
0

我在SpriteKit游戏中检测到碰撞时遇到了一些困难。我只是想检测导弹与敌人和船只之间的碰撞。未检测到碰撞

我有ColliderType:

struct ColliderType { 
static let Boat: UInt32 = 1 
static let Enemy: UInt32 = 2 
static let Wall: UInt32 = 3 
static let Bullet: UInt32 = 4 

} 

class GameplayScene: SKScene, SKPhysicsContactDelegate { 

var player = SKSpriteNode() 
var enemy = SKSpriteNode() 
var boat = SKSpriteNode() 
var missile = SKSpriteNode() 

的didBegin接触:

func didBegin(_ contact: SKPhysicsContact) { 

    var firstBody = SKPhysicsBody() 
    var secondBody = SKPhysicsBody() 

    if contact.bodyA.node?.name == "Missile" { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 
    } else { 
     firstBody = contact.bodyB 
     secondBody = contact.bodyA 
    } 

    if firstBody.node?.name == "Missile" && secondBody.node?.name == 
"Enemy" { 
     incrementScore() 
     secondBody.node?.removeFromParent() 
    } else if firstBody.node?.name == "Missile" && 
secondBody.node?.name == "Boat" { 
     incrementScore() 
    } 

} 
  • 我已经添加在didMove的 “physicsWorld.contactDelegate =自我” toview

我还为所有相关的spritenodes添加了physicsbody:

func fireMissile() { 
    let missile = SKSpriteNode(color: .yellow, size: CGSize(width: 20, 
    height: 5)) 
    missile.name = "Missile" 
    missile.position = CGPoint(x: player.position.x + 28, y: 
    player.position.y + 10) 
    missile.zPosition = 2 
    missile.physicsBody = SKPhysicsBody(rectangleOf: missile.size) 
    missile.physicsBody?.isDynamic = false 
    missile.physicsBody?.categoryBitMask = ColliderType.Bullet 
    missile.physicsBody?.collisionBitMask = ColliderType.Enemy | 
    ColliderType.Boat 
    missile.physicsBody?.contactTestBitMask = ColliderType.Enemy | 
    ColliderType.Boat 


    self.addChild(missile) 

} 


func createEnemies() { 
    let enemy = SKSpriteNode(imageNamed: "Enemy1") 
    enemy.name = "Enemy" 
    enemy.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.size.height 
/2) 
    enemy.physicsBody?.categoryBitMask = ColliderType.Enemy 
    enemy.physicsBody?.affectedByGravity = false 
    enemy.physicsBody?.isDynamic = false 
    enemy.zPosition = 3 

    enemy.position.y = self.frame.height + 100 
    enemy.position.x = CGFloat.randomBetweenNumbers(firstNum: -347.5, 
    secondNum: -85) 


    self.addChild(enemy) 

} 


func createBoat() { 
    let boat = SKSpriteNode(imageNamed: "Boat") 
    boat.name = "Boat" 
    boat.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    boat.physicsBody = SKPhysicsBody(circleOfRadius: boat.size.height/
    2) 
    boat.physicsBody?.categoryBitMask = ColliderType.Boat 
    boat.physicsBody?.affectedByGravity = false 
    boat.physicsBody?.isDynamic = false 
    boat.zPosition = 3 

    boat.position.y = self.frame.height + 100 
    boat.position.x = CGFloat.randomBetweenNumbers(firstNum: 0, 
    secondNum: 0) 


    self.addChild(boat) 


} 

回答

3

首先,你的一些类是错误的:

static let Wall: UInt32 = 3 
static let Bullet: UInt32 = 4 

这有效地Wall定义为既是BoatEnemy。将它们更改为:

static let Wall: UInt32 = 4 
static let Bullet: UInt32 = 8 

(类别应始终是2 - 1,2,4,8,16等的唯一权力)。

其余的看起来不错,所以试试看,让我们知道它是否工作。

编辑:

OK - 只注意到所有你的物理机构有自己的isDynamic属性设置为false - 这意味着,除其他事项外,对身体不会触发接触。所以如果你想要导弹与敌人或船只接触,那么无论是导弹都应该是动态的,或者敌人和船只都应该是动态的(动态的只需要两个物体中的一个)。

+0

我在文档站点上有关于Sprite-Kit中位掩码如何工作的文章很长,但由于文档很快就会被删除,所以我无法再发布链接。 –

+0

我改变了这一点,但它仍然不起作用。我尝试过检测与所有其他类别的碰撞,并且它们都不起作用:/ – Flinigan

+0

好的 - 只是注意到所有的物理实体都将其'isDynamic'属性设置为false - 这意味着除其他外,身体不会触发接触。所以如果你想要“导弹”与“敌方”或“船只”产生接触,那么任何一个导弹都应该是动态的,或者既可以是敌人也可以是小船应该(只有一个接触涉及的物体需要动态) –