How to add an overlay start scene in swift? - swift

can someone code for me please how to add an overlay start scene in swift?
I want to add a startMenu like in Flappy Bird, and then when you click play it just moves/fades away and the game begins.
Can someone help me achieve this effect?
Looking to achieve this.
I will be more than thankful!

Try to post some code of what you have tried so far when asking a question on stack overflow, people tend to not write code for you.
You can basically do this 2 ways.
1)
Either create a StartScene and transition to GameScene with your preferred SKTransition when the play button is pressed e.g SKTransition.crossFade
2)
If you want to do it in the same scene you can just create a SKNode/SKSpriteNode class to use as a menu.
class Menu: SKSpriteNode {
lazy var playLabel: SKLabelNode = {
let label = SKLabelNode(fontNamed: "HelveticaNeue")
label.text = "Play"
label.fontSize = 22
label.fontColor = .yellow
label.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
return label
}()
/// Init with size
init(size: CGSize) {
super.init(texture: nil, color: .red, size: size)
addChild(playLabel)
}
}
}
Than in your GameScene Scene you can add the menu like so with your preferred size, in this example the size of the scene.
class GameScene: SKScene {
lazy var menu: Menu = Menu(size: self.size)
override func didMove(to view: SKView) {
addChild(menu)
}
}
You can add other nodes for UI, including sprites for buttons etc, to that menu class.
Than in GameScene in touches Began you can look for nodes that are touched, e.g the play button and than do your thing e.g to animate out the menu
let action1 = SKAction.fadeAlpha(to: 0, duration: 0.5)
let action2 = SKAction.removeFromParent()
let sequence = SKAction.sequence([action1, action2])
menu.run(sequence)
If you stuck there and want more coding samples you should google how to do this, is basic SpriteKit stuff that you need to know and there is plenty tutorials available. This includes samples of how to make button subclasses using SKSpriteNodes.
Hope this helps

Related

How can I get the safeAreaLayout info for my GameScene?

Am trying to develop a game and am not using storyboard at all. Am building it all via code.
I know how to get the safeAreaLayout info, thanks to this forum) for a UIViewController. My thought was I'd be able to attach my GameScene: SKScene to that and go from there. Found out the hard way that's not the case. I have searched so hard and have tried all the example I found find for the likes of
override func viewDidLayoutSubviews()
and
func viewDidAppear(_ animated: Bool)
And every method I've tried returns either sets of 0's, or the full height of the screen 812
I would like to think that there is a proper method for getting the proper safeArea info to the initial GameScene of my app. Is there?
Hei,
You get the 812 pixels height because that's the scene height. In SpriteKit the games are full screen, you don't need to worry about the safe areas.
From GameViewController present the scene you want to display, in my case MainScene.
if let view = self.view as! SKView?
{
// create a new scene of type Main Scene
let scene = MainScene()
// set the new (MainScene) settings
scene.scaleMode = .resizeFill
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
// present the scene
view.presentScene(scene)
}
If you want to know the size of the scene in MainScene, just get the values like this.
class MainScene: SKScene
{
override func didMove(to view: SKView)
{
let screenHeight = self.scene!.size.height
let screenWidth = self.scene!.size.width
}
}

Sprite Kit Animations and Texture Atlases in Swift 4

Currently working on an application that requires a little bit of animations through an array of images. I've done tons of research online on how to resolve my issue but couldn't run into anything for Swift 4. Below is my code, it shows the first picture in the loop when I run the app but no animation at all. Everything looks fine, I don't see a problem with my code but maybe you guys can help. Appreciate it in advanced!
let atlas = SKTextureAtlas(named: “mypic”)
var TextureArray = [SKTexture]()
var person = SKSpriteNode()
override func didMove(to view: SKView) {
person = SKSpriteNode(imageNamed: "red_1.png")
person.size = CGSize(width: 150, height: 129)
person.position = CGPoint(x: 0, y: 0)
person = SKSpriteNode(imageNamed: atlas.textureNames[0])
for i in 1...atlas.textureNames.count {
let Name = "red_\(i).png"
TextureArray.append(SKTexture(imageNamed: Name))
}
self.addChild(person)
}
override func update(_ currentTime: TimeInterval) {
let myAnimation = SKAction.animate(with: TextureArray, timePerFrame: 0.1)
person.run(SKAction.repeatForever(myAnimation))
}
The animation action is placed in update, which is executed once every frame. So if the game runs at 60 FPS, update gets called 60 times in one second. This means that every second person gets 60 new myAnimation actions that it needs to run.
To fix this, consider placing the animation action somewhere else in your code, e.g. right after adding the person to the scene. Since this is a repeatForever action, the animation will run as you intended until either the action is removed from the node, or the node is removed from the scene.
Hope this helps!

