Search code examples
swiftsprite-kitskscene

Can I have SKSpriteNodes show up on a different scene during a transition


I am making a Game and have a custom transition I am working on. When you click the playButton on the TitleScene, it moves the the GameScene. Here is a gif of it.

enter image description here

Now I would like to have these buttons to fall over the other scene, or be seen on top of the other scene. So essentially the buttons need to be on the GameScene, even though they are part of the TitleScene. Here is my code for the transition:

let transition = SKTransition.revealWithDirection(SKTransitionDirection.Up, duration: 2)
transition.pausesIncomingScene = false
transition.pausesOutgoingScene = false

currentScene.view?.presentScene(futureScene, transition: transition)

I am unsure how to do this. Any help is wanted.

UPDATE

I have realized that the only way of doing this is to copy the SKSpriteNodes from the TitleScene to the GameScene. Check this code out:

func createTransition(transitionFrom presentScene: SKScene, to futureScene: SKScene, withTransition transition: transitionTypes) {

var yPositions : [CGFloat] = []
for child in presentScene.children as! [SKSpriteNode] {
    yPositions.append(child.position.y)
}
let topSprite = yPositions.maxElement() // finds the sprite closest to the top

for child in presentScene.children as! [SKSpriteNode] {
    if child.position.y == topSprite {
        var vel = CGFloat.random(-1, 1)
        if (vel < 0.3 && vel >= 0) {
            vel += 0.5
        }
        if (vel > -0.3 && vel <= 0) {
            vel -= 0.5
        }
        let fallAction = SKAction.applyTorque(vel, duration: 0.5) // slightly turns the Sprite

        presentScene.physicsWorld.gravity.dx = CGFloat.random(-0.3,0.3)

        child.physicsBody?.affectedByGravity = true // Become affected by gravity and falls

        child.runAction(fallAction, completion: {
            for otherChild in presentScene.children as! [SKSpriteNode] {

                if otherChild.name != "background" { //copies all Sprites except the background 

                    let copiedChild = otherChild.copy() as! SKSpriteNode
                    copiedChild.position.y += futureScene.frame.size.height

                    futureScene.physicsWorld.speed = presentScene.physicsWorld.speed
                    futureScene.physicsWorld.gravity = presentScene.physicsWorld.gravity //makes it so they have the same physicsWorlds

                    futureScene.addChild(copiedChild) 
                }
            }
        })

        let transition = SKTransition.pushWithDirection(SKTransitionDirection.Up, duration: 2)
        transition.pausesIncomingScene = false
        transition.pausesOutgoingScene = false

        presentScene.view?.presentScene(futureScene, transition: transition)
    }
}

}

This is what it looks like:

enter image description here

You can see that they don't line up properly, does somebody know something that I am missing?


Solution

  • Scenario 1: One big scene

    +------------+   }
    |            |   }
    |   Title    |   }
    |            |   }
    |            |   }
    |            |   }   Initially visible half of full scene.
    | btn    btn |   }
    |    Play    |   }
    | btn    btn |   }
    +------------+   }  }
    |            |      }
    |            |      }
    |            |      }
    |            |      }
    |   game     |      }   Half of full scene visible after play button is pressed
    |            |      }    (the game)
    |            |      }
    |            |      }
    +------------+      }
    

    When Play is pressed, this big rectangle (14x19) shifts up so that instead of the top rectangle being visible, the bottom rectangle is visible. Because this is technically one big scene, the buttons/title can move freely through the both 'scenes' (it is really just one big scene).

    Scenario 2: Two 'scenes' overlap

                 +------------+   }
                 |            |   }
                 |   Title    |   }
                 |            |   }
                 |            |   }
                 |            |   }   Initially visible half of big scene.
                 | btn    btn |   }     z-pos of the rectangle on the right is higher than
                 |    Play    |   }      the z-pos of the one on the left, thereby allowing
                 | btn    btn |   }     its contents to be visible above those of the gamescene.
    +------------+            |   }  }
    |            |            |      }
    |            |            |      }
    |            |            |      }
    |            |            |      }
    |   game     |            |      }   Half of scene and gamescene visible after play button 
    |            |            |      }    is pressed (the game)
    |            |            |      }
    |            |            |      }
    +------------+------------+      }
    

    These to scenes overlap, with the bottom half of the rightmost scene matching up with the leftmost scene. When the play button is pressed, both scenes move up at the same rate until only the bottom scene is visible. In reality, the bottom half of the rightmost scene is still on top of the smaller scene.

    The alpha of the bigger scene is 0. For the top half of the big scene, you can add a background node; this setup allows the game to be visible and the buttons to still fall above the game.

    To ensure that there are no issues with being unable to interact with the game scene because there is technically a scene on top of it (which may obstruct interaction), remove the bigger scene or change its z-position to be below the gamescene. This may not be necessary but in case it is... you know.

    Remember that you cannot really embed scenes (At least according to this), so you can't really use two scenes in Scenario 2. You can alternatively put the game scene in an SKNode or something like that as a work-around.