0
votes

In my SpriteKit game, I have many tile nodes (>100) arranged randomly and I need to be able to detect collisions between the tiles and the character node. To do this, I use SKPhysicsBody.

I find that if I enable SKPhysicsBody code, my frame rate drops to around 40fps, but If I comment out the code, it goes up to 60fps. I guess this is something to do with the engine trying to simulate physics for 100+ nodes each frame... is there a way I can prevent this from happening but still detect collisions between my character and the tiles?

For the tile physics I'm using the following code for my tiles:

self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
self.physicsBody.affectedByGravity = NO;
self.physicsBody.categoryBitMask = WallCategory;
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = CharacterCategory; 

and for my character:

self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:size];
self.physicsBody.usesPreciseCollisionDetection = YES;

self.physicsBody.restitution = 0;
self.physicsBody.friction = 0;
self.physicsBody.linearDamping = 0;

self.physicsBody.categoryBitMask = CharacterCategory;
self.physicsBody.contactTestBitMask = 0xFFFFFFFF;
self.physicsBody.collisionBitMask = BoundaryCategory; 
2

2 Answers

0
votes

Your low frame rate could be caused by other contributing factors but without setting your entire code, it's hard to localize the main culprit.

If feasible for your game structure, you could consider disabling the physicsBody and running a contact check yourself. You would have to create an array of all your tile objects and then use intersectsNode: from the SKNode Class to check for any contact between player and object.

0
votes

There are a few reasons this could be happening.

First, the simulator does not simulate collisions as a real iPhone would. If you are using the simulator alone, I strongly suggest that you try on an actual device.

Secondly, you should assert that your app's assets are not loaded in an inefficient way such as lazy loading. The assets should be loaded within an asynchronous call to the background thread upon launch. For more detail on this, check out an example project by Apple.

Third, you have not posted your - (void)didBeginContact:(SKPhysicsContact *)contact method. If implemented inefficiently or incorrectly, it can cause laggy collisions.

You should also be profiling your app in Instruments, so you can determine exactly where and when the drop in FPS is happening

Note: the property usesPreciseCollisionDetection may be contributing to a significant amount of overhead, given that you are creating >100 nodes on screen.