In swift, is there a way to select a sprite by its name?

I'm new to coding in Swift so I apologize if this is a silly question.
I have a function that creates a series of Sprites. These Sprites move around and change sizes. Through the function, each is given a unique name.
What I would like to do is have their position/animation/size/texture change when a user presses a separate set of sprites. In other words, I need pressing another sprite to call a function which changes the first set of sprites.
However, I'm having trouble doing this. It seems like I can make it work if I hardwire the particular variable name of a sprite in. However, because there are many, they may change over time, and I may want to cycle through many of them hardwiring is not good.
Essentially, I want to be able to select a sprite and animate it once another sprite is touched.
Any suggestions?
You can make your own subclass of SKSpriteNode, then call them from their object name (the name of the variable or let constant). This means you don't have to hardwire, and you can use any sort of logic / function to change the animation or which names of sprites being called / used etc.
In this demo, I make two objects... one a lightbult, another a lightswitch. When you click the lightswitch, the lightbulb will turn on.
Read the comments to learn how to customize this. You can have any object tell any other sprite to play their personal animation:
class TouchMeSprite: SKSpriteNode {
// This is used for when another node is pressed... the animation THIS node will run:
var personalAnimation: SKAction?
// This is used when THIS node is clicked... the below nodes will run their `personalAnimation`:
var othersToAnimate: [TouchMeSprite]?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// Early exit:
guard let sprites = othersToAnimate else {
print("No sprites to animate. Error?")
return
}
for sprite in sprites {
// Early exit:
if sprite.scene == nil {
print("sprite was not in scene, not running animation")
continue
}
// Early exit:
guard let animation = sprite.personalAnimation else {
print("sprite had no animation")
continue
}
sprite.run(animation)
}
}
}
Here is the GameScene file that shows off the lightswitch and bulb demo:
class GameScene: SKScene {
override func didMove(to: SKView) {
// Bulb:
let lightBulb = TouchMeSprite(color: .black, size: CGSize(width: 100, height: 100))
// Lightbulb will turn on when you click lightswitch:
lightBulb.personalAnimation = SKAction.colorize(with: .yellow, colorBlendFactor: 1, duration: 0)
lightBulb.position = CGPoint(x: 0, y: 400)
lightBulb.isUserInteractionEnabled = true
addChild(lightBulb)
// Switch:
let lightSwitch = TouchMeSprite(color: .gray, size: CGSize(width: 25, height: 50))
// Lightswitch will turn on lightbulb:
lightSwitch.othersToAnimate = [lightBulb]
lightSwitch.isUserInteractionEnabled = true
lightSwitch.position = CGPoint(x: 0, y: 250)
addChild(lightSwitch)
}
}

swift/spritekit: Is there a way to add a SKLabelNode to an SKView?

I'm trying to create a hud that sits at the top of the screen and doesn't move with the rest of the scene. I was able to get a static view up there with this:
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let hud = SKView()
hud.alpha = 0.5
hud.backgroundColor = SKColor.greenColor()
hud.frame = CGRect(x: 0.5, y: 0.5, width: view.bounds.width, height: 50)
self.view?.addSubview(hud)
So with that, my player can walk around the scene, the camera follows him, but there is always a transparent view across the top which is what I think I want.
So next I tried adding things to the hud view at the top but I can't seem to figure it out. For example, if I create an SKLabel node I can't add it with hud.addChild because SKView doesn't have addChild. I tried doing hud.addSubview but a SKLabel isn't a UIView, which is what addSubview expects.
Does anyone know how I add things to the hud like labels?

Unable to add SKSpriteNode to scene

I'm unable to add a SKSpriteNode to a scene in Spritekit with the folling code:
func addScoreNode(){
scoreNode = SKSpriteNode(color: SKColor.blueColor(), size: CGSizeMake(100,100))
scoreNode!.position = CGPointMake(50, 450)
addChild(scoreNode!)
}
When I create the node with a texture, it gets added to the screen.
Any help would be greatly appreciated.
Im not sure if you are just trying to display text which would be a SKLabelNode or if you are trying to apply a picture to the node But try this at the top of your scene under the class Gamescene : SKScene add
var scoreNode = SKSpriteNode()
And then instead of the func addScoreNode() put this in the didMoveToView
scoreNode.color = UIColor.blueColor()
scoreNode.size = CGSizeMake(100,100)
scoreNode.position = CGPointMake(50, 450)
scoreNode.zPosition = 5 //this brings it to the front of the screen if there are multiple things at this position
and either in the didMoveToView or where ever you want it to be called and added to screen
self.addChild(scoreNode)