SpriteKit(Swift)敌人没有被删除/敌人和子弹似乎没有联系

Posted

技术标签:

【中文标题】SpriteKit(Swift)敌人没有被删除/敌人和子弹似乎没有联系【英文标题】:SpriteKit (Swift) Enemy doesn't get deleted / Enemy & bullet doesn't seems to contact 【发布时间】:2019-11-12 04:28:37 【问题描述】:
import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate 

    let player = SKSpriteNode(imageNamed: "Player")

    struct PhysicsCategories 
        static let None: UInt32 = 0
        static let Player: UInt32 = 0b1 //1
        static let Bullet: UInt32 = 0b10 //2
        static let Enemy: UInt32 = 0b100 //4
    

    override func didMove(to view: SKView) 

        self.physicsWorld.contactDelegate = self

        player.setScale(0.2)
        player.position = CGPoint(x: self.size.width/2, y: self.size.height * 0.2)
        player.zPosition = 2
        player.physicsBody = SKPhysicsBody(rectangleOf: player.size)
        player.physicsBody!.affectedByGravity = false
        player.physicsBody!.categoryBitMask = PhysicsCategories.Player
        player.physicsBody!.collisionBitMask = PhysicsCategories.None
        player.physicsBody?.isDynamic = true
        player.physicsBody!.contactTestBitMask = PhysicsCategories.Enemy
        self.addChild(player)

    


    func didBeginContact(contact: SKPhysicsContact) 
        var body1 = SKPhysicsBody()
        var body2 = SKPhysicsBody()

        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask 
            body1 = contact.bodyA
            body2 = contact.bodyB
        
        else 
            body1 = contact.bodyB
            body2 = contact.bodyA
        

        if body1.categoryBitMask == PhysicsCategories.Player && body2.categoryBitMask == PhysicsCategories.Enemy 
            // if player hit enemy

            if body1.node != nil 

                spawnExplosion(spawnPosition: body1.node!.position)
            

            if body2.node != nil 

                spawnExplosion(spawnPosition: body2.node!.position)
            

            body1.node!.removeFromParent()
            body2.node!.removeFromParent()

        

        if body1.categoryBitMask == PhysicsCategories.Bullet && body2.categoryBitMask == PhysicsCategories.Enemy 
            // if bullet hit enemy

            if body2.node != nil 
                if body2.node!.position.y > self.size.height 
                    return
                
                else 
                    spawnExplosion(spawnPosition: body2.node!.position)
                
            

            body1.node!.removeFromParent()
            body2.node!.removeFromParent()

        

    

    func fireBullet()   

        let bullet = SKSpriteNode(imageNamed: "Bullet")
        bullet.setScale(0.8)
        bullet.position = player.position
        bullet.zPosition = 1
        bullet.physicsBody = SKPhysicsBody(rectangleOf: bullet.size)
        bullet.physicsBody!.affectedByGravity = false
        bullet.physicsBody!.categoryBitMask = PhysicsCategories.Bullet
        bullet.physicsBody!.collisionBitMask = PhysicsCategories.None
        bullet.physicsBody?.isDynamic = true
        bullet.physicsBody!.contactTestBitMask = PhysicsCategories.Enemy
        self.addChild(bullet)

        let moveBullet = SKAction.moveTo(y: self.size.height + bullet.size.height, duration: 1)
        let deleteBullet = SKAction.removeFromParent()
        let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet])
        bullet.run(bulletSequence)
    

    func spawnEnemy()

        let randomxStart = randomBetweenNumbers(firstNum: 0, secondNum: frame.width)
        let randomxEnd = randomBetweenNumbers(firstNum: 0, secondNum: frame.width)

        let startPoint = CGPoint(x: randomxStart, y: self.size.height * 1.2 )
        let endPoint = CGPoint(x: randomxEnd, y: -self.size.height * 0.2)

        let Enemy = SKSpriteNode(imageNamed: "EnemyShip")
        Enemy.setScale(0.2)
        Enemy.position = startPoint
        Enemy.zPosition = 2
        Enemy.physicsBody = SKPhysicsBody(rectangleOf: Enemy.size)
        Enemy.physicsBody!.affectedByGravity = false
        Enemy.physicsBody!.categoryBitMask = PhysicsCategories.Enemy
        Enemy.physicsBody!.collisionBitMask = PhysicsCategories.None
        Enemy.physicsBody?.isDynamic = true
        Enemy.physicsBody!.contactTestBitMask = PhysicsCategories.Player | PhysicsCategories.Bullet
        self.addChild(Enemy)

        let moveEnemy = SKAction.move(to: endPoint, duration: 1.5)
        let deleteEnemy = SKAction.removeFromParent()
        let enemySequence = SKAction.sequence([moveEnemy, deleteEnemy])
        Enemy.run(enemySequence)

        let dx = endPoint.x - startPoint.x
        let dy = endPoint.y - startPoint.y
        let amountToRotate = atan2(dy, dx)
        let degreesToRadians = CGFloat.pi / 180
        //  let radiansToDegree = 180 / CGFloat.pi
        Enemy.zRotation = amountToRotate - 90 * degreesToRadians

    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

        fireBullet()
    


所以我刚刚开始通过构建简单的游戏来学习 SpriteKit 和 Swift。代码是构建类似太空入侵者的游戏。我被困在代码的联系报告部分,其中子弹和敌人在接触时被删除/敌人和玩家在接触时被删除。

我已经设置了玩家、敌人、子弹的物理体。在类似问题上看到了一些 *** 问题并输入 isDynamic = true。放入 ifBeginContact -> removeFromParent 但目前我不知道为什么,敌人在被子弹击中时不会被删除。我把基本代码留在里面了。请帮忙。

【问题讨论】:

你需要清理你的代码,删除与这个问题无关的函数,例如 spawnEnemy 和 startNewLevel。您需要尽可能容易地注意到问题可能是什么。其次,您的第二个问题需要转移到它自己的问题上。或者更好的是搜索该问题的堆栈溢出,它已经被问过了。 你为什么要扩展你的节点?你知道子弹是否正在接触物理体,并且物理体确实是正确的尺寸吗?使用view.showPhysics = true查看尸体 好的。添加了 view.ShowPhysics = true。我想通了!将 func didBegin 移到了最底部,显然它起作用了。老实说,在此之前不确定问题出在哪里,但代码由于某种原因有效:l 如果移到底部有效,那么您没有提供代码的准确表示。您在函数内部有一个函数。 好的。谢谢 KnightDragon 和 Ron Myschuk。 【参考方案1】:

可能在评论中提到的另一个函数内部有一个函数。

添加了 view.ShowPhysics = true。将 func didBegin 移到了最底部,显然它起作用了。

【讨论】:

以上是关于SpriteKit(Swift)敌人没有被删除/敌人和子弹似乎没有联系的主要内容,如果未能解决你的问题,请参考以下文章

在屏幕上的 3 个特定位置生成敌人 Swift SpriteKit IOS

SpriteKit - 如何检测使用触摸影响哪个节点?

三击后如何删除精灵

SpriteKit 动画没有在它应该加载的时候加载。我究竟做错了啥?

Xcode 8 SpriteKit:GameScene.swift 文件未被识别/运行

Swift和Spritekit sceneDidLoad被调用多个