第5回「時計 朝 7:00」です。

(※東京リトルロケット(Tokyo Little Rocket)は

4コマ漫画をプログラムで動かそうという企画です)

元絵はこちら

サンプルコード

(Xcode iOS6 iPhone Simulatorで動かしています。)

@interface OutLineLabel : UILabel

@end

@implementation OutLineLabel

– (void)drawTextInRect:(CGRect)rect

{

    CGSize shadowOffset = self.shadowOffset;

    UIColor *textColor = self.textColor;

    

    CGContextRef c = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(c, 10);

    CGContextSetLineJoin(c, kCGLineJoinRound);

    

    CGContextSetTextDrawingMode(c, kCGTextStroke);

    self.textColor = [UIColor whiteColor];

    [super drawTextInRect:rect];

    

    CGContextSetTextDrawingMode(c, kCGTextFill);

    self.textColor = textColor;

    self.shadowOffset = CGSizeMake(0, 0);

    [super drawTextInRect:rect];

    

    self.shadowOffset = shadowOffset;

}

@end

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    UIView *startView;

    

    UIImage *backColorImg;

    UIImage *cloud1Img, *cloud2Img, *cloud3Img;

    UIImage *rabitBodyImg;

    UIImage *rabitFace1Img, *rabitFace2Img, *rabitFace3Img;

    UIImage *rabitHandRImg, *rabitHandLImg;

    UIImage *comment1Img, *comment2Img, *comment3Img;

    UIImage *comment4Img, *comment5Img, *comment6Img;

    UIImage *hourmanImg, *minutemanImg, *secondmanImg;

    UIImage *clockbodyImg, *hourhandImg, *minutehandImg, *secondhandImg;

    UIImage *jirijiriImg, *fukidasiImg;

    UIImage *bedCoverImg, *bedFrameImg;

    

    

    UIView *rabit;

    UIView *secondFrame;

    UIImageView *backscreen;

    UIImageView *rabitbody, *rabitface, *rabithandR, *rabithandL;

    UIImageView *cloud1, *cloud2, *cloud3;

    UIImageView *comment1, *comment2;

    UIImageView *fukidasi;

    UIImageView *jiriri;

    UIImageView *clockbody, *hourhand, *minutehand, *secondhand;

    UIImageView *hourman, *minuteman, *secondman;

    UIImageView *bedFrame, *bedCover;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    [self loadResource];

    [self createOpening];

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    static int lock;

    if(lock == 0) {

        lock++;

        [self showProgram];

    }

}

– (void)loadResource

{

    backColorImg = [UIImage imageNamed:@”backColor”];

    cloud1Img = [UIImage imageNamed:@”cloud1″];

    cloud2Img = [UIImage imageNamed:@”cloud2″];

    cloud3Img = [UIImage imageNamed:@”cloud3″];

    rabitBodyImg = [UIImage imageNamed:@”rabitBody”];

    rabitFace1Img = [UIImage imageNamed:@”rabitFace1″];

    rabitFace2Img = [UIImage imageNamed:@”rabitFace2″];

    rabitFace3Img = [UIImage imageNamed:@”rabitFace3″];

    rabitHandRImg = [UIImage imageNamed:@”rabithandR”];

    rabitHandLImg = [UIImage imageNamed:@”rabithandL”];

    comment1Img = [UIImage imageNamed:@”comment1″];

    comment2Img = [UIImage imageNamed:@”comment2″];

    comment3Img = [UIImage imageNamed:@”comment3″];

    comment4Img = [UIImage imageNamed:@”comment4″];

    comment5Img = [UIImage imageNamed:@”comment5″];

    comment6Img = [UIImage imageNamed:@”comment6″];

    hourmanImg = [UIImage imageNamed:@”hourman”];

    minutemanImg = [UIImage imageNamed:@”minuteman”];

    secondmanImg = [UIImage imageNamed:@”secondman”];

    clockbodyImg = [UIImage imageNamed:@”clockbody”];

    hourhandImg = [UIImage imageNamed:@”hourhand”];

    minutehandImg = [UIImage imageNamed:@”minutehand”];

    secondhandImg = [UIImage imageNamed:@”secondhand”];

    jirijiriImg = [UIImage imageNamed:@”jiririri”];

    fukidasiImg = [UIImage imageNamed:@”fukidasi”];

    bedCoverImg = [UIImage imageNamed:@”bedCover”];

    bedFrameImg = [UIImage imageNamed:@”bedFrame”];

}

