iPhoneせんこうはなび

暑い日が続く、夏なので線香花火がチカチカするようなiPhoneアプリを書いてみます。


動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    UIView *ball;

    NSTimer *timer;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor blackColor];

    [self createStick];

    [self createBackground];

}

– (void)createStick

{

    UIView *stick = [[UIView alloc] initWithFrame:CGRectMake(158, 0, 4, 250)];

    stick.backgroundColor = [UIColor greenColor];

    [self.view addSubview:stick];

    

    ball = [[UIView alloc] initWithFrame:CGRectMake(150, 250, 20, 20)];

    ball.backgroundColor = [UIColor orangeColor];

    ball.layer.cornerRadius = 10;

    [self.view addSubview:ball];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [self start];

}

– (void)start

{

    @synchronized(self) {

        if (!timer || ![timer isValid]) {

            timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(tick:) userInfo:nil repeats:YES];

            

            CABasicAnimation *twinkle = [CABasicAnimation animationWithKeyPath:@”opacity”];

            twinkle.duration = 0.5;

            twinkle.fromValue = @1.0;

            twinkle.toValue = @0.7;

            twinkle.autoreverses = YES;

            twinkle.repeatCount = 10;

            [ball.layer addAnimation:twinkle forKey:nil];

            

            [timer performSelector:@selector(invalidate) withObject:nil afterDelay:10];

        }

    }

}

– (void)tick:(NSTimer*)sender

{

    float angle = ((arc4random() % 36) / 18.0) * M_PI;

    float x = 120 * cos(angle) + 160;

    float y = 120 * sin(angle) + 260;

    

    UIBezierPath *path = [[UIBezierPath alloc] init];

    [path moveToPoint:CGPointMake(160, 260)];

    [path addLineToPoint:CGPointMake(x, y)];

    

    CAShapeLayer *sl = [CAShapeLayer layer];

    sl.strokeColor = CGColorCreateCopyWithAlpha([UIColor yellowColor].CGColor, 0.7);

    sl.lineWidth = 2;

    sl.path = path.CGPath;

    

    [self.view.layer addSublayer:sl];

    [self startDraw:sl];

    

    [self smallFire:[NSValue valueWithCGPoint:CGPointMake(x, y)]];

}

– (void)smallFire:(NSValue*)point

{

    CGPoint p = [point CGPointValue];

    for (int i=0; i<6; i++) {

        float angle = (arc4random() % 6) * (M_PI/3.0);

        float x = 40 * cos(angle) + p.x;

        float y = 40 * sin(angle) + p.y;

        UIBezierPath *path = [[UIBezierPath alloc] init];

        [path moveToPoint:CGPointMake(p.x, p.y)];

        [path addLineToPoint:CGPointMake(x, y)];

        CAShapeLayer *sl = [CAShapeLayer layer];

        sl.strokeColor = CGColorCreateCopyWithAlpha([UIColor yellowColor].CGColor, 0.7);

        sl.lineWidth = 1.5;

        sl.path = path.CGPath;

        [self.view.layer addSublayer:sl];

        [self startDraw:sl];

    }

}

– (void)startDraw:(CAShapeLayer*)l

{

    CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];

    a.duration = 0.1;

    a.fromValue = @0;

    a.toValue = @1;

    [l addAnimation:a forKey:@”strokeEnd”];

    

    if (l.strokeEnd == 0) {

        l.strokeEnd = 1.0;

    }

    

    [l performSelector:@selector(removeFromSuperlayer) withObject:nil afterDelay:0.15];

}

– (void)createBackground

{

    for (int i=0; i< 8 * 16; i++) {

        float x = (i % 8) * (320.0 / 8.0) + 18;

        float y = (i / 8) * (568.0 / 16.0);

        

        UIView *rhombus = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];

        rhombus.center = CGPointMake(x, y);

        rhombus.transform = CGAffineTransformMakeRotation(M_PI/4.0);

        rhombus.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2];

        [self.view addSubview:rhombus];

        

        UIView *inner = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 8)];

        inner.center = CGPointMake(x, y);

        inner.transform = CGAffineTransformMakeRotation(M_PI/4.0);

        inner.backgroundColor = [UIColor blackColor];

        [self.view addSubview:inner];

    }

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end