Change view from SKScene to a ViewController - ios

I am making a game using ARKit. Im having trouble witching to the ARSCNview from a SKSecene.
I have this so far:
import Foundation
import SpriteKit
//Back button
let backToBrand = SKLabelNode(fontNamed: "Electric Boots")
class Lamborghini: SKScene {
override func didMove(to view: SKView) {
//Background
let menuBackground = SKSpriteNode(imageNamed: "Background")
menuBackground.setScale(1)
menuBackground.position = CGPoint(x: self.size.width/2, y:
self.size.height/2)
menuBackground.zPosition = 0
self.addChild(menuBackground)
//Back button
backToBrand.text = "Back"
backToBrand.fontSize = 50
backToBrand.fontColor = SKColor.white
backToBrand.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.left
backToBrand.position = CGPoint(x: self.size.width*0.05, y: self.size.height*0.67)
backToBrand.zPosition = 1
self.addChild(backToBrand)
//Test button
let test = SKLabelNode(fontNamed: "Electric Boots")
test.text = "test AR"
test.fontSize = 100
test.fontColor = SKColor.white
test.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
test.zPosition = 2
test.name = "test"
self.addChild(test)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let pointOfTouch = touch.location(in: self)
let nodeITapped = atPoint(pointOfTouch)
if nodeITapped == backToBrand {
let sceneToMOveTo = BrandMenu(size: self.size)
sceneToMOveTo.scaleMode = self.scaleMode
let sceneTransition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMOveTo, transition: sceneTransition)
}
if nodeITapped.name == "test"{
let sceneToMOveTo = ARView(size: self.size)
sceneToMOveTo.scaleMode = self.scaleMode
let sceneTransition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMOveTo, transition: sceneTransition)
}
}
}
The part having the problem is:
if nodeITapped.name == "test" {
let sceneToMOveTo = ARView(size: self.size)
sceneToMOveTo.scaleMode = self.scaleMode
let sceneTransition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMOveTo, transition: sceneTransition)
}
The AR scene is in a ViewController within the Main.Storyboard.
I can't get the Game Scene to move to the ViewController and move back.

Related

No sound without any errors

I tried to add sound when button pressed but when I press the button no sound. No mistakes in terminal.
I already tried compile on another computer, and debug on iPhone.
No sound persist.
Please help me solve this problem.
class MenuScene : SKScene {
let txtAtlas : SKTextureAtlas = SKTextureAtlas(named: "UI.atlas")
let txtAtlas2 : SKTextureAtlas = SKTextureAtlas(named: "mapbc.atlas")
let startBut = SKSpriteNode()
let tssound = SKAction.playSoundFileNamed("tssound.wav", waitForCompletion: false)
override func didMove(to view: SKView) {
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.backgroundColor = UIColor.black
let logo = SKLabelNode(fontNamed: "Helvetica")
logo.text = "Train Control"
logo.position = CGPoint(x: 0, y: 100)
logo.fontSize = 60
logo.fontColor = UIColor.green
self.addChild(logo)
startBut.texture = txtAtlas.textureNamed("stbut.png")
startBut.size = CGSize(width: 230, height: 85)
startBut.position = CGPoint(x: 0, y: -20)
startBut.name = "StartBtn"
self.addChild(startBut)
let startText = SKLabelNode(fontNamed: "AvenirNext-HeavyItalic")
startText.text = "Start Manage!"
startText.verticalAlignmentMode = .center
startText.position = CGPoint(x: 0, y: 2)
startText.fontSize = 30
startText.name = "StartBtn"
startBut.addChild(startText)
let bcmap = SKSpriteNode()
bcmap.texture = txtAtlas2.textureNamed("mapbc.png")
bcmap.zPosition = -1
bcmap.size = CGSize(width: 400.0, height: 350.0)
bcmap.position = CGPoint(x: -100, y: 0)
bcmap.alpha = 0.7
self.addChild(bcmap)
let stbutaction = SKAction.sequence([SKAction.fadeAlpha(to: 0.7, duration: 0.9),
SKAction.fadeAlpha(to: 1.0, duration: 0.9)])
startBut.run(SKAction.repeatForever(stbutaction))
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches) {
let location = touch.location(in: self)
let nodeTouched = atPoint(location)
if nodeTouched.name == "StartBtn" {
// Player touched the start text or button node
self.view?.presentScene(GameScene(size: self.size))
self.run(tssound)
}
}
}
}
You should probably initialise and run your sound inside GameScene e.g. when the scene loads. You are trying to run the sound on MenuScene which doesn't exist after you have transitioned to GameScene

