2016-11-21 13 views
1

enter image description hereスウィフト3宇宙シューティングゲーム:弾丸の衝突に関する問題

私は現在、衝突が正常に動作し得ることとの難しさを持っスウィフト3で記述されたシューティングゲームを作成しようとしています。弾丸が敵に当たったら、爆発して特定の敵と弾丸をゲームから取り除く必要があります。プレイヤーが敵に当たった場合、その間に爆発が起こり、その特定の敵とプレーヤーを画面から取り外し、ゲームオーバーと呼ぶ。これは私がこれまで持っていたものですが、弾丸はちょうど衝突が起こることなく跳ね返ります。どんな助けでも大歓迎です。

import SpriteKit 
import GameplayKit 

enum CollisonType: UInt32 { 
    case player = 1 
    case ammo = 2 
    case enemy = 4 
} 

class GameScene: SKScene, SKPhysicsContactDelegate { 

    var starfield: SKEmitterNode! 
    var player: SKSpriteNode! 
    var ammo: SKSpriteNode! 
    var enemy: SKSpriteNode! 
    var gameScore: SKLabelNode! 
    var score: Int = 0 { 
     didSet { // didSet a property observer used to update gameScore 
      gameScore.text = "Score: \(score)" 
     } 
    } 

    var possibleEnemies = ["ball", "hammer", "tv"] 
    var gameTimer: Timer! // Used to create enemies regularly. 
    var isGameOver = false // a boolean that will be set to true when we should stop increasing the player's score 

    override func didMove(to view: SKView) { 

     backgroundColor = UIColor.black 

     starfield = SKEmitterNode(fileNamed: "Starfield")! 
     starfield.position = CGPoint(x: 1024, y: 384) 
     starfield.advanceSimulationTime(10) 
     addChild(starfield) 
     starfield.zPosition = -1 

     player = SKSpriteNode(imageNamed: "player") 
     player.position = CGPoint(x: 100, y: 384) 
     player.physicsBody = SKPhysicsBody(texture: player.texture!, size: player.size) 
     player.physicsBody!.categoryBitMask = CollisonType.player.rawValue 
     player.physicsBody!.contactTestBitMask = CollisonType.enemy.rawValue 
     addChild(player) 

     gameScore = SKLabelNode(fontNamed: "Chalkduster") 
     gameScore.text = "Score: 0" 
     gameScore.horizontalAlignmentMode = .left 
     gameScore.position = CGPoint(x: 8, y: 8) 
     addChild(gameScore) 

     physicsWorld.gravity = CGVector(dx: 0, dy: 0) 
     physicsWorld.contactDelegate = self 

     gameTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true) 

     gameTimer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(createAmmo), userInfo: nil, repeats: true) 

    } 

    func createAmmo() { 
     if isGameOver { 
      return 
     } 

     ammo = SKSpriteNode(imageNamed: "bullet") 
     ammo.name = "ammo" 
     ammo.position = CGPoint(x: player.position.x + 100, y: player.position.y) 
     addChild(ammo) 

     ammo.physicsBody = SKPhysicsBody(texture: ammo.texture!, size: ammo.size) 
     ammo.physicsBody!.categoryBitMask = CollisonType.ammo.rawValue 
     ammo.physicsBody!.contactTestBitMask = CollisonType.enemy.rawValue 

     ammo.physicsBody!.velocity = CGVector(dx: 900, dy: 0) 
     ammo.physicsBody!.linearDamping = 0 
     ammo.physicsBody!.angularDamping = 0 

    } 

    func createEnemy() { 
     possibleEnemies = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: possibleEnemies) as! [String] 
     let randomDistribution = GKRandomDistribution(lowestValue: 50, highestValue: 736) 

     enemy = SKSpriteNode(imageNamed: possibleEnemies[0]) 
     enemy.name = "enemy" 
     enemy.position = CGPoint(x: 1200, y: randomDistribution.nextInt()) 
     addChild(enemy) 

     enemy.physicsBody = SKPhysicsBody(texture: enemy.texture!, size: enemy.size) 
     enemy.physicsBody!.categoryBitMask = CollisonType.enemy.rawValue 
     enemy.physicsBody!.contactTestBitMask = CollisonType.player.rawValue | CollisonType.ammo.rawValue 

     enemy.physicsBody!.velocity = CGVector(dx: -300, dy: 0) 
     enemy.physicsBody!.angularVelocity = 5 
     enemy.physicsBody!.linearDamping = 0 
     enemy.physicsBody!.angularDamping = 0 

    } 

    override func update(_ currentTime: TimeInterval) { 
     for node in children { 
      if node.position.x < -300 || node.position.x > 1300 || node.position.y < -300 || node.position.y > 1000 { 
       node.removeFromParent() 
      } 
     } 

     if !isGameOver { 
      score += 1 
     } 
    } 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     guard let touch = touches.first else { return } 
     var location = touch.location(in: self) 

     if location.y < 50 { 
      location.y = 50 
     } else if location.y > 730 { 
      location.y = 730 
     } 

     player.position = location 
    } 

    func didBegin(_ contact: SKPhysicsContact) { 

     if contact.bodyA.node == player { 
      playerCollided(with: contact.bodyB.node!) 
     } else if contact.bodyB.node == player { 
      playerCollided(with: contact.bodyA.node!) 
     } 

     if contact.bodyA.node == ammo { 
      ammoCollided(with: contact.bodyB.node!) 
     } else if contact.bodyB.node == ammo { 
      ammoCollided(with: contact.bodyA.node!) 
     } 

    } 

    func playerCollided(with node:SKNode) { 
     if node.name == "enemy" { 
      let explosion = SKEmitterNode(fileNamed: "explosion")! 
      explosion.position = enemy.position 
      addChild(explosion) 

      player.removeFromParent() 
      enemy.removeFromParent() 
      isGameOver = true 
     } 
    } 

    func ammoCollided(with node:SKNode) { 
     if node.name == "enemy" { 
      let explosion = SKEmitterNode(fileNamed: "explosion")! 
      explosion.position = enemy.position 
      addChild(explosion) 

      ammo.removeFromParent() 
      enemy.removeFromParent() 
     } 
    } 
} 

答えて

0

代わりにこのようなものを試し、調整するために__コアルドコードをリファクタリングしてください。

ノードの等価性をテストしないでください。名前または.categoryBitMaskを使用して、それがどのような種類のノードであるか把握します。

このチュートリアルではカテゴリBitMaskを取得します。 https://www.raywenderlich.com/145318/spritekit-swift-3-tutorial-beginners

またはこれを試してください。

player.name = "player1"

func didBegin(_ contact: SKPhysicsContact) { 

     if contact.bodyA.node.name == "player1" { 
      playerCollided(with: contact.bodyB.node!) 
     } else if contact.node.name == "player1" { 
      playerCollided(with: contact.bodyA.node!) 
     } 

     if contact.bodyA.node.name == "ammo" { 
      ammoCollided(with: contact.bodyB.node!) 
     } else if contact.node.name == "ammo" { 
      ammoCollided(with: contact.bodyA.node!) 
     } 

    } 
+0

私はあなたの提案を試みたが、それはまだ完全には機能しません。衝突の後で弾丸の3/4だけが姿を消した(一部はまだ周囲を跳ねている)。しかし、敵は消えることはありません。爆発も起こらない。爆発は、iPadの右側に散発的にしか発生しません(プレーヤーの視界の範囲外)。あなたが提供したチュートリアルのリンクに従います。ありがとうございました。 – Soja

+0

チュートリアルのリンクに従って、私の問題を解決することができました。再びありがとう@eSpecialized! – Soja

関連する問題