iPhone単純ゲーム ボールを跳ね返す

落ちてくるボールを四角を動かして跳ね返す。という単純なiPhoneゲームを作ってみます。


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

ポイント
ボール用にUIViewnのサブクラスを作成して、速度を保持するようにしています。タイマーの中で、ランダムにボールを生成、その際に、ボールの初速を設定して、あとは、Y方向に落ちていくようにタイマーのループ内で速度を+1するようにしました。

サンプルコード

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

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

@interface BallView : UIView

@property (nonatomic, assign) CGPoint velocity;

@end

@implementation BallView

@synthesize velocity;

@end

@interface ViewController () {

    NSTimer *timer;

    NSMutableArray *balls;

    UIView *cup;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

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

    [self startTimer];

    

    [self createCup:[self color:arc4random()%4]];

}

– (void)startTimer

{

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

}

– (void)tick:(NSTimer*)sender

{    

    // create ball

    [self createBall];

    

    // ball data

    [self updateBallData];

    

    

}

– (void)createBall

{

    if (!balls) {

        balls = [[NSMutableArray alloc] init];

    }

    

    if ((arc4random() % 10) == 0) {

        CGRect rect = CGRectMake(160, 160, 40, 40);

        BallView *ball = [[BallView alloc] initWithFrame:rect];

        float vx = arc4random() % 6;

        ball.velocity = CGPointMake(vx – 3, –20);

        ball.backgroundColor = [self color:arc4random()%4];

        ball.layer.cornerRadius = 20;

        

        [self.view addSubview:ball];

        [balls addObject:ball];

    }

}

– (void)updateBallData

{

    for (int i=0; i<[balls count]; i++) {

        BallView *b = [balls objectAtIndex:i];

        b.velocity = CGPointMake(b.velocity.x, b.velocity.y + 1);

        b.center = CGPointMake(b.center.x + b.velocity.x, b.center.y + b.velocity.y);

        

        if (b.center.y > 568 || b.center.y < –100) {

            [b removeFromSuperview];

            b = nil;

        }

        

        // check collide

        if (CGRectIntersectsRect(b.frame, cup.frame)) {

            b.velocity = CGPointMake(0, –100);

            cup.backgroundColor = [self color:arc4random()%4];

            CAShapeLayer *sl = [cup.layer.sublayers objectAtIndex:0];

            sl.strokeColor = cup.backgroundColor.CGColor;

        }

    }

}

– (void)createCup:(UIColor*)color

{

    UIBezierPath *path = [UIBezierPath bezierPath];

    [path addArcWithCenter:CGPointMake(30, 0) radius:30 startAngle:0 endAngle:M_PI clockwise:YES];

    CAShapeLayer *sl = [[CAShapeLayer alloc] init];

    sl.fillColor = [UIColor colorWithWhite:1 alpha:0.01].CGColor;

    sl.strokeColor = color.CGColor;

    sl.lineWidth = 8;

    sl.path = path.CGPath;

    

    cup = [[UIView alloc] initWithFrame:CGRectMake(160, 400, 60, 60)];

    cup.backgroundColor = color;

    [cup.layer addSublayer:sl];

    [self.view addSubview:cup];

    

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

    [cup addGestureRecognizer:pan];

}

– (void)move:(UIPanGestureRecognizer*)gr

{

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

    gr.view.center = CGPointMake(p.x, gr.view.center.y);

}

– (UIColor*)color:(int)i

{

    switch (i) {

        case 0:

            return UIColorHex(0xFF7B25);

        case 1:

            return UIColorHex(0xFFF566);

        case 2:

            return UIColorHex(0xD3FF3D);

        case 3:

            return UIColorHex(0xFFAFAA);

        case 4:

            return UIColorHex(0x6CEEFF);

        default:

            break;

    }

    return nil;

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end