iPhoneコンパスと宝探し

コンパスを動かして、「はてな」の中から宝(丸印)を探し出す。というシンプルなiPhoneゲームを作ってみます。

動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    UIView *compass;

    UIView *arrow;

    UIView *treasure;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [self color:2];

    

    [self createTreasure];

    

    [self createCompass];

}

– (void)createCompass

{

    compass = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

    compass.backgroundColor = [self color:0];

    compass.layer.cornerRadius = 25;

    compass.layer.borderColor = [self color:1].CGColor;

    compass.layer.borderWidth = 4;

    [self.view addSubview:compass];

    

    // arrow

    arrow = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

    arrow.userInteractionEnabled = NO;

    [compass addSubview:arrow];

    

    UIBezierPath *arrowPath = [UIBezierPath bezierPath];

    [arrowPath moveToPoint:CGPointMake(2, 25)];

    [arrowPath addLineToPoint:CGPointMake(25, 21)];

    [arrowPath addLineToPoint:CGPointMake(25, 29)];

    [arrowPath closePath];

    

    CAShapeLayer *slr = [CAShapeLayer layer];

    slr.fillColor = [self color:4].CGColor;

    slr.path = arrowPath.CGPath;

    [arrow.layer addSublayer:slr];

    

    CAShapeLayer *slg = [CAShapeLayer layer];

    slg.fillColor = [self color:1].CGColor;

    slg.path = arrowPath.CGPath;

    slg.frame = compass.bounds;

    slg.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);

    [arrow.layer addSublayer:slg];

    

    

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

    [compass addGestureRecognizer:pan];

}

– (void)createTreasure

{

    int num = arc4random() % 36;

    

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

        int x = (i % 6) * 50 + 15;

        int y = (i / 6) * 50 + 120;

        

        UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 40, 40)];

        l.text = @”?”;

        l.font = [UIFont boldSystemFontOfSize:30];

        l.textColor = [UIColor whiteColor];

        l.backgroundColor = [self color:3];

        l.textAlignment = NSTextAlignmentCenter;

        [self.view insertSubview:l atIndex:0];

        

        if (i == num) {

            treasure = l;

        }

        

        l.userInteractionEnabled = YES;

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

        [l addGestureRecognizer:tap];

    }

}

– (void)pan:(UIPanGestureRecognizer*)gr

{

    CGPoint p = [gr locationInView:self.view];

    

    if (gr.state == UIGestureRecognizerStateBegan) {

        CGPoint p0 = [gr locationInView:compass];

        float x = p0.x / compass.bounds.size.width;

        float y = p0.y / compass.bounds.size.height;

        compass.layer.anchorPoint = CGPointMake(x, y);

    }

    

    compass.layer.position = p;

    

    // arrow

    float angle = atan2f(compass.center.xtreasure.center.x, treasure.center.ycompass.center.y);

    arrow.transform = CGAffineTransformMakeRotation(angle – M_PI * 0.5);

}

– (void)openPanel:(UITapGestureRecognizer*)gr

{

    [UIView animateWithDuration:0.3 animations:^{

        gr.view.layer.zPosition = 100;

        gr.view.layer.transform = CATransform3DMakeRotation(M_PI*0.5, 1, 0, 0);

    } completion:^(BOOL finished) {

        UILabel *mark = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];

        mark.font = [UIFont boldSystemFontOfSize:40];

        mark.textAlignment = NSTextAlignmentCenter;

        mark.backgroundColor = [self color:3];

        if (gr.view == treasure) {

            // clear

            mark.text = @”◎”;

            mark.textColor = [UIColor blueColor];

        } else {

            mark.text = @”×”;

            mark.textColor = [UIColor redColor];

        }

        [gr.view addSubview:mark];

        [UIView animateWithDuration:0.3 animations:^{

            gr.view.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);;

        } completion:^(BOOL finished) {

            gr.view.layer.zPosition = 0;

            if (gr.view == treasure) {

                // clear

                [self performSelector:@selector(reset) withObject:nil afterDelay:1.0];

            }

        }];

    }];

}

– (void)reset

{

    for (UIView *v in self.view.subviews) {

        if (v != compass) {

            [UIView animateWithDuration:0.3 animations:^{

                v.transform = CGAffineTransformMakeTranslation(400, 0);

            } completion:^(BOOL finished) {

                [v removeFromSuperview];

            }];

        }

    }

    

    [self performSelector:@selector(createTreasure) withObject:nil afterDelay:0.4];

}

#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]

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0x3FB8AF);

        case 1:

            return UIColorHex(0xCEDBD3);

        case 2:

            return UIColorHex(0xFEFEFE);

        case 3:

            return UIColorHex(0xF0E872);

        case 4:

            return UIColorHex(0xC43128);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end