How do I fix this error: Consecutive statements on a line must be separated by ';' - swift

I want to make a space invaders game on Xcode and I get an error in the GameViewController.swift file saying:
Consecutive statements on a line must be separated by ';'
I am new at this and want to learn swift to develop games that can be download from the app store.
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = GameScene(size: CGSize(width: 1536, height: 2048))
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene (scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
}
When I click the test run I expected a window to pop up and show my ship and background but it says "Build Failed" and shows my error and I am not sure how to fix it

Related

Background is not filling the whole view SpriteKit

For some reason my code will not fill the whole SKScene. Here is the code that I am using on Xcode 12 Beta 5.
GameScene.swift
class GameScene: SKScene {
override func didMove(to view: SKView) {
let background = SKSpriteNode(imageNamed: "space")
background.zPosition = 0
background.anchorPoint = CGPoint(x: 0.5, y: 0.5) // default
background.position = CGPoint(x: frame.midX, y: frame.midY)
print("frame.size \(frame.size)")
print("self.size \(self.size)")
print("view \(view.frame.size)")
background.size = CGSize(width: self.size.width, height: self.size.height)
self.addChild(background)
}
}
GameViewController.swift
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GKScene(fileNamed: "GameScene") {
if let sceneNode = scene.rootNode as! GameScene? {
// Present the scene
if let view = self.view as! SKView? {
sceneNode.size = view.bounds.size
sceneNode.anchorPoint = CGPoint.zero
sceneNode.scaleMode = .aspectFit
print("view.bounds.size \(view.bounds.size)")
view.presentScene(sceneNode)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
}
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return .allButUpsideDown
} else {
return .all
}
}
override var prefersStatusBarHidden: Bool {
return true
}
}
Also for some reason, my view size is reporting ->
frame.size (320.0, 480.0) self.size (320.0, 480.0) view (320.0,
480.0)
But my GameScene.sks is set to -> w750, h1336
Why is my code cutting off the tops and the bottoms of the background?
This is going to sound dumb, but do you have a launch Screen? I was having the same problem which would only happen in Xcode 12 and not 11, but the main difference I found was Xcode 11 has a launch screen. Once I added the launch screen storyboard and added it to my plist my SCNView would fill the screen. I am not sure why this would cause the view not to follow the constraints, but after adding it to my other projects it fixes the issue.
Edit:
You do not need to have a launch screen storyboard, you can just add your main storyboard that displays you scene in the plist under "Launch screen interface file base name".
This is definitely caused by not having a launch screen assigned. It's very odd that Xcode 12 has this behavior for SpriteKit by default. I'm sure many many people will be stumped and confused. I noticed that the main visible difference to earlier versions was the lack of a launch screen.
You can either create a launch screen and assign it or define Main.storyboard as the launch screen, as proposed earlier. Probably the easiest thing to just get it working is to go to the project target, then General and choose "Main" where it says "Launch Screen File". This will make it work as expected.
Update: This is still happening in Xcode 12.4 (12D4e). Surprisingly, the launch screen will be missing in a brand-new iOS-only project, whereas it's there in a multi-platform project. It seems like this is an oversight on Apple's part.
How to select Main as your project's Launch Screen File:

Changing the initial game scene in Swift

