タイトル
第7回「時計 おやつ PM 3:00」
今週のあらすじ
今日の主役は時計の針たちです。
チビは駆け足、ノッポはお散歩、太っちょはマイペース。
ウサギのヒョードルはおやつが待ちきれません。
ずーっと時計とにらめっこです。
東京リトルロケット
Tokyo Little Rocket は4コマ漫画をプログラムでショートアニメにするという企画です
四コマの絵
サンプルコード
@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 *clockImg;
UIImage *hourhandImg, *minutehandImg, *secondhandImg;
NSMutableArray *comments;
UIImageView *backScene;
UIImageView *clock;
UIImageView *hourhand, *minutehand, *secondhand;
UIImageView *commentA;
UIImageView *commentB;
NSTimer *timer;
float clockTime;
float nextStartTime;
BOOL clockup;
float clockupRate;
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
{
clockImg = [UIImage imageNamed:@”clock”];
hourhandImg = [UIImage imageNamed:@”hourhand”];
minutehandImg = [UIImage imageNamed:@”minutehand”];
secondhandImg = [UIImage imageNamed:@”secondhand”];
comments = [[NSMutableArray alloc] init];
for (int i=0; i<10; 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];
}];
// clock
clockupRate = 1200.0;
// シーン 1
float delay = 0;
[self showScene:^{
[self scene1];
} afterDelay:delay];
// シーン 2
delay += 16;
[self showScene:^{
[self scene2];
} afterDelay:delay];
// シーン 3
delay += 16;
[self showScene:^{
[self scene3];
} afterDelay:delay];
// シーン 4
delay += 20;
[self showScene:^{
[self scene4];
} afterDelay:delay];
// end
delay += 22;
[self showScene:^{
[self createEnding];
[self playSound:@”end”];
} afterDelay:delay];
}
– (void)scene1
{
clock = [[UIImageView alloc] initWithImage:clockImg];
clock.frame = self.view.bounds;
[self.view insertSubview:clock belowSubview:startView];
hourhand = [[UIImageView alloc] initWithImage:hourhandImg];
hourhand.frame = self.view.bounds;
[self.view insertSubview:hourhand belowSubview:startView];
minutehand = [[UIImageView alloc] initWithImage:minutehandImg];
minutehand.frame = self.view.bounds;
[self.view insertSubview:minutehand belowSubview:startView];
secondhand = [[UIImageView alloc] initWithImage:secondhandImg];
secondhand.frame =self.view.bounds;
[self.view insertSubview:secondhand belowSubview:startView];
[self start];
// 12時26分50秒
clockTime = 12 * 60 * 60 + 26 * 60 + 50;
// コメント:「まま、おやつまだ?」
float delay = 4.0;
[self showScene:^{
commentA = [[UIImageView alloc] initWithImage:[comments objectAtIndex:0]];
commentA.frame = self.view.bounds;
[self.view addSubview:commentA];
[UIView animateWithDuration:4.0 animations:^{
commentA.alpha = 0;
}];
} afterDelay:delay];
// コメント:「たべたばかりでしょ」
delay += 4.0;
[self showScene:^{
commentB = [[UIImageView alloc] initWithImage:[comments objectAtIndex:1]];
commentB.frame = self.view.bounds;
commentB.transform = CGAffineTransformMakeTranslation(-250, 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];
// コメント:「おやつは3時になってからよ」
delay += 4.0;
[self showScene:^{
commentB.image = [comments objectAtIndex:2];
commentB.transform = CGAffineTransformMakeTranslation(-250, 120);
[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
{
clock.alpha = 0.2;
clockup = YES;
[self playSound:@”forward”];
// 13時03分
nextStartTime = 13 * 60 * 60 + 3 * 60;
float delay = (nextStartTime – clockTime) / clockupRate;
[self showScene:^{
clock.alpha = 1.0;
} afterDelay:delay];
// コメント:「まま、三時になった?」
delay += 1.0;
[self showScene:^{
commentA.image = [comments objectAtIndex:3];
commentA.transform = CGAffineTransformMakeTranslation(0, –150);
[UIView animateWithDuration:0.5 animations:^{
commentA.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentA.alpha = 0;
}];
}];
} afterDelay:delay];
// コメント:「まだ、一時間も経ってないわよ」
delay += 5.0;
[self showScene:^{
commentB.image = [comments objectAtIndex:4];
commentB.transform = CGAffineTransformMakeTranslation(-250, 0);
[UIView animateWithDuration:0.5 animations:^{
commentB.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentB.alpha = 0;
}];
}];
} afterDelay:delay];
}
– (void)scene3
{
clock.alpha = 0.2;
clockup = YES;
[self playSound:@”forward”];
// 14時30分
nextStartTime = 14 * 60 * 60 + 30 * 60;
float delay = (nextStartTime – clockTime) / clockupRate;
[self showScene:^{
clock.alpha = 1.0;
} afterDelay:delay];
// コメント:「まま、もう三時?」
delay += 1.0;
[self showScene:^{
commentA.image = [comments objectAtIndex:5];
commentA.transform = CGAffineTransformMakeTranslation(250, 0);
[UIView animateWithDuration:0.5 animations:^{
commentA.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentA.alpha = 0;
}];
}];
} afterDelay:delay];
// コメント:「もう少しかな」
delay += 5.0;
[self showScene:^{
commentB.image = [comments objectAtIndex:6];
commentB.transform = CGAffineTransformMakeTranslation(0, 150);
[UIView animateWithDuration:0.5 animations:^{
commentB.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentB.alpha = 0;
}];
}];
} afterDelay:delay];
}
– (void)scene4
{
clock.alpha = 0.2;
clockup = YES;
[self playSound:@”forward”];
// 14時59分55秒
nextStartTime = 14 * 60 * 60 + 59 * 60 + 55;
float delay = (nextStartTime – clockTime) / clockupRate;
[self showScene:^{
clock.alpha = 1.0;
} afterDelay:delay];
delay += 5.0;
[self showScene:^{
commentA.image = [comments objectAtIndex:9];
commentA.transform = CGAffineTransformMakeTranslation(0, 0);
[UIView animateWithDuration:0.5 animations:^{
commentA.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentA.alpha = 0;
}];
}];
} afterDelay:delay];
// コメント:「3時になったわよ。」
delay += 5.0;
[self showScene:^{
commentB.image = [comments objectAtIndex:7];
commentB.transform = CGAffineTransformIdentity;
[UIView animateWithDuration:0.5 animations:^{
commentB.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentB.alpha = 0;
}];
}];
for (int i=0; i<3; i++) {
UILabel *zzz = [self createWord:@”z” size:60];
zzz.center = CGPointMake(500, 320);
zzz.backgroundColor = [UIColor clearColor];
zzz.textColor = [UIColor blueColor];
[self.view addSubview:zzz];
[UIView animateWithDuration:4.0 delay:0.2*i options:UIViewAnimationOptionAutoreverse animations:^{
zzz.center = CGPointMake(-60, –60);
} completion:^(BOOL finished) {
[zzz removeFromSuperview];
}];
}
} afterDelay:delay];
delay += 5.0;
[self showScene:^{
commentA.image = [comments objectAtIndex:8];
commentA.transform = CGAffineTransformMakeTranslation(0, –100);
[UIView animateWithDuration:0.5 animations:^{
commentA.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:5.0 animations:^{
commentA.alpha = 0;
}];
}];
} afterDelay:delay];
delay += 1.0;
[self showScene:^{
[timer invalidate];
timer = nil;
} afterDelay:delay];
}
– (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
{
if (clockup) {
clockTime += clockupRate / 60.0;
if (clockTime > nextStartTime) {
clockup = NO;
clockTime = nextStartTime;
}
} else {
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(214, 150);
// second hand
// 1 seconds = 2 * PI / 60
// image origin is 50 seconds.
float secondAngle = (seconds – 50) * (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) – 14) * (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 07″ 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 07″ 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