第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.y – 10);
} 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.x – 5, boku.center.y – 10);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
boku.center = CGPointMake(boku.center.x – 5, boku.center.y + 10);
}];
}];
delay += 0.2;
[self showScene:^{
[UIView animateWithDuration:0.1 animations:^{
boku.center = CGPointMake(boku.center.x + 5, boku.center.y – 10);
} 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.y – 20);
} 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.y – 10);
} 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.y – 10);
} 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.y – 30);
boku.center = CGPointMake(bCenter.x, bCenter.y – 40);
} 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