SpriteKit Scene Not Resetting? - ios

I am having an issue with my SpriteKit Scene File. I currently have my GameScene.sks lined to my GameScene.swift file. When my app loads up the user enters a menu, then the user presses play and is transitioned to the GameScene file to play the game via:
let gameScene = SKScene(fileNamed: "GameScene")
gameScene?.scaleMode = .aspectFit
self.view?.presentScene(gameScene!, transition: SKTransition.fade(withDuration: 1.5))
When the player hits an object in the game they die and go back to the menu (also linked to a .sks file) :
let menu = SKScene(fileNamed: "menu")
menu?.scaleMode = .aspectFill
self.view?.presentScene(menu!, transition: transition)
Here where my issue is, after the user is brought back to the menu, the next time they hit play the user immediately dies and is brought back to the menu.
This is because when GameScene is called everything is the same as when the user died. In other words, the player is contacting the same node that caused them to die.
Is there any way to reset the GameScene? I have tried removing all nodes to no avail.
Am I presenting the scenes wrong?

I Figured it out! I moved my removeFromParent() statement into my menu.swift file. Right before I'm about to transition to GameScene:
obstacles.removeFromParent()
then
let gameScene = SKScene(fileNamed: "GameScene")
gameScene?.scaleMode = .aspectFit
self.view?.presentScene(gameScene!, transition: SKTransition.fade(withDuration: 1.5))
Please let me know if you have a better solution. Thanks!

Related

How to add a view controller to window programmatically and bring it to front

I want to do a screen saver for the whole app, but i only can do for 1 screen...now i am changing to appdelegate to start the timer and show the screen saver as a whole...However, i not sure how to add the video screen saver(video player view) as a whole at app delegate window... Timer i did edi, it really print out "Play Video" after 5 second, but the video view didn't show out.
library used:
1. https://github.com/piemonte/Player
2. timer
Please use this if it works for you.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginSignupVC")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
If Not works, then I suggest using one initial UIViewController for this video screen and change to next screen when a video is completed.
UIApplication.shared.keyWindow?.rootViewController?.addChildViewController(self.player)
UIApplication.shared.keyWindow?.addSubview(self.player.view)
this is the best solution.
Credit to : senior Desmond
Not sure but you can try adding video on launcher screen, or if you want the video should run, in that case you need to follow these simple steps
Add a Movie player on applicationDidLaunch
when video finishes on it return back method you need to load you app controller.
I hope this helps do let me know in case you need anything more to help.
[Edit as per the requirement]
I think you need to create a controller in the app delegate
you need to create a class function in your app delegate where you can add a movie player to the screen with auto play on.
also you need to maintain a timer, but be careful while using timer and read well about it, as it needs to be manage very carefully else results in various crashes.
You can manage the timer by getting touch events on the screen by the following logic like
if movieplayer is on screen then, remove movie player else,
invalidate timer and restart the timer
The function with timer will does the following things
invalidate timer
add movie player on the window and bring it to the main screen.

How do I only allow one instance of an SKSpriteNode on screen at one time?

This is my first ever post - I have searched for a long time and could not find the answer.
I am making a game with SpriteKit and want the player to be able to only launch one bomb at a time- i.e they can't fire again until the previous bomb has exploded or gone off screen. Currently when the player taps the screen, they can launch as many bombs as they want.
Any help would be greatly appreciated!
Thanks,
Iain
Steve's idea works out well and is better than mine, but here is a more novice-friendly explanation IMO... Put this in your gamescene :)
var canFireMissile = true
func fireMissile() {
guard canFireMissile else { return }
canFireMissile = false // So you can't fire anymore missiles until 0.5secs later
let wait = SKAction.wait(forDuration: 0.5) // the duration of the missile animation (example)
let reset = SKAction.run { canFireMissile = true } // lets us refire the missile
let sequence = SKAction.sequence([wait, reset])
run(sequence)
}
override func mouseDown(with event: NSEvent) { // touchesBegan on iOS
fireMissile()
}
Create a SKSpriteNode property for your misssile.
Create an SKAction for the movement of the missile and give the action a key so you can refer to it by name).
When the fire button is pressed, check to see if the named action is already running; if it is, do nothing, otherwise run the ‘fireMissile’ action.

