iPhone 雨と傘で色あわせゲーム

あか、あお、みどり、きいろ、4色の雨がふってくるよ。おなじ色のかさで雨をうけとめてみよう。下に色がドンドンたまっていくよ〜。という感じで、おなじ色とちがう色の感覚を学んでもらう子供向けiPhoneゲームのサンプルを書いてみます。

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

ポイント
雨は、画面の上から色のついた雲がでてきて、同じ色の雨粒を一滴だけ降らせて消えていくようにしました。雨と雲はタイマーで動くようにしています。かさはUIPangestureRecognizerを使って、指で動かすと隣と入れ替わるようにしています。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

#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]

@interface ViewController () {

    UIView *scoreBar;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

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

    [self createUmbrellas];

    

    [self createScoreBar];

    

    [self start];

}

– (void)createUmbrellas

{

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

        UIView *umbrella = [self createumbrella:[self colorTheme:i]];

        umbrella.center = CGPointMake(64 * i + 64, 350);

        [self.view addSubview:umbrella];

    }

}

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

{

    UIView *umbrella = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

    umbrella.layer.masksToBounds = NO;

    umbrella.tag = 1;

    [self.view addSubview:umbrella];

    

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(0, 25)];

    [path addArcWithCenter:CGPointMake(25, 25) radius:25 startAngle:M_PI endAngle:0 clockwise:YES];

    [path addLineToPoint:CGPointMake(0, 25)];

    // top

    [path moveToPoint:CGPointMake(25, –5)];

    [path addLineToPoint:CGPointMake(25, 0)];

    // stick

    [path moveToPoint:CGPointMake(25, 25)];

    [path addLineToPoint:CGPointMake(25, 40)];

    [path addArcWithCenter:CGPointMake(30, 40) radius:5 startAngle:M_PI endAngle:0 clockwise:NO];

    

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

    sl.strokeColor = color.CGColor;

    sl.lineWidth = 3;

    sl.path = path.CGPath;

    [umbrella.layer addSublayer:sl];

    

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(replace:)];

    pan.maximumNumberOfTouches = 1;

    [umbrella addGestureRecognizer:pan];

    

    return umbrella;

}

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

{

    CGPoint points[] = {

        CGPointMake(50, 50),

        CGPointMake(10, 50), CGPointMake(30, 30),

        CGPointMake(50, 20), CGPointMake(70, 30),

        CGPointMake(90, 50), CGPointMake(70, 70),

        CGPointMake(50, 80), CGPointMake(30, 70),};

    

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

    [self.view addSubview:cloud];

    

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

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

        circle.center = points[i];

        circle.backgroundColor = color;

        circle.layer.cornerRadius = 20;

        [cloud addSubview:circle];

    }

    

    cloud.transform = CGAffineTransformMakeScale(0.3, 0.2);

    

    return cloud;

}

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

{

    UIView *raindrop = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];

    [self.view addSubview:raindrop];

    

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path moveToPoint:CGPointMake(10, 0)];

    [path addCurveToPoint:CGPointMake(10, 20) controlPoint1:CGPointMake(10, 3) controlPoint2:CGPointMake(20, 15)];

    [path addCurveToPoint:CGPointMake(10, 0) controlPoint1:CGPointMake(0, 15) controlPoint2:CGPointMake(10, 3)];

    

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

    sl.fillColor = color.CGColor;

    sl.path = path.CGPath;

    

    [raindrop.layer addSublayer:sl];

    return raindrop;

}

#pragma mark – gesture

– (void)replace:(UIPanGestureRecognizer*)gr

{

    CGPoint p = [gr locationInView:self.view];

    gr.view.transform = CGAffineTransformMakeTranslation(p.x – gr.view.center.x, 0);

    for (UIView *v in self.view.subviews) {

        if (v.tag == 1) {

            if ((gr.view.center.x > v.center.x && p.x < v.center.x)

                || (gr.view.center.x < v.center.x && p.x > v.center.x)) {

                CGPoint o = gr.view.center;

                gr.view.center = v.center;

                v.center = o;

                gr.view.transform = CGAffineTransformMakeTranslation(p.x – gr.view.center.x, 0);

            }

        }

    }

    

    if (gr.state == UIGestureRecognizerStateEnded) {

        gr.view.transform = CGAffineTransformIdentity;

    }

}

– (void)start

{

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

}

– (void)tick:(NSTimer*)sender

{

    int position = arc4random() % 4 + 1;

    

    UIColor *color = [self colorTheme:arc4random() % 4];

    UIView *cloud = [self createCloud:color];

    cloud.center = CGPointMake(64 * position , 0);

    [self.view addSubview:cloud];

    

    [UIView animateWithDuration:3.0 animations:^{

        CGAffineTransform t = CGAffineTransformMakeTranslation(0, 50);

        t = CGAffineTransformScale(t, 0.6, 0.4);

        cloud.transform = t;

    } completion:^(BOOL finished) {

        [cloud removeFromSuperview];

        

        UIView *drop = [self createRaindrop:color];

        drop.center = CGPointMake(cloud.center.x, 100);

        [self.view addSubview:drop];

        

        [UIView animateWithDuration:2.0 animations:^{

            drop.center = CGPointMake(drop.center.x, 320);

        } completion:^(BOOL finished) {

            for (UIView *v in self.view.subviews) {

                if (v.tag == 1) {

                    if (CGRectIntersectsRect(v.frame, drop.frame)) {

                        

                        [self checkColorMatch:v drop:drop];

                    }

                }

            }

            [drop removeFromSuperview];

        }];

    }];

}

– (void)checkColorMatch:(UIView*)ambrella drop:(UIView*)drop

{

    CAShapeLayer *aLayer = [ambrella.layer.sublayers objectAtIndex:0];

    CAShapeLayer *dLayer = [drop.layer.sublayers objectAtIndex:0];

    if (CGColorEqualToColor(aLayer.strokeColor, dLayer.fillColor)) {

        [self scoreUp:[UIColor colorWithCGColor:dLayer.fillColor]];

    } else {

        [self scoreDown];

    }

}

– (void)createScoreBar{

    scoreBar = [[UIView alloc] initWithFrame:CGRectMake(0, 400, 320, 50)];

    scoreBar.layer.borderColor = [UIColor darkGrayColor].CGColor;

    scoreBar.layer.borderWidth = 2;

    [self.view addSubview:scoreBar];

}

– (void)scoreUp:(UIColor*)color

{

    UIView *last = [scoreBar.subviews lastObject];

    float x = last.frame.origin.x + last.frame.size.width;

    if (x < 320) {

        UIView *up = [[UIView alloc] initWithFrame:CGRectMake(x, 0, 20, 50)];

        up.backgroundColor = color;

        [scoreBar addSubview:up];

    }

}

– (void)scoreDown

{

    [[scoreBar.subviews lastObject] removeFromSuperview];

}

– (UIColor*)colorTheme:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0x0088FF);

        case 1:

            return UIColorHex(0xFF0066);

        case 2:

            return UIColorHex(0x00CC00);

        case 3:

            return UIColorHex(0xFFBB00);

        case 4:

            return UIColorHex(0x212121);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end