1

I've created a SpriteKit project and defined a function in the GameScene.swift file. Said function creates a SKSpriteNode and has no problem running when called within it's class.

func generateShip() {
    self.removeAllChildren()
    let SKSprite1 = SKSpriteNode(imageNamed: "Spaceship")
    SKSprite1.size = CGSize(width: CGFloat(arc4random_uniform(UInt32(200))), height: CGFloat(arc4random_uniform(UInt32(200))))
    SKSprite1.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
    self.addChild(SKSprite1)
}
//if I called it here with touchesBegan, it worked.

Now, in my ViewController, I created a simple button and connected it to its swift file. I did a few things before the following code, but this is the part I'm having trouble with.

let gameScene = GameScene()

@IBAction func newShip(sender: AnyObject) {
    gameScene.generateShip() // am I doing this wrong?
}

When I run the app, and click the button, nothing happens. What do I need to change/ do to make function.... well ... function?

Links: Full Code , Iphone

Austin
  • 421
  • 4
  • 13
  • did you wire up your game scene to the rest of the application? – Christopher Francisco Aug 12 '15 at 20:50
  • Where is this line in the code? `let gameScene = GameScene()`. Looks to me like you may not be working with the correct scene instance. – Ben Kane Aug 12 '15 at 20:59
  • I'm also interested in the full code where you create and present your GameScene – Ben Kane Aug 12 '15 at 21:06
  • @BenKane the full code is in that links below everything. Ill make them more clear on the post but here it is while I do that: http://imgur.com/F7MuWYC I'm creating the instance inside the class itself, but now I'm thinking that's now where it should be... – Austin Aug 12 '15 at 21:23

4 Answers4

2

In theory Swift should be able to link all the files automatically that are inside of your project, so your code should be able to work on its own. However, the only issue that might arise is because you are now relying on the StoryBoard as well, so you have to make sure thats linked correctly. Make sure that its linked correctly.

Check out this question for more information on linking with Swift.

EDIT: Also, look at your code. You are calling the function for the space ship on the class itself and not on an instance of it, so thats why its probably not working. You need to first initialize a gameScene and then use that scene to call a method. I think it might be a lot more work so my advice would be to keep everything inside of your gameScene class and create a spriteNode button inside of there.

Community
  • 1
  • 1
MaxKargin
  • 1,560
  • 11
  • 13
  • Yeah, thats what I intended upon doing initially, but I was curious if you could do it using a UIButton. Appreciate the tip though. – Austin Aug 12 '15 at 21:28
2

The problem is in this code:

let gameScene = GameScene()

override func viewDidLoad() {
    super.viewDidLoad()
    let skView = self.view as! SKView
    skView.presentScene(GameScene(fileNamed: "GameScene"))
}

Your gameScene property isn't the same as the scene you presented. Those are two separate objects. You need to do two things.

  1. Change your gameScene declaration to be like the new one you created in your presenting code. Like so:

    let gameScene = GameScene(fileNamed: "GameScene")
    
  2. In viewDidLoad, present that GameScene object instead of making a new one, like this:

    skView.presentScene(gameScene)
    

This way you create one GameScene object, present it, and call generateShip() on the same object.

Ben Kane
  • 9,331
  • 6
  • 36
  • 58
1

Your code seems fine to me.

If there was any 'access' problem with code from an unknown class / module etc. you'd get a compiler warning about it. This seems not to be the case.

My guess: your button is not wired up correctly! Doublecheck that the @IBAction func newShip(sender: AnyObject) really gets called when you press the button: set a breakpoint inside of the newShip function.

Edit: And if it does stop there: step into the function using the debugger.

Goodsquirrel
  • 1,476
  • 1
  • 15
  • 29
0

You are incorrectly using two different instances of GameScene in your view controller! One is added to the view hierarchy, and the OTHER instance is called when the button is tapped.

This can not be seen from the code in the original question, but from the code you provided in a comment: screenshot of full code

In your view controller your are first creating a GameScene with:

let gameScene = GameScene()

but then you are creating and adding a second instance of GameScene to the view hierarchy with:

skView.presentScene(GameScene(fileNamed:"GameScene"))

and your button action calls the generateShip() method on the first object stored in gameScene, that has not been presented by the SKView.

So the solution is to change the above code to:

let gameScene = GameScene(fileNamed:"GameScene"))

and later:

skView.presentScene(gameScene)
Goodsquirrel
  • 1,476
  • 1
  • 15
  • 29