【问题标题】:didBeginContact isn't being called没有调用 didBeginContact
【发布时间】:2016-07-11 14:16:25
【问题描述】:

所以我已经在这个游戏上工作了一段时间,一切都按照我想要的方式工作,但是我已经卡在 didBeginContact 上几天了,我无法理解它,我想它看起来不错,我检查了几个论坛并得到了几乎相同的结果,因此它适用于我的游戏。但仍然没有:(任何帮助将不胜感激。 所以这是我的 didBeginContact:

func didBeginContact(contact: SKPhysicsContact) {
    print("i worked")
    // Every contact has two bodies, we do not know which body is which.
    // We will find which body is the penguin, then use the other body
    // to determine what type of contact is happening.
    let otherBody:SKPhysicsBody
    // Combine the two penguin physics categories into one mask
    // using the bitwise OR operator |
    let bunnyMask = PhysicsCategory.bunny.rawValue | PhysicsCategory.bunnyDamaged.rawValue
    // Use the bitwise AND operator & to find the penguin.
    // This returns a positive number if bodyA’s category is
    // the same as either the penguin or damagedPenguin:
    if (contact.bodyA.categoryBitMask & bunnyMask) > 0 {
        // bodyA is the penguin, we want to find out what bodyB is:
        otherBody = contact.bodyB
    }
    else {
        // bodyB is the penguin, we will test against bodyA:
        otherBody = contact.bodyA
    }
    // Find the contact type:
    switch otherBody.categoryBitMask {
    case PhysicsCategory.grass.rawValue:
        print("nom nom grass")
    case PhysicsCategory.mud.rawValue:
        print("mud hit")
    case PhysicsCategory.stone.rawValue:
        print("ow my head")
    case PhysicsCategory.lava.rawValue:
        print("it burns")
    case PhysicsCategory.hedgehog.rawValue:
        print("stop touching me!")
    default:
        print("Contact with no game logic")
    }
}

这是兔子的密码:

class Bunny : SKSpriteNode, GameSprite{
var currentSpeed: Double = 5

var textureAtlas: SKTextureAtlas = SKTextureAtlas(named: "bunny.atlas")
var moveAnimation = SKAction()
func spawn(parentNode: SKNode, position: CGPoint, size: CGSize = CGSize(width: 25, height: 25)) {
    parentNode.addChild(self)
    createAnimations()
    self.size = size
    self.position = position
    self.runAction(moveAnimation, withKey: "moveAnimation")
    self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size)
    self.physicsBody?.categoryBitMask = PhysicsCategory.bunny.rawValue
    self.physicsBody?.contactTestBitMask = PhysicsCategory.hedgehog.rawValue
    self.physicsBody?.collisionBitMask = PhysicsCategory.hedgehog.rawValue
    self.physicsBody?.affectedByGravity = false
    self.physicsBody?.dynamic = true

}

还有兔子的 GameScene 代码:

initialBunnyPosition = CGPoint(x: 25, y: self.size.height)
    bunny.zPosition = 1000
    bunny.spawn(world, position: initialBunnyPosition)

任何有任何事情的人请帮忙,如果您需要更多代码片段,请告诉我,我会提供更多信息。 提前致谢。

【问题讨论】:

  • 您是否设置了联系人的代理? (self.physicsWorld.contactDelegate = self)
  • 是的,我有,但仍然一无所有:(
  • 你是否为你的所有角色创建了正确的物理边界:)?
  • 我为我的每个节点都使用了self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size),这就是你的意思吗?对不起,如果我听起来很愚蠢,我对 SpriteKit 和游戏开发很陌生。
  • “我工作过”会被打印出来吗?你能告诉我们你的 PhysicsCategory 原始值吗?您的 Gamescene 类是否实现了 SKPhysicsContactDelete 协议?

标签: ios iphone swift sprite-kit swift2


【解决方案1】:

当您将physicsBodies 设置为您的项目时,您还可以定义您的角色将在哪里玩耍和碰撞的边界。

