観覧車に何人乗ったかをカウントアップしていくサンプル
(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.x – 50.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