– (void)showProgram

{

    // 幕を上げる

    [UIView animateWithDuration:1.0 animations:^{

        startView.center = CGPointMake(250, –300);

    } completion:^(BOOL finished) {

        [startView removeFromSuperview];

    }];

    

    // シーン 1

    float delay = 0;

    [self showScene:^{

        [self scene1];

    } afterDelay:delay];

    

    // シーン 2

    delay += 5;

    [self showScene:^{

        [self scene2];

    } afterDelay:delay];

    

    // シーン 3

    delay += 15;

    [self showScene:^{

        [self scene3];

    } afterDelay:delay];

    // シーン 4

    delay += 9;

    [self showScene:^{

        [self scene4];

    } afterDelay:delay];

    // end

    delay += 6;

    [self showScene:^{

        [self createEnding];

    } afterDelay:delay];

    

}

– (void)scene1

{

    //ウサギが夢の中、雲で漂う。

    backscreen = [[UIImageView alloc] initWithImage:backColorImg];

    backscreen.frame = self.view.bounds;

    [self.view insertSubview:backscreen belowSubview:startView];

    

    

    float delay = 0.5;

    [self showScene:^{

        

        cloud1 = [[UIImageView alloc] initWithImage:cloud1Img];

        cloud1.frame = self.view.bounds;

        cloud1.center = CGPointMake(cloud1.center.x + 500, cloud1.center.y);

        [self.view addSubview:cloud1];

        

        rabit = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 800)];

        rabit.backgroundColor = [UIColor clearColor];

        [self.view addSubview:rabit];

    

        rabitbody = [[UIImageView alloc] initWithImage:rabitBodyImg];

        rabitface = [[UIImageView alloc] initWithImage:rabitFace3Img];

        rabithandR = [[UIImageView alloc] initWithImage:rabitHandRImg];

        rabithandL = [[UIImageView alloc] initWithImage:rabitHandLImg];

        [rabit addSubview:rabithandR];

        [rabit addSubview:rabitbody];

        [rabitbody addSubview:rabitface];

        [rabit addSubview:rabithandL];

        rabit.center = CGPointMake(720, 120);

        rabit.transform = CGAffineTransformMakeScale(0.3, 0.3);

        rabit.transform = CGAffineTransformRotate(rabit.transform, M_PI * 0.4);

        

        CABasicAnimation *yurayura = [CABasicAnimation animationWithKeyPath:@”transform.translation.y”];

        yurayura.fromValue = [NSNumber numberWithDouble:rabit.center.y120];

        yurayura.toValue = [NSNumber numberWithDouble:rabit.center.y110];

        yurayura.autoreverses = YES;

        yurayura.repeatCount = 10;

        yurayura.duration = 1.0;

        yurayura.fillMode = kCAFillModeForwards;

        yurayura.removedOnCompletion = NO;

        yurayura.delegate = self;

        [rabit.layer addAnimation:yurayura forKey:@”yurayura”];

        

        [cloud1.layer addAnimation:yurayura forKey:@”yura”];

        

        [UIView animateWithDuration:1.0 animations:^{

            cloud1.center = CGPointMake(cloud1.center.x500, cloud1.center.y);

            rabit.center = CGPointMake(rabit.center.x500, 120);

        } completion:^(BOOL finished) {

            

            cloud2 = [[UIImageView alloc] initWithImage:cloud2Img];

            cloud2.frame = self.view.bounds;

            cloud2.center = CGPointMake(cloud2.center.x500, cloud2.center.y);

            [self.view insertSubview:cloud2 aboveSubview:rabit];

            

            cloud3 = [[UIImageView alloc] initWithImage:cloud3Img];

            cloud3.frame = self.view.bounds;

            cloud3.center = CGPointMake(cloud3.center.x500, cloud3.center.y);

            [self.view insertSubview:cloud3 belowSubview:cloud1];

            

            [UIView animateWithDuration:30.0 animations:^{

                cloud2.center = CGPointMake(800, cloud2.center.y);

            }];

            [UIView animateWithDuration:20.0 animations:^{

                cloud3.center = CGPointMake(800, cloud3.center.y);

            }];

            

            comment1 = [[UIImageView alloc] initWithImage:comment1Img];

            comment1.frame = self.view.bounds;

            comment1.alpha = 0;

            [self.view addSubview:comment1];

            [UIView animateWithDuration:0.5 animations:^{

                comment1.alpha = 1.0;

            } completion:^(BOOL finished) {

                [UIView animateWithDuration:2.0 animations:^{

                    comment1.alpha = 0;

                }];

            }];

        }];

    } afterDelay:delay];

    

}

