2016-11-28 20 views
0

Мое узлы сталкиваются, когда я запускаю его. Монета отскакивает от игрового узла. Однако, когда я хочу вызвать функцию didBeginContact, он не отвечает ... Я хочу, чтобы в конце концов лейбл отображал оценку +1 каждый раз, когда монета попадает в игрока. Также монета должна исчезнуть при столкновении с игроком. Но мой контакт не работает, поэтому я не могу сделать никаких коллизионных правил, чтобы метка отображала оценку.Узлы сталкиваются, но не реагируют на функцию didBeginContact

import SpriteKit 
import GameplayKit 

// Collision categories 

struct physicsCategory { 
static let playerCat : UInt32 = 1 
static let coinCat : UInt32 = 2 
} 

class GameScene: SKScene, controls, SKPhysicsContactDelegate { 

let player = SKSpriteNode(imageNamed:"trump") 
let points = SKLabelNode() 
let buttonDirLeft = SKSpriteNode(imageNamed: "left") 
let buttonDirRight = SKSpriteNode(imageNamed: "right") 
let background = SKSpriteNode(imageNamed: "background") 
var pressedButtons = [SKSpriteNode]() 
let popUpMenu = SKSpriteNode(imageNamed: "popupmenu") 
var score = 0 
var gameOver = false 
var startGame = false 
var rules = false 

override func didMove(to view: SKView) { 
self.physicsWorld.contactDelegate = self 

//score label 
points.position = CGPoint(x: 530, y: 260) 
points.text = ("\(score)") 
points.zPosition = 6 
points.fontColor = UIColor.black 
points.fontSize = 50 
addChild(points) 

//Set Background 
background.zPosition = 1 
background.position = CGPoint(x: frame.size.width/2, y: frame.size.height/2) 
background.size.width = 580 
background.size.height = 320 

addChild(background) 

// Player 
player.position = CGPoint(x: 250, y: 40) 
player.zPosition = 2 
player.size.width = 40 
player.size.height = 60 
player.physicsBody = SKPhysicsBody(rectangleOf: player.size) 
player.physicsBody?.affectedByGravity = false 
player.physicsBody!.categoryBitMask = physicsCategory.playerCat 
player.physicsBody!.contactTestBitMask = physicsCategory.coinCat 
player.physicsBody?.collisionBitMask = 0 
player.physicsBody?.isDynamic = false 
self.addChild(player) 

//contact has started 
func didBeginContact(contact: SKPhysicsContact){ 
    let firstBody: SKPhysicsBody = contact.bodyA 
    let secondBody: SKPhysicsBody = contact.bodyB 

    if ((firstBody.categoryBitMask == physicsCategory.playerCat) && (secondBody.categoryBitMask == physicsCategory.coinCat)){ 
     CollisionWithCoin(player: firstBody.node as! SKSpriteNode, coins: secondBody.node as! SKSpriteNode) 
    } 
    } 

func CollisionWithCoin(player: SKSpriteNode, coins:SKSpriteNode){ 
    NSLog("Hello") 
} 


//repeat coing spawning 
run(SKAction.repeatForever(
    SKAction.sequence([ 
     SKAction.run(spawnCoins), 
     SKAction.wait(forDuration: 1.0)]))) 
} 
//coin settings 
func random() -> CGFloat { 
    return CGFloat(Float(arc4random())/0xFFFFFFFF) 
} 

func random(min: CGFloat, max: CGFloat) -> CGFloat { 
    return random() * (max - min) + min 
} 

//spawn coins 
func spawnCoins() { 
    // 2 
    let coins = SKSpriteNode(imageNamed: "coins") 
    coins.zPosition = 2 
    coins.size.width = 25 
    coins.size.height = 25 
    coins.physicsBody = SKPhysicsBody(rectangleOf: coins.size) 
    coins.physicsBody!.categoryBitMask = physicsCategory.coinCat 
    coins.physicsBody!.contactTestBitMask = physicsCategory.playerCat 
    coins.physicsBody?.collisionBitMask = 1 
    coins.position = CGPoint(x: frame.size.width * random(min: 0, max: 1), y: frame.size.height + coins.size.height/2) 

    let action = SKAction.moveTo(y: -350, duration: TimeInterval(random(min: 1, max: 5))) 

    let remove = SKAction.run({coins.removeFromParent()}) 

    let sequence = SKAction.sequence([action,remove]) 


    coins.run(sequence) 

    addChild(coins) 

} 

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

