0

我有一个必须在两个物体碰撞时出现的restartButton,当它第一次发生时,一切都很好 - 物体碰撞--> restartButton 出现--> 我通过触摸restartButton 重新启动关卡。这是一个“好的,正确的重启”,问题开始了......

关卡重新启动后,如果我触摸屏幕中心(调用时必须出现restartButton)游戏崩溃,说明如下:

“由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'尝试添加已经有父级的SKNode:名称:'(null)'particleTexture:'enemyPart.png'(100 x 100)位置:{721.33929,175.39999 }累积帧:{{inf,inf},{inf,inf}}'**第一次抛出调用堆栈:(0x2a0fa137等)libc++abi.dylib:以NSException类型的未捕获异常终止“

但是 restartButton 是不可见的,它甚至不存在,因为没有物体发生碰撞。

如果在“良好重启”之后某些敌人与玩家发生碰撞,restartButton 会出现片刻,并且玩家、敌人 1、敌人 2、敌人 3 将从场景中淡出。

如果有人可以提供帮助,我将不胜感激

这是您可以看到所有内容的代码:

import SpriteKit
import UIKit



let player = SKEmitterNode(fileNamed: "playerPart.sks")
let enemy1 = SKEmitterNode(fileNamed: "ePart.sks")
let enemy2 = SKEmitterNode(fileNamed: "ePart.sks")
let enemy3 = SKEmitterNode(fileNamed: "ePart.sks")
let restartButton = SKSpriteNode(imageNamed: "restartButton")
let playerCat: UInt32 = 0x1 << 0
let enemyCat: UInt32 = 0x1 << 1


class Level2: SKScene, SKPhysicsContactDelegate {

    override func didMoveToView(view: SKView) {

        physicsWorld.contactDelegate = self


        initWorld()
        movements()

        player.physicsBody = SKPhysicsBody(circleOfRadius: 50)
        player.position = CGPointMake(819.2 , 693.8)
        player.zPosition = 1
        player.physicsBody?.categoryBitMask = playerCat
        player.physicsBody?.contactTestBitMask = enemyCat
        player.targetNode = self
        self.addChild(player)

        enemy1.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(102, 102))
        enemy1.position = CGPointMake(819.2, 175.4)
        enemy1.zPosition = 1
        enemy1.physicsBody?.affectedByGravity = false
        enemy1.physicsBody?.dynamic = true
        enemy1.physicsBody?.allowsRotation = false
        enemy1.physicsBody?.categoryBitMask = enemyCat
        enemy1.physicsBody?.contactTestBitMask = playerCat
        enemy1.physicsBody?.collisionBitMask = 0x0
        enemy1.targetNode = self
        enemy1.particleBirthRate = 150
        enemy1.particleLifetime = 10
        enemy1.particleLifetimeRange = 20
        enemy1.particlePositionRange = CGVectorMake(50, 60)
        enemy1.emissionAngle = 0
        enemy1.emissionAngleRange = 0
        enemy1.particleSpeed = 0
        enemy1.particleSpeedRange = 0


