iPhone バリスタ気分

エスプレッソボタンとミルクボタンのついたエスプレッソマシンを使ってバリスタ気分を楽しむような簡単iPhoneゲームアプリを作ってみます。

動作イメージ

XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

ポイント
カップはUIBezierpathを使って書いています。内側にコーヒー(or ミルク)のUIViewを追加したときにはみ出さないようにLayerのMaskとしても同じpathを利用するようにしました。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    CGPoint nozzlePoint;

    UIView *cupA;

    int cupInCount;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor colorWithRed:1 green:1.0 blue:0.7 alpha:1.0];

    

    [self createEspressoMachine];

    

    cupA = [self createCup:CGRectMake(50, 200, 80, 60)];

    [self.view addSubview:cupA];

    

    [self createMenu];

}

– (void)createEspressoMachine

{

    UIView *machine = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 200, 280)];

    machine.backgroundColor = [UIColor clearColor];

    

    

    UIView *middle = [[UIView alloc] initWithFrame:CGRectMake(140, 20, 40, 240)];

    middle.backgroundColor = [UIColor grayColor];

    [machine addSubview:middle];

    

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

    top.backgroundColor = [UIColor redColor];

    top.layer.cornerRadius = 50;

    [machine addSubview:top];

    

    UIView *bottom = [[UIView alloc] initWithFrame:CGRectMake(0, 240, 200, 40)];

    bottom.backgroundColor = [UIColor redColor];

    bottom.layer.cornerRadius = 20;

    [machine addSubview:bottom];

    

    UIView *nozzle = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 20, 30)];

    nozzle.backgroundColor = [UIColor grayColor];

    [machine addSubview:nozzle];

    nozzlePoint = [machine convertPoint:nozzle.center toView:self.view];

    

    // button

    UIView *coffeBtn = [[UIView alloc] initWithFrame:CGRectMake(30, 50, 40, 40)];

    coffeBtn.backgroundColor = [UIColor brownColor];

    coffeBtn.layer.cornerRadius = 20;

    [machine addSubview:coffeBtn];

    

    UIView *milkBtn = [[UIView alloc] initWithFrame:CGRectMake(80, 50, 40, 40)];

    milkBtn.backgroundColor = [UIColor whiteColor];

    milkBtn.layer.cornerRadius = 20;

    [machine addSubview:milkBtn];

    

    

    NSArray *btns = @[coffeBtn, milkBtn];

    for (UIView *v in btns) {

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

        [v addGestureRecognizer:tap];

    }

    

    [self.view addSubview:machine];

}

– (void)createMenu

{

    UIView *coffee = [self createCup:CGRectMake(280, 50, 120, 90)];

    UIView *liquidOne = [[UIView alloc] initWithFrame:CGRectMake(0, 30, 90, 60)];

    liquidOne.backgroundColor = [UIColor brownColor];

    [coffee insertSubview:liquidOne atIndex:0];

    [self.view addSubview:coffee];

    

    UIView *coffeelatte = [self createCup:CGRectMake(420, 50, 120, 90)];

    UIView *liquidTwo = [[UIView alloc] initWithFrame:CGRectMake(0, 60, 90, 30)];

    liquidTwo.backgroundColor = [UIColor brownColor];

    UIView *liquidThree = [[UIView alloc] initWithFrame:CGRectMake(0, 30, 90, 30)];

    liquidThree.backgroundColor = [UIColor whiteColor];

    [coffeelatte insertSubview:liquidTwo atIndex:0];

    [coffeelatte insertSubview:liquidThree atIndex:0];

    [self.view addSubview:coffeelatte];

    

    UIView *milkCoffee = [self createCup:CGRectMake(280, 180, 120, 90)];

    UIView *liquidFour = [[UIView alloc] initWithFrame:CGRectMake(0, 60, 90, 30)];

    liquidFour.backgroundColor = [UIColor whiteColor];

    UIView *liquidFive = [[UIView alloc] initWithFrame:CGRectMake(0, 30, 90, 30)];

    liquidFive.backgroundColor = [UIColor brownColor];

    [milkCoffee insertSubview:liquidFour atIndex:0];

    [milkCoffee insertSubview:liquidFive atIndex:0];

    [self.view addSubview:milkCoffee];

    

    UIView *milk = [self createCup:CGRectMake(420, 180, 120, 90)];

    UIView *liquidM = [[UIView alloc] initWithFrame:CGRectMake(0, 30, 90, 60)];

    liquidM.backgroundColor = [UIColor whiteColor];

    [milk insertSubview:liquidM atIndex:0];

    [self.view addSubview:milk];

    

    coffee.tag = 1;

    coffeelatte.tag = 2;

    milkCoffee.tag = 3;

    milk.tag = 4;

}

