
あか、あお、みどり、きいろ、4色の雨がふってくるよ。おなじ色のかさで雨をうけとめてみよう。下に色がドンドンたまっていくよ〜。という感じで、おなじ色とちがう色の感覚を学んでもらう子供向けiPhoneゲームのサンプルを書いてみます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
雨は、画面の上から色のついた雲がでてきて、同じ色の雨粒を一滴だけ降らせて消えていくようにしました。雨と雲はタイマーで動くようにしています。かさはUIPangestureRecognizerを使って、指で動かすと隣と入れ替わるようにしています。
サンプルコード
#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 () {
UIView *scoreBar;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [self colorTheme:4];
[self createUmbrellas];
[self createScoreBar];
[self start];
}
– (void)createUmbrellas
{
for (int i=0; i<4; i++) {
UIView *umbrella = [self createumbrella:[self colorTheme:i]];
umbrella.center = CGPointMake(64 * i + 64, 350);
[self.view addSubview:umbrella];
}
}
– (UIView*)createumbrella:(UIColor*)color
{
UIView *umbrella = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
umbrella.layer.masksToBounds = NO;
umbrella.tag = 1;
[self.view addSubview:umbrella];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 25)];
[path addArcWithCenter:CGPointMake(25, 25) radius:25 startAngle:M_PI endAngle:0 clockwise:YES];
[path addLineToPoint:CGPointMake(0, 25)];
// top
[path moveToPoint:CGPointMake(25, –5)];
[path addLineToPoint:CGPointMake(25, 0)];
// stick
[path moveToPoint:CGPointMake(25, 25)];
[path addLineToPoint:CGPointMake(25, 40)];
[path addArcWithCenter:CGPointMake(30, 40) radius:5 startAngle:M_PI endAngle:0 clockwise:NO];
CAShapeLayer *sl = [[CAShapeLayer alloc] init];
sl.strokeColor = color.CGColor;
sl.lineWidth = 3;
sl.path = path.CGPath;
[umbrella.layer addSublayer:sl];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(replace:)];
pan.maximumNumberOfTouches = 1;
[umbrella addGestureRecognizer:pan];
return umbrella;
}
– (UIView*)createCloud:(UIColor*)color
{
CGPoint points[] = {
CGPointMake(50, 50),
CGPointMake(10, 50), CGPointMake(30, 30),
CGPointMake(50, 20), CGPointMake(70, 30),
CGPointMake(90, 50), CGPointMake(70, 70),
CGPointMake(50, 80), CGPointMake(30, 70),};
UIView *cloud = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[self.view addSubview:cloud];
for (int i=0; i<9; i++) {
UIView *circle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
circle.center = points[i];
circle.backgroundColor = color;
circle.layer.cornerRadius = 20;
[cloud addSubview:circle];
}
cloud.transform = CGAffineTransformMakeScale(0.3, 0.2);
return cloud;
}
– (UIView*)createRaindrop:(UIColor*)color
{
UIView *raindrop = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[self.view addSubview:raindrop];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 0)];
[path addCurveToPoint:CGPointMake(10, 20) controlPoint1:CGPointMake(10, 3) controlPoint2:CGPointMake(20, 15)];
[path addCurveToPoint:CGPointMake(10, 0) controlPoint1:CGPointMake(0, 15) controlPoint2:CGPointMake(10, 3)];
CAShapeLayer *sl = [[CAShapeLayer alloc] init];
sl.fillColor = color.CGColor;
sl.path = path.CGPath;
[raindrop.layer addSublayer:sl];
return raindrop;
}
#pragma mark – gesture
– (void)replace:(UIPanGestureRecognizer*)gr
{
CGPoint p = [gr locationInView:self.view];
gr.view.transform = CGAffineTransformMakeTranslation(p.x – gr.view.center.x, 0);
for (UIView *v in self.view.subviews) {
if (v.tag == 1) {
if ((gr.view.center.x > v.center.x && p.x < v.center.x)
|| (gr.view.center.x < v.center.x && p.x > v.center.x)) {
CGPoint o = gr.view.center;
gr.view.center = v.center;
v.center = o;
gr.view.transform = CGAffineTransformMakeTranslation(p.x – gr.view.center.x, 0);
}
}
}
if (gr.state == UIGestureRecognizerStateEnded) {
gr.view.transform = CGAffineTransformIdentity;
}
}
– (void)start
{
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}
– (void)tick:(NSTimer*)sender
{
int position = arc4random() % 4 + 1;
UIColor *color = [self colorTheme:arc4random() % 4];
UIView *cloud = [self createCloud:color];
cloud.center = CGPointMake(64 * position , 0);
[self.view addSubview:cloud];
[UIView animateWithDuration:3.0 animations:^{
CGAffineTransform t = CGAffineTransformMakeTranslation(0, 50);
t = CGAffineTransformScale(t, 0.6, 0.4);
cloud.transform = t;
} completion:^(BOOL finished) {
[cloud removeFromSuperview];
UIView *drop = [self createRaindrop:color];
drop.center = CGPointMake(cloud.center.x, 100);
[self.view addSubview:drop];
[UIView animateWithDuration:2.0 animations:^{
drop.center = CGPointMake(drop.center.x, 320);
} completion:^(BOOL finished) {
for (UIView *v in self.view.subviews) {
if (v.tag == 1) {
if (CGRectIntersectsRect(v.frame, drop.frame)) {
[self checkColorMatch:v drop:drop];
}
}
}
[drop removeFromSuperview];
}];
}];
}
– (void)checkColorMatch:(UIView*)ambrella drop:(UIView*)drop
{
CAShapeLayer *aLayer = [ambrella.layer.sublayers objectAtIndex:0];
CAShapeLayer *dLayer = [drop.layer.sublayers objectAtIndex:0];
if (CGColorEqualToColor(aLayer.strokeColor, dLayer.fillColor)) {
[self scoreUp:[UIColor colorWithCGColor:dLayer.fillColor]];
} else {
[self scoreDown];
}
}
– (void)createScoreBar{
scoreBar = [[UIView alloc] initWithFrame:CGRectMake(0, 400, 320, 50)];
scoreBar.layer.borderColor = [UIColor darkGrayColor].CGColor;
scoreBar.layer.borderWidth = 2;
[self.view addSubview:scoreBar];
}
– (void)scoreUp:(UIColor*)color
{
UIView *last = [scoreBar.subviews lastObject];
float x = last.frame.origin.x + last.frame.size.width;
if (x < 320) {
UIView *up = [[UIView alloc] initWithFrame:CGRectMake(x, 0, 20, 50)];
up.backgroundColor = color;
[scoreBar addSubview:up];
}
}
– (void)scoreDown
{
[[scoreBar.subviews lastObject] removeFromSuperview];
}
– (UIColor*)colorTheme:(int)i
{
switch (i) {
case 0:
return UIColorHex(0x0088FF);
case 1:
return UIColorHex(0xFF0066);
case 2:
return UIColorHex(0x00CC00);
case 3:
return UIColorHex(0xFFBB00);
case 4:
return UIColorHex(0x212121);
default:
break;
}
return nil;
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end