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