くるくる回りながら、口をパクパクさせている魚をタッチでつり上げるゲームを作ってみましょう。口を開けたタイミングでタップすると、上にピョーンと飛んでいくようにしてみます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
画面の真ん中上寄りに、大きな丸いUIViewを配置、その中に、小さめの丸いUIViewを3つ配置しています。タイマーを使って、大きいViewを時計回りに回転、小さいViewをちょうど反対の方向におんなじ回転速度でまわすことで、その中に表示する魚の向きを一定に保ちながらまわしています。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
NSTimer *timer;
UIView *turnTable;
UILabel *btn;
int score;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
[self createTurnTable];
[self createStart];
}
– (void)createTurnTable
{
turnTable = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
turnTable.layer.cornerRadius = 150;
turnTable.backgroundColor = [UIColor colorWithRed:0.7 green:0.7 blue:1.0 alpha:1];
turnTable.center = CGPointMake(160, 200);
[self.view addSubview:turnTable];
for (int i=0; i<3; i++) {
UIView *fishArea = [self createFishArea];
float x = 90 * cos(M_PI * (2.0/3.0) * i) + 150;
float y = 90 * sin(M_PI * (2.0/3.0) * i) + 150;
fishArea.center = CGPointMake(x, y);
}
}
– (void)createStart
{
btn = [[UILabel alloc] init];
btn.text = @”START”;
btn.font = [UIFont fontWithName:@”Chalkduster” size:40];
btn.textColor = [UIColor whiteColor];
btn.backgroundColor = [UIColor colorWithWhite:0 alpha:0.01];
[btn sizeToFit];
btn.center = CGPointMake(160, 400);
[self.view addSubview:btn];
btn.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(startTimer)];
[btn addGestureRecognizer:tap];
}
– (UIView *)createFishArea
{
UIView *fishArea = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 140, 140)];
fishArea.backgroundColor = [UIColor colorWithRed:0.3 green:0.3 blue:1.0 alpha:1];;
fishArea.layer.cornerRadius = 70;
[turnTable addSubview:fishArea];
for (int i=0; i<3; i++) {
UIView *fish = [self createFish];
float x = 40 * cos(M_PI * (2.0/3.0) * i) + 70;
float y = 40 * sin(M_PI * (2.0/3.0) * i) + 70;
fish.center = CGPointMake(x, y);
[fishArea addSubview:fish];
}
return fishArea;
}
– (UIView *)createFish
{
UIView * fish = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 40)];
fish.layer.masksToBounds = YES;
UIBezierPath *path = [UIBezierPath bezierPath];
path.usesEvenOddFillRule = YES;
[path addArcWithCenter:CGPointMake(25, 25) radius:20 startAngle:0 endAngle:2 * M_PI clockwise:NO];
[path moveToPoint:CGPointMake(10, 10)];
[path addArcWithCenter:CGPointMake(12, 17) radius:2.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[path moveToPoint:CGPointMake(25, 25)];
[path addArcWithCenter:CGPointMake(25, 25) radius:20 startAngle:1.5 * M_PI endAngle:1.8 * M_PI clockwise:YES];
CAShapeLayer *sl = [[CAShapeLayer alloc] init];
NSArray *colors = @[[UIColor redColor], [UIColor orangeColor], [UIColor purpleColor], [UIColor yellowColor]];
sl.fillColor = [[colors objectAtIndex:arc4random()%4] CGColor];
sl.path = path.CGPath;
[fish.layer addSublayer:sl];
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(pac:) userInfo:fish repeats:YES];
return fish;
}
– (void)landFish:(UITapGestureRecognizer*)gr
{
[UIView animateWithDuration:0.6 animations:^{
CGAffineTransform t = CGAffineTransformMakeTranslation(0, –400);
t = CGAffineTransformScale(t, 2.0, 2.0);
gr.view.transform = t;
} completion:^(BOOL finished) {
gr.view.tag = 1; // land the fish.
score ++;
if (score > 8) {
[turnTable removeFromSuperview];
[btn removeFromSuperview];
[self createStart];
[self createTurnTable];
}
}];
}
– (void)startTimer
{
btn.text = @”~~~~~”;
btn.userInteractionEnabled = NO;
timer = [NSTimer scheduledTimerWithTimeInterval:2.0/60 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}
– (void)tick:(NSTimer*)sender
{
turnTable.transform = CGAffineTransformRotate(turnTable.transform, M_PI/ 180.0);
for (UIView *v in turnTable.subviews) {
v.transform = CGAffineTransformRotate(v.transform, –M_PI/ 180.0);
}
}
// timer of fish mouth
– (void)pac:(NSTimer*)sender
{
UIView *fish = sender.userInfo;
if (fish.tag == 1) {
[sender invalidate];
[fish removeFromSuperview];
}
int pac = arc4random() % 4; // 25%
float upperjaw = 1.5 * M_PI;
float jawl = 1.55 * M_PI;
fish.userInteractionEnabled = NO;
if (pac == 0) {
// open mouth
jawl = 1.8 * M_PI;
fish.userInteractionEnabled = YES;
}
UIBezierPath *path = [UIBezierPath bezierPath];
path.usesEvenOddFillRule = YES;
[path addArcWithCenter:CGPointMake(25, 25) radius:20 startAngle:0 endAngle:2 * M_PI clockwise:NO];
[path moveToPoint:CGPointMake(10, 10)];
[path addArcWithCenter:CGPointMake(12, 17) radius:2.5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[path moveToPoint:CGPointMake(25, 25)];
[path addArcWithCenter:CGPointMake(25, 25) radius:20 startAngle:upperjaw endAngle:jawl clockwise:YES];
CAShapeLayer *sl = [fish.layer.sublayers objectAtIndex:0];
sl.path = path.CGPath;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(landFish:)];
[fish addGestureRecognizer:tap];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end