Confusion with node locations in SpriteKit on iOS - ios

I'm still very new to Swift, Spritekit & iOS. I've been doing some experimenting and cant manage to work out why my objects are moving when I change scenes.
Here is a gfycat of what is happening.
https://gfycat.com/FlatAdeptFrenchbulldog
Im using the white box in either scene to switch back to the other. The white box is positioned in the same location in each scene, but after the first switch everything shifts.
My basic scene change code:
let transition = SKTransition.fade(withDuration: 1)
let nextScene = MenuScene(size: self.size)
nextScene.scaleMode = .aspectFill
scene?.view?.presentScene(nextScene, transition: transition)
I must be missing something pretty basic. Any help would be appreciated :)
Edit: Ive done a little more experimenting and noticed that CGPoint(x: 0, y: 0) in my default scene is the very middle of the screen, and this changes to the bottom left after the scene changes. Im guessing this explains what is happening, but Im not sure why it happens?

Related

Is it possible to scale the whole view of an app?

so I've been working on this project that involves the whole app's view to be flipped by scaling( if its even possible). I've done this before with a label but I have no idea where to start with the whole app.
I plan on pressing a button and then the whole screen flips by scaling.
here is my attempt:
#IBAction func Flip(_ sender: Any) {
UIView.animate(withDuration: 2.0,animations: {
self.UIView.transform = CGAffineTransform(scaleX: -1, y: 1)
As I said, I dont know where to start, but I was just wondering if it was even possible to have a whole app just flip and if so, is there any way I could get through this problem.
About Duplicate: My Previous question (that was marked as a duplicate) talks about MapBox, and how I can change the Turn-by-Turn UI, but I thought it was better off knowing how to flip the whole app because adding Navigation and Mapbox to the situation makes it a whole different story.
Since UIWindow inherits from UIView, you might be able to just apply a transform to it:
// Assuming your AppDelegate has a "window" property.
UIApplication.shared.delegate!.window!.transform = CGAffineTransform(scaleX: -1, y: 1)

How to remove or destroy SKSpriteNode once it disappears from screen

I am making a Flappy Bird kind of a game using Swift 3. I spawn pipes with the help of a function 'makePipes()' which I'm calling every 3 seconds with the a timer. The 'makePipes()' function makes SKSpriteNode for the Pipes and moves them from right of the screen to left of the screen.
What I wanna do is, destroy the Node of the Pipe after it has vanished from the screen or after it has completed its movement from one side of the screen to other.
Another solution could be to Re-use the pipes once they have moved from right to left.
pipe1.run(movePipes) {
self.pipe1.removeFromParent()
}
I tried the above solution and it does not work. It shows weird blinking lines across the screen and pipes become weirdly and randomly placed instead of uniform.
Any help is appreciated. I'm very new to iOS.
You could have done something like this:-
movePipesForward = SKAction.moveByX(-dx, y: 0 ,duration: duration)
removePipes = SKAction.removeFromParent()
moveForwardAndRemove = SKAction.sequence([movePipesForward, removePipes])
pipe1.runAction(moveForwardAndRemove)
self.addChild(pipe)

SpriteNode/Shapes change size and disappear after returning to GameScene (Swift SpriteKit)

GIF of the issue in action:
http://i.imgur.com/hiF5lyw.gifv
As you can see, the main Player is a SKSpriteNode, and when you hit a falling block which is a SKShapeNode, the game switches to the GameOver scene. When you click restart in the GameOver scene and move back to the GameScene the falling blocks disappear and the dimensions of the Player sprite is changed along with its y position.
All the code contains pretty detailed comments but if you have any questions about it feel free to ask.
Since the size of my Player sprite is based on the size of the screen, It might have something to do with screen size changes when switching scenes maybe. Also, its strange the falling block enemies dont show up for a few seconds, but then the node count drastically increases and another GameOver scene transition is triggered.
Maybe I have to change something with the GameViewController?
Any help would be greatly appreciated, I've been working at it for hours and I cant seem to figure out why its messing up.
Figured it out.
I created two new variables:
var transition:SKTransition = SKTransition.fadeWithDuration(0.5)
and
var gameOver:SKScene = GameOver(size: self.size)
And then implemented both when calling the scene switch with:
self.view?.presentScene(gameOver, transition: transition)
I think the size: self.size is what fixed it.
If you have troubles with changing size of your nodes when you do transitions, instead of size: self.size, you should use fileNamed: nameOfYourScene. This worked for me.

How can I stop a UIView movement in Swift?

I'm messing around with Swift for the first time and have a square on the screen. The square starts by moving to the right. When I tap on it I want it to go up. I don't want it to continue to the right at all, I want it to just go straight up. Unfortunately the physics and gravity make it curve to the right some more before it goes up. What can I do to completely stop the gravity pull and acceleration of my object, before setting the gravity to the new value?
This turns the object in the right direction, but I need it to come to an instant stop before doing this.
if(self.gravity.gravityDirection.dx == 1){
self.gravity.gravityDirection = CGVectorMake(-1.0, 0.0)
}
The way to stop an item being affected by a behavior is to remove the item from the behavior or remove the behavior from the animator. For example, here you might remove self from the existing gravity behavior.

SKTransition not working in Swift

I have a very simple SpriteKit game written in Swift with two scenes that I am trying to transition between. This code works perfectly:
let skView = self.view as SKView
let scene = GameScene(size: self.scene.size)
scene.size = skView.bounds.size
scene.scaleMode = .AspectFill
//This line shows the new scene immediately (as expected)
skView.presentScene(scene)
The trouble comes when I replace the above line of code with this:
let sceneTransition = SKTransition.doorsCloseHorizontalWithDuration(2.0)
skView.presentScene(scene, transition: sceneTransition)
When I do this nothing happens (the current scene remains on screen). I have tried several different transitions, but always with the same result.
Any thoughts?
SOLVED.
It turns out that there is nothing wrong with the code above. The problem was that I was trying to execute it in the update function based on a specific SKPhysicsBody's position. The transition doesn't happen instantaneously so it gave time for update to get called repeatedly which re-triggered the transition over and over again. This resulted in the transition never happening.
The fix was to add a bool to check if I have started the transition, so I only attempt it once.
If anyone else experiences this, you might also want to pause the outgoing scene. Some of the logic in it might be changing the state or interfering with the transition.
try setting
transition.pausesOutgoingScene = YES;
to see if that help,
either use that as a solution, if that's your intent, or set the breakpoints (try update: after the transition is created) and see what's up.

Resources