iPhone絵合わせアプリの作り方

バクダン、えんぴつ、砂時計、3つの絵が。カードの中にかくれているよ。カードをめくって同じ絵を見つけていこう。という感じのiPhoneアプリの作り方を書いてみます。

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

ポイント
6枚のカードを横2枚、縦3枚にならべるようにしました。枚数も少ないので、NSArrayの中に、UIImageを2つずつ入れてそれをfor文でループさせることで絵柄を設定しています。カードをタップしたときの動きは、90°まわしたところで、画像を隠して、更に90°回転という流れでアニメーションをかけています。

サンプルコード

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

    NSMutableArray *cards;

    UIView *selected;

    int pairCount;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = UIColorHex(0x232326);

    

    [self createCards];

    

    [self shuffle];

}

– (void)createCards

{

    cards = [[NSMutableArray alloc] init];

    

    // images

    UIImage *timer = [UIImage imageNamed:@”timer”];

    UIImage *bomb = [UIImage imageNamed:@”bomb”];

    UIImage *pencil = [UIImage imageNamed:@”pencil”];

    

    NSMutableArray *imageNames = [@[timer, timer, bomb, bomb, pencil, pencil] mutableCopy];

    

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

        float x = (i % 2) * 150 + 35;

        float y = (i / 2) * 150 + 40;

        UIView *card = [[UIView alloc] initWithFrame:CGRectMake(x, y, 100, 120)];

        card.backgroundColor = UIColorHex(0x0B0B0D);

        card.layer.borderColor = UIColorHex(0xA69153).CGColor;

        card.layer.borderWidth = 10;

        card.layer.cornerRadius = 20;

        [self.view addSubview:card];

        

        int imageNo = arc4random() % [imageNames count];

        UIImage *image = [imageNames objectAtIndex:imageNo];

        UIImageView *iv = [[UIImageView alloc] initWithImage:image];

        iv.contentMode = UIViewContentModeScaleAspectFit;

        iv.frame = CGRectMake(0, 0, 80, 100);

        iv.center = CGPointMake(card.bounds.size.width/2.0, card.bounds.size.height/2.0);

        [card addSubview:iv];

        

        // remove used image

        [imageNames removeObjectAtIndex:imageNo];

        

        // to array

        [cards addObject:card];

    }

}

– (void)shuffle

{

    // hide all cards

    for (UIView *card in cards) {

        [self flipCard:card withCheck:NO];

    }

    

    // shuffle array

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

    int count = [cards count];

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

        int newIndex = arc4random() % [cards count];

        [buf addObject:[cards objectAtIndex:newIndex]];

        [cards removeObjectAtIndex:newIndex];

    }

    

    cards = buf;

    //new position

    

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

        float x = (i % 2) * 150 + 35;

        float y = (i / 2) * 150 + 40;

        UIView *card = [cards objectAtIndex:i];

        [UIView animateWithDuration:0.2 animations:^{

            card.frame = CGRectMake(x, y, 100, 120);

        }];

        

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

        [card addGestureRecognizer:tap];

    }

}

– (void)flip:(UITapGestureRecognizer*)gr

{

    [self flipCard:gr.view withCheck:YES];

}

– (void)flipCard:(UIView*)card withCheck:(BOOL)ready

{

    [UIView animateWithDuration:0.3 animations:^{

        card.layer.transform = CATransform3DRotate(card.layer.transform, M_PI/2.0, 0, 1, 0);

    } completion:^(BOOL finished) {

        

        // hide or show image

        UIImageView *iv = [card.subviews objectAtIndex:0];

        iv.alpha = iv.alpha * (-1);

        [UIView animateWithDuration:0.3 animations:^{

            card.layer.transform = CATransform3DRotate(card.layer.transform, M_PI/2.0, 0, 1, 0);

            

        } completion:^(BOOL finished) {

            if (ready) {

                // check

                [self check:card];

            }

        }];

    }];

}

– (void)check:(UIView*)v

{

    if (!selected) {

        selected = v;

        return;

    }

    

    UIImage *selectedImg = ((UIImageView*)[selected.subviews objectAtIndex:0]).image;

    UIImage *vImage = ((UIImageView*)[v.subviews objectAtIndex:0]).image;

    

    if (selectedImg == vImage) {

        // OK

        selected = nil;

        for (UIGestureRecognizer *gr in selected.gestureRecognizers) {

            [selected removeGestureRecognizer:gr];

        }

        for (UIGestureRecognizer *gr in selected.gestureRecognizers) {

            [selected removeGestureRecognizer:gr];

        }

        

        pairCount++;

        if (pairCount == 3) {

            // clear

            [self shuffle];

            pairCount = 0;

        }

        

        return;

    }

    

    // NG

    [self flipCard:selected withCheck:NO];

    [self flipCard:v withCheck:NO];

    selected = nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end