I want to change the initial scene being presented to be another class other than the default GameScene class. From reading other questions, I understand I must change this part from the GameViewController:
if let scene = SKScene(fileNamed: "GameScene") {
print(scene)
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
So within the GameScene.swift file I am creating a new class:
class MainMenu : SKScene {
override func didMove(to view: SKView) {
print("At least it ran")
self.scene?.view?.presentScene(GameScene())
}
}
However, when I change the scene to:
if let scene = SKScene(fileNamed: "MainMenu")
When I run the project, it gets stuck, but when I run it with the string "GameScene" then it works perfectly. I am doing something wrong loading the MainMenu?
In my opinion you should separate your scenes into their own files...
Do you have an corresponding SKS file for MenuScene? You need to create one if you are trying to load it with fileNamed:
or -
Use this code to load a SKScene file that is created in code only and not in the Scene editor
if let skView = self.view as? SKView {
if skView.scene == nil {
let scene = MenuScene(size: skView.bounds.size)
scene.scaleMode = .aspectFill
skView.presentScene(scene)
}
}
and then in your MenuScene file you will need an init func
init(size: CGSize) {
super.init(size: size)
name = "menuScene"
}

Gamescene.swift and Gamescene.sks not working together

I am having a problem with my xCode project. I have a whole gamescene.swift file worth of code (600 lines). But the code will not run. When i run my game in simulator the simulator shows the standard gamescene.sks color, alongside with my ads, but it is not showing any of my code. I have already checked that the custom class in gamescene.sks is correct. Everything is working, expect for the gamescene.swift code, it will not run.
import UIKit
import SpriteKit
import GameplayKit
import GoogleMobileAds
class GameViewController: UIViewController {
#IBOutlet weak var GoogleBannerView: GADBannerView!
#IBOutlet weak var MainMenu: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
GoogleBannerView.adUnitID = "ca-app-pub-13***46014918193/236762****"
GoogleBannerView.rootViewController = self
GoogleBannerView.load(GADRequest())
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .resizeFill
// Present the scene
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
view.showsFPS = false
view.showsNodeCount = false
view.showsPhysics = true
}
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return .allButUpsideDown
} else {
return .all
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden: Bool {
return true
}
}
i managed to fix the problem after countless hours of trying.
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = GameScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .resizeFill
this is the working code. the problem was that instead of specifying what scene i was suppose to lead i had written
if let scene = SKScene(fileNamed: "GameScene")
the simple fix was changing the "SKScene" to my SKScene name.
if let scene = GameScene(Filenamed: "GameScene")
Hope this helps the countless other out there that are having trouble with this problem!
I've had similar problems to this on SOME of my projects but not all. Even on projects that were working and I duplicated the code and scene files for another project they would stop working. I discovered that if there are any spaces or special characters in the your project name the scene files and items in the sks files will not load unless you put in the "Module" name below the Custom Class type.
For me my project was named "Crag & Pig" before any of the sks file would register I had to enter "Crag_Pig" in the "Module" for all of the items in the sks file.
Interestingly, on any projects that didn't have spaces or special characters I didn't have to enter any thing for Module
Thanks. Even the default template in Xcode for SpriteKit Games has this very issue. That since the release of swift 4 + iOS 11.
I always thought it was me somehow, but never took the time to find why. Until now out of curiosity. I changed the line you wrote/fixed and voila.
Just changed the capitals in the parameter fileNamed: of your line
if let scene = GameScene(fileNamed: "GameScene")

Deleting the Gamescene.sks file raises CPU to 25% on device

I just created a brand new Xcode Game Project. I deleted the Gamescene.sks file. Ran it and the cpu instantly to 25-30%. I made another Xcode project just to see if I could replicate it. Ran it before deleting the file and cpu was basically 0%, but sure enough when I deleted the file and ran it again, the cpu jumped up to the same high numbers. My goal is to subclass skscene and use that without the Gamescene.sks file. Can someone explain why this happens?
I was able to replicate this behavior just deleting the .sks file.
The problem is GameViewController is looking for that file at first loading time, as you can see here:
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") { <--------------!!
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
So you need to initialize it another way. Just as an example, you could init an empty scene like this:
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = SKScene(size: CGSize(width: 1000, height: 1000))
scene.scaleMode = .aspectFill
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
and you'll see 1% of CPU load.

GameScene misses initializers

I get an error that "Class 'GameScene' has no initializers" when I try to add a level selection to my game.
I present the scene in GameViewController.swift like this:
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.level(1) {
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
skView.showsPhysics = 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
skView.presentScene(scene)
}
}
And in my GameScene.swift I wanted to handle the level selection like this (got this from Ray Wenderlich iOS Game Development Books)
class func level(levelNum: Int) -> GameScene? {
let scene = GameScene(fileNamed: "Level\(levelNum)")!
scene.currentLevel = levelNum
scene.scaleMode = .AspectFill
return scene
}
But then I get the error as I mentioned and I dont know how to fix this issue :-? Are there any other ways to make a level selection? Currently I have for each level one sks file, which is something I find really handy, since I enables me to lay out the levels visually.
Any recommendations and/or help?
Thanks in advance