
ならんでいる歯を順番にタップして抜いてみよう。運が悪いと噛みつかれちゃうよ!!というロシアンルーレット的なiPhoneアプリの作成方法を書いてみます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
ポイント
口のUIViewを画面の真ん中に配置して、その中に、上8本、下8本の歯をならべています。歯のUIViewにTapGestureRecognizerを設定して、タップしたら歯が飛んでいくようにしました。後は、16本のうち一本だけ当たりを仕込んでおいて、それをタップしたら噛み付くようにしました。当たりかどうかはtagに歯の番号を設定してそれと当たりの番号を比較しています。あとは、噛み付くアニメーションのときに、口のScaleを高さ0.2に設定しているのですが、そのままだと、歯の高さが縮小しすぎるので、歯のScaleを2.5倍にすることで、相対的に歯が小さくなりすぎないようにしました。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
UIView *mouth;
int trap;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
[self createFace];
[self createTooths];
[self setTrap];
}
– (void)createFace
{
UIView *eyeL = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 20, 20)];
eyeL.backgroundColor = [UIColor blackColor];
eyeL.layer.cornerRadius = 10;
[self.view addSubview:eyeL];
UIView *eyeR = [[UIView alloc] initWithFrame:CGRectMake(250, 100, 20, 20)];
eyeR.backgroundColor = [UIColor blackColor];
eyeR.layer.cornerRadius = 10;
[self.view addSubview:eyeR];
mouth = [[UIView alloc] initWithFrame:CGRectMake(50, 200, 220, 150)];
mouth.backgroundColor = [UIColor redColor];
mouth.layer.borderWidth = 5;
mouth.layer.borderColor = [UIColor blackColor].CGColor;
mouth.layer.cornerRadius= 10;
[self.view addSubview:mouth];
}
– (void)createTooths
{
// upper
for (int i=0; i<16; i++) {
float x = (i % 8) * 26 + 7;
float y = –15;
CGPoint ap = CGPointMake(0.5, 0);
if(i > 7) {
// 8 から 下の歯
y = mouth.bounds.size.height – 15;
ap = CGPointMake(0.5, 1.0);
}
UIView *tooth = [[UIView alloc] initWithFrame:CGRectMake(x, y, 23, 30)];
tooth.layer.cornerRadius = 5;
tooth.backgroundColor = [UIColor whiteColor];
tooth.tag = i + 1;
tooth.layer.anchorPoint = ap;
[mouth addSubview:tooth];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pullout:)];
[tooth addGestureRecognizer:tap];
// animation
tooth.transform = CGAffineTransformMakeScale(1.0, 0);
[UIView animateWithDuration:0.4 delay:0.05 * i options:UIViewAnimationOptionCurveEaseIn animations:^{
tooth.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {}];
}
}
– (void)pullout:(UITapGestureRecognizer*)gr
{
if (gr.view.tag == trap) {
// bite
[UIView animateWithDuration:0.2 animations:^{
mouth.transform = CGAffineTransformMakeScale(1.0, 0.2);
for (UIView *tooth in mouth.subviews) {
tooth.transform = CGAffineTransformMakeScale(1.0, 2.5);
}
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.8 animations:^{
mouth.transform = CGAffineTransformIdentity;
for (UIView *tooth in mouth.subviews) {
tooth.transform = CGAffineTransformIdentity;
}
} completion:^(BOOL finished) {
// restart
for (UIView *tooth in mouth.subviews) {
[tooth removeFromSuperview];
}
[self setTrap];
[self createTooths];
}];
}];
return;
}
float dy = 300;
if (gr.view.tag > 8) {
dy = -dy;
}
[UIView animateWithDuration:0.3 animations:^{
gr.view.transform = CGAffineTransformMakeTranslation(0, dy);
} completion:^(BOOL finished) {
[gr.view removeFromSuperview];
}];
}
– (void)setTrap
{
trap = arc4random() % 16 + 1;
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end