Rectangle 27 0

If you look at the definition of Class ArcheryScene you will see it is a subclass of SKScene - so the class you are coding in is already your scene. The UIViewController subclass in your project has loaded ArcheryScene.sks and associated it with an instance of ArcheryScene.

When you subsequently say let scene=SKScene(fileName:"ArcheryScene.sks") you are actually creating a new instance of the scene that isn't presented into your SKView. You then modify the ball in that scene, but nothing happens as this is not the ball that is visible.

let ballChild=self.childNodeWithName("Ball")   
if (ballChild? != nil) {
    let move=SKAction.moveByX(50 y:10 duration:10.0)
    ballChild!.runAction(move)
}

Also, you see that the Ball is a child of the parent: "Environment", what if I want to affect the environment itself? For example: Enviroment!.runAction(move)

Ball is a child of the ArcheryScene SKScene, which in this case is self

self!.runAction(move)

That's right - you can't move a scene - at least not with an action. You can change the frame of the SKView that is holding the scene. If you want to animate a background then add the background as a note and move that. The scene is like the screen of your TV. When something happens in a movie your TV doesn't move across your wall.

ios - Affecting a Child From Another Scene Using Sprite Kit and Swift ...

ios swift sprite-kit skspritenode skscene
Rectangle 27 0

You can add the wheels and all pieces of the train as children of a main SKNode which represents the whole train. You can move that across the screen and simply handle rotation on the wheels.

let train = SKNode()    // add move actions to this
let wheel = SKSPriteNode(imageNamed: "wheel") // add rotation actions to this
train.addChild(wheel)

So far so good. Not sure how to "add move actions to this" and "add rotation actions to this". I thought there have to be some kind of joint made between train and wheel so that they are tied together.

By adding it to the train, that's what you're doing. You should read the SpriteKit docs from apple if you don't know what actions are.

how to make vehicle or train move across the scene in iOS Sprite Kit G...

swift sprite-kit
Rectangle 27 0

The problem lies in ellipse.position = CGPointMake(center). For some reason, this changes the position of the ellipse relative to itself rather than relative to the view - so if you did ellipse.position = CGPoint(x: 100, y: 100) then it would set the position to 100 up and 100 to the right of the ellipse itself as opposed to 100,100 on the scene. If you comment out this line, then you should be able to see you ellipse on the screen - I certainly could when it tried it. Hope that helps you position it to where you want.

swift - SKShapeNode ellipseInRect, sprite does not appear in scene - S...

sprite-kit swift ios8 skshapenode
Rectangle 27 0

The UILabel is not part of your scene. It's an element of the container view. Therefore it is always visible and overtime you create a new one, it will be shown on top of the existing label.

The easiest way is to use global variables. Just place

var Score = Int()
var ScoreLabel = UILabel()

outside of the class definition (and add it only once to the container view).

This stack overflow question is about a different issue, but shows a sample how to use an SKLabel for scoring information: score label display value overwrites

This logic makes sense to me but what do you mean as in outside of the class definition? do you mean list it before the class definition? Also, what do you mean by add it only once to the container view? I apologize but if you could clear that up for me it would be great

Yes. Declare it before the class definition.

Should i declare it once only in the first level?

Add it only once to the container view means add the UILabel only in scene 1. Don't add it for the other scenes again.

Ah, so then do not declare it ever again in any of the other scenes? And then just refer to it in the other scenes

ios - Updating an Int variable in separate scenes in swift? Sprite Kit...

ios swift sprite-kit int var
Rectangle 27 0

If you look at the definition of Class ArcheryScene you will see it is a subclass of SKScene - so the class you are coding in is already your scene. The UIViewController subclass in your project has loaded ArcheryScene.sks and associated it with an instance of ArcheryScene.

When you subsequently say let scene=SKScene(fileName:"ArcheryScene.sks") you are actually creating a new instance of the scene that isn't presented into your SKView. You then modify the ball in that scene, but nothing happens as this is not the ball that is visible.

let ballChild=self.childNodeWithName("Ball")   
if (ballChild? != nil) {
    let move=SKAction.moveByX(50 y:10 duration:10.0)
    ballChild!.runAction(move)
}

