didBeginContact没有被称为斯威夫特

问题描述:

我正在研究一个应用程序,当*球颜色匹配一个较小的球,正在朝*球颜色飞行球员得分。 所以为了这个工作,我需要didBeginContact函数来调用“敌人”和“mainBall”相撞的时候。唯一移动的是敌方球,因为它飞向固定的主球体 我相信我已经正确设置了位掩码,但didBeginContact函数没有被调用。 有人可以帮忙吗?didBeginContact没有被称为斯威夫特

这里是我的代码

struct bitMasks{ 
static let mainBallMask:UInt32 = 0x1 << 0 
static let enemyBall:UInt32 = 0x1 << 1 
} 
class GameScene: SKScene,SKPhysicsContactDelegate { 

var mainBall = SKSpriteNode() 
var ballSetToMainColor = true 
var enemyTimer = Timer() 
var hits = 0 

override func didMove(to view: SKView) { 
    self.physicsWorld.contactDelegate = self 
    mainBall = childNode(withName: "centralBall") as! SKSpriteNode 
    mainBall.zPosition = 1.0 
    mainBall.physicsBody = SKPhysicsBody(circleOfRadius: mainBall.size.width/2) 

    mainBall.physicsBody?.categoryBitMask = bitMasks.mainBallMask 
    mainBall.physicsBody?.collisionBitMask = bitMasks.enemyBall 
    mainBall.physicsBody?.contactTestBitMask = bitMasks.enemyBall 

    mainBall.physicsBody?.isDynamic = false 
    mainBall.physicsBody?.affectedByGravity = false 
    enemyTimer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(enemies), userInfo: nil, repeats: true) 
} 


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

func didBegin(_ contact: SKPhysicsContact) { 
    let firstBody = contact.bodyA.node as! SKSpriteNode 
    let secondBody = contact.bodyB.node as! SKSpriteNode 
    if firstBody.name == "enemy" && secondBody.name == "centralBall"{ 
     collisionMain(enemy: firstBody) 
    }else if firstBody.name == "centralBall" && secondBody.name == "enemy"{ 
     collisionMain(enemy: secondBody) 
    } 
} 

func collisionMain(enemy: SKSpriteNode){ 
    hits += 1 
    enemy.removeAllActions() 
    enemy.removeFromParent() 
    print(hits) 

} 

func touchesCheckForChangedBall(touches: Set<UITouch>){ 
    for t in touches { 
     let location = t.location(in: self) 
     let nodes = self.nodes(at: location) 
     if nodes.isEmpty == false { 
      if let name = nodes[0].name{ 
       if name == "centralBall"{ 
        changeMainBallColor() 
       } 
      } 
     } 
    } 
} 

func changeMainBallColor(){ 
    ballSetToMainColor = !ballSetToMainColor 
    if ballSetToMainColor == true{ 
     mainBall.texture = SKTexture(imageNamed: "ball-mainColor") 
    }else{ 
     mainBall.texture = SKTexture(imageNamed: "ball-secondaryColor") 
    } 
} 

override func update(_ currentTime: TimeInterval) { 
    // Called before each frame is rendered 
} 

func getRandomImageColor()->String{ 
    let randVal = arc4random_uniform(2) 
    if randVal == 0{ 
     return "ball-secondaryColor" 
    }else{ 
     return "ball-mainColor" 
    } 
} 

func enemies(){ 
    let color = getRandomImageColor() 
    let enemy = SKSpriteNode(imageNamed: color) 
    enemy.size = CGSize(width: 30, height: 30) 
    enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.size.width/2) 
    enemy.physicsBody?.categoryBitMask = bitMasks.enemyBall 
    enemy.physicsBody?.collisionBitMask = bitMasks.mainBallMask 
    enemy.physicsBody?.contactTestBitMask = bitMasks.mainBallMask 
    enemy.name = "enemyBall" 
    enemy.physicsBody?.isDynamic = true 
    enemy.physicsBody?.affectedByGravity = false 
    let randomPositionNumber = arc4random() % 3 
    switch randomPositionNumber{ 
    case 0: 
     enemy.position.x = 0 
     let posY = arc4random_uniform(UInt32(frame.size.height)) 
     enemy.position.y = CGFloat(posY) 
     self.addChild(enemy) 
     break 
    case 1: 
     enemy.position.y = frame.size.height 
     let posX = arc4random_uniform(UInt32(frame.size.width)) 
     enemy.position.x = CGFloat(posX) 
     self.addChild(enemy) 
     break 
    case 2: 
     enemy.position.x = frame.size.width 
     let posY = arc4random_uniform(UInt32(frame.size.height)) 
     enemy.position.y = CGFloat(posY) 
     self.addChild(enemy) 
     break 
    default: 
     break 
    } 
    enemy.run(SKAction.move(to: mainBall.position, duration: 3)) 
} 
} 
+0

您将动态设置为false,任何移动并需要物理的对象必须将此设置为true – Knight0fDragon

+0

@ Knight0fDragon移动的唯一东西就是敌人球抱歉,我应该明确地说明我将编辑问题 – spies9149

+3

你命名敌人'enemyBall',但你的联系人正在寻找'敌人' – Knight0fDragon

正如上面提到,似乎你有拼写错误的节点名称。您在碰撞方法中寻找“敌人”,但将您的敌人命名为“enemyBall”。这就是为什么我们应该总是创建常量来避免这种情况

let enemyName = "Enemy" 

,比使用它像这样

enemy.name = enemyName 

您也可以尝试写你的碰撞方法就是这样,这将使我们更好小幅阅读,你只需要1如果每次碰撞声明。这种方式也不需要节点名称来比较物体。

func didBegin(_ contact: SKPhysicsContact) { 

    let firstBody: SKPhysicsBody 
    let secondBody: SKPhysicsBody 

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 
    } else { 
     firstBody = contact.bodyB 
     secondBody = contact.bodyA 
    } 

    // Main ball with enemy or enemy with main ball 
    if (firstBody.categoryBitMask == bitMasks.mainBall) && (secondBody.categoryBitMask == bitMasks.enemy) { 
     // do something 
    } 
} 

我也试着按照快速指导,类,枚举和结构应该以大写字母开头。

希望这有助于

+0

他已经说过mainball不会移动,因此将它设置为动态为true服务无效 – Knight0fDragon

问题是他命名了他的敌人“enemyBall”,但看了他的didBeginContact字的“敌人”。

这就是为什么它是一个糟糕的主意,用字符串比较(以及它比其他比较慢)

我会建议先检查categoryBitmask,其次是名或类视具体怎么的检查你的需要。