import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let balls = [
SKSpriteNode(imageNamed: "blueball.png"),
SKSpriteNode(imageNamed: "greenball.png"),
SKSpriteNode(imageNamed: "realredball.png"),
]
let redRectangle = SKSpriteNode(imageNamed: "redrectangle.png")
let blueRectangle = SKSpriteNode(imageNamed: "bluerectangle.png")
let greenRectangle = SKSpriteNode(imageNamed: "greenrectangle.png")
let blueBallCategory :UInt32 = 0x1 << 0
let greenBallCategory :UInt32 = 0x1 << 1
let realRedBallCategory :UInt32 = 0x1 << 2
let redRectangleCategory : UInt32 = 0x1 << 3
let blueRectangleCategory : UInt32 = 0x1 << 4
let greenRectangleCategory : UInt32 = 0x1 << 5
override func didMove(to view: SKView) {
spawnBallsandRectangles()
physicsWorld.contactDelegate = self
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
physics()
}
func didBegin(_ contact: SKPhysicsContact) {
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if firstBody.categoryBitMask == blueBallCategory && secondBody.categoryBitMask == blueRectangleCategory {
print("alive")
}
else if firstBody.categoryBitMask == greenBallCategory && secondBody.categoryBitMask == greenRectangleCategory {
print("alive")
}
else if firstBody.categoryBitMask == realRedBallCategory && secondBody.categoryBitMask == redRectangleCategory {
print("alive")
}
else if firstBody.categoryBitMask == blueBallCategory || firstBody.categoryBitMask == greenBallCategory && secondBody.categoryBitMask == redRectangleCategory{
print("dead")
}
else if firstBody.categoryBitMask == realRedBallCategory || firstBody.categoryBitMask == greenBallCategory && secondBody.categoryBitMask == blueRectangleCategory {
print("dead")
}
else if firstBody.categoryBitMask == realRedBallCategory || firstBody.categoryBitMask == blueBallCategory && secondBody.categoryBitMask == greenBallCategory {
print("dead")
}
}
func spawnBallsandRectangles() {
let ball = balls[Int(arc4random_uniform(UInt32(balls.count)))]
ball.position = CGPoint(x: -200, y: 250)
ball.size = CGSize(width: 70, height: 70)
redRectangle.position = CGPoint(x: 0, y: -600)
redRectangle.size = CGSize(width: 200, height: 20)
blueRectangle.position = CGPoint(x: -200, y: -600)
blueRectangle.size = CGSize(width: 200, height: 20)
greenRectangle.position = CGPoint(x: 200, y: -600)
greenRectangle.size = CGSize(width: 200, height: 20)
self.addChild(ball)
self.addChild(redRectangle)
self.addChild(blueRectangle)
self.addChild(greenRectangle)
}
func physics(){
for ball in balls{
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height/2)
}
redRectangle.physicsBody = SKPhysicsBody(rectangleOf: redRectangle.size)
redRectangle.physicsBody?.affectedByGravity = false
redRectangle.physicsBody?.isDynamic = false
blueRectangle.physicsBody = SKPhysicsBody(rectangleOf: redRectangle.size)
blueRectangle.physicsBody?.affectedByGravity = false
blueRectangle.physicsBody?.isDynamic = false
greenRectangle.physicsBody = SKPhysicsBody(rectangleOf: redRectangle.size)
greenRectangle.physicsBody?.isDynamic = false
greenRectangle.physicsBody?.affectedByGravity = false
balls[0].physicsBody?.categoryBitMask = blueBallCategory
balls[1].physicsBody?.categoryBitMask = greenBallCategory
balls[2].physicsBody?.categoryBitMask = realRedBallCategory
balls[0].physicsBody?.contactTestBitMask = redRectangleCategory
balls[1].physicsBody?.contactTestBitMask = redRectangleCategory
balls[1].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[2].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[0].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[2].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[0].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[1].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[2].physicsBody?.contactTestBitMask = redRectangleCategory
redRectangle.physicsBody?.categoryBitMask = redRectangleCategory
blueRectangle.physicsBody?.categoryBitMask = blueRectangleCategory
greenRectangle.physicsBody?.categoryBitMask = greenRectangleCategory
}
}
我已经设置了碰撞检测,以便如果球碰撞到匹配颜色的矩形,则程序打印(" Alive")。如果颜色不匹配,则该程序应该打印("死")。它检测到颜色是否匹配并打印(" Alive"),但不会打印("死")。有人可以帮忙吗,谢谢。
您可能会发现这样的didBegin()
这样的结构可能有助于摆脱所有这些else if
S:
func didBegin(_ contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
case blueBallCategory | blueRectangleCategory:
print("Alive! Blue ball has hit blue rectangle.")
case greenBallCategory | greenRectangleCategory:
print("Alive! Green ball has hit green rectangle.")
case redBallCategory | redRectangleCategory:
print("Alive! Red ball has hit red rectangle.")
default :
print("Dead! Some other contact has occurred")
}
}
如果一个球撞到了不同颜色的矩形,您想发生什么?
编辑:
来自您的physics()
功能中的此代码:
balls[0].physicsBody?.contactTestBitMask = redRectangleCategory
balls[1].physicsBody?.contactTestBitMask = redRectangleCategory
balls[1].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[2].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[0].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[2].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[0].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[1].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[2].physicsBody?.contactTestBitMask = redRectangleCategory
每次您为特定物理主体的ContactTestBitMask分配一个新值时,您都在覆盖上一个值,而不是添加。因此,唯一重要的行是:
balls[0].physicsBody?.contactTestBitMask = blueRectangleCategory
balls[1].physicsBody?.contactTestBitMask = greenRectangleCategory
balls[2].physicsBody?.contactTestBitMask = redRectangleCategory
因此,球[0](蓝色球)仅接触蓝色矩形,球[1](绿球)仅接触绿色矩形和球[2](真红球)仅接触红色矩形。因此,如果球接触不同颜色的矩形,则不会调用didBegin()
,这就是为什么您永远不会看到"死亡"消息。
另一个编辑:
如果您希望所有球触发didBegin(),然后与任何矩形联系,则您的contactTestBitMasks
的球应包括所有矩形:
for ball in balls {
balls.physicsBody?.contactTestBitMask = blueRectangleCategory | greenRectangleCategory | redRectangleCategory
}
,或者如果球已经定义了一些联系人,您只想将矩形添加到其碰撞位面具中:
for ball in balls {
balls.physicsBody?.contactTestBitMask |= (blueRectangleCategory | greenRectangleCategory | redRectangleCategory)
}