まんなかにある色が違うボールに書いてある数字と同じになるように、したの何も無い枠の中に、ボールを集めていこう!という感じで足し算の勉強をする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