Not appearing all level after SKTransition - ios

I am trying to do a transition between game menu and the first level.
But instead of all Level1 (it is built by using an Level1.sks file(here I have designed a level) and Level1.swift(here I have created my "hero" etc.)) on the screen appears just hero, but no locations that was designed in Level1.sks.
How I can resolve this problem?
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if (playbutton .containsPoint(location)){
runAction(SKAction.playSoundFileNamed("play.wav", waitForCompletion: false))
let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1)
let scene = Level1(size: CGSizeMake(1024, 768))
scene.scaleMode = SKSceneScaleMode.AspectFill
self.scene?.view?.presentScene(scene, transition: transition)
transition.pausesOutgoingScene = true
}

You need to unarchive the sks file into an SKScene object so that the elements from the file can be loaded into the scene.
XCode usually generates a method called unarchiveFromFile in the SKScene's .swift file.
The following code should work:
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if (playbutton .containsPoint(location)){
runAction(SKAction.playSoundFileNamed("play.wav", waitForCompletion: false))
if let scene = Level1.unarchiveFromFile("GameScene") as? GameScene {
let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1)
scene.scaleMode = SKSceneScaleMode.AspectFill
self.scene?.view?.presentScene(scene, transition: transition)
transition.pausesOutgoingScene = true
}
}
}
}

Related

GameScene won't display correctly after transition from MainMenuScene in Swift

I'm making a game and at the moment I have a MenuScene and a GameScene. If I play the GameScene on its own, everything is displaying correctly. If I set the MenuScene as default and then press start the GameScene is out of position. As if it has been dragged slightly to the bottom left corner.
My Code for the transition:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
let nodesArray = self.nodes(at: location)
if nodesArray.first?.name == "newGameButton" {
let transition = SKTransition.flipHorizontal(withDuration: 0.5)
let gameScene = GameScene(size: self.size)
gameScene.scaleMode = scaleMode
self.view?.presentScene(gameScene, transition: transition)
}
}
}
From searching the issue I see others had the same problem, because they didn't set the scene mode. But I have this "gameScene.scaleMode = scaleMode", I also tried "gameScene.scaleMode = .aspectFill"
My settings for both scenes are the same in the attributes inspector, so not sure what I'm doing wrong. Is it programmable error or settings error. I have added photos. Any help appreciated. Thank you.
I managed to fix it. I changed the Transition code.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
let nodesArray = self.nodes(at: location)
if nodesArray.first?.name == "newGameButton" {
//let gameScene = GameScene(size: self.size)
let gameScene = GameScene(fileNamed: "GameScene")!
let transition = SKTransition.flipHorizontal(withDuration: 0.5)
gameScene.scaleMode = scaleMode
self.view?.presentScene(gameScene, transition: transition)
}
}
}
Now the scene is displaying correctly. Hopefully won't lead to any other issues.

Detecting a touch with Swift/SKScene

I'm trying to figure out how to detect a touch anywhere on the screen with a subclass of SKScene so that I can transition. How do I do so?
Thanks
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let location = touch.location(in: self)
print(location)
//if your touch location = a button or anything it transitions to a new scene
if location = //Startbutton {
let transition = SKTransition.reveal(with: .down, duration: 0.75)
let gameScene = GameScene(size: size)
gameScene.scaleMode = scaleMode
view?.presentScene(gameScene, transition: transition)
Prints the users touch location... hope that helps a bit m8

Switching ViewController Scenes

I'm trying to present a ViewController after a button is pressed on an SKScene. How can I make this work?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
let node = self.nodes(at: location)
if node[0].name == "newGameButton" {
let transition = SKTransition.flipHorizontal(withDuration: 0.5)
let gameScene = GameScene(size: self.size)
self.view!.presentScene(QuestionViewController, transition: transition)
}
}

presentScene() not a member of SKScene

My problem is that when I tried to move to my next Scene using self.scene?.presentScene() an error message pops up and says 'presentScene is not a member of SKScene'.
import SpriteKit
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
/* Setup your scene here */
backgroundColor = SKColor.blackColor()
let start = SKLabelNode(fontNamed: "Chalkduster")
start.position = CGPoint (x: self.frame.width/2-75, y: self.frame.height/2+100)
start.fontSize = 35
start.text = "Start"
addChild(start)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
let MyScene = SecondScene(size: self.size)
MyScene.scaleMode = scaleMode
self.scene?.presentScene(MyScene)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
presentScene is a method of SKView, not SKScene.
So to load a new scene you should write something like this
class GameScene: SKScene {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let myScene = SecondScene(size: self.size)
myScene.scaleMode = scaleMode
self.view?.presentScene(myScene)
}
}
Transition
You can also present the new scene with a transition effect. In this case one this method and pass a SKTransition as second param.
self.view?.presentScene(myScene, transition: SKTransition.crossFadeWithDuration(1))
In the example above I am using a Cross Fade transition having a duration of 1 second. But there are many other transitions to choose from.

Allow multiple instances of an SKAction

I am trying to create a "Space Invaders" game in swift, when the user touches the screen a bullet is shot from the ship, but when I try to touch it again while the bullet is moving across the screen I have an NSException and the game breaks. How do I set up the action so that there can be multiple instances of the action, so that the shooter is semi automatic. Below is my current scene controller.
import SpriteKit
class GameScene: SKScene {
let background = SKSpriteNode(imageNamed: "background")
let heroShip = SKSpriteNode(imageNamed: "heroShip")
let bullet = SKSpriteNode(imageNamed: "bullet")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
background.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))
heroShip.position = CGPointMake(self.size.width/6.0, self.size.height/2.0)
self.heroShip.zPosition = 1.0
self.addChild(background)
self.addChild(heroShip)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
bullet.position = CGPointMake(heroShip.position.x + bullet.size.width/2, heroShip.position.y)
let action = SKAction.moveToX(self.frame.width + self.bullet.size.width, duration: 0.5)
self.addChild(bullet)
bullet.runAction(action, completion: {
self.bullet.removeAllActions()
self.bullet.removeFromParent()
})
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
If you want to have multiple bullets shot from one ship, you have to create multiple instances of a bullet. What you have now is bullet property of GameScene class which is a mistake.
You probably want to instantiate bullets dynamically in your IBAction
So try something like this:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let bullet = SKSpriteNode(imageNamed: "bullet")
bullet.position = CGPointMake(heroShip.position.x + bullet.size.width/2, heroShip.position.y)
let action = SKAction.moveToX(self.frame.width + bullet.size.width, duration: 0.5)
self.addChild(bullet)
bullet.runAction(action, completion: {
bullet.removeAllActions()
bullet.removeFromParent()
})
}
and remove
let bullet = SKSpriteNode(imageNamed: "bullet")
from the top of the class

Resources