Also, you see that the Ball is a child of the parent: "Environment", what if I want to affect the environment itself? For example: Enviroment!.runAction(move)

Ball is a child of the ArcheryScene SKScene, which in this case is self

self!.runAction(move)

That's right - you can't move a scene - at least not with an action. You can change the frame of the SKView that is holding the scene. If you want to animate a background then add the background as a note and move that. The scene is like the screen of your TV. When something happens in a movie your TV doesn't move across your wall.

ios - Affecting a Child From Another Scene Using Sprite Kit and Swift ...

ios swift sprite-kit skspritenode skscene
Rectangle 27 0

let scene = SKScene(fileNamed: "ArcherySceneSKS")

You are creating a new scene. So the ballChild you are accessing is another one (not the one inside your self (ArcheryScene class)).

If you ArcheryScene class is properly instantiated, can't you access the ball by doing like so ?

let ballChild = self.childNodeWithName("Ball")

Also, you see that the Ball is a child of the parent: "Environment", what if I want to affect the environment itself? For example: Enviroment!.runAction(move)

I can't try right now, but you could either do the same thing as you did with the ball (give it a name and access it) or once you have the ball access it's parent property yourBall.parent.runAction(yourAction).

I tried this is says: "animating the position of a SKScene has no effect" I've also tried: self?.runAction(move) and I get the same message

Well the error is explain enough, isn't it ? You're trying to run an action on your scene and not a node. Make your ball is attached to another node for example.

ios - Affecting a Child From Another Scene Using Sprite Kit and Swift ...

ios swift sprite-kit skspritenode skscene
Rectangle 27 0

when changing between scenes, you're going to need to set up a transition, how the scene will change to the next and define which scene you want to transition to.

var transition:SKTransition = SKTransition.fadeWithDuration(1)
fadeWithDuration
SKTransition

as for defining the scene,

var scene:SKScene = GameScene(size: self.size)

You're stating which scene you wish to transition to, in this case GameScene, but should be replaced with whichever scene you wish to transition to.

self.view?.presentScene(scene, transition: transition)

Which will move to the scene scene which was set up in the line prior, using the transition transition which was also defined.

ios - Simplest Way To Change Scene In Swift + Sprite Kit - Stack Overf...

ios swift sprite-kit skscene
Rectangle 27 0

It turns out I had a particle emitter in the menu scene. I forgot to remove it when transitioning. So it was trying to emitting to a scene that did not exist anymore. Fixing it was as simple as adding this line before transitioning to the game scene.

myparticle.removeFromParent();

sprite kit - Swift spritekit change scenes? - Stack Overflow

swift sprite-kit
Rectangle 27 0

First, I want to point out that your line of code: let actionDone = SKAction.removeFromParent() is effectively useless because you never call runAction to use it.

The error message sums it up quite nicely. "Attempted to add a SKNode which already has a parent". You never actually call removeFromParent().

Adding Impenitrible once works fine as you found out, because at the start, Impenitrible has no parent. Subsequent calls will have a conflict because Impenitrible already has the parent that was added via the first call.

runAction(SKAction.removeFromParent())
spawnImpenitrible
Imprenitrible

ios - How do you add multiple nodes to scene and move all of them at o...

ios swift sprite-kit
Rectangle 27 0

let scene = SKScene(fileNamed: "ArcherySceneSKS")

You are creating a new scene. So the ballChild you are accessing is another one (not the one inside your self (ArcheryScene class)).

If you ArcheryScene class is properly instantiated, can't you access the ball by doing like so ?

let ballChild = self.childNodeWithName("Ball")

Also, you see that the Ball is a child of the parent: "Environment", what if I want to affect the environment itself? For example: Enviroment!.runAction(move)

I can't try right now, but you could either do the same thing as you did with the ball (give it a name and access it) or once you have the ball access it's parent property yourBall.parent.runAction(yourAction).

I tried this is says: "animating the position of a SKScene has no effect" I've also tried: self?.runAction(move) and I get the same message

