0

I want to spawn some particles when my user drags their finger on the screen. I have all the drag code in place but my problem is that I simply can't see any particles drawing!

With a bit of googling I've come up with the following class that i've made a subclass of UIView:

#import "PrettyTouch.h"
#import <QuartzCore/QuartzCore.h>

@implementation PrettyTouch
{
    CAEmitterLayer* touchEmitter;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        touchEmitter = (CAEmitterLayer*) self.layer;
        touchEmitter.emitterPosition= CGPointMake(0, 0);
        touchEmitter.emitterSize = CGSizeMake(5,5);
        CAEmitterCell* touch = [CAEmitterCell emitterCell];
        touch.birthRate = 0;
        touch.lifetime = 0.6;
        touch.color = [[UIColor colorWithRed:0.2 green:0.3 blue:1.0 alpha:0.06] CGColor];
        touch.contents = (id)[[UIImage imageNamed:@"part.png"]CGImage];
        touch.velocity = 0;
        touch.velocityRange = 50;
        touch.emissionRange = 2*M_PI;
        touch.scale = 1.0;
        touch.scaleSpeed = -0.1;
        touchEmitter.renderMode = kCAEmitterLayerAdditive;
        touchEmitter.emitterCells = [NSArray arrayWithObject:touch];

    }
    return self;
}
+ (Class) layerClass 
{
    //tell UIView to use the CAEmitterLayer root class
    return [CAEmitterLayer class];
}

- (void) setEmitterPosition:(CGPoint)pos
{
    touchEmitter.emitterPosition = pos;
}
- (void) toggleOn:(bool)on
{
    touchEmitter.birthRate = on? 300 : 0;
}


@end

And then in my game view controller class, in viewDidLoad, i've done this:

@implementation PlayViewController
{
   //...
   PrettyTouch* touch;

}

- (void)viewDidLoad
{
    [super viewDidLoad];
    //...
    touch = [[PrettyTouch alloc]initWithFrame:self.view.frame];
    touch.hidden = NO;
    [self.view addSubview:touch];
    //...

And then in my UIPanGestureRecogniser function I call [touch toggleOn:YES]; when the gesture starts and [touch setEmitterPosition:[gest locationInView:self.view]]; whenever the function is called. (gest is the UIPanGestureRecogniser*).

What might I be missing or do I need to do to get the particle drawing?

Thank you

jackslash
  • 8,550
  • 45
  • 56
Holly
  • 1,956
  • 6
  • 41
  • 57

1 Answers1

3

There are two birthRate properties in play here.

  • Each CAEmitterCell has a birthRate property.
    This is the hardwired birthrate for that cell.

  • The CAEmitterLayer has a birthRate property.
    This is a multiplier applied to each cell's birthRate property to derive an actual birthrate in play.

Your code is confusing the two - you set the cells' birthRate to zero in your initialisation, but change the layer's birthRate multiplier in your toggle method.

Two solutions...

1 - in toggleOn: set the cell's birthRate, not the layer's multiplier:

- (void) toggleOn:(bool)on
  {
     CAEmitterCell* emitterCell = [self.touchEmitter.emitterCells objectAtIndex:0];
    [emitterCell setBirthRate:on? 300 : 0];
  }

2 - in your initialisation, set the cell's birthrate to nonzero:

    touch.birthRate = 1.0;

The multiplier you are using in toggleOn will then apply to this number.

foundry
  • 31,615
  • 9
  • 90
  • 125
  • Oh thank you so much for spotting that for me! While you're here I might as well ask, i'm using the [following image](http://i.imgur.com/2Efn9UO.png) and the particles look just like that with the square shape and black background. I thought using kCAEmitterLayerAdditive would make the image show just the shiney bit in an additive fashion, is there a way to get the image to work like that or should i just go make another png with transparency? Thanks in any case. – Holly Mar 14 '13 at 17:42
  • 1
    @Holly, your existing image will work if you give it something to composite on to: set a non-white background color with alpha 1.0 to your CAEmitterLayer, and it should behave as you expect. But a transparent brush is going to be more versatile (it would do the right thing without setting the background, for example) – foundry Mar 14 '13 at 18:36