Scenedidload Being Called Twice

Swift And Spritekit sceneDidLoad being called more than one

First : I'm using Firebase Database .

So the problem is : I was using If Statement inside the observe .

like :

private func searchForOpponents(){
let ref = Database.database().reference()
ref.child("activePlayers").child("waiting").observe( DataEventType.value) { (snapshot) in
// the problem when I put if statement like this
if snapshot == something {
presentToNextScene()
}
}

ref.observe called more than one in the second so basically I was present to next scene more than one time .

The solution : in my case I use ref.observeSingelEvent() and change the DataEventType to childChange .

Load Spritekit scene from a subclass

It's not necessary as in .sks there is a custom class. You just put "Spielfeld" inside.

Then in viewController:

if let sceneNode = SKScene.init(fileNamed: "Spielfeld(Whatever your name is here)") { 
(sceneNode as! Spielfeld).property = "anyValueToUse"

if let view = self.view as! SKView? {
view.presentScene(sceneNode) //present the scene.
}

If you decided to load from a file, there is no reason to init again. You may add init functions by overriding the following:

   override func sceneDidLoad() {  
} //called after .sks is loaded.

override func didMove(to view: SKView) {
//change the size here.
} // called after presentation.

My GameScene reloads whenever my Text view updates

Scene is a model, and you create new scene (right in call) on each update, so SpriteView thinks it should rebuild.

Try the following:

struct ContentView: View {
@EnvironmentObject var mainData: MainData

@State private var scene = GameScene() // << here, or put in MainData !!

var body: some View {
GeometryReader { geo in
Group {
if mainData.showSpriteScene {
SpriteView(scene: scene, // << here !!
transition: SKTransition.reveal(with: .down, duration: 1.0))
.ignoresSafeArea()

Is it acceptable to create an SKShapeNode in update delegate?

Yes you can create. the only issue you have is it's creating a new node each time update is called. At the moment you can not see multiple nodes because you're positioning them on top of each other if you try to change the position of mySquare on each update call you will see that you have multiple nodes. created which is not effective soon you will run out of frame rates. as you don't have any animations on going you don't see the difference now.

override func update(_ currentTime: TimeInterval) {
let mySquare = SKShapeNode(rectOf: CGSize(width: 50, height: 50))
mySquare.fillColor = SKColor.blue
mySquare.lineWidth = 1

mySquare.position = CGPoint(x: randomX, y: randomY)
self.addChild(mySquare)
}

changing the position of the X and Y will give you the chance to see the nodes being added to different position on the screen.

if for any reason you want to create your mySquare node in the update then you can keep a reference for the node or search the node in the parent node if it's available then don't add any

var mySquare: SKShapeNode

Then in the update check if your Square node is not nil or has the same

override func update(_ currentTime: TimeInterval) {
if mySquire == nil {
mySquare = SKShapeNode(rectOf: CGSize(width: 50, height: 50))
mySquire.name = "your square name"
mySquare.fillColor = SKColor.blue
mySquare.lineWidth = 1

mySquare.position = CGPoint(x: randomX, y: randomY)
self.addChild(mySquare)
}
}

Note: you can even check for the name like

if mySquare.name == "your square name"

then don't add it any more

Right way to return the UISlider method's INT?

I don't think there's a good way to return a UISlider value.

First as Abdullah Shafique stated, you need to create method for UISLider programmatically like:

[yourSlider addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];

Then you might have to call the method you want after selecting the number like:

- (void)valueChanged:(id)sender {
UISlider *slider = (UISlider *)sender;
int value = slider.value;

[self shootMissles:value]; //This line will send the value of slider to the method below.
}

I'm not familiar with INPUT and APPLE BASIC but the line [self shootMissles:value] will pass the slider value to a method where you can do whatever you wish with it. For example:

 - (void)shootMissles:(float)numOfMissles {
//code to shoot x number of missles based on UISlider value - be mindful
//that UISlider spits out float values, you will have to round to get whole numbers.
}


Related Topics



Leave a reply



Submit