0

ran into some trouble with my coding today. Trying to make an "automatic" weapon but can't get the selector to function correctly. Here is the code

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in (touches ){
        let location = touch.location(in: self)func spawnBullets(){
                let Bullet = SKSpriteNode(imageNamed: "circle")
                Bullet.zPosition = -1
                Bullet.position = CGPoint(x: ship.position.x,y: ship.position.y)
                Bullet.size = CGSize(width: 30, height: 30)

                Bullet.physicsBody = SKPhysicsBody(circleOfRadius: 15)
                Bullet.physicsBody?.categoryBitMask = PhysicsCategory.Bullet

                Bullet.name = "Bullet"
                Bullet.physicsBody?.isDynamic = true
                Bullet.physicsBody?.affectedByGravity = false
                self.addChild(Bullet)

                var dx = CGFloat(location.x - base2.position.x)
                var dy = CGFloat(location.y - base2.position.y)

                let magnitude = sqrt(dx * dx + dy * dy)

                dx /= magnitude
                dy /= magnitude

                let vector = CGVector(dx: 30.0 * dx, dy: 30.0 * dy)
                Bullet.physicsBody?.applyImpulse(vector)


            }
            spawnBullets()
            Timer.scheduledTimer(timeInterval: 0.2, target: self, selector:#selector("spawnBullets"),userInfo: nil, repeats: true)
        }

' Yet when I run this, I get an error that the selector doesn't reference anything. can anyone help me please? thanks

2
  • The selector of target / action must be on the top level of the class, the line let location = ... is insane. Commented Apr 8, 2017 at 11:03
  • Yes it is. but it was just a error when i copied the code over Commented Apr 11, 2017 at 20:52

1 Answer 1

1

You didn't add the swift version you are using. There are some minor changes in swift 3.x.

In swift 3.x you don't use selectors with quotes in this way, so you have to remove the quotes & do something like this:

selector:#selector(spawnBullets)

This will also give you some type safety when changing your code. So instead of runtime errors you will get compile time errors when you do something wrong.

What I also would do in your case is to move the function spawnBullets outside of touchBegan like this:

func spawnBullets(_ location: CGPoint) {
    ...
}

You also need another seperate func to deal with timer parameters (more info on that here: https://stackoverflow.com/a/41987413/404659):

func spawnBullets(sender: Timer) {
    if let location = sender.userInfo as! CGPoint? {
        spawnBullets(location)
    }
}

Your touchBegan would then end up something like this:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in (touches ) {

        let location = touch.location(in: self)
        spawnBullets(location)
        Timer.scheduledTimer(
            timeInterval: 0.2, 
            target: self,
            selector:#selector(spawnBullets(sender:)),
            userInfo: location,
            repeats: true
        )

    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.