野球版アプリを落書きしてみた

(XcodeのiOS6 Simulatorで試しています。)

ポイント

・バットとボールをCADisplayLinkで動かす

・画面タップでバットをスイング

・打球は、UIViewのanimationで y=10の座標へ

・点数版はダミー

サンプル

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    CADisplayLink *timer;

    BOOL swing;

    BOOL hit;

    UIView *bat;

    UIView *ball;

    float lastThrow;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

}

– (void)viewDidAppear:(BOOL)animated

{

    // 野球版のグラウンドを作る

    [self createGround];

    

    // バットを用意

    bat = [self createBat];

    

    // タイマーをスタート

    [self start];

    

    // 点数盤

    [self createPointBoard];

    

}

– (void)createGround

{

    // ground

    UIView *green = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];

    green.backgroundColor = [UIColor brownColor];

    green.center = CGPointMake(self.view.center.x, green.center.y150);

    CATransform3D transform = CATransform3DMakeRotation(M_PI * 0.25, 0, 0, 1.0f);

    green.layer.transform = transform;

    [self.view addSubview:green];

    

    

    // ダイヤモンド

    UIView *dia = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 230, 230)];

    dia.backgroundColor = [UIColor greenColor];

    dia.layer.borderColor = [UIColor whiteColor].CGColor;

    dia.layer.borderWidth = 2.0;

    dia.layer.transform = CATransform3DMakeRotation(M_PI * 0.25, 0, 0, 1.0f);

    dia.center = CGPointMake(self.view.center.x, self.view.center.y);

    [self.view addSubview:dia];

    

    

    // ホーム

    UIView *home = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 80)];

    home.layer.cornerRadius = 40.0;

    home.backgroundColor = [UIColor brownColor];

    home.center = CGPointMake(self.view.center.x, 420);

    [self.view addSubview:home];

    

    

    // マウンド

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

    mound.layer.cornerRadius = 25.0;

    mound.backgroundColor = [UIColor brownColor];

    mound.center = CGPointMake(self.view.center.x, self.view.center.y);

    mound.alpha = 0.9;

    [self.view addSubview:mound];

    

    UIView *plate0 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 15)];

    plate0.backgroundColor = [UIColor whiteColor];

    plate0.center = CGPointMake(self.view.center.x, self.view.center.y);

    [self.view addSubview:plate0];

    

    

    // ベース

    CGPoint basePosition[] = {CGPointMake(320, 250), CGPointMake(160, 100), CGPointMake(0, 250), CGPointMake(160, 420)};

    

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

        UIView *base = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];

        base.backgroundColor = [UIColor whiteColor];

        base.center = basePosition[i];

        [self.view addSubview:base];

    }

}

– (UIView*)createBat

{

    // バントしてるみたいに表示

    bat = [[UIView alloc] initWithFrame:CGRectMake(100, 400, 90, 30)];

    bat.backgroundColor = [UIColor clearColor];

    

    //

    UIColor *color = [UIColor blackColor];

    

    // 側面 1

    UIView *sideA = [[UIView alloc] initWithFrame:CGRectMake(0, 10, 100, 10)];

    sideA.backgroundColor = color;

    sideA.transform = CGAffineTransformMakeRotation(M_PI * 0.01);

    sideA.layer.cornerRadius = 5;

    [bat addSubview:sideA];

    

    // 側面 2

    UIView *sideB = [[UIView alloc] initWithFrame:CGRectMake(0, 5, 100, 10)];

    sideB.backgroundColor = color;

    sideB.transform = CGAffineTransformMakeRotation(-M_PI * 0.01);

    sideB.layer.cornerRadius = 5.0;

    [bat addSubview:sideB];

    

    //

    UIView *head = [[UIView alloc] initWithFrame:CGRectMake(90, 10, 10, 10)];

    head.backgroundColor = color;

    [bat addSubview:head];

    

    

    [self.view addSubview:bat];

    return bat;

}

– (void)createPointBoard

{

    NSArray *colors = [NSArray arrayWithObjects:[UIColor yellowColor], [UIColor greenColor], [UIColor redColor], nil];

    int points[] = {10, 20, 50};

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

        UILabel *point = [[UILabel alloc] initWithFrame:CGRectMake(i * 64, 0, 64, 30)];

        point.text = [NSString stringWithFormat:@”%d”, points[i % 3]];

        point.textAlignment = 1; // center

        point.backgroundColor = [colors objectAtIndex: i % 3];

        [self.view addSubview:point];

    }

    

}

– (void)start

{

    timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];

    [timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

}

– (void)tick:(CADisplayLink *)sender

{

    // バットスイング

    if (swing) {

        CATransform3D transform = bat.layer.transform;

        transform = CATransform3DTranslate(transform, –40, 0, 0);

        transform = CATransform3DRotate(transform, –M_PI * 0.1, 0, 0, 1.0f);

        transform = CATransform3DTranslate(transform, 40, 0, 0);

        bat.layer.transform = transform;

        // ストッパーまでまわしたら止める

        CALayer *layer = bat.layer.presentationLayer;

        float currentAngle = [[layer valueForKeyPath:@”transform.rotation.z”] floatValue];

        if (currentAngle > M_PI * 0.9) {

            swing = NO;

        }

    }

    

    

    // ボールを投げる

    if (lastThrow > 2.0) {

        lastThrow = 0;

        [ball removeFromSuperview];

        ball = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];

        ball.backgroundColor = [UIColor whiteColor];

        ball.center = self.view.center;

        ball.layer.borderColor = [UIColor blackColor].CGColor;

        ball.layer.borderWidth = 2.0f;

        ball.layer.cornerRadius = 10.0;

        [self.view addSubview:ball];

    } else {

        lastThrow += sender.duration;

    }

    if (!hit) {

        

        float speed = 5;

        ball.center = CGPointMake(ball.center.x, ball.center.y + speed);

    }

    

    

    // ボールと当たったかチェック

    CGRect ballRect = [ball.layer.presentationLayer frame];

    CGRect batRect = [bat.layer.presentationLayer frame];

    

    if (!hit && CGRectIntersectsRect(ballRect, batRect)) {

        // バットにボールがhit

        hit = YES;

        

        // ボールを飛ばす。

        // 当たったときのバットの角度 (水平が0)

        float currentAngle = [[bat.layer.presentationLayer valueForKeyPath:@”transform.rotation.z”] floatValue];

        

        // 飛ばす方向

        // y = 10で止める。 円からxを計算

        float r = (ball.center.y10.0) / cosf(currentAngle);

        float x = ball.center.x + r * sinf(currentAngle);

        

        [UIView animateWithDuration:0.5 animations:^{

            ball.center = CGPointMake(x, 10);

        } completion:^(BOOL finished) {

            hit = NO;

            [ball removeFromSuperview];

        }];

    }

    

    

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    swing = !swing;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end