Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FPS drops in SpriteKit

I'm developing a simple game with Swift & SpriteKit, and I've noticed FPS drops from 60 to 58-59 (and back). There is a noticeable lag when the drop occurs — it looks like 1 or 2 frames are dropped.

CPU load is about 20-25% and does not change a lot, memory usage is permanently about 8 MB.

Screenshot: App Screenshot

There are 6 object on screen: label, red object (Sprite), 2x green objects (Sprite), one box (Sprite) and "ground" (Rect shape node).

All objects except label have physics body (displayed with white borders).

Green and white objects are dynamically created, move from right to left and destroyed when offscreen:

func scheduleAddingLiquid() {
let wait = SKAction.waitForDuration(NSTimeInterval(getRandomNumber(1, end: 3)))
        let block = SKAction.runBlock({
            [unowned self] in

            let liquidNode = LiquidNode(texture: self.liquidTexture, sceneFrame: self.frame)
            self.addChild(liquidNode)
            liquidNode.move()

            self.scheduleAddingLiquid()
        })

        let sequence = SKAction.sequence([wait, block])
        runAction(sequence)

and:

func move() {
        let moveAction = SKAction.moveToX(-frame.width, duration: NSTimeInterval(3))
        let removeBlock = SKAction.runBlock({
            [unowned self] in

            self.removeFromParent()
            })

        runAction(SKAction.sequence([moveAction, removeBlock]))
    }

Red object "jumps" on screen touch:

if touches.count > 0 && isHeroOnGround && heroNode != nil {
            isHeroOnGround = false
            heroNode.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
            heroNode.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 400))
        }

The lag occurs within random time interval after "jumping" (from about 0.5 to 1.5 seconds after jump).

The lag occurs not when collision occurs, just when red object is "in the air". And it occurs not every jump. The CPU load does not grow when FPS drops.

Tested on iOS 9.3, iPad mini 2.

Upd 1. Tested on iOS 9.3 iPhone 6 — FPS is about 50-55 for first few seconds, then it's constantly 60, without lags. So, it lags on iPad mini 2 only (I have only these two devices, cannot test on other ones).

UPD 2. I've commented out all objects creation code, except red figure. It's still lagging when "jumping". So, now I'm sure that it's related to applyImpulse method.

UPD 3. That's really, REALLY strange: I've removed all code from touchesBegan method, and it still lags on touches! The method is completely empty. I don't know why, but FPS drops if I click several times...

How to debug this?

like image 949
artem Avatar asked Aug 19 '16 22:08

artem


People also ask

Does SpriteKit use GPU?

SpriteKit runs efficiently on the GPU. CoreGraphics runs on the CPU.

What is the difference between SceneKit and SpriteKit?

SceneKit and SpriteKit are very similar to each other. SceneKit is a little harder to learn but it's pretty simple. SceneKit would be the only way to have a 3D model(With the options you provided). You can have a SpriteKit scene over top of the SceneKit scene to display labels that stay put.

What is Apple SpriteKit?

Overview. SpriteKit is a general-purpose framework for drawing shapes, particles, text, images, and video in two dimensions. It leverages Metal to achieve high-performance rendering, while offering a simple programming interface to make it easy to create games and other graphics-intensive apps.

What is SpriteKit used for?

The SpriteKit framework makes it easy to create high-performance, battery-efficient 2D games. With support for custom OpenGL ES shaders and lighting, integration with SceneKit, and advanced new physics effects and animations, you can add force fields, detect collisions, and generate new lighting effects in your games.


2 Answers

It only having issues on the mini makes me think there is something wrong with your mini (or that particular package on your mini). Try making a new project, copy the files over, then run it again. Also, you said 9.3, but there is 9.3.1, 9.3.2, etc. The two devices could have had different builds.

So, first, ensure your iphone and iPad are running the same version of iOS.. Maybe there was a bug, or maybe they patched a bug (thus causing one to work and not the other).

Also, try running it on the different emulators... if it runs flawlessly on the emulators, then I'm even more suspect of the mini (in it's current configuration).

This way, you can also see if (maybe) the problem has to do with the orientation (widescreen of iphone vs 4:3 or whatever of iPad).

Sometimes, I've had "very strange" things happen to my project files (even without plugins) and simply creating a new project, copying all the files over fixed it. If it's lagging when you click on an empty "touchesBegan" ... makes me think something buggy with Xcode / your mini is at hand--since it only happens on that one device (thus we know so far)...

Other things to consider,

  1. Which version of Xcode are you using? Try The latest beta / go back to 7.3. Any differences?

  2. Do you have another computer you could try building the project from?

  3. If swapping out the [unowned self] or leaving it in didn't fix anything, then my suggestion would be to load up your code with print statements and see what's going on.

  4. If you used the Scene Editor to make the sprite nodes, delete them all and remake them, or try making them programmatically. This has fixed random bugs in some of my projects (for seemingly no reason).

We need more code / info, but the above should hopefully fix your problem.

like image 151
Fluidity Avatar answered Oct 07 '22 08:10

Fluidity


Well I suppose it is a bit late but I have a performance drop when I add some SKShapeNode to my scene. I have no lags with 200+ plain SKSpriteNode and everything starts freezing when there are 80 nodes with only about 30 SKShapeNode among them. Of course with no additional functionality, just a path, stroke/fill colours and lineWidth

like image 25
Pavel Stepanov Avatar answered Oct 07 '22 09:10

Pavel Stepanov