第4回「雪合戦」です。

(※東京リトルロケット(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 *backImage;

    

    UIImage *snowballImg;

    UIImage *snowManImg;

    UIImage *snowImg;

    

    // papa

    UIImage *papaBodyImg;

    UIImage *papaHandR, *papaHandL;

    UIImage *papaFace1, *papaFace2, *papaFace3;

    

    // boku

    UIImage *bokuBodyImg;

    UIImage *bokuHandR, *bokuHandL;

    UIImage *bokuFace1, *bokuFace2, *bokuFace3, *bokuFace4;

    

    // mama

    UIImage *mamaBodyImg;

    UIImage *mamaHandR, *mamaHandL;

    UIImage *mamaFace1, *mamaFace2;

    

    //————

    // View

    //————

    UIView *papa;

    UIImageView *papaBody;

    UIImageView *papaHR, *papaHL;

    UIImageView *papaFace;

    

    UIView *boku;

    UIImageView *bokuBody;

    UIImageView *bokuHR, *bokuHL;

    UIImageView *bokuFace;

    UIImageView *bokuFaceSnow;

    

    UIView *mama;

    UIImageView *mamaBody;

    UIImageView *mamaHR, *mamaHL;

    UIImageView *mamaFace;

    

    UIImageView *back;

    UIImageView *snowBall;

    UIImageView *snowMan;

    UIImageView *snow;

}

@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

{

    backImage = [UIImage imageNamed:@”back”];

    snowballImg = [UIImage imageNamed:@”snowBall”];

    snowManImg = [UIImage imageNamed:@”snowMan”];

    snowImg = [UIImage imageNamed:@”snow”];

    papaBodyImg = [UIImage imageNamed:@”papabody”];

    papaHandR = [UIImage imageNamed:@”papaHandR”];

    papaHandL = [UIImage imageNamed:@”papaHandL”];

    papaFace1 = [UIImage imageNamed:@”papaFace1″];

    papaFace2 = [UIImage imageNamed:@”papaFace2″];

    papaFace3 = [UIImage imageNamed:@”papaFace3″];

    

    bokuBodyImg = [UIImage imageNamed:@”bokuBody”];

    bokuHandR = [UIImage imageNamed:@”bokuHandR”];

    bokuHandL = [UIImage imageNamed:@”bokuHandL”];

    bokuFace1 = [UIImage imageNamed:@”bokuFace1″];

    bokuFace2 = [UIImage imageNamed:@”bokuFace2″];

    bokuFace3 = [UIImage imageNamed:@”bokuFace3″];

    bokuFace4 = [UIImage imageNamed:@”bokuFace4″];

    

    mamaBodyImg = [UIImage imageNamed:@”mamaBody”];

    mamaHandR = [UIImage imageNamed:@”mamaHandR”];

    mamaHandL = [UIImage imageNamed:@”mamaHandL”];

    mamaFace1 = [UIImage imageNamed:@”mamaFace1″];

    mamaFace2 = [UIImage imageNamed:@”mamaFace2″];

}

– (void)showProgram

{

    // 幕を上げる

    [UIView animateWithDuration:1.0 animations:^{

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

    } completion:^(BOOL finished) {

        [startView removeFromSuperview];

    }];

    

    // シーン 1

    float delay = 0.5;

    [self showScene:^{

        [self scene1];

    } afterDelay:delay];

    

    // シーン 2

    delay += 3;

    [self showScene:^{

        [self scene2];

    } afterDelay:delay];

    // シーン 3

    delay += 5;

    [self showScene:^{

        [self scene3];

    } afterDelay:delay];

    // シーン 4

    delay += 3;

    [self showScene:^{

        [self scene4];

    } afterDelay:delay];

    

    // end

    delay += 1;

    [self showScene:^{

        [self createEnding];

    } afterDelay:delay];

    

}

– (void)scene1

{

    back = [[UIImageView alloc] initWithImage:backImage];

    back.frame = self.view.bounds;

    [self.view addSubview:back];

    

    snow = [[UIImageView alloc] initWithImage:snowImg];

    snow.transform = CGAffineTransformMakeScale(0.5, 0.5);

    snow.center = CGPointMake(150, 40);

    [self.view addSubview:snow];

    

    // papa

    papa = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 180)];

    papa.center = CGPointMake(150, 210);

    papa.transform = CGAffineTransformMakeScale(0.3, 0.3);

    papa.layer.transform = CATransform3DRotate(papa.layer.transform, M_PI, 0, 1, 0);

    [self.view addSubview:papa];

    

    

    papaHR = [[UIImageView alloc] initWithImage:papaHandR];

    papaHR.layer.anchorPoint = CGPointMake(155/papaHR.bounds.size.width, 40.0/papaHR.bounds.size.height);

    papaHR.center = CGPointMake(20,80);

    [papa addSubview:papaHR];

    

    papaBody = [[UIImageView alloc] initWithImage:papaBodyImg];

    papaBody.center = CGPointMake(papa.bounds.size.width * 0.5, papa.bounds.size.height * 0.5);

    [papa addSubview:papaBody];

    

    papaFace = [[UIImageView alloc] initWithImage:papaFace2];

    papaFace.center = CGPointMake(35,-10);

    [papa addSubview:papaFace];

    

    papaHL = [[UIImageView alloc] initWithImage:papaHandL];

    papaHL.center = CGPointMake(100,140);

    [papa addSubview:papaHL];

    

    

    

    // mama

    mama = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 180)];

    mama.center = CGPointMake(360, 180);

    mama.transform = CGAffineTransformMakeScale(0.3, 0.3);

    [self.view addSubview:mama];

    

    

    mamaHR = [[UIImageView alloc] initWithImage:mamaHandR];

    mamaHR.layer.anchorPoint = CGPointMake(135/mamaHR.bounds.size.width, 26.0/mamaHR.bounds.size.height);

    mamaHR.center = CGPointMake(0,80);

    [mama addSubview:mamaHR];

    

    mamaBody = [[UIImageView alloc] initWithImage:mamaBodyImg];

    mamaBody.center = CGPointMake(mama.bounds.size.width * 0.5, mama.bounds.size.height * 0.5);

    [mama addSubview:mamaBody];

    

    mamaFace = [[UIImageView alloc] initWithImage:mamaFace2];

    mamaFace.center = CGPointMake(35,-10);

    [mama addSubview:mamaFace];

    

    mamaHL = [[UIImageView alloc] initWithImage:mamaHandL];

    mamaHL.center = CGPointMake(100,140);

    [mama addSubview:mamaHL];

    

    

    // boku

    boku = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 120)];

    boku.center = CGPointMake(400, 230);

    boku.transform = CGAffineTransformMakeScale(0.3, 0.3);

    [self.view addSubview:boku];

    

    

    bokuHR = [[UIImageView alloc] initWithImage:bokuHandR];

    bokuHR.layer.anchorPoint = CGPointMake(100/bokuHR.bounds.size.width, 30.0/bokuHR.bounds.size.height);

    bokuHR.center = CGPointMake(-10,100);

    [boku addSubview:bokuHR];

    

    bokuBody = [[UIImageView alloc] initWithImage:bokuBodyImg];

    bokuBody.center = CGPointMake(boku.bounds.size.width * 0.5, boku.bounds.size.height * 0.5);

    [boku addSubview:bokuBody];

    

    bokuFace = [[UIImageView alloc] initWithImage:bokuFace2];

    bokuFace.center = CGPointMake(20,25);

    [boku addSubview:bokuFace];

    

    bokuHL = [[UIImageView alloc] initWithImage:bokuHandL];

    bokuHL.center = CGPointMake(60,150);

    [boku addSubview:bokuHL];

        

    snowBall = [[UIImageView alloc] initWithImage:snowballImg];

    snowBall.center = CGPointMake(80,100);

    [papaHR addSubview:snowBall];

    

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

    rota.duration = 0.6;

    rota.autoreverses = NO;

    rota.removedOnCompletion = NO;

    rota.fromValue = [NSNumber numberWithFloat: 0];

    rota.toValue = [NSNumber numberWithFloat: M_PI];

    [papaHR.layer addAnimation: rota forKey: @”rotation”];

    

    

    // パパが雪を投げる

    [self showScene:^{

        [UIView animateWithDuration:0.5 animations:^{

            papa.layer.transform = CATransform3DRotate(papa.layer.transform, 0.2*M_PI, 0, 0, 1);

        } completion:^(BOOL finished) {

            

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

            rota.duration = 0.5;

            rota.autoreverses = NO;

            rota.removedOnCompletion = NO;

            rota.fromValue = [NSNumber numberWithFloat: M_PI];

            rota.toValue = [NSNumber numberWithFloat: 0];

            [papaHR.layer addAnimation: rota forKey: @”rotation”];

            

            [UIView animateWithDuration:0.5 animations:^{

                papa.layer.transform = CATransform3DRotate(papa.layer.transform, –0.2*M_PI, 0, 0, 1);

            }];

        }];

    } afterDelay:0.1];

    

    // ボクの顔に雪が当たる

    [self showScene:^{

        [self.view insertSubview:papa aboveSubview:boku];

        

        [UIView animateWithDuration:1.0 animations:^{

            snowBall.center = [bokuFace convertPoint:bokuFace.center toView:papaHR

                               ];

        } completion:^(BOOL finished) {

            

            [UIView animateWithDuration:0.1 animations:^{

                snowBall.alpha = 0;

            }];

            

            bokuFaceSnow = [[UIImageView alloc] initWithImage:bokuFace4];

            bokuFaceSnow.center = CGPointMake(50, –20);

            [boku addSubview:bokuFaceSnow];

            [UIView animateWithDuration:0.3 animations:^{

                boku.center = CGPointMake(boku.center.x, boku.center.y10);

            } completion:^(BOOL finished) {

                [UIView animateWithDuration:0.2 animations:^{

                    boku.center = CGPointMake(boku.center.x, boku.center.y + 10);

                }];

            }];

        }];

    } afterDelay:0.8];

    

}