– (void)scene2

{

    // 目覚ましへのカウントダウン

    fukidasi = [[UIImageView alloc] initWithImage:fukidasiImg];

    fukidasi.alpha = 0.0;

    fukidasi.frame = self.view.bounds;

    fukidasi.transform = CGAffineTransformMakeScale(0.3, 0.3);

    [self.view addSubview:fukidasi];

    

    for (int i=1;i<11;i++) {

        UILabel *l = [self createWord:[NSString stringWithFormat:@”%d”, i] size:40];

        l.center = CGPointMake(-50, 200);

        l.backgroundColor = [UIColor clearColor];

        l.textColor = [UIColor redColor];

        l.transform = CGAffineTransformMakeScale(0.5, 0.5);

        [self.view addSubview:l];

        [UIView animateWithDuration:3.0 delay:1.0*i options:UIViewAnimationOptionCurveLinear animations:^{

            l.center = CGPointMake(300, 250);

            l.transform = CGAffineTransformMakeScale(1 + 0.1*i, 1+ 0.1*i);

        } completion:^(BOOL finished) {

            fukidasi.center = l.center;

            fukidasi.alpha = 0.8;

            fukidasi.transform = CGAffineTransformMakeScale(0.3 + 0.1*i, 0.3+ 0.1*i);

            [UIView animateWithDuration:0.2 animations:^{

                fukidasi.alpha = 0;

            }];

            

            [UIView animateWithDuration:3.0 animations:^{

                l.center = CGPointMake(600, 200);

                l.transform = CGAffineTransformMakeScale(0.5, 0.5);

            } completion:^(BOOL finished) {

                [l removeFromSuperview];

            }];

        }];

    }

    

    // うさぎハッとする

    float delay = 15.0;

    [self showScene:^{

        rabitface.image = rabitFace2Img;

        

        //コメント「?」

        comment1.image = comment2Img;

        comment1.transform = CGAffineTransformMakeTranslation(300, 0);

        [UIView animateWithDuration:0.5 animations:^{

            comment1.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:2.0 animations:^{

                comment1.alpha = 0;

                comment1.transform = CGAffineTransformMakeTranslation(300, –100);

            } completion:^(BOOL finished) {

                comment1.transform = CGAffineTransformIdentity;

            }];

        }];

        

    } afterDelay:delay];

    

}

– (void)scene3

