-1

I have three moving sprites. One is a ball, one is a line, and one is a triangle. When the ball hits the line, I want to do score++ and then spawn another ball with the addBall() function. When the ball hits the triangle, I want to end the game.

Below is my code. The ball passes right through both the ball and triangle without any collision. Can anyone point me in the right direction?

import SpriteKit




class GameScene: SKScene, SKPhysicsContactDelegate  {



var center = SKSpriteNode()
var center2 = SKSpriteNode()
var centerLine = SKSpriteNode()
var bg = SKSpriteNode()
var bigCircle = SKSpriteNode()
let counterClockwise = SKAction.rotateByAngle(CGFloat(3.14), duration:1)
let clockwise = SKAction.rotateByAngle(CGFloat(-3.14), duration:1)
var spin = SKAction()
var score = 0
var setCenter = SKAction.rotateByAngle(CGFloat(-1.75), duration:1)
var setCenter2 = SKAction.rotateByAngle(CGFloat(1.75), duration:1)


struct PhysicsCategory {
    static let None       : UInt32 = 0
    static let All        : UInt32 = UInt32.max
    static let ball       : UInt32 = 0x1         // 1
    static let triangle   : UInt32 = 0x1 << 1    // 2
    static let line      : UInt32 = 0x1 << 2    // 4
}









    override func didMoveToView(view: SKView) {

    let value = UIInterfaceOrientation.LandscapeLeft.rawValue
    UIDevice.currentDevice().setValue(value, forKey: "orientation")



//Background
    var bgTexture = SKTexture(imageNamed: "images/bg.png")
    bg = SKSpriteNode(texture:bgTexture)
    bg.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
    bg.zPosition = -4
    self.addChild(center)

//Center Circle
    var bigCircleTexture = SKTexture(imageNamed: "images/bigCircle.png")
    bigCircle = SKSpriteNode(texture:bigCircleTexture)
    bigCircle.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
    self.addChild(bigCircle)
    bigCircle.zPosition = -3
//Center Triangle
    var centerTexture = SKTexture(imageNamed: "center.png")
    center = SKSpriteNode(texture:centerTexture)
    center.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
    center.zPosition = -1
    center.physicsBody = SKPhysicsBody(rectangleOfSize: center.size)
    center.physicsBody?.categoryBitMask = PhysicsCategory.triangle
    self.addChild(center)
    center.runAction(setCenter)
    center.removeAllActions()
    spin = clockwise
    center.runAction(SKAction.repeatActionForever(spin))
//Center Triangle 2
        var centerTexture2 = SKTexture(imageNamed: "center.png")
        center2 = SKSpriteNode(texture:centerTexture)
        center2.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        center2.zPosition = -1
        center2.physicsBody = SKPhysicsBody(rectangleOfSize: center2.size)
        center2.physicsBody?.categoryBitMask = PhysicsCategory.triangle
        self.addChild(center)
        center2.runAction(setCenter2)
        center2.removeAllActions()
        spin = clockwise
        center.runAction(SKAction.repeatActionForever(spin))

//Center Line
        var centerLineTexture = SKTexture(imageNamed: "centerLine.png")
        centerLine = SKSpriteNode(texture:centerLineTexture)
        centerLine.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) + center.size.height)
        centerLine.zPosition = -2
        centerLine.physicsBody = SKPhysicsBody(rectangleOfSize: centerLine.size)
        centerLine.physicsBody?.categoryBitMask = PhysicsCategory.line
        self.addChild(centerLine)
        spin = clockwise
        centerLine.runAction(SKAction.repeatActionForever(spin))