Swift SpriteKit: Game won't restart properly? Whats going?

I have this game so that when my player dies I should just be able to tap the screen and the game should restart, but instead nothing moves no matter how many times I tap. There are no errors.
Here is the code for my restart function: (willing to post any other necessary code)
func restart() {
cloudGenerator.stopClouds()
let newScene = GameScene(size: view!.bounds.size)
view!.presentScene(newScene)
newScene.scaleMode = .AspectFill
}
So, an easy solution is to transition from your current scene to your current scene. By doing this, your code will run from the beginning of the file. You can also add fancy transitions. Here is the code:
let transition = SKTransition.fadeWithDuration(1.0) //create a transition
let gamePlayScene = GamePlayScene(fileNamed: "GamePlayScene") // create a new scene from your file (let variableName = NameOfGameFile(fileNamed: "NameOfGameFile")
self.view?.presentScene(gamePlayScene, transition: transition) // present the scene with the transition
Just put this in the touches began method and have a conditional that if the clouds have been stopped and the user touches the screen, transition to current game scene.
Hope this helped and good luck.

Cannot unpause game when bringing app back to Foreground

SpriteKit is automatically pausing my app when it goes into the background. This is fine, except it stays paused when the app becomes active again. I'm trying to un-pause the game in the appropriate application events, to no avail. I'm manually un-pausing the two SKViews and the game Scene that constitute the app. From inside the AppDelegate file:
func applicationWillEnterForeground(application: UIApplication) {
if let vw = self.window?.rootViewController {
let gc = vw as! GameViewController
let parView = gc.view as! SKView
parView.paused = false
gc.gameView.paused=false
gc.gameScene.paused=false
println("paused = \(gc.gameScene.paused)")
}
}
func applicationDidBecomeActive(application: UIApplication) {
if let vw = self.window?.rootViewController {
let gc = vw as! GameViewController
let parView = gc.view as! SKView
parView.paused = false
gc.gameView.paused=false
gc.gameScene.paused=false
println("paused = \(gc.gameScene.paused)")
}
}
At the end I print the pause state. If I hit the device's Home key and then return to the app, it prints false as desired. However, somewhere (not by my code) this is being immediately set back to true, and the game remains paused.
Update
I overrode the scene's paused property, and it is definitely being set back to true after I un-pause in the given events. Confusing, because from reading other questions, the typical behavior of sprite kit is to automatically un-pause the game when the app is reactivated. Yet it's doing the exact opposite for me.
Well, I basically gave up on trying to control whether the game pauses/resumes during the app's state changes. Instead I overrode the scene's paused property, so now I can just detect whenever sprite kit decides to pause or resume, and handle that accordingly. My suspicion is that my hierarchy of SKViews in my app might not be conventional, and maybe caused sprite kit difficulty in controlling the scene state, but that's only a guess.

Resetting Whole Scene (Swift, SpriteKit)

I'm trying to create a replay button for my game, but whenever I go back to the game scene, It seems as if nothing ever stopped. The time is a negative number and the game will just crash. I tried...
if timeInt < 0 {
//////////////
let retryScene = RetryScene(size: self.frame.size)
self.view?.presentScene(retryScene)
self.removeAllChildren()
self.removeAllActions()
///// end game
timeInt = 45
}
I figured removing all children would work and resetting the time would work too. I used a function that updates every second to make the time work. So all functions keep going as if the scene never ended. What should I do?
All the time i whant to restart game I'am presenting Game scene. (starting game scene from begining)
It should look like this
if (node.name == "ReplayButton") {
var gameScene = GameScene(size: self.size)
var transition = SKTransition.doorsCloseHorizontalWithDuration(0.5)
gameScene.scaleMode = SKSceneScaleMode.AspectFill
self.scene!.view?.presentScene(gameScene, transition: transition)
}
I fixed it by stopping the timer that makes the update function.
if time < 0 {
timer.invalidate()
}

Resources