観覧車に何人乗ったかをカウントアップしていくサンプル

(XcodeのiOS6 iPhone Simulatorで動かしています。)

概要

0から10まで乗り込んだ人の数を表示する。

パネルをタッチすることで、人が登場、

観覧車前まで進んでいって、近くにゴンドラがきたら乗り込む。

– このとき、観覧車の中央の数字をカウントアップ。

ゴンドラが下の方まで来たら、降りて、帰っていく。

– このとき、観覧車の中央の数字をカウントダウン。

と言った感じの動きにしてみた。

ポイント

NSTimerで観覧車をCATransform3Dでまわす、

まわした際に、ゴンドラが画面に水平な状態で連動するように、

観覧車のSubviewにアンカー用のViewを配置しておく、

(※このViewは回転してしまうので、位置座標を利用するために配置。)

その座標と、観覧車の引っ掛けたい座標をあわせる。


サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    NSTimer *timer;

    UIView *wheel;

    NSMutableArray *gondola;

    UILabel *counter;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    [self createSky];

    

    [self createWheel];

    

    [self createBase];

    

    [self createGondola];

    

    [self startTimer];

    

    [self createUI];

}

– (void)createSky

{

    //Red : 137 Green : 189 Blue : 222

    self.view.backgroundColor = [UIColor whiteColor];

    UIView *backColor = [[UIView alloc] initWithFrame:self.view.bounds];

    CAGradientLayer *s = [CAGradientLayer layer];

    UIColor *color1 = [UIColor colorWithRed:137.0/255.0 green:189.0/255.0 blue:255.0/255.0 alpha:1.0];

    UIColor *color2 = [UIColor whiteColor];

    s.colors = [NSArray arrayWithObjects:(id)color2.CGColor, color1.CGColor, nil];

    s.frame = backColor.bounds;

    [backColor.layer addSublayer:s];

    [self.view addSubview:backColor];

}

– (void)createWheel

{

    wheel = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 210, 210)];

    wheel.userInteractionEnabled = NO;

    wheel.backgroundColor = [UIColor clearColor];

    [self.view addSubview:wheel];

    

    UIBezierPath *path = [[UIBezierPath alloc] init];

    CGPoint c = [wheel convertPoint:wheel.center fromView:self.view];

    [path addArcWithCenter:c radius:wheel.bounds.size.width * 0.5 startAngle:0 endAngle:2*M_PI clockwise:NO];

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

        float d = M_PI / 5.0;

        float r1 = 20.0;

        float r2 = 100.0;

        [path moveToPoint:CGPointMake(c.x + r1 * cos(d * i), c.y + r1 * sin(d * i))];

        [path addLineToPoint:CGPointMake(c.x + r2 * cos(d * i), c.y + r2 * sin(d * i))];

    }

    

    CAShapeLayer *shape = [[CAShapeLayer alloc] initWithLayer:wheel.layer];

    shape.fillColor = [UIColor clearColor].CGColor;

    shape.strokeColor = [UIColor blackColor].CGColor;

    shape.lineWidth = 2.0;

    [wheel.layer addSublayer:shape];

    shape.path = path.CGPath;

    

}

– (void)createBase

{

    UIView *circle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];

    circle.backgroundColor = [UIColor whiteColor];

    circle.layer.cornerRadius = 30.0;

    circle.center = wheel.center;

    [self.view addSubview:circle];

    counter = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 40, 40)];

    counter.text = @”0″;

    counter.textAlignment = 1;

    counter.font = [UIFont fontWithName:@”Noteworthy-Bold” size:30];

    [circle addSubview:counter];

    

    UIBezierPath *path = [[UIBezierPath alloc] init];

    CGPoint c = wheel.center;

    [path moveToPoint:c];

    [path addLineToPoint:CGPointMake(c.x50.0, 310)];

    [path moveToPoint:c];

    [path addLineToPoint:CGPointMake(c.x + 50.0, 310)];

    CAShapeLayer *shape = [[CAShapeLayer alloc] initWithLayer:wheel.layer];

    shape.fillColor = [UIColor clearColor].CGColor;

    shape.strokeColor = [UIColor darkGrayColor].CGColor;

    shape.lineWidth = 10.0;

    shape.path = path.CGPath;

    [self.view.layer insertSublayer:shape atIndex:1];

    

    UIView *base = [[UIView alloc] initWithFrame:CGRectMake(0, 300, 320, 200)];

    base.backgroundColor = [UIColor greenColor];

    [self.view addSubview:base];

}

– (void)createGondola

{

    gondola = [[NSMutableArray alloc] init];

    

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

        float d = M_PI / 5.0;

        float r = 110.0;

        

        

        CGPoint c0 = [wheel convertPoint:wheel.center fromView:self.view];

        float x0 = c0.x + r * cos(d * i);

        float y0 = c0.y + r * sin(d * i);

        UIView *anchor = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];

        anchor.userInteractionEnabled = NO;

        anchor.center = CGPointMake(x0, y0);

        anchor.backgroundColor = [UIColor redColor];

        [wheel addSubview:anchor];

        

        CGPoint c = wheel.center;

        float x = c.x + r * cos(d * i);

        float y = c.y + r * sin(d * i);

        UIView *g = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];

        g.userInteractionEnabled = NO;

        g.center = CGPointMake(x, y + 10);

        g.backgroundColor = [UIColor redColor];

        g.tag = 2;

        g.layer.cornerRadius = 15.0;

        [self.view addSubview:g];

        

        //window

        UIView *roof = [[UIView alloc] initWithFrame:CGRectMake(5, 5, 30, 20)];

        roof.userInteractionEnabled = NO;

        roof.backgroundColor = [UIColor colorWithRed:137.0/255.0 green:189.0/255.0 blue:255.0/255.0 alpha:1.0];

        roof.layer.cornerRadius = 5;

        roof.layer.masksToBounds = YES;

        [g addSubview:roof];

        

        [gondola addObject:anchor];

        [gondola addObject:g];

    }

}

