第8回「時計 ねんね PM 9:00」

今週のあらすじ
いつまでもテレビを見て寝ないヒョードル
居眠りしていると部屋の様子がおかしいぞ
気付けば雲にのって空の上
雲の布団はきもちいな〜ふわふわ〜
と、夢の中

東京リトルロケットは四コマちょっとアニメです。
ちょっとだけアニメーションするようにiOSでプログラム。( iPhoneで動かしています。)
作:nakai & mizusima

元の四コマ

サンプルコード

@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>

#import <AVFoundation/AVFoundation.h>

@interface ViewController () {

    UIView *startView;

    

    UIImage *livingroomImg, *bedroomImg;

    UIImage *comfortersImg;

    UIImage *cloud1Img, *cloud2Img;

    UIImage *clockImg1, *clockImg2;

    UIImage *hourhandImg, *minutehandImg, *secondhandImg;

    UIImage *rabitbodyImg, *rabitheadImg;

    UIImage *face1Img, *face2Img, *face3Img, *face4Img;

    UIImage *starImg;

    UIImage *dreamframeImg;

    NSMutableArray *comments;

    

    UIImageView *backScene;

    UIImageView *comforters;

    UIImageView *dreamframe;

    UIImageView *clock;

    UIImageView *hourhand, *minutehand, *secondhand;

    UIImageView *rabitbody, *rabithead, *rabitface;

    UIImageView *commentA;

    UIImageView *commentB;

    UIImageView *cloud1, *cloud2;

    UIImageView *star;

    

    UIImageView *dreamScreenShot;

    

    UIView *blueBack;

    

    NSTimer *timer;

    float clockTime;

    

    AVAudioPlayer *player;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    [self prepareSound];

    

    self.view.backgroundColor = [UIColor blackColor];

    [self loadResource];

    [self createOpening];

}

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

{

    static int lock;

    if(lock == 0) {

        lock++;

        [self showProgram];

    }

//    

//    CGPoint p = [[touches anyObject] locationInView:clock];

//    NSLog(@”%f %f”, p.x, p.y);

}

– (void)loadResource

{

    clockImg1 = [UIImage imageNamed:@”clock1″];

    clockImg2 = [UIImage imageNamed:@”clock2″];

    

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

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

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

    

    livingroomImg = [UIImage imageNamed:@”scene1″];

    bedroomImg = [UIImage imageNamed:@”bed”];

    dreamframeImg = [UIImage imageNamed:@”dreamframe”];

    comfortersImg = [UIImage imageNamed:@”comforters”];

    

    cloud1Img = [UIImage imageNamed:@”cloud”];

    cloud2Img = [UIImage imageNamed:@”clouds”];

    

    rabitbodyImg = [UIImage imageNamed:@”rabitbody”];

    rabitheadImg = [UIImage imageNamed:@”rabithead”];

    face1Img = [UIImage imageNamed:@”facesmile”];

    face2Img = [UIImage imageNamed:@”face2″];

    face3Img = [UIImage imageNamed:@”face3″];

    face4Img = [UIImage imageNamed:@”face4″];

    

    starImg = [UIImage imageNamed:@”star”];

    

    comments = [[NSMutableArray alloc] init];

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

        [comments addObject:[UIImage imageNamed:[NSString stringWithFormat:@”comment%d”, i+1]]];

    }

}

– (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 += 13;

    [self showScene:^{

        [self scene2];

    } afterDelay:delay];

    

    // シーン 3

    delay += 5;

    [self showScene:^{

        [self scene3];

    } afterDelay:delay];

    

    // シーン 4

    delay += 10;

    [self showScene:^{

        [self scene4];

    } afterDelay:delay];

    

    // end

    delay += 13;

    [self showScene:^{

        [self createEnding];

    } afterDelay:delay];

    delay += 1.5;

    [self showScene:^{

        [self playSound:@”end”];

    } afterDelay:delay];

    

}

– (void)scene1

