iPhone アプリくるまの順番

Startを押すと、車が3台通ります。通った車と同じ順番で、同じ色のボタンを押していこう!という感じの教育iPhoneアプリを作ってみます。


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

ポイント
車の通る順番をArrayに入れておいて、この順序でanimationの設定を調整しています。信号を模したボタンを押した順番を入れておくArrayも用意しておいて、ボタンを3階押したタイミングで、車の順番と比較するようにしました。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    NSMutableArray *colorOrder;

    NSMutableArray *colorAnswer;

    int counter;

    UILabel *btn;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [self color:4];

    [self createCheckerBackground];

    [self createButton];

}

– (UIView*)createCar:(UIColor*)color

{

    float w = 100.0;

    float h = 100.0 / 1.618;

    UIView *car = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, h)];

    car.backgroundColor = [UIColor clearColor];

    [self.view addSubview:car];

    

    UIView *top = [[UIView alloc] initWithFrame:CGRectMake(w * 0.2, 0, w*0.6, h * 0.3)];

    top.backgroundColor = color;

    [car addSubview:top];

    

    UIView *body = [[UIView alloc] initWithFrame:CGRectMake(0, h*0.3, w, h*0.5)];

    body.backgroundColor = top.backgroundColor;

    [car addSubview:body];

    CGPoint p[2] = {CGPointMake(w * 0.2, h* 0.8), CGPointMake(w * 0.8, h* 0.8)};

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

        UIView *tire = [[UIView alloc] initWithFrame:CGRectMake(0, 0, h * 0.4, h*0.4)];

        tire.center = p[i];

        tire.backgroundColor = [UIColor blackColor];

        tire.layer.cornerRadius = h * 0.2;

        [car addSubview:tire];

    }

    

    return car;

}

– (void)createButton

{

    btn = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 280, 100)];

    btn.center = CGPointMake(160, 450);

    btn.text = @”start”;

    btn.textColor = [UIColor whiteColor];

    btn.textAlignment = NSTextAlignmentCenter;

    btn.font = [UIFont fontWithName:@”Marker Felt” size:40];

    btn.backgroundColor = [UIColor blackColor];

    [self.view addSubview:btn];

    

    btn.userInteractionEnabled = YES;

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

    [btn addGestureRecognizer:tap];

}

– (void)start:(UITapGestureRecognizer*)gr

{

    [gr removeTarget:self action:@selector(start:)];

    gr.view.layer.zPosition = 100;

    [self go];

    

    [UIView animateWithDuration:0.3 animations:^{

        gr.view.layer.transform = CATransform3DMakeRotation(M_PI/2.0, 1, 0, 0);

    } completion:^(BOOL finished) {

        [(UILabel*)gr.view setText:nil];

        [gr.view addSubview:[self createSignal]];

        

        [UIView animateWithDuration:0.3 animations:^{

            gr.view.layer.transform = CATransform3DIdentity;

        }];

    }];

}

– (UIView*)createSignal

{

    UIView *signal = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 280, 100)];

    signal.backgroundColor = [UIColor clearColor];

    

    UIView *green = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 80, 80)];

    green.backgroundColor = [self color:1];

    green.layer.cornerRadius = 40;

    [signal addSubview:green];

    

    UIView *yellow = [[UIView alloc] initWithFrame:CGRectMake(100, 10, 80, 80)];

    yellow.backgroundColor = [self color:0];

    yellow.layer.cornerRadius = 40;

    [signal addSubview:yellow];

    

    UIView *red = [[UIView alloc] initWithFrame:CGRectMake(190, 10, 80, 80)];

    red.backgroundColor = [self color:3];

    red.layer.cornerRadius = 40;

    [signal addSubview:red];

    

    NSArray *colorBtns = @[green, yellow, red];

    for (UIView *v in colorBtns) {        

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

        [v addGestureRecognizer:tap];

    }

    

    return signal;

}

– (void)selectBtn:(UITapGestureRecognizer*)gr

{

    gr.view.userInteractionEnabled = NO;

    gr.view.layer.zPosition = 101;

    

    if (!colorAnswer) {

        colorAnswer = [[NSMutableArray alloc] init];

    }

    [colorAnswer addObject:gr.view.backgroundColor];

    

    gr.view.center = [btn convertPoint:gr.view.center toView:self.view];

    [self.view addSubview:gr.view];

    float points[3] = {60, 160, 260};

    float x = points[counter];

    [self.view addSubview:gr.view];

    [UIView animateWithDuration:0.5 animations:^{

        gr.view.center = CGPointMake(x, 180);

    }];

    counter++;

    

    if (counter > 2) {

        [[btn.subviews objectAtIndex:0] removeFromSuperview];

        [self check];

    }

}

– (void)check

{

    BOOL correct = YES;

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

        UIColor *a = [colorOrder objectAtIndex:i];

        UIColor *b = [colorAnswer objectAtIndex:i];

        

        if (![a isEqual:b]) {

            correct = NO;

        }

    }

    

    if (correct) {

        btn.text = @”OK!”;

    } else {

        btn.text = @”Miss!”;

    }

    

    // restart

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

}

– (void)restart

{

    counter = 0;

    colorAnswer = nil;

    colorOrder = nil;

    self.view.layer.sublayers = nil;

    

    [self createCheckerBackground];

    [self createButton];

}

– (void)go

{

    NSMutableArray *colors = [@[[self color:1], [self color:0], [self color:3]] mutableCopy];

    colorOrder = [[NSMutableArray alloc] init];

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

        UIColor *color = [colors objectAtIndex:arc4random() % [colors count]];

        [colorOrder addObject:color];

        [colors removeObject:color];

        

        UIView *car = [self createCar:color];

        car.center = CGPointMake(-300, 160);

        

        [UIView animateWithDuration:1.5 + i animations:^{

            car.center = CGPointMake(600, 160);

        }];

    }

}

– (void)createCheckerBackground

{

    UIBezierPath *path = [UIBezierPath bezierPath];

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

        if (i%2) {

            continue;

        }

        float x = (i % 9) * 40;

        float y = (i / 9) * 40;

        [path appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(x, y, 40, 40)]];

    }

    

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

    sl.fillColor = [self color:2].CGColor;

    sl.path = path.CGPath;

    sl.opacity = 0.3;

    

    [self.view.layer addSublayer:sl];

}

#define UIColorHex(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0xFAC744);

        case 1:

            return UIColorHex(0x70AF42);

        case 2:

            return UIColorHex(0x1F7089);

        case 3:

            return UIColorHex(0xDF1F29);

        case 4:

            return UIColorHex(0xF5EBCA);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end