2016-11-21 77 views
1

enter image description here斯威夫特3太空射击游戏:问题与子弹的碰撞

我想创建写在斯威夫特3.让碰撞的正常工作目前遇到了困难射击游戏。如果子弹击中敌人,我需要发生爆炸,然后从游戏中移除特定的敌人和子弹。如果玩家击中敌人,我需要在两者之间发生爆炸,然后从屏幕上移除特定的敌人和玩家,并将其命名为gameover。这是我到目前为止,子弹只是反弹而没有发生碰撞。任何帮助是极大的赞赏。

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

尝试类似这样的做法,并重构您的___Collided代码进行调整。

不要测试节点相等性。使用名称或.categoryBitMask来确定它是什么类型的节点。

获得本教程中的categoryBitMask; 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