{

    backScene = [[UIImageView alloc] initWithImage:livingroomImg];

    backScene.frame = self.view.bounds;

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

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

    rabitbody.frame = self.view.bounds;

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

    

    rabithead = [[UIImageView alloc] initWithImage:rabitheadImg];

    rabithead.frame = self.view.bounds;

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

    

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

    rabitface.frame = self.view.bounds;

    [rabithead addSubview:rabitface];

    

    clock = [[UIImageView alloc] initWithImage:clockImg1];

    clock.frame = self.view.bounds;

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

    

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

    hourhand.frame = self.view.bounds;

    [clock addSubview:hourhand];

    

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

    minutehand.frame = self.view.bounds;

    [clock addSubview:minutehand];

    

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

    secondhand.frame =self.view.bounds;

    [clock addSubview:secondhand];

    

    // 頭こっくりこっくり

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

    kokukoku.repeatCount = 4;

    kokukoku.autoreverses = YES;

    kokukoku.toValue = [NSNumber numberWithFloat:-M_PI * 0.1];

    kokukoku.duration = 2.0;

    [rabithead.layer addAnimation:kokukoku forKey:@”koku”];

    

    

    [self start];

    

    // 2159…. ちょうど九時で終わるように調整

    clockTime = 21 * 60 * 60 + 59 * 60 + 26;

    

    float delay = 2.0;

    // コメント:「はやくねなさい」

    [self showScene:^{

        commentB = [[UIImageView alloc] initWithImage:[comments objectAtIndex:1]];

        commentB.frame = self.view.bounds;

        commentB.transform = CGAffineTransformMakeTranslation(0, 150);

        [self.view addSubview:commentB];

        [UIView animateWithDuration:0.5 animations:^{

            commentB.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:5.0 animations:^{

                commentB.alpha = 0;

            }];

        }];

    } afterDelay:delay];

    

    

    // コメント:「まだテレビみるの」

    delay += 3.0;

    [self showScene:^{

        commentA = [[UIImageView alloc] initWithImage:[comments objectAtIndex:0]];

        commentA.frame = self.view.frame;

        commentA.transform = CGAffineTransformMakeTranslation(0, 100);

        [self.view addSubview:commentA];

        [UIView animateWithDuration:4.0 animations:^{

            commentA.alpha = 0;

        }];

    } afterDelay:delay];

    

    

    // コメント:「もう九時よ」

    delay += 3.0;

    [self showScene:^{

        commentB.image = [comments objectAtIndex:2];

        [self.view addSubview:commentB];

        [UIView animateWithDuration:0.5 animations:^{

            commentB.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:5.0 animations:^{

                commentB.alpha = 0;

            }];

        }];

    } afterDelay:delay];

}

– (void)scene2

{

    // シーン転換 夢の中へ

    dreamframe = [[UIImageView alloc] initWithImage:dreamframeImg];

    dreamframe.frame = self.view.bounds;

    dreamframe.transform = CGAffineTransformMakeScale(1.1, 1.1);

    dreamframe.alpha = 0;

    [self.view addSubview:dreamframe];

    

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

    blueBack.backgroundColor = [UIColor blueColor];

    [self.view insertSubview:blueBack belowSubview:backScene];

    

    [UIView animateWithDuration:3.0 animations:^{

        backScene.alpha = 0;

        dreamframe.alpha = 1.0;

    }];

    

    star = [[UIImageView alloc] initWithImage:starImg];

    [self.view addSubview:star];

    star.alpha = 0;

    

    // コメント「あれ?」

    float delay = 1.0;

    [self showScene:^{

        rabitface.image = face3Img;

        commentA.image = [comments objectAtIndex:4];

        commentA.transform = CGAffineTransformMakeTranslation(-50, –150);

        [UIView animateWithDuration:0.5 animations:^{

            commentA.alpha = 1.0;

            star.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:5.0 animations:^{

                commentA.alpha = 0;

                star.alpha = 0;

            }];

        }];

    } afterDelay:delay];

}

– (void)scene3