– (void)pushButton:(UITapGestureRecognizer*)gr

{

    cupInCount ++;

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

    liquid.backgroundColor = gr.view.backgroundColor;

    liquid.layer.cornerRadius = 5;

    liquid.center = CGPointMake(nozzlePoint.x, nozzlePoint.y + 20);

    liquid.layer.anchorPoint = CGPointMake(0.5, 0);

    [self.view addSubview:liquid];

    

    [UIView animateWithDuration:0.3 animations:^{

        liquid.transform = CGAffineTransformMakeScale(1.0, 8.0);

    } completion:^(BOOL finished) {

        float y = cupA.frame.size.height * ((3.0cupInCount) / 3.0);

        float w = cupA.frame.size.width *  (3.0/4.0);

        float h = cupA.frame.size.height / 3.0;

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

        cupin.backgroundColor = gr.view.backgroundColor;

        [cupA insertSubview:cupin atIndex:0];

        

        cupin.layer.anchorPoint = CGPointMake(0.5, 1.0);

        cupin.layer.position = CGPointMake(cupin.layer.position.x, cupin.layer.position.y + cupin.bounds.size.height/2.0);

        cupin.transform = CGAffineTransformMakeScale(1.0, 0.1);

        

        [UIView animateWithDuration:0.3 animations:^{

            liquid.transform = CGAffineTransformMakeTranslation(0, 50);

            liquid.alpha = 0.3;

            cupin.transform = CGAffineTransformIdentity;

        } completion:^(BOOL finished) {

            [liquid removeFromSuperview];

            

            // check serve!

            if (cupInCount >= 2) {

                [UIView animateWithDuration:0.5 animations:^{

                    cupA.transform = CGAffineTransformMakeTranslation(-120, 0);

                } completion:^(BOOL finished) {

                    // reset cupA

                    cupInCount = 0;

                    [cupA removeFromSuperview];

                    cupA = [self createCup:CGRectMake(50, 200, 80, 60)];

                    [self.view addSubview:cupA];

                }];

            }

        }];

    }];

}

– (UIView*)createCup:(CGRect)rect

{

    UIBezierPath *path = [self cupPath:rect];

    

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

    sl.fillColor = [UIColor clearColor].CGColor;

    sl.strokeColor = [UIColor blackColor].CGColor;

    sl.lineWidth = rect.size.height * 0.06;

    sl.path = path.CGPath;

    

    // mask

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

    mask.fillColor = [UIColor blackColor].CGColor;

    mask.strokeColor = [UIColor blackColor].CGColor;

    mask.lineWidth = rect.size.height * 0.06;

    mask.path = path.CGPath;

    

    UIView *cup = [[UIView alloc] initWithFrame:rect];

    [cup.layer addSublayer:sl];

    cup.layer.mask = mask;

    return cup;

}

– (UIBezierPath*)cupPath:(CGRect)rect

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    float w = rect.size.width * (3.0/4.0);

    

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

    [path addLineToPoint:CGPointMake(0, rect.size.height * 0.6)];

    [path addQuadCurveToPoint:CGPointMake(w * 0.4, rect.size.height) controlPoint:CGPointMake(0, rect.size.height)];

    [path addLineToPoint:CGPointMake(w * 0.6, rect.size.height)];

    [path addQuadCurveToPoint:CGPointMake(w, rect.size.height * 0.6) controlPoint:CGPointMake(w, rect.size.height)];

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

    [path closePath];

    [path moveToPoint:CGPointMake(w, rect.size.height * 0.15)];

    [path addQuadCurveToPoint:CGPointMake(w, rect.size.height * 0.65) controlPoint:CGPointMake(rect.size.width * 1.2, rect.size.height * 0.25)];

    

    return path;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end