指で引っ張って飛ばすゴルフゲーム
(XcodeのiOS6 Simulatorでつくってみた。)
ポイント
・touchesMovedでボールから引っ張った絵を描画
・UIViewに減衰に関する値を設定して、ボール通る速さを変える
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
// ボールの状態
typedef enum {
BallStop,
BallTouch,
BallRelease,
} BallStatus;
@interface ViewController () {
BallStatus status;
CGPoint startPoint;
CGPoint releasePoint;
float speed;
CADisplayLink *timer;
}
@property (nonatomic, strong) UIView *ball;
@property (nonatomic, strong) UIView *sibaA;
@property (nonatomic, strong) UIView *sibaB;
@property (nonatomic, strong) UIView *banker;
@property (nonatomic, strong) UIView *cup;
@property (nonatomic, strong) NSMutableArray *anchorArray;
@end
@implementation ViewController
@synthesize ball, anchorArray;
@synthesize sibaA, sibaB, banker, cup;
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
anchorArray = [[NSMutableArray alloc] init];
// グラウンド
[self createGround];
// ボール
[self setUpBall];
// スタート
[self start];
}
– (void)viewDidDisappear:(BOOL)animated
{
ball = nil;
anchorArray = nil;
}
– (void)createGround
{
// グラウンドを作る
sibaA = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
sibaA.backgroundColor = [UIColor colorWithRed:0 green:0.6 blue:0 alpha:1.0];
sibaA.center = CGPointMake(160, 340);
sibaA.layer.cornerRadius = 15.0;
[self.view addSubview:sibaA];
sibaB = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 50)];
sibaB.backgroundColor = [UIColor colorWithRed:0 green:0.4 blue:0 alpha:1.0];
sibaB.center = CGPointMake(120, 120);
sibaB.layer.cornerRadius = 15.0;
[self.view addSubview:sibaB];
banker = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
banker.backgroundColor = [UIColor brownColor];
banker.center = CGPointMake(220, 200);
banker.layer.cornerRadius = 25.0;
[self.view addSubview:banker];
cup = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
cup.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1.0];
cup.center = CGPointMake(280, 50);
cup.layer.cornerRadius = 20.0;
cup.layer.transform = CATransform3DMakeRotation(M_PI * 0.2, 1.0, 0, 0);
cup.layer.zPosition = 100;
[self.view addSubview:cup];
}
– (void)setUpBall
{
// ゴルフボールを作る
ball = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
ball.center = CGPointMake(160, 350);
ball.backgroundColor = [UIColor whiteColor];
ball.layer.cornerRadius = 10.0;
ball.layer.zPosition = 200;
[self.view addSubview:ball];
}
– (void)start
{
timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisp:)];
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
– (void)updateDisp:(CADisplayLink*)sender
{
if (status == BallRelease) {
float dx = (startPoint.x – releasePoint.x) * speed * 0.001;
float dy = (startPoint.y – releasePoint.y) * speed * 0.001;
ball.center = CGPointMake(ball.center.x + dx, ball.center.y + dy);
float groundCondition = [self checkGroundCondition:ball.frame];
// カップに入ったかチェックする
if (groundCondition < 0) {
status = BallStop;
[UIView animateWithDuration:1.0 animations:^{
ball.center = cup.center;
ball.transform = CGAffineTransformMakeScale(0.5, 0.5);
} completion:^(BOOL finished) {
// クリアエフェクト
UILabel *clearLabel = [[UILabel alloc] init];
clearLabel.font = [UIFont boldSystemFontOfSize:50];
clearLabel.text = @”Clear!”;
[clearLabel sizeToFit];
clearLabel.center = CGPointMake(160, –200);
clearLabel.backgroundColor = [UIColor clearColor];
[self.view addSubview:clearLabel];
[UIView animateWithDuration:0.5 animations:^{
clearLabel.center = self.view.center;
}];
}];
}
speed = speed – groundCondition;
if (speed < 0) {
status = BallStop;
startPoint = ball.center;
}
}
}
– (float)checkGroundCondition:(CGRect)rect
{
// 地面によってスピードの減衰を変える
if (CGRectIntersectsRect(rect, sibaA.frame)) {
return 2.0;
}
else if (CGRectIntersectsRect(rect, sibaB.frame)) {
return 3.0;
}
else if (CGRectIntersectsRect(rect, banker.frame)) {
return 10.0;
}
else if (CGRectIntersectsRect(rect, cup.frame)) {
return –1.0;
}
return 1.0;
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
CGPoint p = [t locationInView:self.view];
if (CGRectContainsPoint(ball.frame, p)) {
startPoint = ball.center;
}
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// 引っ張るとアンカーがのびるように
UITouch *t = [touches anyObject];
CGPoint p = [t locationInView:self.view];
for (UIView *v in self.anchorArray) {
[v removeFromSuperview];
}
float dx = startPoint.x – p.x;
float dy = startPoint.y – p.y;
int len = hypotf(dx, dy);
for (int i=10; i<len; i+=10) {
UIView *anchorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
anchorView.layer.borderColor = [UIColor colorWithWhite:0.7 alpha:0.6].CGColor;
anchorView.layer.borderWidth = 2.0;
anchorView.layer.cornerRadius = 5.0;
anchorView.center = CGPointMake(startPoint.x – i * (dx / len), startPoint.y – i * (dy / len));
[self.view addSubview:anchorView];
[self.anchorArray addObject:anchorView];
}
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// 離すとボールを飛ばす
UITouch *t = [touches anyObject];
CGPoint p = [t locationInView:self.view];
releasePoint = p;
speed = hypotf(startPoint.x – p.x, startPoint.y – p.y);
status = BallRelease;
for (UIView *v in self.anchorArray) {
[v removeFromSuperview];
}
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end