2016-11-13 86 views
1

我正在研究一個應用程序,當中央球顏色匹配一個較小的球,正在朝中央球顏色飛行球員得分。 所以爲了這個工作,我需要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

回答

1

正如上面提到,似乎你有拼寫錯誤的節點名稱。您在碰撞方法中尋找「敵人」,但將您的敵人命名爲「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

3

問題是他命名了他的敵人「enemyBall」,但看了他的didBeginContact字的「敵人」。

這就是爲什麼它是一個糟糕的主意,用字符串比較(以及它比其他比較慢)

我會建議先檢查categoryBitmask,其次是名或類視具體怎麼的檢查你的需要。