{

    // ジリリリ

    jiriri = [[UIImageView alloc] initWithImage:jirijiriImg];

    jiriri.frame = self.view.bounds;

    jiriri.alpha = 0.6;

    [self.view addSubview:jiriri];

    

    CABasicAnimation *kuru = [CABasicAnimation animationWithKeyPath:@”transform.rotation.z”];

    kuru.fromValue = [NSNumber numberWithDouble:0];

    kuru.toValue = [NSNumber numberWithDouble:M_PI*1.99];

    kuru.repeatCount = 10;

    kuru.duration = 1.0;

    kuru.fillMode = kCAFillModeForwards;

    kuru.removedOnCompletion = NO;

    [jiriri.layer addAnimation:kuru forKey:@”kuru”];

    

    // 斜めに入ってくる

    secondFrame = [[UIView alloc] initWithFrame:self.view.bounds];

    secondFrame.backgroundColor = [UIColor blackColor];

    secondFrame.transform = CGAffineTransformMakeRotation(M_PI * 0.2);

    secondFrame.transform = CGAffineTransformTranslate(secondFrame.transform, 800, 320);

    [self.view insertSubview:secondFrame belowSubview:jiriri];

    

    [UIView animateWithDuration:8.0 animations:^{

        cloud1.transform = CGAffineTransformTranslate(cloud1.transform, –100, –100);

        rabit.transform = CGAffineTransformTranslate(rabit.transform, –100, –100);

        secondFrame.transform = CGAffineTransformIdentity;

    }];

    

    // 妖精?

    hourman = [[UIImageView alloc] initWithImage:hourmanImg];

    hourman.frame = self.view.bounds;

    [secondFrame addSubview:hourman];

    

    minuteman = [[UIImageView alloc] initWithImage:minutemanImg];

    minuteman.frame = self.view.bounds;

    [secondFrame addSubview:minuteman];

    

    secondman = [[UIImageView alloc] initWithImage:secondmanImg];

    secondman.frame = self.view.bounds;

    [secondFrame addSubview:secondman];

    

    

    // 時計

    clockbody = [[UIImageView alloc] initWithImage:clockbodyImg];

    clockbody.frame = CGRectMake(0,0,self.view.bounds.size.width, self.view.bounds.size.width);

    clockbody.center = secondFrame.center;

    clockbody.alpha = 0.7;

    [secondFrame addSubview:clockbody];

    

    hourhand = [[UIImageView alloc] initWithImage:hourhandImg];

    hourhand.frame = CGRectMake(0,0,self.view.bounds.size.width, self.view.bounds.size.width);

    [clockbody addSubview:hourhand];

    

    minutehand = [[UIImageView alloc] initWithImage:minutehandImg];

    minutehand.frame = CGRectMake(0,0,self.view.bounds.size.width, self.view.bounds.size.width);

    [clockbody addSubview:minutehand];

    

    secondhand = [[UIImageView alloc] initWithImage:secondhandImg];

    secondhand.frame = CGRectMake(0,0,self.view.bounds.size.width, self.view.bounds.size.width);

    [clockbody addSubview:secondhand];

    CABasicAnimation *kuru2 = [CABasicAnimation animationWithKeyPath:@”transform.rotation.z”];

    kuru2.fromValue = [NSNumber numberWithDouble:M_PI*1.99];

    kuru2.toValue = [NSNumber numberWithDouble:0];

    kuru2.repeatCount = 3;

    kuru2.duration = 5.0;

    kuru2.fillMode = kCAFillModeForwards;

    kuru2.removedOnCompletion = NO;

    [clockbody.layer addAnimation:kuru2 forKey:@”kurukuru”];

    

    //ウサギ、落ちる

    float delay = 5.0;

    [self.view addSubview:rabit];

    [self showScene:^{

        //コメント「おちる」

        comment1.image = comment4Img;

        [self.view addSubview:comment1];

        [UIView animateWithDuration:0.5 animations:^{

            comment1.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:2.0 animations:^{

                comment1.alpha = 0;

            }];

        }];

        

        [UIView animateWithDuration:5.0 animations:^{

            rabit.center = CGPointMake(rabit.center.x, rabit.center.y + 500);

        }];

    } afterDelay:delay];

    

}

– (void)scene4

