2016-11-13 18 views
1

私は中央のボールの色が中央のボールの色に向かって飛んでいる小さなボールと一致すると、プレーヤーがポイントを獲得するというアプリに取り組んでいます。 これを行うには、「敵」と「メインボール」が衝突したときに呼び出すdidBeginContact関数が必要です。唯一動いているのは、敵のボールが静止しているメインボールに向かって飛ぶときです。 私はビットマスクを正しく設定していると思いますが、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

あなたは動的に偽に設定されています。移動して物理的に必要なオブジェクトは、これをtrueに設定する必要があります。 – Knight0fDragon

+0

@ Knight0fDragon唯一動いているのは敵のボールです。私はそのことを明確にしておきます。 – spies9149

+3

あなたは敵の 'enemyBall'と名を連ねるが、あなたの連絡先は'敵 'を探している – Knight0fDragon

答えて

1

です。あなたは衝突方法で "敵"を探していますが、あなたの敵は "enemyBall"と名付けました。これを避けるために常に定数を作成する必要があります。それは少しよりよい読みすると、あなただけの1を必要とするべきである

let enemyName = "Enemy" 

そして、あなたはまた、このようなあなたの衝突の方法を書いて試すことができますので、

enemy.name = enemyName 

のようにそれを使用するよりも

、もし衝突あたりの声明。また、この方法では、ボディを比較するためにノード名は必要ありません。

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に言葉「敵」を探しました。

文字列比較を使用することは悪い考えである理由です(だけでなく、それは他の比較よりも遅くなる)

私はどのように特定のAのに応じて、名前やクラスに続いて、最初categoryBitmaskのチェックをお勧めします必要なことを確認してください。

関連する問題