【问题标题】:Contact Bit Mask接触位掩码
【发布时间】:2018-12-13 16:35:12
【问题描述】:

所以我在我的应用程序中使用了物理 Body 和 contactbitmasks/physicscategories,但它们无法正常工作。我希望球在遇到危险时重置,或者在触球后移动到下一个级别。目前,我将其设置为仅出于测试原因打印语句。

我已经在代码中设置了它们,但它仍然无法正常工作。有什么问题?

import SpriteKit
import GameplayKit

class GameScene: SKScene {

var ball = SKSpriteNode()
var danger1 = SKSpriteNode()
var danger2 = SKSpriteNode()
var goal = SKSpriteNode()


override func didMove(to view: SKView) {

    ball = self.childNode(withName: "ball") as! SKSpriteNode
    danger1 = self.childNode(withName: "danger1") as! SKSpriteNode
    danger2 = self.childNode(withName: "danger2") as! SKSpriteNode
    goal = self.childNode(withName: "goal") as! SKSpriteNode

    let border = SKPhysicsBody(edgeLoopFrom: self.frame)
    border.friction = 0
    border.restitution = 0

    danger1.physicsBody = SKPhysicsBody()
    danger1.physicsBody?.categoryBitMask = PhysicsCategories.dangerCategory
    danger2.physicsBody = SKPhysicsBody()
    danger2.physicsBody?.categoryBitMask = PhysicsCategories.dangerCategory

    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width/2)
    ball.physicsBody?.categoryBitMask = PhysicsCategories.ballCategory
    ball.physicsBody?.contactTestBitMask = PhysicsCategories.dangerCategory
    ball.physicsBody?.collisionBitMask = PhysicsCategories.none

    goal.physicsBody = SKPhysicsBody()
    goal.physicsBody?.categoryBitMask = PhysicsCategories.goalCategory

    danger1.physicsBody?.isDynamic = true
    ball.physicsBody?.isDynamic = true
    goal.physicsBody?.isDynamic = true
    danger2.physicsBody?.isDynamic = true
    danger2.physicsBody!.affectedByGravity = false
    danger1.physicsBody!.affectedByGravity = false
    goal.physicsBody!.affectedByGravity = false
    ball.physicsBody!.affectedByGravity = false
    setupPhysics()

}
func setupPhysics() {
    physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
    physicsWorld.contactDelegate = self
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        ball.position.x = location.x
        ball.position.y = location.y
        print("x: \(ball.position.x), y: \(ball.position.y)")
    }
}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
}
}

extension GameScene: SKPhysicsContactDelegate {



func didBegin(_ contact: SKPhysicsContact) {
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    if contactMask == PhysicsCategories.ballCategory | PhysicsCategories.dangerCategory {
        print("Contact")
    } else if contactMask == PhysicsCategories.ballCategory | PhysicsCategories.goalCategory {
        print("Goal!")
    }
}

}

【问题讨论】:

  • 没有人知道 PhysicsCategories.ballCategory 和 PhysicsCategories.dangerCategory 是什么。
  • 它直接说它是一个SpriteNode?不要认为你需要知道其他任何事情。除非我错了,但是.....
  • Schmobr - 你的 GameScene 必须是 SKPhysicsContactDelegate,除了下面 KoD 的回答。

标签: swift xcode sprite-kit


【解决方案1】:

你的危险区域的物理体没有大小,所以怎么会发生碰撞?

danger1.physicsBody = SKPhysicsBody() should be danger1.physicsBody = SKPhysicsBody(rectangleOf:danger1.size)

现在对于一些高级注释,除非您的精灵确实在移动,否则请关闭 isDynamic。在现实世界中,除非墙倒塌在球的顶部,否则您的墙永远不会与球发生碰撞。

清理应该如下所示:

physicsWorld.contactDelegate = self
ball = self.childNode(withName: "ball") as! SKSpriteNode
danger1 = self.childNode(withName: "danger1") as! SKSpriteNode
danger2 = self.childNode(withName: "danger2") as! SKSpriteNode
goal = self.childNode(withName: "goal") as! SKSpriteNode

let border = SKPhysicsBody(edgeLoopFrom: self.frame)
border.friction = 0
border.restitution = 0

danger1.physicsBody = SKPhysicsBody(rectangleOf:danger1.size)
danger1.physicsBody?.categoryBitMask = PhysicsCategories.dangerCategory
danger1.physicsBody?.isDynamic = false

danger2.physicsBody = SKPhysicsBody(rectangleOf:danger2.size)
danger2.physicsBody?.categoryBitMask = PhysicsCategories.dangerCategory
danger2.physicsBody?.isDynamic = false

ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width/2)
ball.physicsBody?.categoryBitMask = PhysicsCategories.ballCategory
ball.physicsBody?.contactTestBitMask = PhysicsCategories.dangerCategory | PhysicsCategories.goalCategory
ball.physicsBody?.collisionBitMask = PhysicsCategories.none
ball.physicsBody?.isDynamic = true
ball.physicsBody!.affectedByGravity = false

goal.physicsBody = SKPhysicsBody(rectangleOf:goal.size)
goal.physicsBody?.categoryBitMask = PhysicsCategories.goalCategory
goal.physicsBody?.isDynamic = false
//setupPhysics()  Remove this

【讨论】:

  • 好的!一旦我回到我的编码,我会尝试它。感谢您的帮助,我会告诉您它是否有效:)
  • 当我删除 setupPhysics() 没有任何东西被打印/没有发生碰撞。我将 SKPhysicsBody 更改为现在允许打印项目,但如果我将打印语句更改为 ball.position = CGPoint(x: 0, y: 550) 之类的内容,则不会发生任何事情。此外,当球仍然接触球门时,什么也不会发生
  • 您是否将联系人代表移至我在此处列出的主要功能?不知道你的目标问题
  • 它说“无法将类型 'GameScene' 的值分配给类型 'SKPhysicsContactDelegate?'”
  • 不知道你做了什么,这是你的代码,我只是把这条线移出了设置物理。你不知何故失去了你曾经分配给游戏场景的代表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-02
相关资源
最近更新 更多