– (void)scene2

{

    

    // ボク:顔の雪を落とす。

    float delay = 0;

    

    bokuFace.image = bokuFace1;

    [UIView animateWithDuration:0.8 animations:^{

        bokuFaceSnow.alpha = 0.0;

    }];

    

    [UIView animateWithDuration:0.1 animations:^{

        boku.center = CGPointMake(boku.center.x5, boku.center.y10);

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:0.1 animations:^{

            boku.center = CGPointMake(boku.center.x5, boku.center.y + 10);

        }];

    }];

    

    delay += 0.2;

    [self showScene:^{

        [UIView animateWithDuration:0.1 animations:^{

            boku.center = CGPointMake(boku.center.x + 5, boku.center.y10);

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:0.1 animations:^{

                boku.center = CGPointMake(boku.center.x + 5, boku.center.y + 10);

            }];

        }];        

    } afterDelay:delay];

    

    

    // ボク、雪を投げかえす

    delay += 1.5;

    [self showScene:^{

        snowBall.alpha = 1.0;

        snowBall.center = CGPointMake(0, 50);

        [bokuHR addSubview:snowBall];

        

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

        rota.duration = 0.6;

        rota.autoreverses = NO;

        rota.removedOnCompletion = NO;

        rota.fromValue = [NSNumber numberWithFloat: 0];

        rota.toValue = [NSNumber numberWithFloat: M_PI];

        [bokuHR.layer addAnimation: rota forKey: @”rotation”];

        

        [UIView animateWithDuration:0.5 animations:^{

            boku.layer.transform = CATransform3DRotate(boku.layer.transform, 0.2*M_PI, 0, 0, 1);

        } completion:^(BOOL finished) {

            

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

            rota.duration = 0.5;

            rota.autoreverses = NO;

            rota.removedOnCompletion = NO;

            rota.fromValue = [NSNumber numberWithFloat: M_PI];

            rota.toValue = [NSNumber numberWithFloat: 0];

            [bokuHR.layer addAnimation: rota forKey: @”rotation”];

                        

            [UIView animateWithDuration:1.0 delay:0.2 options:UIViewAnimationOptionCurveLinear animations:^{

                boku.layer.transform = CATransform3DRotate(boku.layer.transform, –0.2*M_PI, 0, 0, 1);

                snowBall.center = [self.view convertPoint:CGPointMake(papa.center.x, 300) toView:bokuHR];

            } completion:^(BOOL finished) {}];

            

            [UIView animateWithDuration:0.2 delay:0.9 options:UIViewAnimationOptionCurveLinear animations:^{

                papa.center = CGPointMake(papa.center.x, papa.center.y20);

            } completion:^(BOOL finished) {

                [UIView animateWithDuration:0.2 animations:^{

                    papa.center = CGPointMake(papa.center.x, papa.center.y + 20);

                    snowBall.alpha = 0;

                }];

            }];

        }];

    } afterDelay:delay];

    

    // ボクまた悔しがる

    delay += 2.0;

    [self showScene:^{

        [UIView animateWithDuration:0.1 animations:^{

            boku.center = CGPointMake(boku.center.x, boku.center.y10);

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:0.1 animations:^{

                boku.center = CGPointMake(boku.center.x, boku.center.y + 10);

            }];

        }];

    } afterDelay:delay];

    

    delay += 0.2;

    [self showScene:^{

        [UIView animateWithDuration:0.1 animations:^{

            boku.center = CGPointMake(boku.center.x, boku.center.y10);

        } completion:^(BOOL finished) {

            [UIView animateWithDuration:0.1 animations:^{

                boku.center = CGPointMake(boku.center.x, boku.center.y + 10);

            }];

        }];

    } afterDelay:delay];

}

