Is GameScene.sks not recommended for game building?
It's all personal preference really. I think the reason why people delete it though (at least in my opinion) is due to the following reasons:
- You have to specify an initial scene size in the file. Whereas if you create the scene programmatically you can set the size to the view size.
- The editor is very limiting. Xcode 7 however greatly expands the editor to include much more such as custom classes.
- There were some pretty big bugs/crashes in the initial release of Xcode 6.
- When learning Sprite Kit it's good to know how to programmatically do things instead of doing it visually. This is because games often have dynamic gameplay so you will certainly have to do things programmatically (especially when you consider the limitations of the Xcode 6 editor).
- Some people (including myself) may use their own custom editor for designing levels etc. Whereas interface builder is standard because it has become very powerful over the years and works perfectly with UIKit.
What's the relationship between GameScene.swift and GameScene.sks files in SpriteKit template
The .sks
file is a static archive of your scene's content. If you've used Interface Builder to set up UI apps before, it's much the same idea, if rather different in implementation.
In a UI app, you could do everything in code:
override func viewDidLoad() {
let someText = UITextField(...)
let aButton = UIButton(...)
// ... position everything
// ... style everything
// ... etc ...
}
Or you could do all the static content setup in IB (a xib or storyboard), and use code only for setting up the dynamic behavior of your app — the things that happen when somebody starts touching those buttons. When you do that, the view controller you write code for exists as a proxy object in the xib/storyboard, making a bridge between what you set up in IB and what you set up in code.
In SpriteKit, you have the same choice. Before Xcode 6, many SK games took the all-code approach:
override func didMoveToView(view: SKView) {
let player = PlumberSprite(color: .Red)
player.position = // ...
player.physicsBody = // ...
self.addChild(player)
let ground = SKSpriteNode(...)
ground.position = // ...
ground.physicsBody = // ...
self.addChild(ground)
let block = QuestionBlockSprite()
block.position = // ...
block.physicsBody = // ...
block.contents = CoinSprite()
self.addChild(block)
// ... etc etc etc ...
}
That's a lot of code for what's ultimately a graphical, static scene — even before you start adding code to make it into a game (input handling, enemy behavior, physics callbacks that increment the score or go to game over, etc). And it doesn't lend itself well to designs where you split out the general game logic from the content, so it's harder to add multiple levels to your game.
Instead, you can use the SpriteKit editor in Xcode to build your static content (levels), and stick to code for dynamic behavior and game logic. Just like how, in IB, the view controller is a bridge between your storyboard and your code, your scene class (GameScene.swift
in the template) is the bridge between the editor and code. When you load an .sks
file at run time (the code for this is in GameViewController.swift
in the template), it becomes an instance of your GameScene
class, and anything you set up in the editor is accessible as child nodes of the scene.
Checking out WWDC talks is a good idea, but you missed the one that covers this: see session 608: Best Practices for Building SpriteKit Games for more on the motivation behind the SpriteKit editor, how to use it, and how to work with the scene contents loaded from an .sks
file in your scene code.
GameScene.sks file is not being used
Possibly not the EXACT answer you're looking for but it will work (unless I'm misinterpreting your question). I generally tend to find it's better to load a scene from its .swift file rather than the .sks file (which I don't use at all). An easy way to do this is:
func loadGameScene() {
let scene = GameScene(size: view.bounds.size)
scene.scaleMode = .resizeFill
let transitionType = SKTransition.flipHorizontal(withDuration: 1.0)
let skView1 = view as! SKView
skView1.ignoresSiblingOrder = true
skView1.presentScene(scene,transition: transitionType)
}
You can put this function in your GameViewController, and call it from GameViewController whenever you click the button. If you really want to use your .sks file you can just edit this function to use your .sks instead.
If you don't know how to call that function from another SKScene class(MenuScene), this is how you do it:
In your Scene, create a variable viewController
like so:
class MenuScene: SKScene{
var viewController: GameViewController!
This points to your GameViewController. Now in your GameViewController, right after presenting the MenuScene, add:
scene.viewController = self
Now in your MenuScene you can just call viewController.loadGameScene()
to switch the scenes
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:
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
Hope it helps.
XCode Scene Editor or Coding for SpriteKit Games
depends on game to game if you are creating a small game which you want to support ios7 too then best choice programmatically because i think Scene Editor
Scene Editor are always best choice if you targeting ios8 and above these are some major benifits of Scene Editor.
1)easy to set multiple SKScene as you don't need to manually set x and y position of every sprite.
2)live testing of physics simulation don't need to recompile project again and again
3)easy subclassing of sknode instance
4) set physics body propeties easily
5)if ios9 then don't worry about refusing a texture again and again sprite kit handle cache mechainsim for you
6)if ios9 then you have a inbuilt timeline which would help you to create sprite animation live
7)build in custom shader support
8)many more check out below
[click here][1]
https://developer.apple.com/videos/play/wwdc2015-604/
Sprite Kit Scene Editor GameScene.sks scene width and height
Pixel density
First of all the size of the Scene is defined in Points
not Pixels
.
Let's see how the devices that support iOS 9 deal with this:
- 1 point = 1x1 pixel: iPad 2, iPad mini
- 1 point = 2x2 pixels: iPhone 4s, iPhone 5, iPhone 5c, iPhone 5s, iPhone 6, iPhone 6s, iPad mini 2, iPad mini 3, iPad mini 4, iPad 3,
iPad 4, iPad Air, iPad Air 2, iPad Pro, iPod touch 5, iPod touch 6- 1 point = 3x3 pixels: iPhone 6 Plus, iPhone 6s Plus
This allow you to specify a size that is automatically converted for the pixel density of a particular device.
Screen size
There are several screen sizes available on the iPhone/iPad supported by iOS 9.
With SpriteKit you can easily face this problem setting the scaleMode
property of your Scene
.
You can chose among 4 options:
- Fill: Scale the SKScene to fill the entire SKView.
- AspectFill: Scale the SKScene to fill the SKView while preserving the scene's aspect ratio. Some cropping may occur if the view has a
different aspect ratio.- AspectFit: Scale the SKScene to fit within the SKView while preserving the scene's aspect ratio. Some letterboxing may occur if
the view has a different aspect ratio.- ResizeFill: Modify the SKScene's actual size to exactly match the SKView.
You probably want to set AspectFill
but it really depends on your game.
To set the property open GameViewController.swift
(or .m
if you use Objective-C), in viewDidLoad
you'll find this line. Just change it to mach your preference.
/* Set the scale mode to scale to fit the window */
gameScene.scaleMode = .AspectFill
Can't reference Xcode GameScene.sks with swift
You need to use the childNodeWithName
method on SKNode
. For example:
func timerDidFire() {
let label = childNodeWithName("countDownTimerLabel") as! SKLabelNode
label.text = --countDown
// I believe this is an appropriate case for force unwrapping since you're going to
// want to know if your scene doesn't contain your label node.
}
Since you're going to be accessing the SKLabelNode
often, and it takes time to search through the node tree (not very much but something to bear in mind), it may be a good idea to keep a reference to the label. For example, in your SKScene
subclass:
lazy var labelNode: SKLabelNode = self.childNodeWithName("countDownTimerLabel") as! SKLabelNode
On a related note, if you're looking for multiple nodes there's the enumerateChildNodesWithName(_:usingBlock:)
, also on SKNode
.
Finally, for more information have a look at Apple's WWDC 2014 talk: Best Practices for Building SpriteKit Games where they cover both the methods I mentioned.
New SKScene Set as Default in SpriteKit Game Turns Out Blank
If you have a corresponding SKS file created in the Scene editor then you load your scene like so...
// Load the SKScene from WelcomeScene.sks'
if let welcomeScene = WelcomeScene(fileNamed: "WelcomeScene") {
welcomeScene.scaleMode = .aspectFill
view.presentScene(welcomeScene)
}
if you do not have a corresponding SKS file created in the scene editor but would rather load the scene that was created in code use...
welcomeScene= WelcomeScene(size: skView.bounds.size)
welcomeScene.scaleMode = .aspectFill
skView.presentScene(welcomeScene)
Related Topics
Error "No Such Module" When Installed Framework with Pod in Swift 3
Swift Firebase Using an Unspecified Index
How to Switch to Swift 4.0 in Xcode 9.3
Is There an Kotlin Equivalent 'With' Function in Swift
Swift 3: Converting Data to String Returns a Nil Value
Send Mail with File Attachment
Applewatch Messages Url Works Hard Coded But Not with Variables
How to Disable "Save to Files" in iOS 11
Change the Font of a Datepicker
Why Is Deinit Not Called Until Uiview Is Added to Parent Again
How to Implement a 'Next' Property to a Caseiterable Enum in Swift
How to Create Apple Watchos5 Complication
Swift Protocol as Generic Parameter
How to Set iOS 13 Glyphs Programmatically