JoyStick only moves when Camera Controls = true Xcode, SWIFT, SpriteKit, SceneKit

Hey I have a 3D game thats not really a game yet. But it has a SceneKit 3D scene and a overlayskscene for the HUD/Controls. the "base" is the base of the joystick and the ball is the handle the problem is that the joystick does not move at all unless the scnView.allowsCameraControl = true. I find that weird. and this is my entire view controller code so nothings left out and if you want you can literally copy and paste it into Xcode to see what I'm talking about. Any help?
Code:
import iAd
import UIKit
import GameKit
import SceneKit
import StoreKit
import SpriteKit
import QuartzCore
import Foundation
import AVFoundation
import AudioToolbox
class GameViewController: UIViewController, ADBannerViewDelegate, SKPhysicsContactDelegate, SKSceneDelegate, SCNSceneRendererDelegate, SCNPhysicsContactDelegate{
var stickActive:Bool = false
let base = SKSpriteNode(imageNamed:"VirtualJoystickBase")
let ball = SKSpriteNode(imageNamed:"VirtualJoyStickHandle")
let ship = SKSpriteNode(imageNamed:"Ship")
var ButtonA = SKSpriteNode(imageNamed:"GreenAButton")
var ButtonO = SKSpriteNode(imageNamed:"CircleButton")
var ButtonY = SKSpriteNode(imageNamed:"YellowYButton")
var ButtonSquare = SKSpriteNode(imageNamed:"BlueSquareButton")
let FieldScene = SCNScene(named: "art.scnassets/TesingCampusField.dae")!
let GuyScene = SCNScene(named: "art.scnassets/Guy.dae")!
let overlayScene = SKScene(size: CGSizeMake(100, 100))
override func viewDidLoad() {
super.viewDidLoad()
let scnView = self.view as! SCNView
scnView.overlaySKScene = overlayScene
scnView.backgroundColor = UIColor.whiteColor()
scnView.scene = FieldScene
scnView.delegate = self
scnView.overlaySKScene!.delegate = self
scnView.overlaySKScene!.anchorPoint = CGPointMake(0, 0)
scnView.overlaySKScene!.physicsWorld.contactDelegate = self
scnView.overlaySKScene!.physicsWorld.gravity = CGVectorMake(0.0, 0.0)
scnView.allowsCameraControl = true
scnView.showsStatistics = false
let Guy1: SCNNode = GuyScene.rootNode.childNodeWithName("Bob_014", recursively: true)!
FieldScene.rootNode.addChildNode(Guy1)
//----Positioning-the-Base-of-the-Joystick-----------
base.size = CGSize(width: 14, height: 24)
base.position = CGPointMake(15, 19)
base.zPosition = 0
overlayScene.addChild(base)
//----Positing-the-Ball/Joystick-----------
ball.size = CGSize(width: 10, height: 17)
ball.position = base.position
ball.zPosition = 1
overlayScene.addChild(ball)
//----A-Button--Creation -------------------
ButtonA.size = CGSize(width: 6, height: 9)
ButtonA.anchorPoint = CGPointMake(-13.3, -0.5)
ButtonA.zPosition = 0
overlayScene.addChild(ButtonA)
//----B-Button--Creation -------------------
ButtonO.size = CGSize(width: 6, height: 9)
ButtonO.anchorPoint = CGPointMake(-14.4, -1.7)
ButtonO.zPosition = 0
overlayScene.addChild(ButtonO)
//----C-Button--Creation -------------------
ButtonSquare.size = CGSize(width: 6, height: 9)
ButtonSquare.anchorPoint = CGPointMake(-12.2, -1.7)
ButtonSquare.zPosition = 0
overlayScene.addChild(ButtonSquare)
//----C-Button--Creation -------------------
ButtonY.size = CGSize(width: 6, height: 9)
ButtonY.anchorPoint = CGPointMake(-13.3, -2.7)
ButtonY.zPosition = 0
overlayScene.addChild(ButtonY)
//---Setting-Up-Ships-Position/PhysicsBody---------------------
ship.position = CGPointMake(0, 100)
ship.size = CGSize(width: 80, height: 80)
ship.physicsBody?.dynamic = true
ship.physicsBody?.allowsRotation = true
ship.physicsBody?.affectedByGravity = true
ship.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Ship"), size: ship.size)
ship.physicsBody!.friction = 0
ship.physicsBody!.restitution = 0
ship.physicsBody!.linearDamping = 0
ship.physicsBody!.angularDamping = 0
//--------------------------
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
GuyScene.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 5, z: 15)
//-----------------------------------------------
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = SCNLightTypeOmni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
FieldScene.rootNode.addChildNode(lightNode)
//-----------------------------------------------
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = SCNLightTypeAmbient
ambientLightNode.light!.color = UIColor.darkGrayColor()
FieldScene.rootNode.addChildNode(ambientLightNode)
//----------------------------------------------
}
func YButtonPressed() {
let YButtonPressed = SKTexture(imageNamed: "YellowYButtonPressed")
let OrignalButtonY = SKTexture(imageNamed:"YellowYButton")
let YButtonPressedAnimation = SKAction.animateWithTextures([YButtonPressed, OrignalButtonY], timePerFrame: 0.2)
let RunYButtonPressedAnimation = SKAction.repeatAction(YButtonPressedAnimation, count: 1)
ButtonY.runAction(RunYButtonPressedAnimation)
}
func OButtonPressed() {
let OButtonPressed = SKTexture(imageNamed: "CircleButtonPressed")
let OrignalButtonO = SKTexture(imageNamed:"CircleButton")
let OButtonPressedAnimation = SKAction.animateWithTextures([OButtonPressed, OrignalButtonO], timePerFrame: 0.2)
let RunOButtonPressedAnimation = SKAction.repeatAction(OButtonPressedAnimation, count: 1)
ButtonO.runAction(RunOButtonPressedAnimation)
}
func SquareButtonPressed() {
let SquareButtonPressed = SKTexture(imageNamed: "BlueSquareButtonPressed")
let OrignalButtonSquare = SKTexture(imageNamed:"BlueSquareButton")
let SquareButtonPressedAnimation = SKAction.animateWithTextures([SquareButtonPressed, OrignalButtonSquare], timePerFrame: 0.2)
let RunSquareButtonPressedAnimation = SKAction.repeatAction(SquareButtonPressedAnimation, count: 1)
ButtonSquare.runAction(RunSquareButtonPressedAnimation)
}
func AButtonPressed() {
let AButtonPressed = SKTexture(imageNamed: "GreenAButtonPressed")
let OrignalButtonA = SKTexture(imageNamed:"GreenAButton")
let AButtonPressedAnimation = SKAction.animateWithTextures([AButtonPressed, OrignalButtonA], timePerFrame: 0.2)
let RunAButtonPressedAnimation = SKAction.repeatAction(AButtonPressedAnimation, count: 1)
ButtonA.runAction(RunAButtonPressedAnimation)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self.overlayScene)
if (CGRectContainsPoint(base.frame, location)) {
print("stickActive = true")
stickActive = true
} else {
print("stickActive = false")
stickActive = false
}
}
for touch: AnyObject in touches {
let location1 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location1) == self.ButtonA {
AButtonPressed()
print("AButtonPressed")
}
}
for touch: AnyObject in touches {
let location2 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location2) == self.ButtonO {
OButtonPressed()
print("OButtonPressed")
}
}
for touch: AnyObject in touches {
let location3 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location3) == self.ButtonY {
YButtonPressed()
print("YButtonPressed")
}
}
for touch: AnyObject in touches {
let location4 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location4) == self.ButtonSquare {
SquareButtonPressed()
print("SquarButtonPressed")
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location) == self.ball {
if (stickActive == true) {
let v = CGVector(dx: location.x - base.position.x, dy: location.y - base.position.y)
let angle = atan2(v.dy, v.dx)
//println( deg + 180)
let length:CGFloat = base.frame.size.height / 2
let xDist:CGFloat = sin(angle - 1.57879633) * length
let yDist:CGFloat = cos(angle - 1.57879633) * length
if (CGRectContainsPoint(base.frame, location)) {
ball.position = location
} else {
ball.position = CGPointMake( base.position.x - xDist, base.position.y + yDist)
}
ship.zRotation = angle - 1.57879633
let calcRotation : Float = Float(angle - 1.57879633) + Float(M_PI_2);
let intensity : CGFloat = 200.0 // put your value
let xVelocity = intensity * CGFloat(cosf(calcRotation))
let yVelocity = intensity * CGFloat(sinf(calcRotation))
let vector : CGVector = CGVectorMake(xVelocity, yVelocity)
//Apply force to spaceship
ship.physicsBody?.applyForce(vector)
// ends stackActive
}
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location) == self.ball {
if (stickActive == true) {
let move:SKAction = SKAction.moveTo(base.position, duration: 0.05)
move.timingMode = .EaseOut
ball.runAction(move)
}
}
}
}
//====================================================================
override func shouldAutorotate() -> Bool {
return true
}
//====================================================================
override func prefersStatusBarHidden() -> Bool {
return true
}
//====================================================================
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}
//====================================================================
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
}
there's an issue in SceneKit where the SpriteKit overlay isn't automatically redrawn when changes are made in the 2D scene but the 3D scene is left untouched. In other words, the 2D overlay is only redrawn when the 3D view needs to be redrawn.
You can set the playing property of the SCNView to YES to fix this. Alternatively you can call -setNeedsDisplay whenever you make a change to the overlay scene.