– (void)scene3

{

    //ママが雪を投げる

    float delay = 0;

    snowBall.alpha = 1.0;

    snowBall.center = CGPointMake(0, 90);

    [mamaHR addSubview:snowBall];

    

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

    rota.duration = 0.6;

    rota.autoreverses = NO;

    rota.removedOnCompletion = NO;

    rota.fromValue = [NSNumber numberWithFloat: 0];

    rota.toValue = [NSNumber numberWithFloat: M_PI];

    [mamaHR.layer addAnimation: rota forKey: @”rotation”];

    

    [UIView animateWithDuration:0.5 animations:^{

        mama.layer.transform = CATransform3DRotate(mama.layer.transform, 0.05*M_PI, 0, 0, 1);

    } completion:^(BOOL finished) {

        

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

        rota.duration = 0.5;

        rota.autoreverses = NO;

        rota.removedOnCompletion = NO;

        rota.fromValue = [NSNumber numberWithFloat: M_PI];

        rota.toValue = [NSNumber numberWithFloat: 0];

        [mamaHR.layer addAnimation: rota forKey: @”rotation”];

        

        

        [mama insertSubview:snowBall aboveSubview:mamaHR];

        snowBall.center = [snowBall convertPoint:snowBall.center fromView:mama];

        [UIView animateWithDuration:.5 delay:0.2 options:UIViewAnimationOptionCurveLinear animations:^{

            mama.layer.transform = CATransform3DRotate(mama.layer.transform, –0.05*M_PI, 0, 0, 1);

            snowBall.center = [self.view convertPoint:CGPointMake(snow.center.x, snow.center.y) toView:mamaHR];

        } completion:^(BOOL finished) {}];

    }];

    

    // 木の上の雪がぐらぐら

    delay += 1.5;

    [self showScene:^{

        [UIView animateWithDuration:0.2 animations:^{

            snowBall.alpha = 0;

        }];

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

        guragura.duration = 0.2;

        guragura.repeatCount = 5;

        guragura.autoreverses = YES;

        guragura.removedOnCompletion = NO;

        guragura.fromValue = [NSNumber numberWithFloat: 10];

        guragura.toValue = [NSNumber numberWithFloat: 0];

        [snow.layer addAnimation:guragura forKey: @”guragura”];

    } afterDelay:delay];

    

    // 雪が落ちる

    delay += 1.0;

    [self showScene:^{

        [UIView animateWithDuration:0.5 animations:^{

            [self.view insertSubview:snow aboveSubview:papa];

            snow.center = CGPointMake(snow.center.x, self.view.center.y);

            snow.transform = CGAffineTransformMakeScale(1.0, 3.0);

        } completion:^(BOOL finished) {

            papa.alpha = 0;

            snowMan = [[UIImageView alloc] initWithImage:snowManImg];

            snowMan.transform = CGAffineTransformMakeScale(0.3, 0.3);

            snowMan.center = CGPointMake(papa.center.x + 5, papa.center.y + 5);

            [self.view insertSubview:snowMan belowSubview:snow];

            

            papaFace.image = papaFace1;

            papaFace.center = CGPointMake(100, 100);

            [snowMan addSubview:papaFace];

            

            [UIView animateWithDuration:0.5 animations:^{

                snow.alpha = 0;

            }];

        }];

    } afterDelay:delay];

    

}

