在 SpriteKit 中,未检测到 SKPhysicsContactDelegate 接触
In SpriteKit SKPhysicsContactDelegate contact is not detected
我正尝试在 Swift 中使用 Spritekit 编写游戏。目的是逃脱他的角色迎面而来的矩形。现在我在 SKPhysicsContactDelegate (didBegin ()) 方法中犯了一个错误,因此无法识别图形与其中一个矩形的接触。谁能帮我找出错误?
import SpriteKit
enum bodyType: UInt32 {
case rechteckRechts = 1
case rechteckLinks = 2
case figur = 4
}
class PlayScene: SKScene, SKPhysicsContactDelegate {
let figur = SKSpriteNode(imageNamed: "Punkt.jpg")
@objc func addRechteck(){
let rechteckRechts = SKSpriteNode(imageNamed: "Rechteck.gif")
rechteckRechts.physicsBody = SKPhysicsBody()
rechteckRechts.physicsBody?.isDynamic = false
rechteckRechts.physicsBody?.categoryBitMask = bodyType.rechteckRechts.rawValue
let rechteckLinks = SKSpriteNode(imageNamed: "Rechteck.gif")
rechteckLinks.physicsBody = SKPhysicsBody()
rechteckLinks.physicsBody?.isDynamic = false
rechteckLinks.physicsBody?.categoryBitMask = bodyType.rechteckLinks.rawValue
let groesse = arc4random_uniform(5)+1
print(groesse)
switch groesse {
case 1:
rechteckLinks.xScale = 0.5
rechteckRechts.xScale = 1.5
case 2:
rechteckLinks.xScale = 1.5
rechteckRechts.xScale = 0.5
case 3:
rechteckLinks.xScale = 1
rechteckRechts.xScale = 1
case 4:
rechteckLinks.xScale = 1.25
rechteckRechts.xScale = 0.75
case 5:
rechteckLinks.xScale = 0.75
rechteckRechts.xScale = 1.25
default:
print("Fehler in der Wahrscheinlichkeit!!!")
}
rechteckRechts.position = CGPoint(x: frame.minX + (rechteckRechts.size.width / 2), y: frame.maxY)
rechteckLinks.position = CGPoint(x: frame.maxX - (rechteckLinks.size.width / 2), y: frame.maxY)
let moveDown = SKAction.moveBy(x: 0, y: -5000, duration: 20.0)
rechteckLinks.run(moveDown)
rechteckRechts.run(moveDown)
self.addChild(rechteckRechts)
self.addChild(rechteckLinks)
}
override func didMove(to view: SKView) {
physicsWorld.gravity = .zero
physicsWorld.contactDelegate = self
figur.xScale = 0.4
figur.yScale = 0.4
figur.position = CGPoint(x: frame.midX, y: frame.maxY / 4)
figur.physicsBody = SKPhysicsBody()
figur.physicsBody?.isDynamic = false
figur.physicsBody?.categoryBitMask = bodyType.figur.rawValue
self.addChild(figur)
self.backgroundColor = SKColor.white
let wait1 = SKAction.wait(forDuration: 3)
let timer = SKAction.repeatForever(SKAction.sequence([wait1, SKAction.run {
self.addRechteck()
}]))
self.run(timer, withKey: "addRechteck")
}
func didBegin(_ contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
case bodyType.figur.rawValue | bodyType.rechteckLinks.rawValue:
print("contact")
case bodyType.figur.rawValue | bodyType.rechteckRechts.rawValue:
print("contact")
default:
return
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ){
let location = touch.location(in: self)
if figur.contains(location){
figur.position = location
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ) {
let location = touch.location(in: self)
if figur.contains(location){
figur.position = location
}
}
}
}
您似乎没有设置碰撞和接触测试位掩码。这些是物理体的属性。 collisionBitMask
控制哪些对象从其他对象反弹。默认情况下,所有内容都会反弹。
contactTestBitMask
在这种情况下很重要,因为它控制在联系其他对象时哪些对象调用“didBegin”。默认情况下,这是 0,这意味着没有注册联系人。请在此处查看我的回答: 以获得详细说明。
在您的具体示例中,您似乎想知道 figur
何时与 rechteckLinks
或 rechteckRechts
联系,因此您需要关注 contactTestBitMasks
:
figur.physicsBody!.cagegoryBitMask = bodyType.figur
figur.physicsBody!.contactTestBitMask = bodyType.rechteckRechts | bodyType.rechteckLinks
编辑:更正 figur
物理体的定义:
我们改变了?到 !这样,如果物理体不存在,我们就会崩溃。我们还将 isDynamic
属性 更改为 true
因为不是动态的物理实体无法注册联系人(我认为)。其他 2 个不是动态的也可以。我们将 collisionTestBitMask
分配给我们希望收到碰撞通知的所有类别的值,逻辑上“或”在一起:
figur.physicsBody!.isDynamic = true
figur.physicsBody!.categoryBitMask = bodyType.figur.rawValue
figur.physicsBody!.contactTestBitMask = bodyType.rechteckRechts.rawValue | bodyType.rechteckLinks.rawValue
我正尝试在 Swift 中使用 Spritekit 编写游戏。目的是逃脱他的角色迎面而来的矩形。现在我在 SKPhysicsContactDelegate (didBegin ()) 方法中犯了一个错误,因此无法识别图形与其中一个矩形的接触。谁能帮我找出错误?
import SpriteKit
enum bodyType: UInt32 {
case rechteckRechts = 1
case rechteckLinks = 2
case figur = 4
}
class PlayScene: SKScene, SKPhysicsContactDelegate {
let figur = SKSpriteNode(imageNamed: "Punkt.jpg")
@objc func addRechteck(){
let rechteckRechts = SKSpriteNode(imageNamed: "Rechteck.gif")
rechteckRechts.physicsBody = SKPhysicsBody()
rechteckRechts.physicsBody?.isDynamic = false
rechteckRechts.physicsBody?.categoryBitMask = bodyType.rechteckRechts.rawValue
let rechteckLinks = SKSpriteNode(imageNamed: "Rechteck.gif")
rechteckLinks.physicsBody = SKPhysicsBody()
rechteckLinks.physicsBody?.isDynamic = false
rechteckLinks.physicsBody?.categoryBitMask = bodyType.rechteckLinks.rawValue
let groesse = arc4random_uniform(5)+1
print(groesse)
switch groesse {
case 1:
rechteckLinks.xScale = 0.5
rechteckRechts.xScale = 1.5
case 2:
rechteckLinks.xScale = 1.5
rechteckRechts.xScale = 0.5
case 3:
rechteckLinks.xScale = 1
rechteckRechts.xScale = 1
case 4:
rechteckLinks.xScale = 1.25
rechteckRechts.xScale = 0.75
case 5:
rechteckLinks.xScale = 0.75
rechteckRechts.xScale = 1.25
default:
print("Fehler in der Wahrscheinlichkeit!!!")
}
rechteckRechts.position = CGPoint(x: frame.minX + (rechteckRechts.size.width / 2), y: frame.maxY)
rechteckLinks.position = CGPoint(x: frame.maxX - (rechteckLinks.size.width / 2), y: frame.maxY)
let moveDown = SKAction.moveBy(x: 0, y: -5000, duration: 20.0)
rechteckLinks.run(moveDown)
rechteckRechts.run(moveDown)
self.addChild(rechteckRechts)
self.addChild(rechteckLinks)
}
override func didMove(to view: SKView) {
physicsWorld.gravity = .zero
physicsWorld.contactDelegate = self
figur.xScale = 0.4
figur.yScale = 0.4
figur.position = CGPoint(x: frame.midX, y: frame.maxY / 4)
figur.physicsBody = SKPhysicsBody()
figur.physicsBody?.isDynamic = false
figur.physicsBody?.categoryBitMask = bodyType.figur.rawValue
self.addChild(figur)
self.backgroundColor = SKColor.white
let wait1 = SKAction.wait(forDuration: 3)
let timer = SKAction.repeatForever(SKAction.sequence([wait1, SKAction.run {
self.addRechteck()
}]))
self.run(timer, withKey: "addRechteck")
}
func didBegin(_ contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
case bodyType.figur.rawValue | bodyType.rechteckLinks.rawValue:
print("contact")
case bodyType.figur.rawValue | bodyType.rechteckRechts.rawValue:
print("contact")
default:
return
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ){
let location = touch.location(in: self)
if figur.contains(location){
figur.position = location
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ) {
let location = touch.location(in: self)
if figur.contains(location){
figur.position = location
}
}
}
}
您似乎没有设置碰撞和接触测试位掩码。这些是物理体的属性。 collisionBitMask
控制哪些对象从其他对象反弹。默认情况下,所有内容都会反弹。
contactTestBitMask
在这种情况下很重要,因为它控制在联系其他对象时哪些对象调用“didBegin”。默认情况下,这是 0,这意味着没有注册联系人。请在此处查看我的回答:
在您的具体示例中,您似乎想知道 figur
何时与 rechteckLinks
或 rechteckRechts
联系,因此您需要关注 contactTestBitMasks
:
figur.physicsBody!.cagegoryBitMask = bodyType.figur
figur.physicsBody!.contactTestBitMask = bodyType.rechteckRechts | bodyType.rechteckLinks
编辑:更正 figur
物理体的定义:
我们改变了?到 !这样,如果物理体不存在,我们就会崩溃。我们还将 isDynamic
属性 更改为 true
因为不是动态的物理实体无法注册联系人(我认为)。其他 2 个不是动态的也可以。我们将 collisionTestBitMask
分配给我们希望收到碰撞通知的所有类别的值,逻辑上“或”在一起:
figur.physicsBody!.isDynamic = true
figur.physicsBody!.categoryBitMask = bodyType.figur.rawValue
figur.physicsBody!.contactTestBitMask = bodyType.rechteckRechts.rawValue | bodyType.rechteckLinks.rawValue