Well the error is explain enough, isn't it ? You're trying to run an action on your scene and not a node. Make your ball is attached to another node for example.

ios - Affecting a Child From Another Scene Using Sprite Kit and Swift ...

ios swift sprite-kit skspritenode skscene
Rectangle 27 0

Too add a button the simplest way is to detect touches on your sprite(s) in the relevant SKScene.

enum NodeName: String {
   case coloredSprite1
   case coloredSprite2
}

class GameScene: SKScene {

     let coloredSprite = SKSpriteNode(imageNamed: "YourImageName")

     /// Scene setup
     override func didMove(to view: SKView) {
       // set up your colored sprite if necessary
       // Give your sprites unique names to identify them

       coloredSprite.name = NodeName.coloredSprite1.rawValue // always use enums for things like string identifiers so you avoid typos
     }

     /// Touches
     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         for touch in touches {
             let location = touch.location(in: self)
             let touchedNode = atPoint(location)

             // Way 1 by node (probably less preferable)
             switch touchedNode {
             case coloredSprite:
                 // do something (e.g call loadScene method)
                // see below
             default: 
                 break
             }

             // Way 2 by node name (probably more preferable)
             // name is an optional so we have to unwrap it when using it in the switch statement. 
             // The easiest way is by providing an alternative string, by using the nil coalescing operator (?? "NoNodeNameFound")

             switch touchedNode.name ?? "NoNodeNameFound" {
             case NodeName.coloredSprite1.rawValue:
                // do something (e.g call loadScene method)
                // see below
             default: 
                break
             }
        }
    }

    // Also call touchesEnded, touchesMoved and touchesCancelled and do necessary stuff
}

For a more reusable solution you ideally want to create a button subclass. There is quite a few tutorials to google on how to do this.

To than transition between SKScenes you can create a loadScene method in each scene and than call them when necessary.

// Start Scene
class StartScene: SKScene {
   ...

   func loadGameScene() {

        // If you do everything in code
        let gameScene = GameScene(size: self.size)
        view?.presentScene(gameScene, transition: ...)

        // If you use SpriteKit scene editor
        guard let gameScene = SKScene(fileNamed: "GameScene") else { return } // fileNamed is the name you gave the .sks file
        view?.presentScene(gameScene, transition: ...)
   }
}

// Game scene
class GameScene: SKScene {
     ....

     func loadStartScene() {
        // If you do everything in code
        let startScene = StartScene(size: self.size)
        view?.presentScene(startScene, transition: ...)

        // If you use SpriteKit scene editor
        guard let startScene = SKScene(fileNamed: "StartScene") else { return } // fileNamed is the name you gave the .sks file
        view?.presentScene(startScene, transition: ...)
   }
}

You are very welcome. Happy coding

ios - How to go back to the previous scene after tapping a colour spri...

ios swift button sprite-kit scene
Rectangle 27 0

when changing between scenes, you're going to need to set up a transition, how the scene will change to the next and define which scene you want to transition to.

var transition:SKTransition = SKTransition.fadeWithDuration(1)
fadeWithDuration
SKTransition

as for defining the scene,

var scene:SKScene = GameScene(size: self.size)

You're stating which scene you wish to transition to, in this case GameScene, but should be replaced with whichever scene you wish to transition to.

self.view?.presentScene(scene, transition: transition)

Which will move to the scene scene which was set up in the line prior, using the transition transition which was also defined.

ios - Simplest Way To Change Scene In Swift + Sprite Kit - Stack Overf...

ios swift sprite-kit skscene
Rectangle 27 0

Thanks for your NSNotification method for exiting a sprite kit scene back to the calling view controller. This is a simple way to jump back to UIKit & will post my code. I'm working is swift & just added 4 lines of code for those working in Swift. This code was added to the view controller in the viewDidLoad function.

override func viewDidLoad() {
    super.viewDidLoad()

    if let scene = GameLevels.unarchiveFromFile("GameLevels") as? GameLevels{
        // Configure the view.
        let skView = self.view as! SKView
        skView.showsFPS = true
        skView.showsNodeCount = true

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true

        /* Set the scale mode to scale to fit the window */
        scene.scaleMode = .AspectFill

        //set up notification so scene can get back to this view controller
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "quitToLevel:", name: "quitToLevelID", object: nil)
        skView.presentScene(scene)
    }
}

