iosswiftskspritenodesksceneskshapenode

How to Create multiple SKShapeNode in a correct order?


multiple SKShapeNode are created like below:

for i in 1...20 {
        let waitAct = SKAction.wait(forDuration: delay)
        self.run(waitAct) {
                let disc = SKShapeNode(rectOf: CGSize(width: width, height: height), cornerRadius: height/2)
                disc.position = CGPoint(x: self.frame.midX, y: self.frame.maxY)
                disc.fillColor = self.discColors[i]
                disc.strokeColor = .clear
                disc.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: width, height: height))
                disc.physicsBody?.affectedByGravity = true
                disc.physicsBody?.density = 0.5 
                disc.physicsBody?.mass = 0.2
                disc.physicsBody?.friction = 1.0
                disc.physicsBody?.restitution = 0
                disc.physicsBody?.isDynamic = true
                disc.physicsBody?.allowsRotation = false
                disc.name = "\(i)"
                self.addChild(disc)

                let label = SKLabelNode(text: "\(i)")
                label.fontColor = .white
                label.fontName = "Arial Rounded MT Bold"
                label.fontSize = fontSize
                label.verticalAlignmentMode = .center
                disc.addChild(label)

                print(i)
        }    
        delay += 0.2
}

All discs are created at the top of the screen, and then drop down automatically, all discs are stacked vertically.

Here are two questions:

  1. Discs should be stacked in order from 1 to 20. When print, they are correct. But when check the labelNode text, they works on real device, but for several discs, sometimes fails on simulator (especially at the beginning of the run on large screen device such as iPad Pro, iPhone 11 Pro), I think it's a problem of computer speed :-(. For safety, by now I set 'delay += 0.2'. I think it's also dropping down animation issue. How can I ensure they can be placed in order? (keeping a short delay as possible)

  2. When the discs dropping down completed and are stacked, they keep on bouncing very very slightly and continually. More discs, more bouncing. I think it's an issue of disc.physicsBody?.affectedByGravity = true, but this must be enabled for moving later. How to make them stay still?

Thanks.

=== Edited ===

Solution for question 2: There is a floor below the discs, their restitution must both be set to 0.


Solution

  • Addressing the performance of SpriteKit on a simulator, I would suggest reviewing this page:

    Developing Metal Apps that Run in Simulator

    Of note, this section:

    Simulator doesn't try to exactly simulate the GPU from the iOS or tvOS device you are simulating. For example, if you are simulating the iPhone XS, Simulator does not try to emulate the capabilities of an A12 GPU. Instead, Simulator translates any calls you make and directs them to the selected GPU on the host Mac.

    If you enable the following, you will likely see that your simulator falls below 60.0 fps, based upon your host machine's performance:

    skView.showsFPS = true
    

    However, setting that to true and using it on hardware should consistently provide for 60.0 fps.

    Ultimately, when developing anything that is based upon metal, of which SpriteKit is, you cannot guarantee performance on the simulator. After all, it is a simulator, not an emulator.

    To quote Apple one last time:

    Simulator is best used to rapidly prototype and test application behavior, and to develop the basic rendering or compute capabilities of your app.

    Sure, you can come up with some hack to work around these limitations, but then you will not be testing your released code (which will again perform differently when optimized for release over debug).