{

    // ベット、うさぎ、妖精

    bedFrame = [[UIImageView alloc] initWithImage:bedFrameImg];

    bedFrame.frame = self.view.bounds;

    [self.view insertSubview:bedFrame atIndex:0];

    

    [self.view insertSubview:rabit atIndex:1];

    rabit.center = CGPointMake(220, 170);

    rabit.transform = CGAffineTransformRotate(rabit.transform, M_PI * 0.9);

    rabitface.image = rabitFace1Img;

    

    bedCover = [[UIImageView alloc] initWithImage:bedCoverImg];

    bedCover.frame = self.view.bounds;

    [self.view insertSubview:bedCover atIndex:2];

 

    

    // 夢から覚める

    [UIView animateWithDuration:2.0 animations:^{

        backscreen.alpha = 0;

        secondFrame.alpha = 0;

    } completion:^(BOOL finished) {

        [cloud1 removeFromSuperview];

        [backscreen removeFromSuperview];

        [secondFrame removeFromSuperview];

        

        hourman.transform = CGAffineTransformMakeScale(0.4, 0.4);

        hourman.transform = CGAffineTransformRotate(hourman.transform, M_PI*0.5);

        hourman.center = CGPointMake(80, 60);

        [self.view addSubview:hourman];

        

        minuteman.transform = CGAffineTransformMakeScale(0.4, 0.4);

        minuteman.center = CGPointMake(100, 60);

        [self.view addSubview:minuteman];

        

        secondman.transform = CGAffineTransformMakeScale(0.4, 0.4);

        secondman.transform = CGAffineTransformRotate(secondman.transform, M_PI*0.5);

        secondman.center = CGPointMake(120, 60);

        [self.view addSubview:secondman];

    }];

    

    float delay = 2.0;

    [self showScene:^{

        // ジリリを上に

        [UIView animateWithDuration:3.0 animations:^{

            jiriri.center = CGPointMake(jiriri.center.x, jiriri.center.y300);

        } completion:^(BOOL finished) {

            // 妖精ジャンプ、その後にげさる

            CABasicAnimation *pyon = [CABasicAnimation animationWithKeyPath:@”transform.translation.y”];

            pyon.fromValue = [NSNumber numberWithDouble:0];

            pyon.toValue = [NSNumber numberWithDouble:10];

            pyon.autoreverses = YES;

            pyon.repeatCount = 3;

            pyon.duration = 0.2;

            pyon.fillMode = kCAFillModeForwards;

            pyon.removedOnCompletion = NO;

            [hourman.layer addAnimation:pyon forKey:@”pyon”];

            [minuteman.layer addAnimation:pyon forKey:@”pyon”];

            [secondman.layer addAnimation:pyon forKey:@”pyon”];

            

            [self showScene:^{

                [UIView animateWithDuration:1.0 animations:^{

                    hourman.center = CGPointMake(-100, hourman.center.y);

                    secondman.center = CGPointMake(-200, secondman.center.y);

                    minuteman.center = CGPointMake(-150, minuteman.center.y);

                }];

            } afterDelay:0.7];

        }];

    } afterDelay:delay];

    

    for (int i=0; i<5; i++) {

        delay += 0.3;

        [self showScene:^{

            // 目をぱちぱち

            rabitface.image = rabitFace3Img;

        } afterDelay:delay];

        

        delay += 0.3;

        [self showScene:^{

            // 目をぱちぱち

            rabitface.image = rabitFace1Img;

        } afterDelay:delay];

    }

    delay += 0.3;

    [self showScene:^{

        // 目をぱちぱち

        rabitface.image = rabitFace3Img;

    } afterDelay:delay];

    

    

    

}

#pragma – mark TLR Create Helper

– (void)showScene:(void (^)(void))block afterDelay:(NSTimeInterval)delay

{

    [self performSelector:@selector(executeBlock:) withObject:block afterDelay:delay];

}

– (void)executeBlock:(void (^)(void))block

{

    block();

}

– (UILabel*)createWord:(NSString*)word size:(int)size

{

    OutLineLabel *label = [[OutLineLabel alloc] init];

    label.font = [UIFont fontWithName:@”Chalkduster” size:30];

    label.text = word;

    label.backgroundColor = [UIColor clearColor];

    [label sizeToFit];

    return label;

}

– (void)createOpening

{

    UIImage *rocket = [UIImage imageNamed:@”rocket_back.jpg”];

    startView = [[UIImageView alloc] initWithImage:rocket];

    [self.view addSubview:startView];

    

    UILabel *l = [self createWord:@” Start \n\n Tokyo Little Rocket\n 05″ size:30];

    l.numberOfLines = 0;

    l.textColor = [UIColor blueColor];

    l.frame = CGRectMake(0, 0, 500, 320);

    l.center = startView.center;

    [startView addSubview:l];

}

– (void)createEnding

{

    UIImage *rocket = [UIImage imageNamed:@”rocket_back.jpg”];

    UIImageView *endView = [[UIImageView alloc] initWithImage:rocket];

    endView.frame = CGRectMake(0, –340, 500, 320);

    [self.view addSubview:endView];

    

    UILabel *l = [self createWord:@” End \n\n Tokyo Little Rocket\n 05″ size:30];

    l.numberOfLines = 0;

    l.textColor = [UIColor redColor];

    l.frame = CGRectMake(0, 0, 500, 320);

    [endView addSubview:l];

    [UIView animateWithDuration:1 animations:^{

        endView.center = CGPointMake(250, 160);

    }];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end