{

    CAGradientLayer *layer = [CAGradientLayer layer];

    layer.frame = self.view.bounds;

    //    144, 215, 236

    UIColor *c1 = [UIColor colorWithRed:144.0/255.0 green:215.0/255.0 blue:226.0/255.0 alpha:1.0];

    UIColor *c2 = [UIColor colorWithRed:144.0/255.0 green:215.0/255.0 blue:255.0/255.0 alpha:1.0];

    layer.colors = [NSArray arrayWithObjects:(id)c1.CGColor, (id)c2.CGColor, nil];

    layer.startPoint = CGPointMake(0.5, 0.4);

    layer.endPoint = CGPointMake(0.5, 1.0);

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

    backSky.alpha = 0;

    [backSky.layer addSublayer:layer];

    [blueBack addSubview:backSky];

    

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

    cloud1.frame = self.view.bounds;

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

    cloud1.alpha = 0;

    

    CABasicAnimation *pukupuku = [CABasicAnimation animationWithKeyPath:@”transform.scale”];

    pukupuku.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];

    pukupuku.toValue =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)];

    pukupuku.repeatCount = 6;

    pukupuku.autoreverses = YES;

    pukupuku.duration = 1.0;

    [cloud1.layer addAnimation:pukupuku forKey:@”puku”];

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

    cloud2.frame = self.view.bounds;

    cloud2.transform = CGAffineTransformMakeScale(0.6, 0.6);

    [self.view insertSubview:cloud2 belowSubview:backScene];

    cloud2.alpha = 0;

    

    CABasicAnimation *pukupuku2 = [CABasicAnimation animationWithKeyPath:@”transform.scale”];

    pukupuku2.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1.0)];

    pukupuku2.toValue =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.4, 0.4, 1.0)];

    pukupuku2.repeatCount = 4;

    pukupuku2.autoreverses = YES;

    pukupuku2.duration = 1.5;

    [cloud2.layer addAnimation:pukupuku2 forKey:@”puku”];

    

    [UIView animateWithDuration:0.5 animations:^{

        clock.alpha = 0;

        backSky.alpha = 1.0;

        cloud2.alpha = 1.0;

        rabitbody.alpha = 0;

        rabithead.alpha = 0;

    } completion:^(BOOL finished) {

        cloud1.alpha = 1.0;

        rabitbody.transform = CGAffineTransformMakeTranslation(0, 200);

        rabithead.transform = CGAffineTransformMakeTranslation(0, 200);

        cloud1.transform = CGAffineTransformMakeTranslation(0, 200);

        [UIView animateWithDuration:0.5 animations:^{

            rabitbody.transform = CGAffineTransformIdentity;

            rabithead.transform = CGAffineTransformIdentity;

            cloud1.transform = CGAffineTransformIdentity;

            rabitbody.alpha = 1;

            rabithead.alpha = 1;

        }];

    }];

    

    float delay = 1.0;

    

    [self showScene:^{

        rabitface.image = face1Img;

    } afterDelay:delay];

    

    

    // コメント「雲の布団だ」

    delay += 1.0;

    [self showScene:^{

        commentA.image = [comments objectAtIndex:5];

        commentA.transform = CGAffineTransformMakeTranslation(100, 60);

        [UIView animateWithDuration:0.5 animations:^{

            commentA.alpha = 1.0;

        }];

    } afterDelay:delay];

    

    

    // コメント「きもちいい」

    delay += 3.0;

    [self showScene:^{

        commentA.image = [comments objectAtIndex:6];

        commentA.transform = CGAffineTransformMakeTranslation(100, 60);

        

        [UIView animateWithDuration:3.0 animations:^{

            commentA.alpha = 0.5;

        } completion:^(BOOL finished) {

            commentA.alpha = 0;

            

            // capture screen

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

                dreamScreenShot = [[UIImageView alloc] initWithImage:[self captureScreen]];

                CALayer *mask = [CALayer layer];

                mask.contents = (id)[[UIImage imageNamed:@”mask”] CGImage];

                mask.frame = CGRectMake(60, 60, dreamScreenShot.bounds.size.width120, dreamScreenShot.bounds.size.height120);

                dreamScreenShot.layer.mask = mask;

                dreamScreenShot.layer.masksToBounds = YES;

                dreamScreenShot.layer.opacity = 0.8;

            });

            

            

        }];

    } afterDelay:delay];

}

– (void)scene4