    if pressedButtons.index(of: buttonDirLeft) != nil { 
     player.position.x -= 4.0 
    } 
    if pressedButtons.index(of: buttonDirRight) != nil { 
     player.position.x += 4.0 
    } 

} 
//MOVEMENT FUNCTIONS START HERE 
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    for touch: AnyObject in touches { 
     let location = touch.location(in: self) 
     let previousLocation = touch.previousLocation(in: self) 

     for button in [buttonDirLeft, buttonDirRight] { 
      // I check if they are already registered in the list 
      if button.contains(location) && pressedButtons.index(of: button) == nil { 
       pressedButtons.append(button) 

       } 
      } 
     } 
    } 


override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch: AnyObject in touches { 
     let location = touch.location(in: self) 
     let previousLocation = touch.previousLocation(in: self) 

     for button in [buttonDirLeft, buttonDirRight] { 
      // if I get off the button where my finger was before 
      if button.contains(previousLocation) 
       && !button.contains(location) { 
       // I remove it from the list 
       let index = pressedButtons.index(of: button) 
       if index != nil { 
        pressedButtons.remove(at: index!) 
       } 
      } 

       // if I get on the button where I wasn't previously 
      else if !button.contains(previousLocation) 
       && button.contains(location) 
       && pressedButtons.index(of: button) == nil { 
       // I add it to the list 
       pressedButtons.append(button) 

      }}}} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch: AnyObject in touches { 
     let location = touch.location(in: self) 
     let previousLocation = touch.previousLocation(in: self) 

     for button in [buttonDirLeft, buttonDirRight] { 
      if button.contains(location) { 
       let index = pressedButtons.index(of: button) 
       if index != nil { 
        pressedButtons.remove(at: index!) 
       } 
      } 
      else if (button.contains(previousLocation)) { 
       let index = pressedButtons.index(of: button) 
       if index != nil { 
        pressedButtons.remove(at: index!) 
       } 
      } 
     } 
    } 
} 


override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch: AnyObject in touches { 
     let location = touch.location(in: self) 
     let previousLocation = touch.previousLocation(in: self) 

    for button in [buttonDirLeft, buttonDirRight] { 
     if button.contains(location) { 
      let index = pressedButtons.index(of: button) 
      if index != nil { 
       pressedButtons.remove(at: index!) 
      } 
     } 
     else if (button.contains(previousLocation)) { 
      let index = pressedButtons.index(of: button) 
      if index != nil { 
       pressedButtons.remove(at: index!) 
      } 
     } 
    } 
} 
} 

} 

ответ

1

Можете ли вы попытаться определить свои битовые маски следующим образом.

enum PhysicsCategory { 
     static let playerCat: UInt32 = 0x1 << 0 
     static let coinCat: UInt32 = 0x1 << 1 
} 

и вы можете попробовать этот код в своем методе контакта. Также обратите внимание, что если вы используете Swift 3, имя имени метода контакта изменилось.

//contact has started 
    func didBegin(_ contact: SKPhysicsContact) { 
     let firstBody: SKPhysicsBody = contact.bodyA 
     let secondBody: SKPhysicsBody = contact.bodyB 


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

     if ((firstBody.categoryBitMask == physicsCategory.playerCat) && (secondBody.categoryBitMask == physicsCategory.coinCat)){ 
      CollisionWithCoin(player: firstBody.node as! SKSpriteNode, coins: secondBody.node as! SKSpriteNode) 
    } 
    } 
} 

Вы также пользуетесь несколькими! в вашем коде, что делает его менее безопасным. Попробуйте использовать? и «если допустим», когда это возможно, когда речь идет о опционах. Так, например, напишите ваши физические тела, как это, хотя вы знаете, что вы только что создали его. Вы делаете это иногда и в другое время, когда используете, будьте последовательны.

player.physicsBody?.categoryBitMask... 
    etc 

Если это физическое тело по какой-либо причине является/становится нулевым, и вы используете! вы рухнете.

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

func collisionWithCoin(player: SKSpriteNode?, coins:SKSpriteNode?){ 
     guard let player = player, let coins = coins else { return } 

     print("Hello") 
    } 

и чем называть это как так в методе didBeginContact

collisionWithCoin(player: firstBody.node as? SKSpriteNode, coins: secondBody.node as? SKSpriteNode) 

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

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

+0

@ cashoverride777 - Объекты встречным, но я все еще могу напечатать «Hello», когда они делают .... Я не понимаю, почему они коллизия не признается? – Andrew

+0

Вы пробовали мои предложения? Также убедитесь, что 1 из ваших тел динамичен. – crashoverride777

+0

Да, да. Я изменил монету на Dynamic, так что теперь она отскакивает от игрока и продолжает падать (havent реализовал удаление из родительской функции), но он даже не печатает привет ... поэтому я не могу писать никаких правил для столкновения, потому что это не признавая это. – Andrew