Sprite 接触检测在 swift 中不起作用
Sprite contact detection not working in swift
我创建了一个圆,4种颜色均分,每种颜色是一个节点。
然后还有一个节点是一个球从屏幕顶部飞到屏幕中心,当球接触到圆圈时,得1分。
我现在面临的问题是接触检测不起作用,这是代码。
我还想知道为 FourColorSquare 中的每个节点设置单独的物理体以检测与每种颜色的碰撞有什么更好的方法?
// move groups outside of class, so that other game scene can use it
let ballGroup:UInt32 = 1
let nodeGroup:UInt32 = 2
class 四色圆:SKShapeNode {
override init() {
super.init()
self.createCircle()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func createCircle () {
let center = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
// node1
let node1bezierPath = UIBezierPath()
node1bezierPath.addArcWithCenter(center, radius: 100, startAngle: 0.78, endAngle: 2.35, clockwise: true)
node1bezierPath.addLineToPoint(center)
let node1 = SKShapeNode(path: node1bezierPath.CGPath)
node1.strokeColor = SKColor.redColor()
node1.fillColor = SKColor.redColor()
node1.physicsBody?.categoryBitMask = nodeGroup
node1.physicsBody?.collisionBitMask = ballGroup
node1.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node1)
// node2
let node2bezierPath = UIBezierPath()
node2bezierPath.addArcWithCenter(center, radius: 100, startAngle: 2.35, endAngle: 3.92, clockwise: true)
node2bezierPath.addLineToPoint(center)
let node2 = SKShapeNode(path: node2bezierPath.CGPath)
node2.strokeColor = SKColor.blueColor()
node2.fillColor = SKColor.blueColor()
node2.physicsBody?.categoryBitMask = nodeGroup
node2.physicsBody?.collisionBitMask = ballGroup
node2.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node2)
// node3
let node3bezierPath = UIBezierPath()
node3bezierPath.addArcWithCenter(center, radius: 100, startAngle: 3.92, endAngle: 5.48, clockwise: true)
node3bezierPath.addLineToPoint(center)
let node3 = SKShapeNode(path: node3bezierPath.CGPath)
node3.strokeColor = SKColor.greenColor()
node3.fillColor = SKColor.greenColor()
node3.physicsBody?.categoryBitMask = nodeGroup
node3.physicsBody?.collisionBitMask = ballGroup
node3.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node3)
// node4
let node4bezierPath = UIBezierPath()
node4bezierPath.addArcWithCenter(center, radius: 100, startAngle: 5.48, endAngle: 0.78, clockwise: true)
node4bezierPath.addLineToPoint(center)
let node4 = SKShapeNode(path: node4bezierPath.CGPath)
node4.strokeColor = SKColor.yellowColor()
node4.fillColor = SKColor.yellowColor()
node4.physicsBody?.categoryBitMask = nodeGroup
node4.physicsBody?.collisionBitMask = ballGroup
node4.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node4)
}
func rotate(angle : CGFloat, animated : Bool) {
var rotateAction : SKAction!
if animated {
rotateAction = SKAction.rotateByAngle(angle, duration: 0.6)
}
else {
rotateAction = SKAction.rotateByAngle(angle, duration: 0)
}
self.runAction(rotateAction)
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var ball = SKShapeNode(circleOfRadius: 10)
var ballColor = ["red", "blue", "green", "yellow"]
let circle = FourColorCircle()
override func didMoveToView(view: SKView) {
self.physicsWorld.contactDelegate = self
ball.physicsBody?.dynamic = true
ball.physicsBody?.categoryBitMask = ballGroup
ball.physicsBody?.collisionBitMask = nodeGroup
ball.physicsBody?.contactTestBitMask = nodeGroup
circle.physicsBody?.categoryBitMask = nodeGroup
circle.physicsBody?.collisionBitMask = ballGroup
circle.physicsBody?.contactTestBitMask = ballGroup
backgroundColor = SKColor.whiteColor()
circle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.addChild(circle)
self.addChild(ball)
ball.position = CGPointMake(150, 0)
println("Initial Ball Pos: \(ball.position)")
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
rotateCenterCircle()
setBallPosition()
setRandomColor()
ballMove()
// test ball position
println("--------------")
println("Ball Pos: \(ball.position)")
println("Circle pos: \(circle.position)")
println("Midpoint: \(CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame) + self.frame.size.width))")
println("--------------")
// super.touchesBegan(touches as Set<NSObject> , withEvent:event)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
func rotateCenterCircle() {
circle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
circle.rotate(-3.14/2, animated: true)
}
func ballMove() {
let ballMovement = SKAction.moveTo(CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)), duration: 3)
ball.runAction(ballMovement)
}
func setRandomColor() {
ball.strokeColor = SKColor.whiteColor()
ball.zPosition = 10
let ballColorIndex = Int(arc4random_uniform(UInt32(ballColor.count)))
switch(ballColorIndex) {
case 0:
ball.fillColor = SKColor.redColor()
case 1:
ball.fillColor = SKColor.blueColor()
case 2:
ball.fillColor = SKColor.greenColor()
case 3:
ball.fillColor = SKColor.yellowColor()
default:
println("Unexpected random index value ", ballColorIndex)
}
}
func setBallPosition() {
ball.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame) + (self.frame.size.width / 2))
println("ball position = \(ball.position)")
}
func didBeginContact(contact: SKPhysicsContact) {
if contact.bodyA.categoryBitMask == nodeGroup || contact.bodyB.categoryBitMask == nodeGroup {
println("contact")
}
}
}
所以当两个精灵相互接触时,控制台没有打印日志。
在为节点的物理体设置属性之前,您首先需要创建一个。有基于体积的物体,例如圆形或矩形,也有基于边的物理物体,这些物体是从路径创建的。
鉴于您当前正在使用球,您将使用基于体积的物体,例如 init(circleOfRadius:)
或 init(circleOfRadius:center:)
。最好在继续之前阅读 SKPhysicsBody class 参考资料。
我创建了一个圆,4种颜色均分,每种颜色是一个节点。 然后还有一个节点是一个球从屏幕顶部飞到屏幕中心,当球接触到圆圈时,得1分。 我现在面临的问题是接触检测不起作用,这是代码。
我还想知道为 FourColorSquare 中的每个节点设置单独的物理体以检测与每种颜色的碰撞有什么更好的方法?
// move groups outside of class, so that other game scene can use it
let ballGroup:UInt32 = 1
let nodeGroup:UInt32 = 2
class 四色圆:SKShapeNode {
override init() {
super.init()
self.createCircle()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func createCircle () {
let center = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
// node1
let node1bezierPath = UIBezierPath()
node1bezierPath.addArcWithCenter(center, radius: 100, startAngle: 0.78, endAngle: 2.35, clockwise: true)
node1bezierPath.addLineToPoint(center)
let node1 = SKShapeNode(path: node1bezierPath.CGPath)
node1.strokeColor = SKColor.redColor()
node1.fillColor = SKColor.redColor()
node1.physicsBody?.categoryBitMask = nodeGroup
node1.physicsBody?.collisionBitMask = ballGroup
node1.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node1)
// node2
let node2bezierPath = UIBezierPath()
node2bezierPath.addArcWithCenter(center, radius: 100, startAngle: 2.35, endAngle: 3.92, clockwise: true)
node2bezierPath.addLineToPoint(center)
let node2 = SKShapeNode(path: node2bezierPath.CGPath)
node2.strokeColor = SKColor.blueColor()
node2.fillColor = SKColor.blueColor()
node2.physicsBody?.categoryBitMask = nodeGroup
node2.physicsBody?.collisionBitMask = ballGroup
node2.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node2)
// node3
let node3bezierPath = UIBezierPath()
node3bezierPath.addArcWithCenter(center, radius: 100, startAngle: 3.92, endAngle: 5.48, clockwise: true)
node3bezierPath.addLineToPoint(center)
let node3 = SKShapeNode(path: node3bezierPath.CGPath)
node3.strokeColor = SKColor.greenColor()
node3.fillColor = SKColor.greenColor()
node3.physicsBody?.categoryBitMask = nodeGroup
node3.physicsBody?.collisionBitMask = ballGroup
node3.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node3)
// node4
let node4bezierPath = UIBezierPath()
node4bezierPath.addArcWithCenter(center, radius: 100, startAngle: 5.48, endAngle: 0.78, clockwise: true)
node4bezierPath.addLineToPoint(center)
let node4 = SKShapeNode(path: node4bezierPath.CGPath)
node4.strokeColor = SKColor.yellowColor()
node4.fillColor = SKColor.yellowColor()
node4.physicsBody?.categoryBitMask = nodeGroup
node4.physicsBody?.collisionBitMask = ballGroup
node4.physicsBody?.contactTestBitMask = ballGroup
self.addChild(node4)
}
func rotate(angle : CGFloat, animated : Bool) {
var rotateAction : SKAction!
if animated {
rotateAction = SKAction.rotateByAngle(angle, duration: 0.6)
}
else {
rotateAction = SKAction.rotateByAngle(angle, duration: 0)
}
self.runAction(rotateAction)
}
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var ball = SKShapeNode(circleOfRadius: 10)
var ballColor = ["red", "blue", "green", "yellow"]
let circle = FourColorCircle()
override func didMoveToView(view: SKView) {
self.physicsWorld.contactDelegate = self
ball.physicsBody?.dynamic = true
ball.physicsBody?.categoryBitMask = ballGroup
ball.physicsBody?.collisionBitMask = nodeGroup
ball.physicsBody?.contactTestBitMask = nodeGroup
circle.physicsBody?.categoryBitMask = nodeGroup
circle.physicsBody?.collisionBitMask = ballGroup
circle.physicsBody?.contactTestBitMask = ballGroup
backgroundColor = SKColor.whiteColor()
circle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.addChild(circle)
self.addChild(ball)
ball.position = CGPointMake(150, 0)
println("Initial Ball Pos: \(ball.position)")
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
rotateCenterCircle()
setBallPosition()
setRandomColor()
ballMove()
// test ball position
println("--------------")
println("Ball Pos: \(ball.position)")
println("Circle pos: \(circle.position)")
println("Midpoint: \(CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame) + self.frame.size.width))")
println("--------------")
// super.touchesBegan(touches as Set<NSObject> , withEvent:event)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
func rotateCenterCircle() {
circle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
circle.rotate(-3.14/2, animated: true)
}
func ballMove() {
let ballMovement = SKAction.moveTo(CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)), duration: 3)
ball.runAction(ballMovement)
}
func setRandomColor() {
ball.strokeColor = SKColor.whiteColor()
ball.zPosition = 10
let ballColorIndex = Int(arc4random_uniform(UInt32(ballColor.count)))
switch(ballColorIndex) {
case 0:
ball.fillColor = SKColor.redColor()
case 1:
ball.fillColor = SKColor.blueColor()
case 2:
ball.fillColor = SKColor.greenColor()
case 3:
ball.fillColor = SKColor.yellowColor()
default:
println("Unexpected random index value ", ballColorIndex)
}
}
func setBallPosition() {
ball.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame) + (self.frame.size.width / 2))
println("ball position = \(ball.position)")
}
func didBeginContact(contact: SKPhysicsContact) {
if contact.bodyA.categoryBitMask == nodeGroup || contact.bodyB.categoryBitMask == nodeGroup {
println("contact")
}
}
}
所以当两个精灵相互接触时,控制台没有打印日志。
在为节点的物理体设置属性之前,您首先需要创建一个。有基于体积的物体,例如圆形或矩形,也有基于边的物理物体,这些物体是从路径创建的。
鉴于您当前正在使用球,您将使用基于体积的物体,例如 init(circleOfRadius:)
或 init(circleOfRadius:center:)
。最好在继续之前阅读 SKPhysicsBody class 参考资料。