// Function to pop this view controller and go back to my Levels screen
func quitToLevel(notification: NSNotification) {
    self.navigationController!.popViewControllerAnimated(true)
}
else if nodeTouched.name == "quit"
        {
            NSNotificationCenter.defaultCenter().postNotificationName("quitToLevelID", object: nil)
        }

Now when I hit the "quit" labelNode, it will let me run a function called quitToLevel in the view controller that presented my scene. This function pops me back to my main screen since I'm using a navigation controller but could be used for any purpose.

I tried several other methods of exiting a scene, but had issues if I was jumping around in multiple scenes of loosing the reference back to the view controller. I can use this method from any scene

great solution because it was as simple as you can get adding only a few lines. thanks.

ios - How to reference the current Viewcontroller from a Sprite Kit Sc...

ios reference sprite-kit viewcontroller skscene
Rectangle 27 0

Thank you but it didnt worked. I tried some other changes and it worked but I dont know why.

if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
                let skView = self.view as SKView!
                skView.ignoresSiblingOrder = true

                scene.scaleMode = .AspectFill
                skView.presentScene(scene)
            }

Now both Scenes have the same size.

Swift -- Sprite Kit -- Scenes have different sizes - Stack Overflow

swift sprite-kit
Rectangle 27 0

Too add a button the simplest way is to detect touches on your sprite(s) in the relevant SKScene.

enum NodeName: String {
   case coloredSprite1
   case coloredSprite2
}

class GameScene: SKScene {

     let coloredSprite = SKSpriteNode(imageNamed: "YourImageName")

     /// Scene setup
     override func didMove(to view: SKView) {
       // set up your colored sprite if necessary
       // Give your sprites unique names to identify them

       coloredSprite.name = NodeName.coloredSprite1.rawValue // always use enums for things like string identifiers so you avoid typos
     }

     /// Touches
     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         for touch in touches {
             let location = touch.location(in: self)
             let touchedNode = atPoint(location)

             // Way 1 by node (probably less preferable)
             switch touchedNode {
             case coloredSprite:
                 // do something (e.g call loadScene method)
                // see below
             default: 
                 break
             }

             // Way 2 by node name (probably more preferable)
             // name is an optional so we have to unwrap it when using it in the switch statement. 
             // The easiest way is by providing an alternative string, by using the nil coalescing operator (?? "NoNodeNameFound")

             switch touchedNode.name ?? "NoNodeNameFound" {
             case NodeName.coloredSprite1.rawValue:
                // do something (e.g call loadScene method)
                // see below
             default: 
                break
             }
        }
    }

    // Also call touchesEnded, touchesMoved and touchesCancelled and do necessary stuff
}

For a more reusable solution you ideally want to create a button subclass. There is quite a few tutorials to google on how to do this.

To than transition between SKScenes you can create a loadScene method in each scene and than call them when necessary.

// Start Scene
class StartScene: SKScene {
   ...

   func loadGameScene() {

        // If you do everything in code
        let gameScene = GameScene(size: self.size)
        view?.presentScene(gameScene, transition: ...)

        // If you use SpriteKit scene editor
        guard let gameScene = SKScene(fileNamed: "GameScene") else { return } // fileNamed is the name you gave the .sks file
        view?.presentScene(gameScene, transition: ...)
   }
}

// Game scene
class GameScene: SKScene {
     ....

     func loadStartScene() {
        // If you do everything in code
        let startScene = StartScene(size: self.size)
        view?.presentScene(startScene, transition: ...)

        // If you use SpriteKit scene editor
        guard let startScene = SKScene(fileNamed: "StartScene") else { return } // fileNamed is the name you gave the .sks file
        view?.presentScene(startScene, transition: ...)
   }
}

You are very welcome. Happy coding

ios - How to go back to the previous scene after tapping a colour spri...

ios swift button sprite-kit scene