首先你必须插入SKPhysicsContactDelegate 以使用didBeginContact 方法并设置委托如下..

这只是一个你可以开始的例子:

class GameScene: SKScene, SKPhysicsContactDelegate { 
    override func didMoveToView(view: SKView) {

        self.physicsWorld.gravity = CGVectorMake(0, -6) //gravity
        self.physicsWorld.contactDelegate = self  //

        // Set physics boundaries
        let fieldBody = SKPhysicsBody.init(edgeLoopFromRect: self.frame)
        self.physicsBody = fieldBody
        self.physicsBody!.affectedByGravity = false
        self.physicsBody!.usesPreciseCollisionDetection = true
        self.physicsBody!.dynamic = true
        self.physicsBody!.mass = 0.8
        self.physicsBody!.friction = 0
        self.physicsBody!.linearDamping = 0
        self.physicsBody!.angularDamping = 0
        self.physicsBody!.restitution = 0
        self.physicsBody!.categoryBitMask = PhysicsCategory.field.rawValue
        self.physicsBody!.contactTestBitMask = PhysicsCategory.hedgehog.rawValue | PhysicsCategory.bunny.rawValue
        //self.physicsBody!.collisionBitMask = 0
    }
}

【讨论】:

  • 你不需要边界来让碰撞起作用,只是为了阻止字符离开屏幕边缘,但这可以通过其他方式实现。如果 OP 的精灵在没有调用 dBC 的情况下接触/重叠,那么边界不是他的问题。
  • 事实上,在我的示例史蒂夫中不仅有边界,我还报告了如何定义类,如何设置委托,显然我不知道 OP 是否正确设置了所有physicsBodies,但正如我一样已经解释了这只是 OP 可以开始的一点(由于有问题的信息很少)
  • 它有点工作,现在我得到“我工作”和“没有游戏逻辑的联系”,但非常感谢您的帮助。 :)
  • Conor - 查看我发布的新答案。
【解决方案2】:

Conor - 你说你的 dBC 正在被调用。你有这个工作吗?如果没有,请为您的didBeginContact 尝试此操作,看看它是否识别出正确的冲突:

func didBeginContact(contact: SKPhysicsContact) {

    print("i worked")
      let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

       switch contactMask

       case PhysicsCategory.bunny.rawValue | PhysicsCategory.grass.rawValue:
        print("nom nom grass")
    case PhysicsCategory.bunny.rawValue | PhysicsCategory.mud.rawValue:
        print("mud hit")
    case PhysicsCategory.bunny.rawValue | PhysicsCategory.stone.rawValue:
        print("ow my head")
    case PhysicsCategory.bunny.rawValue | PhysicsCategory.lava.rawValue:
        print("it burns")
    case PhysicsCategory.bunny.rawValue | PhysicsCategory.hedgehog.rawValue:
        print("stop touching me!")
    default:
        print("Contact with no game logic")
    }
}

它对PhysicsCategory.bunnyDamaged.rawValue 没有任何作用,但如果我们可以让基本检测正常工作,我们可以添加它。

【讨论】:

  • 伙计,OP 请求为什么没有调用 didBeginContact 并且您发布了 didBeginContact 示例?什么样的帮助可以给这个帖子?
  • @Allessandro - OP 在 cmets 中声明他的 didBeginContact 现在正在被调用,但是这些接触测试都不匹配,所以我虽然发布了一个适用于大多数人的 dBC 布局,看看这是否对他有帮助。
  • 我不认识你,所以我没兴趣和你讽刺,我说的是线程标题和你的帖子,通常当OP谈到其他问题时,正确的方式是说: 请您必须就这个与您的请求无关的新问题提出另一个问题或编辑您正在回答的问题以提高清晰度和重点回答,人们没有时间阅读所有 cmets stackoverflow.com/help/how-to-answer
  • 我现在试试,稍后我会发布结果。感谢您的意见
  • 嘿史蒂夫,我试过这个还是没有运气:(这很奇怪,因为每个节点都分配了它的位掩码编号,但联系不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多