2016-11-28 2 views
0

Meine Knoten kollidieren, wenn ich sie starte. Die Münze springt vom Spielerknoten. Wenn ich jedoch die Funktion didBeginContact aufrufen möchte, reagiert es nicht ... Ich möchte irgendwann ein Label haben, um jedes Mal, wenn die Münze den Spieler trifft, die Punktzahl +1 anzuzeigen. Außerdem sollte die Münze verschwinden, wenn sie mit dem Spieler kollidiert. Aber mein Kontakt funktioniert nicht, also kann ich keine Kollisionsregeln machen, damit das Etikett die Punktzahl anzeigt.Knoten kollidieren, reagieren aber nicht auf die Funktion 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!) 
      } 
     } 
    } 
} 
} 

} 

Antwort

1

Können Sie versuchen, Ihre Bitmasken so zu definieren.

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

und können Sie diesen Code in Ihrer Kontaktmethode versuchen. Beachten Sie auch, dass der Name der Kontaktmethode geändert wurde, wenn Sie Swift 3 verwenden.

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

Sie verwenden auch ein paar! in deinem Code, der es weniger sicher macht. Versuchen Sie es mit? und "wenn lassen", wann immer es möglich ist, wenn es um Optionale geht. Schreibe zum Beispiel deine Physikkörper so, obwohl du weißt, dass du sie gerade erstellt hast. Sie tun es manchmal und andere Male, die Sie verwenden!, Seien Sie konsequent.

player.physicsBody?.categoryBitMask... 
    etc 

Wenn dieser Physikkörper aus irgendeinem Grund ist/wird Null und Sie verwenden! du wirst zusammenbrechen.

Ich würde auch Ihre Kontaktmethode so schreiben, um sicherzustellen, dass Sie auch nicht abstürzen, wenn die Kontaktmethoden mehr als einmal für die gleiche Kollision ausgelöst werden.

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

     print("Hello") 
    } 

und als es nennen, wie dies in der didBeginContact Methode

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

Schließlich möchte ich auch die schnellen Richtlinien zu folgen versuchen, Ihre Methoden sollten mit kleinen Buchstaben und Klassen beginnen, sollten structs mit Startkapital Briefe.

hoffe, das hilft

+0

@ cashoverride777 - Die Objekte kollidieren, aber ich kann immer noch das „Hallo“ drucken, wenn sie es tun .... Ich verstehe nicht, warum sie Kollision nicht erkannt wird? – Andrew

+0

Haben Sie meine Vorschläge versucht? Stellen Sie außerdem sicher, dass einer Ihrer Körper dynamisch ist. – crashoverride777

+0

Ja, tat ich. Ich habe die Münze in Dynamic geändert, so dass sie jetzt vom Spieler abprallt und weiter fällt (die Elternfunktion wurde nicht entfernt), aber es druckt nicht einmal das Hallo ... also kann ich keine Regeln für die Kollision schreiben, weil das nicht der Fall ist erkennt es .. – Andrew

Verwandte Themen