Passing Data Between Scenes (SpriteKit)

How do I pass information in SpriteKit from one scene to another? In my game I have two scenes, the GameScene and the GameOverScene. The score is displayed in the GameScene as it increases, but how do I send this information to the second scene?
This function is called when the player runs out of lives which changes the scene.
func changeScene(){
let secondScene = GameOverScene(size: self.size)
secondScene.scaleMode = scaleMode
let transition = SKTransition.fadeWithDuration(0.5)
self.view?.presentScene(secondScene, transition: transition)
}
This is my gameOverScene
class GameOverScene: SKScene {
var playAgainLabel = SKLabelNode(fontNamed:"Chalkduster")
var currentScore: Int
var scoreLabel = SKLabelNode(fontNamed: "Chalkduster")
var highScore = 0
var highScoreLabel = SKLabelNode(fontNamed: "Chalkduster")
var gameScene = GameScene()
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.blackColor()
playAgainLabel.text = "Click To Play Again!"
playAgainLabel.fontSize = 30
playAgainLabel.fontColor = SKColor.whiteColor()
playAgainLabel.position = CGPoint(x: frame.width / 2, y: frame.height / 2)
self.addChild(playAgainLabel)
if currentScore > highScore {
highScore = currentScore
}
scoreLabel.text = "Score: " + String(currentScore)
scoreLabel.fontSize = 20
scoreLabel.fontColor = SKColor.whiteColor()
scoreLabel.position = CGPoint(x: frame.width/2, y: frame.height/1.4)
self.addChild(scoreLabel)
highScoreLabel.text = "Best: " + String(highScore)
highScoreLabel.fontSize = 20
highScoreLabel.fontColor = SKColor.whiteColor()
highScoreLabel.position = CGPoint(x: frame.width / 2, y: frame.height / 1.6)
self.addChild(highScoreLabel)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
let playingScene = GameScene(size: self.size)
playingScene.scaleMode = scaleMode
let fadeTransition = SKTransition.fadeWithDuration(0.5)
self.view?.presentScene(playingScene, transition: fadeTransition)
}
}
}
For instance, your GameOverScene could be something like this:
class GameOverScene: SKScene {
var object: SomeObject!
}
Now, in your changeScene:
func changeScene(){
let secondScene = GameOverScene(size: self.size)
secondScene.scaleMode = scaleMode
secondScene.object = somethingInFirstSceneThatNeedToBePassed //here we do the passing
let transition = SKTransition.fadeWithDuration(0.5)
self.view?.presentScene(secondScene, transition: transition)
}
Subclass SKScene and create a new initializer with arguments that you want to pass. As you transition from GameScene to second scene, create second scene by using the initializer you created and pass the score. Then present the second scene.

