我创建了一个4种颜色均匀划分的圆圈,每种颜色都是一个节点。 然后还有另一个节点,一个球从屏幕顶部飞到scree的中心,当球接触圆圈时,得1分。 我现在面临的问题是接触检测不起作用,这是代码。
另外,我想知道在FourColorSquare中为每个节点设置单独的物理主体以检测每种颜色的碰撞更好吗?
// move groups outside of class, so that other game scene can use it
let ballGroup:UInt32 = 1
let nodeGroup:UInt32 = 2
class FourColorCircle: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")
}
}
}
所以当两个精灵彼此接触时,控制台中没有打印日志。
答案 0 :(得分:0)
在为节点的物理主体设置属性之前,首先需要创建一个属性。有基于体积的体,例如圆形或矩形,并且有从路径创建的基于边缘的物理体。
如果您正在使用球,则可以使用基于体积的身体,例如init(circleOfRadius:)
或init(circleOfRadius:center:)
。如果您在继续之前阅读SKPhysicsBody课程参考资料,那将是最好的。