How to Change The Default Skscene That Displays on Startup

How do you change the presented view of an SKScene?

You're not supposed to alter the scene's size in this manner. Creating a scene of 7000*7000 points would have a Retina iPad render 98 megapixels 60 times per second. Ouch.

Scale a child node

Simply create a new SKnode sceneContents and add your SKShapeNode as a child to this node. When you wish to "zoom", scale down the sceneContents node (through the xScale and yScale properties of SKNode). You can use SKAction for this, so it's nice and smooth.

SKCameraNode

If you can move to iOS 9, I would recommend looking into SKCameraNode. This is still in beta at the moment but it works nicely.
Simply create an SKCameraNode, add it to the scene and set it to be the camera for the scene.

SKCameraNode *camera = [SKCameraNode new];
[self.scene addChild:camera];
self.scene.camera = camera;
camera.xScale = 10.f;
camera.yScale = 10.f;

Hm, I should learn Swift at some point. Nevertheless, the concept should be clear. You can use SKAction to manipulate the camera node with an animation.

Make SKScene fill whole screen using Swift

I had to manually add an image set named LauchImage in the Images.xcassets.

How to edit a property of GameViewController from GameScene

This was happened because you re-create the GameViewController inside your scene with the line:

var viewController = GameViewController()

instead of get the already existent GameViewController.

There are many ways to solve your issue.
So, for example using the "hello world" Sprite-kit template if you have your GameViewController as the initial viewController of your game you can do:

GameViewController:

import UIKit
import SpriteKit
class GameViewController: UIViewController {
var uiLabelContainer:UILabel!
override func viewDidLoad() {
super.viewDidLoad()
uiLabelContainer = UILabel(frame: CGRect(x:0,y: 0,width: 250,height: 50))
uiLabelContainer.textAlignment = NSTextAlignment.left
uiLabelContainer.textColor = .white
uiLabelContainer.text = "This is a Label"
self.view.addSubview(uiLabelContainer)
uiLabelContainer.isHidden = true
if let view = self.view as! SKView? {
if let scene = SKScene(fileNamed: "GameScene") {
scene.scaleMode = .aspectFill
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
func printStuff() {
print("printStuff")
}
}

GameScene:

import SpriteKit
class GameScene: SKScene {
private var label : SKLabelNode?
var viewController : GameViewController!
override func didMove(to view: SKView) {
self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
if let label = self.label {
label.alpha = 0.0
label.run(SKAction.fadeIn(withDuration: 2.0))
}
self.run(SKAction.wait(forDuration: 2),completion:{[unowned self] in
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if let vc = appDelegate.window?.rootViewController {
self.viewController = vc as! GameViewController
self.viewController.uiLabelContainer.isHidden = false
}
})
self.run(SKAction.wait(forDuration: 5),completion:{[unowned self] in
let scene2 = GameScene2()
scene2.scaleMode = .aspectFill
self.view?.presentScene(scene2)
})
}
deinit {
print("\n THE SCENE \((type(of: self))) WAS REMOVED FROM MEMORY (DEINIT) \n")
}
}

GameScene2:

(created only for test, to see the correct GameScene deallocation)

import SpriteKit
class GameScene2: SKScene {
private var label : SKLabelNode?
override func didMove(to view: SKView) {
print("gameScene2")
}
}

Output:Sample Image

How to add an .sks files to existing Swift/Sprite-Kit project?

The reason why you are getting the required is because you have variables that are not optional or not initialized before init takes place.

If you have variables that need to be assigned inside of an init function, then you would do:

required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}

But then you will ask me: Mr Knight0fDragon, it is telling me to replace fileNamed with coder, and it is not compiling when I switch it.

Well this is because init(fileNamed:) is a convenience init, not a designated init. In order to be able to subclass a class and get all of it's convenience inits, you need to override all of it's designated inits.

Now with SKScene, you have 3, and you already know about 1.

Let's override the other 2:

override init() {
super.init()
}
override init(size: CGSize) {
super.init(size: size)
}

Alright, now this puppy should be ready to compile, we just need to get the variables assigned.

Well what I like to do is create a setup method for any variable that has to be assigned in any version of initialization after the super is called.

Unfortunately we can't do this for constants before super is called, so those we would need to set up in each method. The reason being is that self does not fully exist yet.

This would end up looking like this:

let constant : String
required init?(coder aDecoder: NSCoder)
{
constant = "hi"
super.init(coder: aDecoder)
setup()
}
override init() {
constant = "hi"
super.init()
setup()
}
override init(size: CGSize) {
constant = "hi"
super.init(size: size)
setup()
}

Gamescene.sks and GameScene.swift don't seem to be linked in my project

We have a normal GameScene.swift that should be print "hello" with his GameScene.sks called by a GameViewController. You did not specify what is GameController but this is not a problem because I think you could simply lost the flow of your game so I try to help you about it (dont' worry,
it happens when you are focused on the rest of the game a long time and can not remember the starting flow).

In your Main.storyboard you probably don't have a situation like this:

Sample Image

Sample Image

where your GameViewController is the initial view controller.
What I mean is you should check who call GameViewController on your storyboard or if your AppDelegate.swift (in didFinishLaunchingWithOptions) stop the flow or call other views before calling GameViewController.

So , check who is the IVC (initial view controller) and be sure your GameViewController is called from start or by other viewControllers using breakpoint or simply launch this print in your viewDidLoad:

print("∙ \(type(of: self))")

Another situation could be happen when you add or remove files with the same name in library. In this case try to remove GameScene.swift and GameScene.sks, clean and build your project and re-add these files (be sure as your screen GameScene.sks have the right custom class..)
Check your Compile Sources list to control your GameScene.swift

Sample Image

Hope it helps.

SKScene Viewable Size smaller than View bounds

I think this might be because Apple has mistakenly removed the launch screen from the iOS-only SpriteKit game template (it's still there in the multi-platform template). You need to either add and assign a launch screen or choose Main as your launch screen.

The launch screen defines the working area for the app, so without it the view bounds and scene scale mode will not fix this issue.

More info in Background is not filling the whole view SpriteKit.

Trouble using SKReferenceNode programmatically

As I mentioned in another post, I found a workaround.

In my case, I substituted the SKReferenceNode with an SKScene.

I first made sure that, in my .sks scene, all SKSpriteNodes were children of one main node. It doesn't have to be a direct link, you can still respect the hierarchies of your scene, but it's important that at the end of the "hierarchy tree" they are linked to one node, which in my case is the background, but it can also be an empty node.

Sample Image

In my GameScene file I then wrote the following code:

class GameScene: SKScene {
var mainNode: SKNode? = nil
override func didMove(to view: SKView) {
var mySksScene = SKScene(fileNamed: "Caribbeans")
mainNode = upperBackground?.childNode(withName: "backgroundCaribbean")
mainNode?.removeFromParent()
mySksScene = nil
addChild(mainNode)
}
}

I first declared an optional SKNode variable. Then, inside didMove(:to:), I loaded my .sks file in an optional SKScene() variable. I then set SKNode as the main node, the node which is the parent of all the other nodes (in my case: backgroundCaribbean). I then removed my mainNode from its parent scene, THEN set to nil the variable that used to contain the .sks scene, and only THEN I added my mainNode as a Child of my GameScene.



Related Topics



Leave a reply



Submit