{

    // set up real space

    backScene.image = bedroomImg;

    backScene.alpha = 1.0;

    comforters = [[UIImageView alloc] initWithImage:comfortersImg];

    comforters.frame = self.view.bounds;

    [self.view addSubview:comforters];

    rabitface.image = face2Img;

    

    clock.image = clockImg2;

    clock.alpha = 1;

    

    // overlay captuer screen

    [self.view addSubview:dreamScreenShot];

    [blueBack removeFromSuperview];

    [dreamframe removeFromSuperview];

    

    [UIView animateWithDuration:3.0 animations:^{

        CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);

        transform = CGAffineTransformTranslate(transform, 300, –150);

        dreamScreenShot.transform = transform;

    } completion:^(BOOL finished) {

        CABasicAnimation *puku = [CABasicAnimation animationWithKeyPath:@”transform.scale”];

        puku.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1.0)];

        puku.toValue =   [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.6, 0.6, 1.0)];

        puku.repeatCount = 4;

        puku.autoreverses = YES;

        puku.duration = 1.5;

        [dreamScreenShot.layer addAnimation:puku forKey:@”puku”];

    }];

    

    float delay = 1.0;

    

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

        delay += 0.4;

        [self showScene:^{

            UILabel *z = [self createWord:@”Z” size:50];

            z.textColor = [UIColor blueColor];

            z.center = CGPointMake(260 + i*50, 150);

            z.transform = CGAffineTransformMakeTranslation(0, –300);

            [self.view addSubview:z];

            

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

            move.fromValue = [NSNumber numberWithInt:0];

            move.toValue = [NSNumber numberWithInt:-100];

            move.duration = 3.0;

            move.repeatCount = 1;

            [z.layer addAnimation:move forKey:@”move”];

            

        } afterDelay:delay];

    }

    

    

    // コメント「九時だよ」

    delay += 6.01.2;

    [self showScene:^{

        commentB.image = [comments objectAtIndex:7];

        [self.view addSubview:commentB];

        commentB.transform = CGAffineTransformMakeTranslation(30, –150);

        [UIView animateWithDuration:0.5 animations:^{

            commentB.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:5.0 animations:^{

                dreamScreenShot.alpha = 0;

                commentB.alpha = 0;

            }];

        }];        

    } afterDelay:delay];

    

    delay += 2.0;

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

        delay += 0.4;

        [self showScene:^{

            UILabel *z = [self createWord:@”Z” size:50];

            z.textColor = [UIColor blueColor];

            z.center = CGPointMake(260 + i*50, 150);

            z.transform = CGAffineTransformMakeTranslation(0, –300);

            [self.view addSubview:z];

            

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

            move.fromValue = [NSNumber numberWithInt:0];

            move.toValue = [NSNumber numberWithInt:-100];

            move.duration = 3.0;

            move.repeatCount = 1;

            [z.layer addAnimation:move forKey:@”move”];

            

        } afterDelay:delay];

    }

    

    // コメント「おやすみ」

    delay += 3.02.2;

    [self showScene:^{

        commentB.image = [comments objectAtIndex:8];

        [self.view addSubview:commentB];

        [UIView animateWithDuration:0.5 animations:^{

            commentB.alpha = 1.0;

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:5.0 animations:^{

                commentB.alpha = 0;

            }];

        }];

    } afterDelay:delay];

    

    delay += 4.0;

    [self showScene:^{

        [timer invalidate];

    } afterDelay:delay];

}

– (UIImage*)captureScreen

{

    UIGraphicsBeginImageContext(self.view.bounds.size);

    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *captureImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return captureImage;

}

– (void)turnView:(UIView*)v atPoint:(CGPoint)p angle:(float)angle

{

    CGAffineTransform t = CGAffineTransformIdentity;

    t = CGAffineTransformTranslate(t, -(v.center.x – p.x), -(v.center.y – p.y));

    t = CGAffineTransformRotate(t, angle);

    t = CGAffineTransformTranslate(t, v.center.x – p.x, v.center.y – p.y);

    v.transform = t;

}

– (void)start

{

    timer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(tick) userInfo:nil repeats:YES];

}

– (void)tick

{

    clockTime += 1.0 / 60.0;

    

    

    int hours = clockTime / pow(60.0, 2);

    int minutes = (clockTime – hours * pow(60.0, 2)) / 60.0;

    int seconds = clockTime – hours * pow(60.0, 2) – minutes * 60.0;

    

    CGPoint handCenter = CGPointMake(113, 57);

    

    // second hand

    // 1 seconds = 2 * PI / 60

    // image origin is 50 seconds.

    float secondAngle = (seconds – 10) * (2 * M_PI / 60.0);

    [self turnView:secondhand atPoint:handCenter angle:secondAngle];

    

    // minutehand

    float minuteAngle = minutes * (2 * M_PI / 60.0);

    [self turnView:minutehand atPoint:handCenter angle:minuteAngle];

    

    // hourhand

    float hourAngle = (5 * (hours + minutes / 60.0) + 9) * (2 * M_PI / 60.0);

    [self turnView:hourhand atPoint:handCenter angle:hourAngle];

    

    // sound clock

    if (clockTime – (hours * 60 * 60 + minutes * 60 + seconds) == 0) {

        [self playSound:@”second”];

    }

    

}

– (void)prepareSound

{

    NSString *path = [[NSBundle mainBundle] pathForResource:@”second” ofType:@”mp3″];

    player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];

    [player prepareToPlay];

}

#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:size];

    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 08″ 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 08″ 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)playSound:(NSString*)name

{

    if ([player isPlaying]) {

        [player stop];

    }

    NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@”mp3″];

    player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];

    [player prepareToPlay];

    [player play];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end