        enemy2.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(102, 102))
        enemy2.position = CGPointMake(614.4, 386.6)
        enemy2.zPosition = 1
        enemy2.physicsBody?.affectedByGravity = false
        enemy2.physicsBody?.dynamic = true
        enemy2.physicsBody?.allowsRotation = false
        enemy2.physicsBody?.categoryBitMask = enemyCat
        enemy2.physicsBody?.contactTestBitMask = playerCat
        enemy2.physicsBody?.collisionBitMask = 0x0
        enemy2.targetNode = self
        enemy2.particleBirthRate = 150
        enemy2.particleLifetime = 10
        enemy2.particleLifetimeRange = 20
        enemy2.particlePositionRange = CGVectorMake(50, 60)
        enemy2.emissionAngle = 0
        enemy2.emissionAngleRange = 0
        enemy2.particleSpeed = 0
        enemy2.particleSpeedRange = 0

        enemy3.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(102, 102))
        enemy3.position = CGPointMake(409.6, 181.8)
        enemy3.zPosition = 1
        enemy3.physicsBody?.affectedByGravity = false
        enemy3.physicsBody?.dynamic = true
        enemy3.physicsBody?.allowsRotation = false
        enemy3.physicsBody?.categoryBitMask = enemyCat
        enemy3.physicsBody?.contactTestBitMask = playerCat
        enemy3.physicsBody?.collisionBitMask = 0x0
        enemy3.targetNode = self
        enemy3.particleBirthRate = 150
        enemy3.particleLifetime = 10
        enemy3.particleLifetimeRange = 20
        enemy3.particlePositionRange = CGVectorMake(50, 60)
        enemy3.emissionAngle = 0
        enemy3.emissionAngleRange = 0
        enemy3.particleSpeed = 0
        enemy3.particleSpeedRange = 0


    func initWorld() {

        self.addChild(enemy1)
        self.addChild(enemy2)
        self.addChild(enemy3)

    }


    func movements() {

        let move11 = SKAction.moveTo(CGPointMake(819.2, 386.6), duration: 1.5)
        let move12 = SKAction.moveTo(CGPointMake(614.4, 386.6), duration: 1.5)
        let move13 = SKAction.moveTo(CGPointMake(614.4, 175.4), duration: 1.5)
        let move14 = SKAction.moveTo(CGPointMake(819.2, 175.4), duration: 1.5)
        let enemy1m = SKAction.sequence([move11, move12, move13, move14])
        let enemy1move = SKAction.repeatActionForever(enemy1m)

        let move21 = SKAction.moveTo(CGPointMake(614.4, 591.4), duration: 1.5)
        let move22 = SKAction.moveTo(CGPointMake(409.6, 591.4), duration: 1.5)
        let move23 = SKAction.moveTo(CGPointMake(409.6, 386.6), duration: 1.5)
        let move24 = SKAction.moveTo(CGPointMake(614.4, 386.6), duration: 1.5)
        let enemy2m = SKAction.sequence([move21, move22, move23, move24])
        let enemy2move = SKAction.repeatActionForever(enemy2m)

        let move31 = SKAction.moveTo(CGPointMake(409.6, 386.6), duration: 1.5)
        let move32 = SKAction.moveTo(CGPointMake(204.8, 386.6), duration: 1.5)
        let move33 = SKAction.moveTo(CGPointMake(204.8, 181.8), duration: 1.5)
        let move34 = SKAction.moveTo(CGPointMake(409.6, 181.8), duration: 1.5)
        let enemy3m = SKAction.sequence([move31, move32, move33, move34])
        let enemy3move = SKAction.repeatActionForever(enemy3m)

        enemy1.runAction(enemy1move)
        enemy2.runAction(enemy2move)
        enemy3.runAction(enemy3move)
    }


    func didBeginContact(contact: SKPhysicsContact) {
        let collision:UInt32 = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)

        if collision == (playerCat | enemyCat) {
            self.removeAllActions()
            self.runAction(SKAction.waitForDuration(0.1), completion: {
                self.runAction(SKAction.waitForDuration(0.2), completion:
                    {self.removeAllActions()
                        self.removeChildrenInArray([enemy1, enemy2, enemy3, player])})

                restartButton.size = CGSizeMake(200, 200)
                restartButton.position = CGPointMake(512, 384)
                restartButton.zPosition = 1
                self.addChild(restartButton)
            })


        }
    }




    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)

            if (restartButton .containsPoint(location)) {
                restartButton.runAction(fadeAway)
                restartButton.removeFromParent()
                println(1)
                self.runAction(SKAction.waitForDuration(1.5), completion: {
                let repeatLevel = SKTransition.fadeWithDuration(2)
                let level2 = Level2(fileNamed: "Level2")
                self.view?.presentScene(level2, transition:     repeatLevel)


                })
            }

        }
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }
}
4

2 回答 2

0

当您的 playerCat 和enemyCat 第一次碰撞时,您的 restartButton 将首次设置其大小,这很好。

由于 restartButton 现在有一个大小。您可以检查您的触摸是否在restartButton 的范围内。

if (restartButton .containsPoint(location)) {

就像你已经这样做了,但你在任何时候都没有检查 restartButton 是否添加到场景中。快速修复可能是:

if (restartButton.parent != nil && restartButton .containsPoint(location)) {

如果不需要特别检查它是否与节点的边界。您可以直接使用它进行检查。这将消除检查父母的需要。

if (self.nodeAtPoint(location) == restartButton) {

我注意到的另一件事是,在您的碰撞检测中,您永远不会检查它是否已经发生碰撞。因此,您可能会多次运行相同的代码,只需不断删除所有操作,然后添加一个新操作即可。

您可以添加一个简单的变量来防止冗余

var detectionMade = false

并重置为

override func didMoveToView(view: SKView) {
    physicsWorld.contactDelegate = self

    initWorld()
    movements()

    detectionMade = false
    ...

并在第一次碰撞和检查时设置为 true

if collision == (playerCat | enemyCat) && !detectionMade {
    detectionMade = true
    ...
于 2015-04-12T00:50:31.183 回答
0

@martinmeincke 我做到了!通过做这个:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)

            if (restartButton .containsPoint(location) && restartButton.parent == nil) {
                restartButton.runAction(fadeAway)

                println(1)



                }
            }

        }


    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            let location = touch.locationInNode(self)

            if (restartButton .containsPoint(location)) {
                restartButton.removeFromParent()
                self.runAction(SKAction.waitForDuration(1.5), completion: {
                    let repeatLevel = SKTransition.fadeWithDuration(2)
                    let level2 = Level2(fileNamed: "Level2")
                    self.view?.presentScene(level2, transition: repeatLevel)
            })

        }
    }
    }
于 2015-04-12T13:37:31.530 回答