Swift Sprite Kit passing Bool

I got a Image with 2 faces, Up and Down ( Imagine a Card ).
Whenever you tap the Image, it changes it image.
I used a Bool to get the expression. However, after the Scene is presented again, I want to show the image which was Up/Down in the last Scene. Note that this is only 1 Scene, and it presents itself again.
How can I pass a Bool value between the Scene?
//Update:
My Code:
....
var FaceUp = true
....
override func didMoveToView(view: SKView) {
TTexture = SKTexture(imageNamed: "TCard.png")
TTexture.filteringMode = .Nearest
T2Texture = SKTexture(imageNamed: "T2Card.png")
T2Texture.filteringMode = .Nearest
Card = SKSpriteNode(texture: TTexture)
Card.position = CGPoint(x: Rate.position.x - (TransparentLayer.size.width / 3), y: Rate.position.y)
Card.size = CGSize(width: 50, height: 50)
Card.name = "Card"
Card.zPosition = 100
self.addChild(Card)
flip(FaceUp)
}
func flip(state : Bool) {
FaceUp = state
if (!state) {
Card.texture = TTexture //Error
Player.texture = T1
Player.runAction(RunAnimation1)
FaceUp = true
} else {
Card.texture = T2Texture //Error
Player.texture = T2
Player.runAction(RunAnimation2)
FaceUp = false
}
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch:UITouch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
let Node:SKNode = self.nodeAtPoint(touchLocation)
if Node.name == "Card" {
let Scale1 = SKAction.scaleTo(0.7, duration: 0.1)
let Scale2 = SKAction.scaleTo(1, duration: 0.1)
let Scaling = SKAction.sequence([Scale1, Scale2])
Card.runAction(Scaling)
self.flip(FaceUp)
}
}
func Restart(){
self.saveHighScore()
LastScore = Score
self.addLeaderboardScore(self.Score)
let Transition = SKTransition.fadeWithDuration(1.8)
let Scene = GameScene(size: self.frame.size)
Scene.LastScore = Score
Scene.FaceUp = FaceUp
scene?.scaleMode = SKSceneScaleMode.AspectFill
self.scene?.view?.presentScene(Scene, transition: Transition)
}
You can define a function in GameScene like the following.
func setCardState(state : Bool) {
FaceUp = state
if (!state) {
Card.texture = Texture2
Player.texture = T2
} else {
Card.texture = Texture1
Player.texture = T1
}
}
And call it from didMoveToView in the new scene.
override func didMoveToView(view: SKView) {
TTexture = SKTexture(imageNamed: "TCard.png")
TTexture.filteringMode = .Nearest
T2Texture = SKTexture(imageNamed: "T2Card.png")
T2Texture.filteringMode = .Nearest
Card = SKSpriteNode(texture: TTexture)
Card.position = CGPoint(x: Rate.position.x - (TransparentLayer.size.width / 3), y: Rate.position.y)
Card.size = CGSize(width: 50, height: 50)
Card.name = "Card"
Card.zPosition = 100
self.addChild(Card)
setCardState(FaceUp) // added line.
}
Also set the old FaceUp value in the new scene in Restart function.
func Restart(){
self.saveHighScore()
LastScore = Score
self.addLeaderboardScore(self.Score)
let Transition = SKTransition.fadeWithDuration(1.8)
let Scene = GameScene(size: self.frame.size)
Scene.LastScore = Score
scene?.scaleMode = SKSceneScaleMode.AspectFill
Scene.FaceUp = FaceUp //changed line.
self.scene?.view?.presentScene(Scene, transition: Transition)
}

