1

My current project contains a gravity simulator where sprites move in accordance with the forces they experience in the game scene.

One of my features involve allowing moving sprites to draw a line behind them so you can see what paths they take.

Shown here:

enter image description here

However, as the Sprite continues it's movements around the screen, the FPS begins to dive. This can be seen in this second image where some time has passed since the sprite first started its movement.

enter image description here

When researching, I found other people had posted with similar problems:

Multiple skshapenode in one draw?

However, in the question above, the answer's poster detailed that it (The answer) was meant for a static image, which isn't something I want, because this line will change in real time depending on what influences the sprites path, this was reflected when I tried implementing a function to add a new Line to the old one which didn't work. That Code here

I'm asking if anyone can assist me in finding a way to properly stop this constant FPS drop that comes from all the draw operations. My current draw code consists of two Functions.

-(void)updateDrawPath:(CGPoint)a B:(CGPoint)b
{
    CGPathAddLineToPoint(_lineToDraw, NULL, b.x, b.y);
    _lineNode.path = _lineToDraw;
}

-(void)traceObject:(SKPlanetNode *)p
{
    _lineToDraw = CGPathCreateMutable();
    CGPathMoveToPoint((_lineToDraw), NULL, p.position.x, p.position.y);
    _lineNode = [SKShapeNode node];
    _lineNode.path = _lineToDraw;
    _lineNode.strokeColor = [SKColor whiteColor];
    _lineNode.antialiased = YES;
    _lineNode.lineWidth = 3;
    [self addChild:_lineNode];
}
  • updateDrawPath: Draws line to latest position of Sprite.

  • traceObject: Takes SKPlanetNode (Subclass of SKSpriteNode), and sets it up to have a line drawn after it.

If anyone can suggest a way to do this and also reduce the terrible overhead I keep accumulating, it would be fantastic!

Community
  • 1
  • 1
Micrified
  • 3,338
  • 4
  • 33
  • 59
  • drawing sprites gets to be n^2 if they are related to each other... try drawing your line as a bezier curve or bitmap and composite it... – Grady Player Jan 16 '15 at 01:08
  • I found a solution in answering this question : http://stackoverflow.com/questions/24553245/poor-performance-with-skshapenode-in-sprite-kit/24557658#24557658 -- It was in relation to drawing with touch, but the solution is directly applicable to your current issue. – prototypical Jan 16 '15 at 01:13
  • @prototypical It's your solution! Also ". If you set showsDrawCount on your SKView instance, you will see what I mean." I don't get an extremely high draw count but this problem is still visible – Micrified Jan 16 '15 at 01:15
  • that's what I said, I found a solution in answering that question. – prototypical Jan 16 '15 at 01:17
  • It's the "caching" element of my answer you need to take note of. A SKShapeNode is NOT efficient when you have all those segments and gets even worse as you continue to draw. – prototypical Jan 16 '15 at 01:19
  • @prototypical My bad, should I use the moving sprites as canvas's (Number 3 in your list)? – Micrified Jan 16 '15 at 01:20
  • The canvas is what you are drawing on. Each time your sprite moves, draw a line from it's old position to the new. Every so often, you cache via flattening and recycling those shape nodes you are drawing with. – prototypical Jan 16 '15 at 01:28
  • @prototypical Sorry to bug you, but I've tried implementing your solution and I'm having trouble with the cacheSegments method (Marked in file) http://pastebin.com/uJK1pRBS – Micrified Jan 16 '15 at 02:14
  • I'd have to know the problem you are having. As I said in the answer, it's not all inclusive code, but was an example of the core concepts. "not working" is pretty vague :) error message ? – prototypical Jan 16 '15 at 04:00
  • @prototypical Found the problem, wasn't initializing something I needed. No visible lines yet though. – Micrified Jan 16 '15 at 04:04
  • @prototypical Thanks for the help! Lines aren't staying on screen but I'll just try again tomorrow. – Micrified Jan 16 '15 at 04:21
  • Unlike forum sites, we don't use "Thanks", or "Any help appreciated", or signatures on [so]. See "[Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). BTW, it's "Thanks in advance", not "Thanks in advanced". – John Saunders Jan 16 '15 at 04:42

1 Answers1

-1

A couple suggestions:

  • Consider that SKShapeNode is more or less just a tool for debug drawing mostly, due to the fact that it doesn't draw in batches it's really not suitable to make a game around that or to use it extensively (both many shapes as well as few but complex shapes).
  • You could draw lines using a custom shader which will likely be faster and more elegant solution, though of course you may have to learn how to write shader programs first.
  • Be sure to measure performance only on a device, never the simulator.
CodeSmile
  • 64,284
  • 20
  • 132
  • 217
  • Custom shaders not supported in iOS7, which happens to be what I'm working with. I'll have no choice but to ditch Spritekit or find some alternative to SKShapeNode. . , unless someone can suggest a workaround. Sigh . . – Micrified Jan 17 '15 at 02:36
  • If you just started you'll certainly get more freedom to draw your own stuff with SpriteBuilder + Cocos2D-Swift. I think the CCRenderer even has a built-in method to draw lines. – CodeSmile Jan 17 '15 at 08:40