I want to make the background for the scene in GameScene.sks. I have Tile Map Node there, but when I set background in GameScene.swift the picture is on my textures. I want it on the back of the scene.
Here is the code of GameScene.swift:
import SpriteKit
class GameScene: SKScene {
var background = SKSpriteNode(imageNamed: "BackGround")`
override func didMove (to view: SKView) {
background.zPosition = 1
background.position = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
addChild(background)
}
}
Here is the code of GameViewController.swift:
import UIKit
import SpriteKit
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
}
}
override var prefersStatusBarHidden: Bool {
return true
}
Does 1 the least z position in your scene? If so, try to set ignoresSiblingOrder property of your SKView to false. Also I would suggest you to read SKScene and SKNode documentations at least. And SpriteKit documentation in general.
Related
i have the problem, that the GameViewController doesn't load my GameMenu. If i simulate my app it only shows a grey screen with node:0 and the fps count.
Here the Code from GameViewController.swift:
import UIKit
import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = GameMenu(fileNamed: "GameMenu") {
// 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
}
}
I tried also the line:
if let scene = SKScene(fileNamed: "GameMenu")
but it changed nothing.
I also added the Custom Class "GameMenu" to the GameMenu.sks
I think the problem is this if let scene = SKScene(fileNamed: "GameMenu") line.
I have read a lot about this problem but i my case nothing was successful.
I also tried this:
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let gkScene = GKScene(fileNamed: "GameMenu.sks") {
if let skScene = gkScene.rootNode as? SKScene {
// Set the scale mode to scale to fit the window
skScene.scaleMode = .aspectFill
// Present the scene
view.presentScene(skScene)
}
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
but nothing happend.
You have to load it as GKScene from .sks file and get SKScene from its rootNode attribute.
if let gkScene = GKScene(fileNamed: "GameMenu") {
if let skScene = gkScene.rootNode as? SKScene {
// TODO
}
}
I am trying to direct the user to a main menu file as soon my game loads (made with Swift 4 SpriteKit). However, when I try to redirect the user to this .swift file (where a label should be displayed onto the users screen) the screen is simply blank except the for the node and FPS counter.
Here's my code in the MainMenuScene.swift file I created:
import Foundation
import SpriteKit
class MainMenu: SKScene {
override func didMove(to view: SKView) {
print("In scene")
let myLabel = SKLabelNode(fontNamed: "The Bold Font")
myLabel.fontColor = SKColor.blue
myLabel.text = "My Label"
myLabel.fontSize = 50
myLabel.position = CGPoint(x: 0, y: 0)
myLabel.zPosition = 1
self.addChild(myLabel)
}
}
Here's my code in the GameViewController.swift
import UIKit
import SpriteKit
import GameplayKit
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: "MainMenuScene") {
// 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
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 changed the
if let scene = SKScene(fileNamed: "GameScene")
to
if let scene = SKScene(fileNamed: "MainMenuScene")
That line of code should redirect the user to MainMenuScene.swift, but when I run the program the screen is simply blank.
Anyone know what im doing wrong?
Thanks!
Try using the code below after
super.viewDidLoad()
Also make sure that your Menu class is called "MainMenuScene" and that you changed the scene name to the same at MainMenuScene.sks
CODE:
if let scene = GKScene(fileNamed: "MainMenuScene") {
// Get the SKScene from the loaded GKScene
if let sceneNode = scene.rootNode as! MainMenuScene? {
scene.scaleMode = .aspectFill
// Present the scene
if let view = self.view as! SKView? {
view.presentScene(sceneNode)
view.ignoresSiblingOrder = true
//view.showsFPS = true
//view.showsNodeCount = true
}
}
}
I am creating a simple Game and I would like to get the actually size (width/height) of a SpriteKit scene to be able to present a SKNode ( / SKSpriteNode) to fill the whole display, but apparently
backgroundNode.size = CGSize(width: view.frame.width, height: view.frame.height)
or anything similar doesn't work. The node is presented, but is just a quarter of the actually screen size.
I present the SKScene from GameViewController.swift like this:
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = GameScene(size: view.bounds.size)
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
view.ignoresSiblingOrder = true
}
So how could one get the actually SpriteKit Scene size or is there another way to present an SKNode / SKSpriteNode fullscreen in a GameScene?
Update: I tried this as well:
let displaySize: CGRect = UIScreen.main.bounds
let displayWidth = displaySize.width
let displayHeight = displaySize.height
which gives me for an iPhone 8 375x667 as a size, but the Node is still displayed as a quarter of the screen.
I created a sample project with the code below. This creates a red-colored node that fills the screen. You can use UIScreen.main.bounds and I'm using it here as a global variable. I find it helpful this way since I can access it from any code file, as I often need to use the screen size in a calculation.
GameViewController.swift
import SpriteKit
let displaySize: CGRect = UIScreen.main.bounds
class GameViewController: UIViewController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let skView = self.view as! SKView
if let scene = SKScene(fileNamed: "GameScene") {
scene.scaleMode = .aspectFill
scene.size = view.bounds.size
skView.ignoresSiblingOrder = true
skView.presentScene(scene)
}
}
}
GameScene.swift
import SpriteKit
class GameScene: SKScene {
let backgroundNode = SKSpriteNode()
override func didMove(to view: SKView) {
backgroundNode.size = CGSize(width: displaySize.width, height: displaySize.height)
backgroundNode.color = .red
self.addChild(backgroundNode)
}
}
This is probably a dumb question ,but here is my situation.
I have an SKShapeNode rect that goes from left to right on the screen as follows :
// GameScene.swift
var rect = SKShapeNode()
var counter = 0{
didSet{
rect.position = CGPoint(x: CGFloat(counter) , y: frame.midY)
if CGFloat(counter) > frame.width{
counter = 0
}}}
override func update(_ currentTime: TimeInterval) {
counter = counter + 4
}
In the ViewController.swift I try to get the rect.position like this , which I know is wrong because it creates a new Instance.
//ViewController.swift
let gameScene = GameScene()
#IBAction func button(_ sender: Any) {
// gameScene.rect.position = games.frame.CGPoint(x: 200, y: 400)
print(gameScene.rect.position) // Always returns (0,0)
}
Question: How can I get rect.position in real time from the other class. So that whenever I press the button , I get the actual position of the rect?
UPDATE
On Ron's suggestion I updated the viewDidLoad method in my ViewController.swift from this :
let gameScene = GameScene()
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.spriteView {
// 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)
}}
to this :
var gameScene : GameScene!
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.spriteView {
// Load the SKScene from 'GameScene.sks'
if let scene = GameScene(fileNamed: "GameScene") { // SKScene changed to GameScene
self.gameScene = scene // scene assigned to gameScene variable
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
}
INTENTION
I wanted to get the position of the moving bar when the play button was clicked.
Note that the GameScene only represents a part of the actual screen
When you first transition to your GameScene (Assuming that you are going directly from your GameViewController to your GameScene) create a class level variable for gameScene. Then when you need the information from GameScene use that same variable vs. creating a new GameScene variable
var gameScene: GameScene!
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let gameScene = GameScene(fileNamed: "GameScene") {
self.gameScene = gameScene
gameScene = .aspectFill
// Present the scene
view.presentScene(gameScene)
}
}
}
func getCoords() {
print("gameScene.rect.position \(gameScene.rect.position)")
}
Tried to perform an SKTransition for the very first loading of GameScene from GameViewController but nothing seemed to happen. Can't we perform some transition while presenting a scene directly from the GameViewController? It seemed to me quite hilarious that the normal present scene is working but not the one with transition. Here is the code :
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
let scene = GameScene(size: view.bounds.size)
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
//transition
let transition = SKTransition.doorsOpenVertical(withDuration: 2)
// Present the scene
view.presentScene(scene, transition: transition)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
}
class GameScene: SKScene {
override func didMove(to view: SKView) {
self.backgroundColor = SKColor.red
}
}
Please solve the query.