クレーンゲームの落書きをしてみました。
(XcodeのiOS6 Simulatorで試しています。)
ポイント
・touchBegin, Move, Endで該当するUIViewの長押しを検知
・CALayerをのばしたり、パーツ化したけど、描画タイミングに難あり。
(※きっと設定があるはず。)
・掴むと言うより、磁石で吸い寄せ的なものになってしまった。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
// クレーンの状態
typedef enum {
ClawStop,
ClawLeft,
ClawRight,
ClawDown,
ClawMiss,
ClawCatch,
} ClawStatus;
@interface ViewController () {
ClawStatus status;
CADisplayLink *timer;
}
@property (nonatomic, strong) NSArray *prizes;
@property (nonatomic, strong) UIView *claw;
@property (nonatomic, strong) UILabel *left;
@property (nonatomic, strong) UIView *center;
@property (nonatomic, strong) UILabel *right;
@end
@implementation ViewController
@synthesize prizes, claw, left, center, right;
– (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// 入れ物を作る
[self createBox];
// 景品を作る
[self createPrizes];
// クローを作る
[self createClaw];
// ボタンを3つ
[self createControlPanel];
// スタート
[self start];
}
– (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[timer invalidate];
timer = nil;
prizes = nil;
left = nil;
right = nil;
center = nil;
}
– (void)createBox
{
UIView *top = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
top.backgroundColor = [UIColor redColor];
[self.view addSubview:top];
// ガラスっぽく
UIView *middle = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 320, 330)];
CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = CGRectMake(0, 0, 320, 330);
UIColor *color1 = [UIColor colorWithRed:0 green:0 blue:0.4 alpha:0.5];
UIColor *color2 = [UIColor colorWithRed:0 green:0 blue:0.6 alpha:0.3];
layer.colors = [NSArray arrayWithObjects:(id)color1.CGColor, color2.CGColor, nil];
[middle.layer addSublayer:layer];
[self.view addSubview:middle];
UIView *bottom = [[UIView alloc] initWithFrame:CGRectMake(0, 380, 320, 100)];
bottom.backgroundColor = [UIColor redColor];
[self.view addSubview:bottom];
}
– (void)createPrizes
{
// 赤、青、黄色の箱をおいておく
UIView *red = [[UIView alloc] initWithFrame:CGRectMake(40, 350, 30, 30)];
red.backgroundColor = [UIColor redColor];
red.layer.borderColor = [UIColor greenColor].CGColor;
red.layer.borderWidth = 2.0;
[self.view addSubview:red];
UIView *blue = [[UIView alloc] initWithFrame:CGRectMake(100, 350, 30, 30)];
blue.backgroundColor = [UIColor blueColor];
blue.layer.borderColor = [UIColor greenColor].CGColor;
blue.layer.borderWidth = 2.0;
[self.view addSubview:blue];
UIView *yellow = [[UIView alloc] initWithFrame:CGRectMake(160, 350, 30, 30)];
yellow.backgroundColor = [UIColor yellowColor];
yellow.layer.borderColor = [UIColor greenColor].CGColor;
yellow.layer.borderWidth = 2.0;
[self.view addSubview:yellow];
// 掴んだりするために、配列に入れておく
self.prizes = [NSArray arrayWithObjects:red, blue, yellow, nil];
}
– (void)createClaw
{
self.claw = [[UIView alloc] initWithFrame:CGRectMake(self.view.center.x, 50, 70, 330)];
self.claw.backgroundColor = [UIColor clearColor];
[self.view addSubview:self.claw];
CALayer *arm = [CALayer layer];
arm.frame = CGRectMake(30, 0, 10, 100);
arm.backgroundColor = [UIColor blackColor].CGColor;
[self.claw.layer addSublayer:arm];
CALayer *hand = [CALayer layer];
hand.frame = CGRectMake(0, 100, 70, 5);
hand.backgroundColor = [UIColor blackColor].CGColor;
[self.claw.layer addSublayer:hand];
CALayer *finger1 = [CALayer layer];
finger1.frame = CGRectMake(0, 100, 5, 40);
finger1.backgroundColor = [UIColor blackColor].CGColor;
[self.claw.layer addSublayer:finger1];
CALayer *finger2 = [CALayer layer];
finger2.frame = CGRectMake(65, 100, 5, 40);
finger2.backgroundColor = [UIColor blackColor].CGColor;
[self.claw.layer addSublayer:finger2];
}
– (void)createControlPanel
{
// コントロール用のボタンを配置
left = [[UILabel alloc] initWithFrame:CGRectMake(60, 400, 50, 50)];
left.text = @”<“;
left.font = [UIFont boldSystemFontOfSize:25];
left.textColor = [UIColor whiteColor];
left.textAlignment = 1; // center
left.layer.cornerRadius = 25.0;
left.layer.borderColor = [UIColor whiteColor].CGColor;
left.layer.borderWidth = 3.0;
left.backgroundColor = [UIColor blackColor];
[self.view addSubview:left];
right = [[UILabel alloc] initWithFrame:CGRectMake(210, 400, 50, 50)];
right.text = @”>”;
right.font = [UIFont boldSystemFontOfSize:25];
right.textColor = [UIColor whiteColor];
right.textAlignment = 1; // center
right.layer.cornerRadius = 25.0;
right.layer.borderColor = [UIColor whiteColor].CGColor;
right.layer.borderWidth = 3.0;
right.backgroundColor = [UIColor blackColor];
[self.view addSubview:right];
center = [[UILabel alloc] initWithFrame:CGRectMake(self.view.center.x – 30, 400, 60, 50)];
center.backgroundColor = [UIColor blackColor];
[self.view addSubview:center];
}
– (void)start
{
timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisp:)];
[timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
– (void)updateDisp:(CADisplayLink*)sender
{
switch (status) {
case ClawDown:
case ClawMiss:
case ClawCatch:
[self updateClaw];
break;
case ClawLeft:
claw.center = CGPointMake(claw.center.x – 1, claw.center.y);
break;
case ClawRight:
claw.center = CGPointMake(claw.center.x + 1, claw.center.y);
break;
default:
break;
}
}
– (void)updateClaw
{
// CALayerの描画タイミングが微妙、なにか設定があれば探そう。。
CALayer *arm = [claw.layer.sublayers objectAtIndex:0];
CALayer *hand = [claw.layer.sublayers objectAtIndex:1];
CALayer *finger1 = [claw.layer.sublayers objectAtIndex:2];
CALayer *finger2 = [claw.layer.sublayers objectAtIndex:3];
float armHeight = arm.frame.size.height;
if (status == ClawDown) {
// アームをおろす
arm.frame = CGRectMake(arm.frame.origin.x, arm.frame.origin.y, arm.frame.size.width, armHeight + 1);
hand.position = CGPointMake(hand.position.x, hand.position.y + 1);
finger1.position = CGPointMake(finger1.position.x, finger1.position.y + 1);
finger2.position = CGPointMake(finger2.position.x, finger2.position.y + 1);
// 接触したら止める
for (UIView *v in prizes) {
CGPoint p1 = [self.view convertPoint:finger1.position fromView:claw];
CGPoint p2 = [self.view convertPoint:finger2.position fromView:claw];
p1.y += 20;
p2.y += 20;
if (CGRectContainsPoint(v.frame, p1) || CGRectContainsPoint(v.frame, p2)) {
status = ClawMiss;
}
}
if (armHeight > 260) {
// 下まで来たら止める
for (UIView *prize in prizes) {
if (abs(prize.center.x – claw.center.x) < 20) {
// 景品がある場合
status = ClawCatch;
return;
}
}
// 景品が掴めない
status = ClawMiss;
}
}
else if (status == ClawMiss) {
// アームを上げる
arm.frame = CGRectMake(arm.frame.origin.x, arm.frame.origin.y, arm.frame.size.width, armHeight – 1);
hand.position = CGPointMake(hand.position.x, hand.position.y – 1);
finger1.position = CGPointMake(finger1.position.x, finger1.position.y – 1);
finger2.position = CGPointMake(finger2.position.x, finger2.position.y – 1);
if (armHeight < 100) {
// 上まで来たら止める
status = ClawStop;
}
}
else if (status == ClawCatch) {
// アームを景品ごと上げる
arm.frame = CGRectMake(arm.frame.origin.x, arm.frame.origin.y, arm.frame.size.width, armHeight – 1);
hand.position = CGPointMake(hand.position.x, hand.position.y – 1);
finger1.position = CGPointMake(finger1.position.x, finger1.position.y – 1);
finger2.position = CGPointMake(finger2.position.x, finger2.position.y – 1);
for (UIView *prize in prizes) {
if (abs(prize.center.x – claw.center.x) < 20) {
prize.layer.position = CGPointMake(prize.layer.position.x, prize.layer.position.y – 1);
}
}
if (armHeight < 100) {
// 上まで来たら止める
status = ClawStop;
}
}
[claw setNeedsDisplay];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
CGPoint tPoint = [t locationInView:self.view];
[self buttonControl:tPoint];
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
CGPoint tPoint = [t locationInView:self.view];
[self buttonControl:tPoint];
}
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// タッチした位置でクレーンの状態を変更
if (status != ClawDown && status != ClawMiss && status != ClawCatch) {
status = ClawStop;
}
}
– (void)buttonControl:(CGPoint)p
{
// タッチした位置でクレーンの状態を変更
if (status != ClawDown && status != ClawMiss && status != ClawCatch) {
if(CGRectContainsPoint(left.frame, p)) {
status = ClawLeft;
return;
}
if(CGRectContainsPoint(center.frame, p)) {
status = ClawDown;
return;
}
if(CGRectContainsPoint(right.frame, p)) {
status = ClawRight;
return;
}
// それ以外の場合
status = ClawStop;
}
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end