Scene transition in spritekit not transitioning

I am in sprite kit making a game in swift. (I am new to swift) And I would like to transition a scene when a node is pressed. I looked it up and the proper way to transition is
let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
let scene = GameScene(size: self.scene.size)
scene.scaleMode = SKSceneScaleMode.AspectFill
self.scene.view.presentScene(scene, transition: transition)
But when I am programming it doesn't like the self.scene.size and puts a question mark on scene. Here is my code
let playView = PlayScene(size: self.scene?.size)
And I don't know how to fix this. Any suggestions? (Or it might be just a simple error in my part because I am new to swift.
Here is more of my code
In the GameScene.swift File
class GameScene: SKScene {
var playButton = SKSpriteNode(imageNamed: "Play")
var levelsButton = SKSpriteNode(imageNamed: "Levels")
var optionsButton = SKSpriteNode(imageNamed: "Options")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let myLabel = SKLabelNode(fontNamed:"Helvetica-Light")
myLabel.text = "Mini Golf";
myLabel.fontSize = 30;
myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:525);
println(size.height)
println(size.width)
let backgroundNode = SKSpriteNode(imageNamed: "Background")
backgroundNode.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame));
playButton.position = CGPoint(x: CGRectGetMidX(self.frame), y: 360)
levelsButton.position = CGPoint(x: CGRectGetMidX(self.frame), y: 295)
optionsButton.position = CGPoint(x: CGRectGetMidX(self.frame), y: 230)
self.addChild(backgroundNode)
self.addChild(playButton)
self.addChild(levelsButton)
self.addChild(optionsButton)
self.addChild(myLabel)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
super.touchesBegan(touches, withEvent: event)
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
//let touchedNode = nodeAtPoint(Location)
//touchedNode.postiion =location
let transitionToPlayScene = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
if CGRectContainsPoint(playButton.frame, location) {
let playView = PlayScene(size: self.scene?.size)
}
}
}
This is the code in the PlayScene.swift file
import Foundation
import UIKit
import SpriteKit
private let WALL_CATEGORY: UInt32 = 0x1 << 0
private let HOLE_CATEGORY: UInt32 = 0x1 << 1
private let GOLF_CLUB_CATEGORY: UInt32 = 0x1 << 2
private let BALL_CATEGORY: UInt32 = 0x1 << 4
private let DECORATION_BORDER_CATEGORY: UInt32 = 0x1 << 5
class PlayScene: SKScene, SKPhysicsContactDelegate {
var ballNode = SKSpriteNode(imageNamed: "Ball")
var flag = SKSpriteNode(imageNamed: "Flag")
var club = SKSpriteNode(imageNamed: "Golf Club")
var tee = SKSpriteNode(imageNamed: "Tee")
var hole = SKSpriteNode(imageNamed: "Hole")
var decoBorder1 = SKSpriteNode(imageNamed: "Border 1")
var decoBorder2 = SKSpriteNode(imageNamed: "Border 2")
override func didMoveToView(view: SKView) {
//Setting up the view's physics
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame);
self.physicsBody = borderBody
self.physicsBody?.friction = 0.0
self.physicsBody?.categoryBitMask = WALL_CATEGORY
self.physicsWorld.gravity = CGVectorMake(0.0 ,0.0);
self.physicsWorld.contactDelegate = self
//Setting the ball's properties
ballNode.position = CGPoint(x: CGRectGetMidX(self.frame), y: 100);
ballNode.physicsBody = SKPhysicsBody(rectangleOfSize: ballNode.frame.size);
ballNode.physicsBody?.categoryBitMask = BALL_CATEGORY
ballNode.physicsBody?.mass = 50.0
ballNode.physicsBody?.dynamic = true
ballNode.physicsBody?.allowsRotation = true
self.addChild(ballNode)
//Setting the club's properties
club.position = CGPoint(x: CGRectGetMidX(self.frame)-20, y: 75);
club.physicsBody = SKPhysicsBody(rectangleOfSize: self.frame.size);
club.physicsBody?.categoryBitMask = GOLF_CLUB_CATEGORY
club.physicsBody?.mass = 150.0
club.physicsBody?.dynamic = true
club.physicsBody?.allowsRotation = false
self.addChild(club)
//Setting the Tee's properties
tee.position = CGPoint(x: CGRectGetMidX(self.frame), y: 70);
//self.addChild(tee)
//Setting the decoration border nodes
decoBorder1.position = CGPoint(x: CGRectGetMinX(self.frame), y: 500);
decoBorder2.position = CGPoint(x: CGRectGetMaxX(self.frame), y:500);
decoBorder1.physicsBody = SKPhysicsBody(rectangleOfSize: self.frame.size);
decoBorder2.physicsBody = SKPhysicsBody(rectangleOfSize: self.frame.size);
decoBorder1.physicsBody?.categoryBitMask = DECORATION_BORDER_CATEGORY
decoBorder1.physicsBody?.dynamic = false;
decoBorder1.physicsBody?.allowsRotation = false
decoBorder2.physicsBody?.categoryBitMask = DECORATION_BORDER_CATEGORY
decoBorder2.physicsBody?.dynamic = false;
decoBorder2.physicsBody?.allowsRotation = false
//self.addChild(decoBorder1)
//self.addChild(decoBorder2))
//Setting the Hole properties
hole.position = CGPoint(x: CGRectGetMidX(self.frame), y: 550);
hole.physicsBody = SKPhysicsBody(rectangleOfSize: self.frame.size);
hole.physicsBody?.categoryBitMask = HOLE_CATEGORY
hole.physicsBody?.dynamic = false
hole.physicsBody?.allowsRotation = false
//self.addChild(hole)
}
The question mark comes from optional chaining because your scene property must have been declared like this SKScene?. This isn't a problem though, it just means that if your scene is nil, it won't get the size property.
The real problem is probably this line:
self.scene.view.presentScene(scene, transition: transition)
Reason being, your scene probably doesn't have a view before it's presented.
You probably wanted something like this:
(self.view as SKView).presentScene(scene, transition: transition)
You'll notice I said probably a lot. I'm only speculating on the problem because I don't see enough code, but I appreciate the effort to try and narrow down your problem. You should post more though because it may be somewhere else.
Edit
Try replacing this:
let transitionToPlayScene = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
if CGRectContainsPoint(playButton.frame, location) {
let playView = PlayScene(size: self.scene?.size)
}
With this
if CGRectContainsPoint(playButton.frame, location) {
let transitionToPlayScene = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
let nextScene = PlayScene(size: self.size)
self.view!.presentScene(nextScene, transition: transitionToPlayScene)
}
What ended up working for me was this:
let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
let scene = GameScene(size: (self.scene as SKScene!).size)
scene.scaleMode = SKSceneScaleMode.AspectFill
(self.view as SKView!).presentScene(scene, transition: transition)

Resources