iPhone蚊取り線香アプリ

ボタンを押すと、ブタさんの口の中においた蚊取り線香が燃えていく、というiPhoneアプリを作ってみます。


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

ポイント
10秒くらいで燃え尽きるようにします。蚊取り線香は、UIBezierPathを使って螺旋状に書いています。CAShapeLayerは緑色用、燃え尽きた灰色用、燃えている赤色の3つをよういして、CABasicAnimationを使って燃えた感じを出すようにしました。

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    CAShapeLayer *sl;

    UIBezierPath *path;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor brownColor];

    

    [self createKatoriSenko];

    

    [self createPigBox];

    

    [self createButton];

}

– (void)createKatoriSenko

{

    path = [[UIBezierPath alloc] init];

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

    float d = M_PI / 180.0;

    float r = 10;

    float th = 0;

    float a = 0.7;

    for (int i = 0; i<360 * 4; i++) {

        float x = r * pow(th, a) * cos(th) + 160;

        float y = r * pow(th, a) * sin(th) + 300;

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

        th += d;

    }

    

    sl = [[CAShapeLayer alloc] init];

    sl.fillColor = [UIColor clearColor].CGColor;

    sl.strokeColor = [UIColor greenColor].CGColor;

    sl.lineWidth = 10;

    sl.path = path.CGPath;

    

    sl.transform = CATransform3DMakeRotation(M_PI * 0.3, 1, 0, 0);

    sl.zPosition = 100;

    [self.view.layer addSublayer:sl];

}

– (void)createPigBox

{

    UIView *box = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];

    box.backgroundColor = [UIColor colorWithRed:1 green:0.7 blue:0.7 alpha:1];

    [self.view addSubview:box];

    

    UIView *nose = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 220, 220)];

    nose.center = CGPointMake(160, 170);

    nose.layer.cornerRadius = 110;

    nose.backgroundColor = [UIColor blackColor];

    nose.layer.borderColor = [UIColor colorWithRed:1 green:0.6 blue:0.6 alpha:1].CGColor;

    nose.layer.borderWidth = 20;

    [box addSubview:nose];

    

    

    CGRect p[] = {CGRectMake(50, 20, 40, 40), CGRectMake(230, 20, 40, 40)};

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

        UIView *eye = [[UIView alloc] initWithFrame:p[i]];

        eye.layer.cornerRadius = 20;

        eye.backgroundColor = [UIColor blackColor];

        [box addSubview:eye];

    }

    

    

    CGRect p2[] = {CGRectMake(20, 300, 40, 40), CGRectMake(260, 300, 40, 40)};

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

        UIView *foot = [[UIView alloc] initWithFrame:p2[i]];

        foot.backgroundColor = box.backgroundColor;

        [box addSubview:foot];

    }

    

}

– (void)createButton

{

    float w = 220;

    float h = w / 1.618;

    UILabel *startBtn = [[UILabel alloc] initWithFrame:CGRectMake(50, 370, w, h)];

    startBtn.layer.borderColor = [UIColor whiteColor].CGColor;

    startBtn.layer.borderWidth = 10;

    startBtn.backgroundColor = self.view.backgroundColor;

    startBtn.text = @”Fire”;

    startBtn.textAlignment = NSTextAlignmentCenter;

    startBtn.textColor = [UIColor whiteColor];

    startBtn.font = [UIFont fontWithName:@”Marker Felt” size:80];

    [self.view addSubview:startBtn];

    

    startBtn.userInteractionEnabled = YES;

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fire)];

    [startBtn addGestureRecognizer:tap];

}

– (void)fire

{

    CAShapeLayer *red = [[CAShapeLayer alloc] init];

    red.fillColor = [UIColor clearColor].CGColor;

    red.strokeColor = [UIColor redColor].CGColor;

    red.lineWidth = sl.lineWidth;

    red.transform = sl.transform;

    red.path = path.CGPath;

    red.strokeStart = 0;

    red.strokeEnd = 0.01;

    red.zPosition = 101;

    CABasicAnimation *strokeS = [CABasicAnimation animationWithKeyPath:@”strokeStart”];

    strokeS.fromValue = @0.98;

    strokeS.toValue = @0;

    

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

    strokeE.fromValue = @1.0;

    strokeE.toValue = @0.02;

    

    CAAnimationGroup *group = [CAAnimationGroup animation];

    group.duration = 10.0;

    group.animations = [NSArray arrayWithObjects:strokeS, strokeE, nil];

    

    [red addAnimation:group forKey:nil];

    

    

    CAShapeLayer *ash = [[CAShapeLayer alloc] init];

    ash.fillColor = [UIColor clearColor].CGColor;

    ash.strokeColor = [UIColor lightGrayColor].CGColor;

    ash.lineWidth = sl.lineWidth;

    ash.transform = sl.transform;

    ash.path = path.CGPath;

    ash.strokeStart = 0;

    ash.strokeEnd = 1;

    ash.zPosition = 101;

    

    

    CABasicAnimation *toashes = [CABasicAnimation animationWithKeyPath:@”strokeStart”];

    toashes.fromValue = @1;

    toashes.toValue = @0;

    toashes.duration = 10.1;

    [ash addAnimation:toashes forKey:nil];

    

    [self.view.layer addSublayer:red];

    [self.view.layer addSublayer:ash];

    

    [self performSelector:@selector(restart) withObject:nil afterDelay:12];

}

– (void)restart

{

    self.view.layer.sublayers = nil;

    [self createKatoriSenko];

    [self createPigBox];

    [self createButton];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end