【问题标题】:Swift: didBeginContact() is not called after reloading levelSwift:重新加载关卡后不调用 didBeginContact()
【发布时间】:2015-09-10 06:18:29
【问题描述】:

我是 swift 语言的新手,但遇到了一些问题。我猜这是一个简单的错误,但无论如何我似乎无法找到问题所在。我在做游戏。你输了之后,我在屏幕上创建了一个重播按钮。单击后,我开始重置游戏。

我基本上重置了所有值,删除所有子项,然后重新初始化。它重新初始化很好 - 所有背景和精灵都在正确移动,但如果我触摸尖峰(游戏的失败机制),游戏不会结束;没有调用 didBeginContact 函数来再次执行代码的丢失部分。我猜它与collisionBitMasks和categoryBitMasks有关。

球员和钉鞋之间的接触,以及球员和平台之间的接触(以保持得分)都不起作用。

注意:我的代码目前很乱。我想在开始大修之前让它工作起来,让它变得漂亮和优化。

func didBeginContact(contact: SKPhysicsContact) {
//...
if contact.bodyA.categoryBitMask == spikeGroup && contact.bodyB.categoryBitMask == playerGroup {
    gameOver = true
    movingObjectsNode.speed = 0
    //...

    rplay.frame = CGRectMake(100, 100, 100, 50)
    rplay.backgroundColor = UIColor.greenColor()
    rplay.setTitle("Replay", forState: UIControlState.Normal)
    rplay.addTarget(self, action: "rplayAction", forControlEvents: UIControlEvents.TouchUpInside)
    self.view?.addSubview(rplay)
} else if contact.bodyA.categoryBitMask == playerGroup && contact.bodyB.categoryBitMask == platformGroup {
    var contactedPlatform = contact.bodyB.node
    contactHistory.append(contactedPlatform!)
    if contactHistory.count >= 3 {
        contactHistory.removeAtIndex(0)
    }
    if contactHistory.count > 1 {
        if contactHistory[0].name != contactHistory[1].name {
            score = score + 1
            scoreLabel.text = String(score)
        }
    } else {
        score = score + 1
        scoreLabel.text = String(score)
    }
}
func rplayAction() {
    rplay.removeFromSuperview()
    self.removeAllChildren()

    bgOnArray.removeAll(keepCapacity: false)
    platformHistArray.removeAll(keepCapacity: false)
    platformOnScreenArrayB.removeAll(keepCapacity: false)
    platformOnScreenArrayW.removeAll(keepCapacity: false)
    movingObjectsNode.removeAllChildren()
    gameOverTabHolderNode.removeAllChildren()
    pW.removeAll(keepCapacity: false)
    pB.removeAll(keepCapacity: false)
    pWMask.removeAll(keepCapacity: false)
    pBMask.removeAll(keepCapacity: false)
    contactHistory.removeAll(keepCapacity: false)

    state = true
    gstate = false
    allowContact = true
    gameOver = false
    score = 0
    count = 0
    scoreLabel.text = "0"
    scoreLabelArray.removeAll(keepCapacity: false)
    movingObjectsNode.speed = 1

    self.physicsWorld.contactDelegate = self
    self.physicsWorld.gravity = CGVectorMake(0, -20)
    self.addChild(movingObjectsNode)

    var bgWTexture = SKTexture(imageNamed: "img/bgW")
    var bgBTexture = SKTexture(imageNamed: "img/bgB")
    var playerBTexture = SKTexture(imageNamed: "img/playerB")
    var playerWTexture = SKTexture(imageNamed: "img/playerW")

    var movebg = SKAction.moveByX(-bgWTexture.size().width, y: 0, duration: 10.0) //4.48 = 20 pixels a sec?
    var replacebg = SKAction.moveByX(bgWTexture.size().width, y: 0, duration: 0)
    var movebgForever = SKAction.repeatActionForever(SKAction.sequence([movebg, replacebg]))

    makeBackground()

    //note: for some reason spikes take forever to load (because of the tempFloatPoint was condensed into one line)
    for var i:CGFloat=0; i<36; i++ {
        var floorSpikes = SKShapeNode()
        var tempInt = Int(i)
        var tempString = String(tempInt)
        var tempFloatPoint = CGFloat()
        var path = CGPathCreateMutable()

        CGPathMoveToPoint(path, nil, 0, 0)
        CGPathAddLineToPoint(path, nil, bg.size.width/14 , 0)
        CGPathAddLineToPoint(path, nil, bg.size.width/28, bg.size.height/9)
        CGPathCloseSubpath(path)
        floorSpikes.path = path
        floorSpikes.lineWidth = 0;
        floorSpikes.name = "2 " + tempString
        tempFloatPoint = CGRectGetMidX(self.frame)
        tempFloatPoint = tempFloatPoint - (bg.size.width/7)
        tempFloatPoint = tempFloatPoint + (bg.size.width/14 * i)

        if i <= 7 {
            floorSpikes.position = CGPoint(x: tempFloatPoint, y: 0)
        } else if i > 7 && i <= 20 {
            floorSpikes.position = CGPoint(x: tempFloatPoint - 5, y: 0)
        } else if i > 20 && i <= 36 {
            floorSpikes.position = CGPoint(x: tempFloatPoint - 10, y: 0)
        }

        floorSpikes.runAction(movebgForever)
        floorSpikes.zPosition = 100
        floorSpikes.physicsBody = SKPhysicsBody(polygonFromPath: path)
        floorSpikes.physicsBody!.dynamic = false
        floorSpikes.physicsBody!.categoryBitMask = spikeGroup
        movingObjectsNode.addChild(floorSpikes)
    }

    for var i:CGFloat=0; i<36; i++ {
        var ceilingSpikes = SKShapeNode()
        var tempInt = Int(i)
        var tempString = String(tempInt)
        var tempFloatPoint = CGFloat()
        var path = CGPathCreateMutable()

        CGPathMoveToPoint(path, nil, 0, 0)
        CGPathAddLineToPoint(path, nil, bg.size.width/14 , 0)
        CGPathAddLineToPoint(path, nil, bg.size.width/28, -bg.size.height/9)
        CGPathCloseSubpath(path)
        ceilingSpikes.path = path
        ceilingSpikes.lineWidth = 0;
        ceilingSpikes.name = "3 " + tempString
        tempFloatPoint = CGRectGetMidX(self.frame)
        tempFloatPoint = tempFloatPoint - (bg.size.width/7)
        tempFloatPoint = tempFloatPoint + (bg.size.width/14 * i)

        if i <= 7 {
            ceilingSpikes.position = CGPoint(x: tempFloatPoint, y: CGRectGetMaxY(self.frame))
        } else if i > 7 && i <= 20 {
            ceilingSpikes.position = CGPoint(x: tempFloatPoint - 5, y: CGRectGetMaxY(self.frame))
        } else if i > 20 && i <= 36 {
            ceilingSpikes.position = CGPoint(x: tempFloatPoint - 10, y: CGRectGetMaxY(self.frame))
        }

        ceilingSpikes.runAction(movebgForever)
        ceilingSpikes.zPosition = 100
        ceilingSpikes.physicsBody = SKPhysicsBody(polygonFromPath: path)
        ceilingSpikes.physicsBody!.dynamic = false
        ceilingSpikes.physicsBody!.categoryBitMask = spikeGroup
        movingObjectsNode.addChild(ceilingSpikes)
    }

    //player stuff
    player = SKSpriteNode(texture: playerBTexture)

    player.xScale = 0.1
    player.yScale = 0.1
    player.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) + self.frame.size.height/8)

    player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(player.size.width, player.size.height))
    player.physicsBody!.restitution = 0.0
    player.physicsBody!.allowsRotation = false
    player.physicsBody!.angularDamping = 0.0
    player.physicsBody!.angularVelocity = 0.0
    player.physicsBody!.dynamic = true
    player.physicsBody!.categoryBitMask = playerGroup
    player.physicsBody!.collisionBitMask = spikeGroup
    player.physicsBody!.contactTestBitMask = spikeGroup
    player.physicsBody!.collisionBitMask = platformGroup
    player.physicsBody!.contactTestBitMask = platformGroup

    self.addChild(player)

    var screen = CGRectMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame), UIScreen.mainScreen().bounds.width, self.frame.height)

    scoreLabel.fontName = "GKFont"
    scoreLabel.fontSize = 60
    scoreLabel.fontColor = UIColor.blackColor()
    scoreLabel.text = "0"
    scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame) + screen.width/2 - screen.width/10, self.frame.height - self.frame.height/4)
    self.addChild(scoreLabel)
    scoreLabelArray.append(scoreLabel)

    makeStarterPlatforms()
}

我认为问题在于这两个功能之一。提前感谢您愿意提供的任何帮助!

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    最终我想通了。我不知道为什么,但是在重玩游戏并重新加载所有内容后,发生碰撞的顺序是相反的。对于每个碰撞语句,我都必须更改....

    contact.bodyA.categoryBitMask == playerGroup && contact.bodyB.categoryBitMask == platformGroup
    

    到....

    contact.bodyA.categoryBitMask == playerGroup && contact.bodyB.categoryBitMask == platformGroup || contact.bodyA.categoryBitMask == platformGroup && contact.bodyB.categoryBitMask == playerGroup
    

    如果有人可以澄清为什么需要实施此更改,请随时在下面发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      相关资源
      最近更新 更多