2016-11-13 4 views
1

Я работаю над приложением, что, когда цвет центрального шара соответствует меньшему шару, который летит к цвету центрального шарика, игрок набирает очки. Для этого мне нужна функция didBeginContact для вызова, когда сталкиваются «враг» и «mainBall». Единственное, что движется, это вражеский мяч, когда он летит к неподвижному mainBall. Я считаю, что я правильно установил бит-маски, но функция didBeginContact не вызывается. Может кто-нибудь помочь?didBeginContact не называется Swift

Вот мой код

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

ответ

1

Как уже упоминалось выше, кажется, вы неправильно ваши имена узлов. Вы ищете «врага» в методе столкновений, но назвали своих врагов «врагБал». Вот почему мы всегда должны создавать константы, чтобы избежать этого, например.

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 
    } 
} 

Я хотел бы также попытаться следовать Свифта Guidlines, классы, перечислений и структуры должны начинаться с прописных букв.

Надеется, что это помогает

+0

Он уже сказал, что основной шар не двигается, поэтому его динамическое значение истинно не служит цели – Knight0fDragon

3

выпуска был он назвал свой враг «enemyBall»., Но искал слово «враг» в его didBeginContact.

Вот почему это плохая идея использовать сравнение строк (как и быть медленнее, чем другие сравнения)

Я бы рекомендовал первую проверку categoryBitmask, а затем по имени или классу в зависимости от того, как специфичных для проверьте, что вам нужно.

Смежные вопросы