Created
February 27, 2013 03:44
-
-
Save tyrone-sudeium/5044864 to your computer and use it in GitHub Desktop.
Cloudsdale's fireworks background view.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FireworksView.m | |
// Cloudsdale | |
// | |
// Created by Tyrone Trevorrow on 24/05/12. | |
// Copyright (c) 2012 Cloudsdale. All rights reserved. | |
// | |
#import <QuartzCore/QuartzCore.h> | |
#import "FireworksView.h" | |
@interface FireworksView () | |
@property (nonatomic, strong) CALayer *rootLayer; | |
@property (nonatomic, strong) CAEmitterLayer *mortor; | |
@property (nonatomic, strong) NSTimer *fireworkTimer; | |
- (void) setup; | |
@end | |
@implementation FireworksView | |
@synthesize rootLayer, mortor, fireworkTimer; | |
- (id) init | |
{ | |
self = [super init]; | |
if (self) { | |
[self startAfterDelay: 1.0]; | |
} | |
return self; | |
} | |
- (id) initWithFrame:(CGRect)frame | |
{ | |
self = [super initWithFrame: frame]; | |
if (self) { | |
[self startAfterDelay: 1.0]; | |
} | |
return self; | |
} | |
-(void)awakeFromNib | |
{ | |
[self startAfterDelay: 1.0]; | |
} | |
- (void) startAfterDelay: (NSTimeInterval) delay | |
{ | |
[NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(setup) object: nil]; | |
[self performSelector: @selector(setup) withObject: nil afterDelay: delay]; | |
} | |
- (void) fireworkTimerAction | |
{ | |
self.mortor.birthRate = 1; | |
double delayInSeconds = 0.00001; | |
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); | |
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ | |
self.mortor.birthRate = 0; | |
}); | |
} | |
- (void) setup | |
{ | |
//Create the root layer | |
self.rootLayer = [CALayer layer]; | |
//Set the root layer's attributes | |
self.rootLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height); | |
self.rootLayer.backgroundColor = [UIColor colorWithWhite: 0.0 alpha: 0.0].CGColor;; | |
//Load the spark image for the particle | |
id img = (id) [UIImage imageNamed: @"Sparkle.png"].CGImage; | |
self.mortor = [CAEmitterLayer layer]; | |
self.mortor.emitterPosition = CGPointMake(self.rootLayer.bounds.size.width / 2.0, self.rootLayer.bounds.size.height); | |
self.mortor.renderMode = kCAEmitterLayerAdditive; | |
self.mortor.speed = 1.0; | |
//self.mortor.birthRate = 0; | |
//Invisible particle representing the rocket before the explosion | |
CAEmitterCell *rocket = [CAEmitterCell emitterCell]; | |
rocket.emissionLongitude = (3 * M_PI) / 2; | |
rocket.emissionLatitude = 0; | |
rocket.lifetime = 1.2; | |
rocket.birthRate = 1; | |
rocket.velocity = 400; | |
rocket.velocityRange = 200; | |
rocket.yAcceleration = 250; | |
rocket.emissionRange = M_PI / 4; | |
rocket.color = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.5].CGColor;; | |
rocket.redRange = 0.5; | |
rocket.greenRange = 0.5; | |
rocket.blueRange = 0.5; | |
//Name the cell so that it can be animated later using keypath | |
[rocket setName:@"rocket"]; | |
//Flare particles emitted from the rocket as it flys | |
CAEmitterCell *flare = [CAEmitterCell emitterCell]; | |
flare.contents = img; | |
flare.emissionLongitude = (4 * M_PI) / 2; | |
flare.scale = 0.4; | |
flare.velocity = 100; | |
flare.birthRate = 45; | |
flare.lifetime = 1.5; | |
flare.yAcceleration = -350; | |
flare.emissionRange = M_PI / 7; | |
flare.alphaSpeed = -0.7; | |
flare.scaleSpeed = -0.1; | |
flare.scaleRange = 0.1; | |
flare.beginTime = 0.01; | |
flare.duration = 0.7; | |
//The particles that make up the explosion | |
CAEmitterCell *firework = [CAEmitterCell emitterCell]; | |
firework.contents = img; | |
firework.birthRate = 3000; | |
firework.scale = 0.6; | |
firework.velocity = 90; | |
firework.lifetime = 2; | |
firework.alphaSpeed = -0.2; | |
firework.yAcceleration = 80; | |
firework.beginTime = 1.1; | |
firework.duration = 0.1; | |
firework.emissionRange = 2 * M_PI; | |
firework.scaleSpeed = -0.1; | |
firework.spin = 2; | |
//Name the cell so that it can be animated later using keypath | |
[firework setName:@"firework"]; | |
//preSpark is an invisible particle used to later emit the spark | |
CAEmitterCell *preSpark = [CAEmitterCell emitterCell]; | |
preSpark.birthRate = 80; | |
preSpark.velocity = firework.velocity * 0.70; | |
preSpark.lifetime = 1.7; | |
preSpark.yAcceleration = firework.yAcceleration * 0.85; | |
preSpark.beginTime = firework.beginTime - 0.2; | |
preSpark.emissionRange = firework.emissionRange; | |
preSpark.greenSpeed = 100; | |
preSpark.blueSpeed = 100; | |
preSpark.redSpeed = 100; | |
//Name the cell so that it can be animated later using keypath | |
[preSpark setName:@"preSpark"]; | |
//The 'sparkle' at the end of a firework | |
CAEmitterCell *spark = [CAEmitterCell emitterCell]; | |
spark.contents = img; | |
spark.lifetime = 0.05; | |
spark.yAcceleration = -250; | |
spark.beginTime = 0.8; | |
spark.scale = 0.4; | |
spark.birthRate = 10; | |
preSpark.emitterCells = [NSArray arrayWithObjects:spark, nil]; | |
rocket.emitterCells = [NSArray arrayWithObjects:flare, firework, preSpark, nil]; | |
self.mortor.emitterCells = [NSArray arrayWithObjects:rocket, nil]; | |
[self.rootLayer addSublayer:mortor]; | |
[self.layer addSublayer: self.rootLayer]; | |
} | |
- (void) dealloc | |
{ | |
[self.fireworkTimer invalidate]; | |
self.fireworkTimer = nil; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment