9

One part of my app shows a landscape, but it's kinda boring as of now. Therefore, I'm planning to animate some particles over the screen (think of something like tiny wings - http://www.youtube.com/watch?v=DpmcX-rWGfs). However, i have not yet found any built-in particle system; How can i do this memory-efficiently? I've already implemented my own animation system for some clouds animating over the landscape using CADisplayLink, and it's kind of sluggish (though i hope to make it faster soon). Another very heavy system, like animating 20 small points at a time i suppose, will probably break it.

Erik S
  • 1,939
  • 1
  • 18
  • 44

4 Answers4

5

I have not yet found any built-in particle system;

There are several "Free" projects that embed particle systems out there, you can visit this video tutorial for a Particle System that will be more than efficient enough for the needs that you mention. That way of making a particle system is basically the same way that Cocos2d is using, so watch the tutorial, and then download the project files, you can easily embed their Particle Emitter in your project.

How can i do this memory-efficiently?

I would recommend you using the "Object Pool Pattern", basically you preallocate a "Pool" of particles, let's say 1000 objects. Then your emitters, ask the pool for particles when they need them. If the pool get's empty you can manage the case accordingly. This may not look efficient from a memory perspective, but it's very efficient performance wise ( to avoid real time allocation of many small objects like particles ).

Some suggestions, when you declare your particle structure try to be lightweight and aligned to powers of 2 ( this will make your structure more cache friendly ), this one is 32 bytes:

struct Particle 
{
    CGPoint position;
    CGPoint speed;  
    float life;
    float decay;
    unsigned short index;
    unsigned char color_R;
    unsigned char color_G;
    unsigned char color_B;
    unsigned char color_A;
    unsigned char rotation;
};

But depending of your needs, this could be much smaller, maybe you don't really need color/index/etc. You will have to evaluate that yourself.

Finally I would recommend you to take a look at cocos2d CCParticleSystem class, you can download the code here. Their implementation is not that lightweight, but it's quite flexible and can achieve very nice effects.

Good luck with your particles :)

Goles
  • 11,599
  • 22
  • 79
  • 140
  • Hm, this sounds quite good! I've tried creating a object pool before, but somehow it didnt work and i put it away till later. Are 1000 particles in memory still no problem memory-wise? I honestly still don't know how much much memory objects take. – Erik S Apr 01 '11 at 16:26
  • Well, if your particles are 32 bytes ( like this structure ), 1000 particles take 32.25 kB (of contiguous memory if you make an array/vector of them). So it's not a lot, you have to consider that you will have to code a "Particle Emitter" that actually emit this particles, but you won't have 1000 emitters in the same scene, specially on embedded devices. I hope this helps you :) – Goles Apr 01 '11 at 16:34
  • Very interesting stuff in general! I've never looked into structs too deep, i had no idea how much it could save me. I also had not looked into using memory blocks of powers of 2, as i had underestimated it. But clearly it's a good idea when using particles, like this. Do you think something similar could be used for an image? Not for the particles this question is about, but i also have some raindrops falling sometimes. – Erik S Apr 01 '11 at 19:44
  • Well cache friendly structures are mostly helpul, I would recommend to profile your Structures size from time to time... , you can get surprised by doing it. You can always look: http://en.wikipedia.org/wiki/Data_structure_alignment – Goles Apr 02 '11 at 04:04
  • One more thing: what would you use to animate the particles created with this? Cocos2d particles? I'd like a hint as to where to look before i learn all about cocos2d, as i'm on a relatively tight schedule atm ;) – Erik S Apr 02 '11 at 16:26
  • You should look at the emitter, the particle itself is only the "basic unit", the emitter is what will give the particle an initial speed, maybe gravity, a source point, etc. :) – Goles Apr 03 '11 at 03:26
4

You should check out the new book iOS Recipes written by Matt Drance:

http://pragprog.com/titles/cdirec/ios-recipes

Among the recipes is one to make use of the built-in CoreAnimation CAReplicatorLayer to build an emitter in "Construct a simple Emitter".

The book is still in alpha but if you buy it now you get updates as it is finished.

Kendall Helmstetter Gelner
  • 74,769
  • 26
  • 128
  • 150
  • 2
    A book that's in alpha... now i've seen everything ;) Thanks for the link, i'll try to look for the CAReplicatorLayer. – Erik S Mar 31 '11 at 15:46
  • Pragmatic Programmers does that with all of the books they sell, it's actually quite nice as you can buy the eBook and keep getting updates, and give feedback before the book is "finished". – Kendall Helmstetter Gelner Mar 31 '11 at 19:18
  • Hm, sounds good; once i got some spare money i'll look into that :P However, the emitter doesn't sound exactly like what i need. I basically just need about 30-50 images or similar floating through the screen (preferrably in some sort of sine form, though i can make that with a CAPath). – Erik S Mar 31 '11 at 19:20
  • That to me seems exactly when you would want to use an emitter because it replicates layers that generally have the same content (like repeating images). You could also look for other CAReplicatorLayer examples online. – Kendall Helmstetter Gelner Mar 31 '11 at 19:29
  • Hm, one thing didn't really get clear for me from the things i read about it... Can you make them fly in and 'wave' seperately? It seemed like the replicatorlayer would apply the same transformation to all elements, but will it apply them at all at the same time? Please check the youtube link in my original post to see what i mean ;) – Erik S Apr 01 '11 at 06:34
  • I don't have enough direct experience to say so, but I think it would work... however you may also want to look at Cocos2D which I think includes a particle system as well. – Kendall Helmstetter Gelner Apr 01 '11 at 20:06
  • Can i simply use Cocos2D within one layer of my app? When you start reading their beginner's guide it starts explaining about those scenes and stuff right away, while i just want it to draw things within one view (and its subviews, that is). – Erik S Apr 01 '11 at 23:40
  • You should be able to use Cocos2D within one window, although I'm not sure how to set that up. Any view can have an OpenGL backing... – Kendall Helmstetter Gelner Apr 02 '11 at 17:03
4

Cocos2D is a 2D graphics engine that uses OpenGL ES 1 for rendering. It comes with a built-in particle system. The code of the particle engine is quite simple. It uses VBOs to draw textured quads for the particles. You should be able to adapt that to your own needs.

Hollance
  • 2,958
  • 16
  • 15
  • upvoted! I use it on apps mixing OpenGL and UIKit, works perfectly and is easy to setup, and tune to achieve desired effect! AFAIK, CoreAnimation = CPU, which should bring lower FPS at moving sprites... – Vincent Guerci Apr 01 '11 at 19:06
  • @vincent that's right, CA is (more) CPU based and brings terrible FPS soon ;) Problem is i had always read that you should stay away from cocos2d if you're not making a game, possibly for battery concerns. – Erik S Apr 03 '11 at 09:55
  • @Erik I doubt that making the same algorithm involving drawing using CPU will consume less battery than using a specialized GPU... – Vincent Guerci Apr 03 '11 at 10:00
  • True that... Thought it might've been because it was faster, but now im thinking of it again after a night of sleep it sounds like bullshit indeed. Probably just has to do with complexity of CA (or usually, just very simple UIView animations) vs Cocos2d? – Erik S Apr 03 '11 at 14:38
0

If you want to target iOS5 and above, you can use the built-in facilities of the OS, which is the CAEmitterLayer.

DrMickeyLauer
  • 4,455
  • 3
  • 31
  • 67