Christmas Tree の電飾ぽいエフェクトのメモ

(XcodeのiOS6 Simlatorで試しています。)

ポイント

・切り絵てきにViewを貼ってツリーの形に(緑のとこ)

・ライトは、タイマーでランダムにピカピカ光らせる

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    NSTimer *timer;

}

@property (nonatomic, strong) NSMutableArray *lights;

@end

@implementation ViewController

@synthesize lights;

– (void)viewDidLoad

{

    [super viewDidLoad];

}

#define TopFloor 7

#define LeefSize 23

#define Margin 2

– (void)viewDidAppear:(BOOL)animated

{

    CGPoint center = CGPointMake(self.view.center.x, self.view.center.y);

    

    // Wood

    // 茶色

    UIView *wood = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 100)];

    wood.backgroundColor = [UIColor brownColor];

    wood.center = CGPointMake(center.x, center.y + 150);

    [self.view addSubview:wood];

    

    // Tree

    // 緑の部分

    // 擬似的にViewを散らして三角っぽく

    NSMutableArray *leafs = [[NSMutableArray alloc] init];

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

        

        float size = LeefSize + Margin;

        

        float y = center.y + i * size;

        float x = center.x – (i * size / 2); //左端の調整

        

        for (int j=0; j<i+1; j++) {

            UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, LeefSize, LeefSize)];

            

            v.center = CGPointMake(x + j*size, y);

            v.backgroundColor = [UIColor greenColor];

            [leafs addObject:v];

            [self.view addSubview:v];

        }

    }

    

    

    // ライト

    self.lights = [[NSMutableArray alloc] init];

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

        UIView *l = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];

        l.backgroundColor = [UIColor yellowColor];

        l.center = [self randomPositionInViewArea:leafs];

        [self.view addSubview:l];

        

        [self.lights addObject:l];

    }

    

    // 点滅

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

    [timer fire];

}

– (CGPoint)randomPositionInViewArea:(NSArray*)views

{

    // 座標の範囲を計算

    CGPoint max = CGPointMake(0, 0);

    CGPoint min = CGPointMake(1000, 1000);

    for (UIView *v in views) {

        

        float vx = v.frame.origin.x + v.frame.size.width;

        if (vx > max.x) {

            max.x = vx;

        }

        

        if (v.frame.origin.x < min.x) {

            min.x = v.frame.origin.x;

        }

        

        float vy = v.frame.origin.y + v.frame.size.height;

        if (vy > max.y) {

            max.y = vy;

        }

        

        if (v.frame.origin.y < min.y) {

            min.y = v.frame.origin.y;

        }

    }

    

    // 上記範囲内のランダム座標を取得

    float x = min.x + (max.x – min.x) * 0.01 * (arc4random() % 100);

    float y = min.y + (max.y – min.y) * 0.01 * (arc4random() % 100);

    CGPoint result = CGPointMake(x, y);

    

    // 座標がViewにのっているか確認    

    for (UIView *v in views) {

        CGPoint local = [self.view convertPoint:result toView:v];

        if ([v pointInside:local withEvent:nil]) {

            return result;

        }

    }

    

    // のっていなかったら再帰

    return [self randomPositionInViewArea:views];

}

– (void)lightControl

{

    for (UIView *v in self.lights) {

        

        // color change

        NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor blueColor], [UIColor purpleColor], [UIColor yellowColor], [UIColor yellowColor], [UIColor yellowColor], nil];

        v.backgroundColor = [colors objectAtIndex:arc4random() % 6];

        

        // 0 ~ 1秒のどこかで1秒点灯させる

        int xMsec = arc4random() % 2000;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, xMsec * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{

            [UIView animateWithDuration:0.8 animations:^{

                v.alpha = 1.0;

            } completion:^(BOOL finished) {

                [UIView animateWithDuration:0.8 animations:^{

                    v.alpha = 0.4;

                }];

            }];

        });

        

    }

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end