iPhone 足し算ボール

まんなかにある色が違うボールに書いてある数字と同じになるように、したの何も無い枠の中に、ボールを集めていこう!という感じで足し算の勉強をするiPhoneアプリを作ってみます。


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

ポイント
今回は、便利メソッドとして、UIViewにグラデーション付け、UIViewにドットで丸角のボーダーライン、NAMutableArrayのシャッフルを切り分けてみました。シャッフルした、1から25までの数字を入れたArrayをつくったメソッドでシャッフルした後に、縦横5×5でならべました。

サンプルコード

#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 () {

    int answer;

    int ball;

    UIView *ballBox;

    NSMutableArray *ballsInBox;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    [self addGradientLayer:self.view color1:[self color:2] color2:[self color:3]];

    

    [self createAnswer];

    

    [self createBallBox];

    

    [self createNumbers];

}

– (void)createNumbers

{

    UIView *numbersFrame = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 300, 300)];

    [self addDotBorder:numbersFrame];

    [self.view addSubview:numbersFrame];

    

    // create numbers and shuffle

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

    for (int i=1; i<26; i++) {

        [arr addObject:@(i)];

    }

    [self shuffle:arr];

    

    // 配置

    for (int i=0; i<[arr count]; i++) {

        int number = [[arr objectAtIndex:i] intValue];

        float size = 300.0 / 5.5;

        float x = (i % 5) * size + size/4.0 + 10;

        float y = (i / 5) * size + size/4.0 + 10;

        

        UIView *num = [[UIView alloc] initWithFrame:CGRectMake(x, y, size, size)];

        

        num.tag = number; // use check answer

        

        num.layer.masksToBounds = YES;

        num.layer.cornerRadius = size / 2.0;

        num.transform = CGAffineTransformMakeScale(0.9, 0.9);

        [self addGradientLayer:num color1:[self color:3] color2:[self color:4]];

        

        UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size, size)];

        l.text = [NSString stringWithFormat:@”%d”, number];

        l.font = [UIFont fontWithName:@”Marker Felt” size:size/2.8];

        l.textAlignment = NSTextAlignmentCenter;

        l.textColor = [self color:0];

        

        l.backgroundColor = [UIColor clearColor];

        [num addSubview:l];

        [self.view addSubview:num];

        

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

        [num addGestureRecognizer:pan];

    }

}

– (void)createAnswer

{

    // ready

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

    for (int i=1; i<26; i++) {

        [arr addObject:@(i)];

    }

    [self shuffle:arr];

    

    // ランダムに3つ足す

    answer = [[arr objectAtIndex:0] intValue];

    answer += [[arr objectAtIndex:1] intValue];

    answer += [[arr objectAtIndex:2] intValue];

    

    

    float size = 300.0 / 5.5;

    UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size * 1.2, size * 1.2)];

    aView.center = CGPointMake(160, 330 + size/2.0);

    [self addDotBorder:aView];

    [self.view addSubview:aView];

    

    UIView *num = [[UIView alloc] initWithFrame:CGRectMake(size*0.1, size*0.1, size, size)];

    num.layer.masksToBounds = YES;

    num.layer.cornerRadius = size / 2.0;

    num.transform = CGAffineTransformMakeScale(0.9, 0.9);

    [self addGradientLayer:num color1:[self color:1] color2:[self color:2]];

    [aView addSubview:num];

    

    UILabel *aL = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size, size)];

    aL.text = [NSString stringWithFormat:@”%d”, answer];

    aL.font = [UIFont fontWithName:@”Marker Felt” size:size/2.8];

    aL.textAlignment = NSTextAlignmentCenter;

    aL.textColor = [self color:0];

    aL.backgroundColor = [UIColor clearColor];

    [num addSubview:aL];

    

}

– (void)createBallBox

{

    

    float size = 300.0 / 5.5;

    float x = size * 1.5;

    float y = 340 + size * 1.2;

    ballBox = [[UIView alloc] initWithFrame:CGRectMake(x, y, size * 3, size*1.2)];

    [self addDotBorder:ballBox];

    [self.view addSubview:ballBox];

}

– (void)move:(UIPanGestureRecognizer*)gr

{

    CGPoint o = gr.view.center;

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

    

    [gr.view.superview addSubview:gr.view];

    

    gr.view.transform = CGAffineTransformMakeTranslation(p.x – o.x , p.y – o.y);

    

    if (gr.state == UIGestureRecognizerStateBegan) {

        [ballsInBox removeObject:gr.view];

    }

    

    

    if (gr.state == UIGestureRecognizerStateEnded

        || gr.state == UIGestureRecognizerStateCancelled) {

        

        if (!CGRectContainsPoint(ballBox.frame, p)) {

            gr.view.transform = CGAffineTransformMakeScale(0.9, 0.9);

            

        } else {

            // ball in box

            gr.view.transform = CGAffineTransformScale(gr.view.transform, 0.9, 0.9);

            

            // check answer

            [self checkAnswer:gr.view];

        }

    }

}

– (void)checkAnswer:(UIView*)v

{

    if (!ballsInBox) {

        ballsInBox = [[NSMutableArray alloc] init];

    }

    

    [ballsInBox addObject:v];

    

    int number = 0;

    for (UIView *v in ballsInBox) {

        number += v.tag;

    }

    

    if (answer == number) {

        [self gameClear];

    }

}

– (void)gameClear

{

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

        if (v.tag > 0) {

            [UIView animateWithDuration:0.3 animations:^{

                v.alpha = 0;

            } completion:^(BOOL finished) {

                self.view.layer.sublayers = nil;

                ballsInBox = nil;

                

                [self addGradientLayer:self.view color1:[self color:2] color2:[self color:3]];

                [self createAnswer];

                [self createBallBox];

                [self createNumbers];

            }];

        }

    }

}

#pragma mark – utility method

– (void)shuffle:(NSMutableArray*)arr

{

    NSUInteger count = [arr count];

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

        int nElements = count – i;

        int n = (arc4random() % nElements) + i;

        [arr exchangeObjectAtIndex:i withObjectAtIndex:n];

    }

}

– (void)addGradientLayer:(UIView*)view color1:(UIColor *)c1 color2:(UIColor*)c2

{

    CAGradientLayer *gradient = [CAGradientLayer layer];

    gradient.frame = view.bounds;

    gradient.colors = [NSArray arrayWithObjects:(id)[c1 CGColor], (id)[c2 CGColor], nil];

    [view.layer insertSublayer:gradient atIndex:0];

}

– (void)addDotBorder:(UIView*)view

{

    // dot frame

    UIBezierPath *path =[UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(10, 10)];

    

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

    sl.fillColor = [UIColor clearColor].CGColor;

    sl.strokeColor = [self color:0].CGColor;

    sl.lineWidth = 2;

    sl.lineDashPattern = @[@8,@3];

    sl.path = path.CGPath;

    

    [view.layer addSublayer:sl];

}

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0xCEF087);

        case 1:

            return UIColorHex(0xA8DBA8);

        case 2:

            return UIColorHex(0x79BD9A);

        case 3:

            return UIColorHex(0x3B8686);

        case 4:

            return UIColorHex(0x0B486B);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end