羽子板でスカッシュするようなものを作る方法のメモ
(XcodeのiOS6 Simulatorで試しています。)
ポイント
・3次元座標で羽の位置を計算
・表示はx,y を投影、 zは影に(とてもアバウトに)
タッチで羽を壁打ちする
サンプルコード
[Kokinoko.h]
@interface Kokinoko : NSObject
@property (nonatomic, assign) float x;
@property (nonatomic, assign) float y;
@property (nonatomic, assign) float z;
@property (nonatomic, assign) float vx;
@property (nonatomic, assign) float vy;
@property (nonatomic, assign) float vz;
– (void)swing:(CGPoint)point;
– (void)updateWithDuration:(float)duration;
@end
[Kokinoko.m]
@implementation Kokinoko
@synthesize x,y,z, vx,vy,vz;
– (void)swing:(CGPoint)point
{
float dx = abs(x-point.x);
float dy = abs(y-point.y);
if (dx < 50 && dy < 50 && z < 50) {
// 打ち返す
if (vz == 0) {
vz = 200;
vy = –100;
} else {
vz = – vz;
vy = –100;
vx = (arc4random() % 10) – 5.0;
}
}
}
– (void)updateWithDuration:(float)duration
{
x = x + duration * vx;
vy = vy + 20 * 9.8 * duration;
y = y + duration * vy;
z = z + duration * vz;
if (z > 200) {
vz = –vz;
vy = – 100;
}
}
@end
[ViewController.m]
#import <QuartzCore/QuartzCore.h>
#import “ViewController.h”
#import “Kokinoko.h”
@interface ViewController () {
CADisplayLink *timer;
}
@property (nonatomic, strong) Kokinoko *hane;
@property (nonatomic, strong) UIView *haneView;
@property (nonatomic, strong) UIView *haneShadow;
@end
@implementation ViewController
@synthesize hane, haneView;
– (void)viewDidLoad
{
[super viewDidLoad];
// 羽子板の羽根を初期化
self.hane = [[Kokinoko alloc] init];
hane.x = 100;
hane.y = 100;
hane.z = 30.0;
// コート 200 x 200 の正方形で考えてみる
// 赤いライン
UIView *line1 = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 320, 10)];
line1.backgroundColor = [UIColor redColor];
[self.view addSubview:line1];
UIView *line2 = [[UIView alloc] initWithFrame:CGRectMake(0, 200, 320, 10)];
line2.backgroundColor = [UIColor redColor];
[self.view addSubview:line2];
UIView *floor = [[UIView alloc] initWithFrame:CGRectMake(0, 280, 320, 480)];
floor.backgroundColor = [UIColor brownColor];
[self.view addSubview:floor];
//羽の初期化
self.haneView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
self.haneView.layer.cornerRadius = 10.0;
self.haneView.backgroundColor = [UIColor blackColor];
self.haneView.layer.zPosition = 100;
[self.view addSubview:self.haneView];
// 赤
UIView *red = [[UIView alloc] initWithFrame:CGRectMake(-5, 0, 6, –20)];
red.backgroundColor = [UIColor redColor];
// 回転中心を変更してから回転する
CGAffineTransform transform = CGAffineTransformMakeTranslation(-3, –10);
transform = CGAffineTransformRotate(transform, –0.1 * M_PI);
transform = CGAffineTransformTranslate(transform,3,10);
red.transform = transform;
[self.haneView addSubview:red];
// 黄
UIView *yellow = [[UIView alloc] initWithFrame:CGRectMake(7, 0, 6, –20)];
yellow.backgroundColor = [UIColor yellowColor];
[self.haneView addSubview:yellow];
// 緑
UIView *green = [[UIView alloc] initWithFrame:CGRectMake(20, 0, 6, –20)];
green.backgroundColor = [UIColor greenColor];
transform = CGAffineTransformMakeTranslation(-3, –10);
transform = CGAffineTransformRotate(transform, 0.1 * M_PI);
transform = CGAffineTransformTranslate(transform,3,10);
green.transform = transform;
[self.haneView addSubview:green];
self.haneShadow = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
self.haneShadow.layer.cornerRadius = 10.0;
self.haneShadow.backgroundColor = [UIColor blackColor];
self.haneShadow.layer.transform = CATransform3DMakeRotation(M_PI * 0.3, 1.0, 0.0, 0.0);
self.haneShadow.layer.zPosition = 10;
[self.view addSubview:self.haneShadow];
[self displayHaneAndShadow];
}
– (void)viewDidAppear:(BOOL)animated
{
[self start];
}
– (void)start
{
timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisp:)];
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
– (void)updateDisp:(CADisplayLink*)sender
{
[self.hane updateWithDuration:sender.duration];
[self displayHaneAndShadow];
}
– (void)displayHaneAndShadow
{
// 玉
float rate = 1.5 – 0.004 * hane.z;
self.haneView.transform = CGAffineTransformMakeScale(rate, rate);
self.haneView.center = CGPointMake(self.hane.x, self.hane.y);
// 羽の傾き
CATransform3D transform = CATransform3DIdentity;
if (self.hane.vy > 0 && self.hane.vz != 0) {
transform = CATransform3DRotate(transform, 0.3 * M_PI, 1.0, 0.0, 0);
} else if (self.hane.vy < 0 && self.hane.vz != 0) {
transform = CATransform3DRotate(transform, 0.6 * M_PI, 1.0, 0.0, 0);
}
self.haneView.layer.transform = transform;
// 影
self.haneShadow.center = CGPointMake(self.hane.x, 480 – self.hane.z);
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
UIView *ita = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 60)];
ita.backgroundColor = [UIColor blackColor];
ita.alpha = 0.3;
UIView *grip = [[UIView alloc] initWithFrame:CGRectMake(15, 60, 10, 20)];
grip.backgroundColor = [UIColor blackColor];
grip.alpha = 0.3;
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 140)];
v.center = [touch locationInView:self.view];
[v addSubview:ita];
[v addSubview:grip];
[self.view addSubview:v];
v.layer.transform = CATransform3DMakeRotation(-M_PI * 0.2, 1.0, 0.0, 0.0);
[UIView animateWithDuration:0.3 animations:^{
v.layer.transform = CATransform3DMakeRotation(M_PI * 0.5, 1.0, 0.0, 0.0);
} completion:^(BOOL finished) {
[v removeFromSuperview];
}];
[self.hane swing:v.center];
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end