野球版アプリを落書きしてみた
(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.y – 150);
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.y – 10.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