//Create Balls

    //Ball Settings
    func randomCGFloat() -> CGFloat {
            return CGFloat(Double(arc4random())/Double(UInt32.max) )
        }

        var ball = SKSpriteNode(imageNamed: "newBall.png")

        var randomBall = arc4random_uniform(4) + 1
        var moveBall = SKAction.moveTo(CGPointMake(self.size.width/2,self.size.height/2), duration:3.0)
        ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.height / 2)
        ball.physicsBody?.dynamic = false
        ball.physicsBody?.allowsRotation = false
        ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
        ball.physicsBody?.collisionBitMask = PhysicsCategory.triangle
        ball.physicsBody?.contactTestBitMask = PhysicsCategory.triangle
        ball.physicsBody?.collisionBitMask = PhysicsCategory.line

        //Initial Ball
        if score == 0 {
            ball.position = CGPointMake(self.size.width/2, self.size.height)
            self.addChild(ball)
            ball.runAction(moveBall)
        }



        //Spawning and Moving Balls


        func addBall() {


        if randomBall == 1 {
            ball.position = CGPointMake(self.size.width/2, self.size.height)
            self.addChild(ball)
            ball.runAction(moveBall)
        }

        else if randomBall == 2 {
            ball.position = CGPointMake(self.size.width,     self.size.height/2)
            self.addChild(ball)
            ball.runAction(moveBall)
         }

        else if randomBall == 3{
            ball.position = CGPointMake(self.size.width/2, -self.size.height)
            self.addChild(ball)
            ball.runAction(moveBall)
        }

        else if randomBall == 4 {
            ball.position = CGPointMake(self.size.width - self.size.width, self.size.height/2)
            self.addChild(ball)
            ball.runAction(moveBall)
        }

        }



        func didBeginContact(contact: SKPhysicsContact) {
            if contact.bodyA.categoryBitMask == PhysicsCategory.line     {
                score++
                println("\(score)")

            } else if contact.bodyA.categoryBitMask == PhysicsCategory.triangle {
                println("lost")
            }
        }





}







override func touchesBegan(touches: NSSet, withEvent event: UIEvent)     {
    /* Called when a touch begins */
    if spin == clockwise  {
        center.removeAllActions()
        centerLine.removeAllActions()
        spin = counterClockwise



    }

    else {
        center.removeAllActions()
        centerLine.removeAllActions()
        spin  = clockwise

    }
    center.runAction(SKAction.repeatActionForever(spin))
    centerLine.runAction(SKAction.repeatActionForever(spin))
}


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

1 Answers1

0

First, you need to set a SKPhysicsBody for each object you want to interact with physics (gravity, collision, ...). Which is currently not the case for your line and triangle.

After that, you group (category bitmask) aren't set properly. Indeed, 0 << 3 isn't right. You might want to declare your category bitmask like so :

struct PhysicsCategory {
    static let None       : UInt32 = 0
    static let All        : UInt32 = UInt32.max
    static let Ball       : UInt32 = 0b1       // 1
    static let Triangle   : UInt32 = 0b10      // 2
    static let Line       : UInt32 = 0b100     // 4
}

Or like so :

struct PhysicsCategory {
    static let None       : UInt32 = 0
    static let All        : UInt32 = UInt32.max
    static let Ball       : UInt32 = 0x1         // 1
    static let Triangle   : UInt32 = 0x1 << 1    // 2
    static let Line       : UInt32 = 0x1 << 2    // 4
}

Here is a table I've made for another question, that might help you too for category bitmask : http://goo.gl/7D8EGY

Community
  • 1
  • 1
lchamp
  • 6,592
  • 2
  • 19
  • 27
  • Thanks for your response. Everything makes sense and I know why my code wasn't working, but now I have a new problem. When I try to run the app the build succeeds but immediately fails. I get a yellow icon and a green line in the AppDeleegate.swift file highlighting the AppDelegate class saying 'signal SIGBRT'. My code is below. I'm not sure what I did wrong to change the outcome like this. I'm trying to fix on my own now but appreciate any help from others. http://pastebin.com/JMb54xJc – StudioSevenDesigns Apr 25 '15 at 09:42
  • You might want to post your new code instead of the old one. (Make sure you haven't placed a Breakpoint by mistake) – lchamp Apr 25 '15 at 09:44
  • Sorry - pressed enter before I could finish the comment. I added the code in a pastbin and will also update the original – StudioSevenDesigns Apr 25 '15 at 09:47
  • You should try to keep a "clean" code at all time. If the code you provided is the one you use you have function inside function for no reason. A tried to clean it a bit ( http://pastebin.com/128j2NQz ) but I can't see if there is any error with it. And, why do you need to set the orientation on UIDevice ? – lchamp Apr 25 '15 at 10:16
  • Try with the code I provided in the comment above (there might be some error to clean before you can compile). If it doesn't work, I might be able to give a look a little later but you'll have to upload the project if possible (so I can compile (all files, images, ...). – lchamp Apr 25 '15 at 10:18