– (void)scene4

{

    // ママとボク笑顔でジャンプ

    bokuFace.image = bokuFace3;

    mamaFace.image = mamaFace1;

    

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

    rota.duration = 0.6;

    rota.autoreverses = NO;

    rota.removedOnCompletion = NO;

    rota.fromValue = [NSNumber numberWithFloat: 0];

    rota.toValue = [NSNumber numberWithFloat: 0.7 * M_PI];

    [mamaHR.layer addAnimation: rota forKey: @”rotation”];

    [bokuHR.layer addAnimation: rota forKey: @”rotation”];

    

    

    float delay = 0.5;

    [self showScene:^{

        CALayer *layer = [mamaHR.layer presentationLayer];

        mamaHR.layer.transform = layer.transform;

        

        layer = [bokuHR.layer presentationLayer];

        bokuHR.layer.transform = layer.transform;

    } afterDelay:delay];

    

    CGPoint mCenter = mama.center;

    CGPoint bCenter = boku.center;

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

        [self showScene:^{

            [UIView animateWithDuration:0.2 animations:^{

                mama.center = CGPointMake(mCenter.x, mCenter.y30);

                boku.center = CGPointMake(bCenter.x, bCenter.y40);

            } completion:^(BOOL finished) {

                [UIView animateWithDuration:0.2 animations:^{

                    mama.center = mCenter;

                    boku.center = bCenter;

                }];

            }];

        } afterDelay:0.5 * i];

    }

}

#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 04″ 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 04″ 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