バクダン、えんぴつ、砂時計、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