– (void)createUI

{

    UIView *panelA = [[UIView alloc] initWithFrame:CGRectMake(10, 400, 50, 50)];

    panelA.backgroundColor = [UIColor orangeColor];

    // 255-165-0

    UIColor *color = [UIColor colorWithRed:255.0/255.0 green:195.0/255.0 blue:100.0/255.0 alpha:1.0];

    CAShapeLayer *shape = [self createPersonShape:CGRectMake(0, 0, 30, 40) color:color];

    shape.position = CGPointMake(10, 5);

    [panelA.layer addSublayer:shape];

    [self.view addSubview:panelA];

    

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

    [panelA addGestureRecognizer:tap];

}

– (void)createPerson

{

    UIView *person = [[UIView alloc] initWithFrame:CGRectMake(100, 400, 20, 30)];

    person.backgroundColor = [UIColor clearColor];

    [self.view addSubview:person];

    

    CAShapeLayer *shape = [self createPersonShape:person.bounds color:[UIColor darkGrayColor]];

    [person.layer addSublayer:shape];

    

    [UIView animateWithDuration:2.0 animations:^{

        person.center = CGPointMake(wheel.center.x, wheel.center.y + 150);

    } completion:^(BOOL finished) {

        [self rideOn:person];

    }];

}

– (void)rideOn:(UIView *)person

{

    BOOL ride = NO;

    for (UIView *g in gondola) {

        if (CGRectIntersectsRect(g.frame, person.frame)) {

            UIView *roof = [g.subviews objectAtIndex:0];

            if ([roof.subviews count] == 0) {

                person.center = CGPointMake(20,20);

                [roof addSubview:person];

                ride = YES;

                counter.text = [NSString stringWithFormat:@”%d”, [counter.text intValue]+1];

            }

        }

    }

    

    if (!ride) {

        [self performSelector:@selector(rideOn:) withObject:person afterDelay:0.1];

    }

}

– (void)rideOff:(UIView*)g

{

    UIView *roof = [g.subviews objectAtIndex:0];

    if ([roof.subviews count] > 0) {

        UIView *person = [roof.subviews objectAtIndex:0];

        person.center = CGPointMake(wheel.center.x + 20, wheel.center.y + 150);

        [self.view addSubview:person];

        

        [UIView animateWithDuration:2.0 animations:^{

            person.center = CGPointMake(wheel.center.x + 200, wheel.center.y + 150);

        } completion:^(BOOL finished) {

            [person removeFromSuperview];

        }];

        

        counter.text = [NSString stringWithFormat:@”%d”, [counter.text intValue]-1];

    }

}

– (CAShapeLayer*)createPersonShape:(CGRect)rect color:(UIColor*)color

{

    CGSize size = rect.size;

    

    UIBezierPath *path = [[UIBezierPath alloc] init];

    [path addArcWithCenter:CGPointMake(size.width * 0.5, size.height * 0.1) radius:size.height * 0.1 startAngle:0 endAngle:2*M_PI clockwise:YES];

    [path moveToPoint:CGPointMake(size.width * 0.5, size.height * 0.1)];

    [path addLineToPoint:CGPointMake(size.width * 0.5, size.height*0.6)];

    

    // hand

    [path moveToPoint:CGPointMake(size.width*0.5, size.height * 0.4)];

    [path addLineToPoint:CGPointMake(0, size.height*0.5)];

    [path moveToPoint:CGPointMake(size.width*0.5, size.height * 0.4)];

    [path addLineToPoint:CGPointMake(size.width, size.height*0.5)];

    // foot

    [path moveToPoint:CGPointMake(size.width*0.5, size.height * 0.6)];

    [path addLineToPoint:CGPointMake(size.width*0.3, size.height)];

    [path moveToPoint:CGPointMake(size.width*0.5, size.height * 0.6)];

    [path addLineToPoint:CGPointMake(size.width*0.8, size.height)];

    

    CAShapeLayer *shape = [[CAShapeLayer alloc] initWithLayer:wheel.layer];

    shape.fillColor = [UIColor clearColor].CGColor;

    shape.strokeColor = color.CGColor;

    shape.lineWidth = 5.0;

    shape.lineCap = kCALineCapRound;

    shape.path = path.CGPath;

    

    return shape;

}

– (void)startTimer

{

    timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(tick:) userInfo:nil repeats:YES];

}

– (void)tick:(NSTimer*)sender

{

    float x0 = wheel.center.x + 100 * cos(0.35 * M_PI);

    float y0 = wheel.center.y + 100 * sin(0.35 * M_PI);

    

    float d = M_PI * 0.001;

    if (d >= 2*M_PI) {

        d = 2*M_PI;

    }

    wheel.layer.transform = CATransform3DRotate(wheel.layer.transform, d, 0, 0, 1);

    for (int i=0; i < [gondola count] – 1; i += 2) {

        UIView *anchor = [gondola objectAtIndex:i];

        UIView *g = [gondola objectAtIndex:i+1];

        CGPoint p = [wheel convertPoint:anchor.center toView:self.view];

        g.center = CGPointMake(p.x, p.y + 10);

        

        if (CGRectContainsPoint(CGRectMake(x0, y0, 2, 50), g.center)) {

            [self rideOff:g];

        }

    }

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end