暑い日が続く、夏なので線香花火がチカチカするようなiPhoneアプリを書いてみます。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
#import “ViewController.h”
#import <QuartzCore/QuartzCore.h>
@interface ViewController () {
UIView *ball;
NSTimer *timer;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self createStick];
[self createBackground];
}
– (void)createStick
{
UIView *stick = [[UIView alloc] initWithFrame:CGRectMake(158, 0, 4, 250)];
stick.backgroundColor = [UIColor greenColor];
[self.view addSubview:stick];
ball = [[UIView alloc] initWithFrame:CGRectMake(150, 250, 20, 20)];
ball.backgroundColor = [UIColor orangeColor];
ball.layer.cornerRadius = 10;
[self.view addSubview:ball];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self start];
}
– (void)start
{
@synchronized(self) {
if (!timer || ![timer isValid]) {
timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
CABasicAnimation *twinkle = [CABasicAnimation animationWithKeyPath:@”opacity”];
twinkle.duration = 0.5;
twinkle.fromValue = @1.0;
twinkle.toValue = @0.7;
twinkle.autoreverses = YES;
twinkle.repeatCount = 10;
[ball.layer addAnimation:twinkle forKey:nil];
[timer performSelector:@selector(invalidate) withObject:nil afterDelay:10];
}
}
}
– (void)tick:(NSTimer*)sender
{
float angle = ((arc4random() % 36) / 18.0) * M_PI;
float x = 120 * cos(angle) + 160;
float y = 120 * sin(angle) + 260;
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(160, 260)];
[path addLineToPoint:CGPointMake(x, y)];
CAShapeLayer *sl = [CAShapeLayer layer];
sl.strokeColor = CGColorCreateCopyWithAlpha([UIColor yellowColor].CGColor, 0.7);
sl.lineWidth = 2;
sl.path = path.CGPath;
[self.view.layer addSublayer:sl];
[self startDraw:sl];
[self smallFire:[NSValue valueWithCGPoint:CGPointMake(x, y)]];
}
– (void)smallFire:(NSValue*)point
{
CGPoint p = [point CGPointValue];
for (int i=0; i<6; i++) {
float angle = (arc4random() % 6) * (M_PI/3.0);
float x = 40 * cos(angle) + p.x;
float y = 40 * sin(angle) + p.y;
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(p.x, p.y)];
[path addLineToPoint:CGPointMake(x, y)];
CAShapeLayer *sl = [CAShapeLayer layer];
sl.strokeColor = CGColorCreateCopyWithAlpha([UIColor yellowColor].CGColor, 0.7);
sl.lineWidth = 1.5;
sl.path = path.CGPath;
[self.view.layer addSublayer:sl];
[self startDraw:sl];
}
}
– (void)startDraw:(CAShapeLayer*)l
{
CABasicAnimation *a = [CABasicAnimation animationWithKeyPath:@”strokeEnd”];
a.duration = 0.1;
a.fromValue = @0;
a.toValue = @1;
[l addAnimation:a forKey:@”strokeEnd”];
if (l.strokeEnd == 0) {
l.strokeEnd = 1.0;
}
[l performSelector:@selector(removeFromSuperlayer) withObject:nil afterDelay:0.15];
}
– (void)createBackground
{
for (int i=0; i< 8 * 16; i++) {
float x = (i % 8) * (320.0 / 8.0) + 18;
float y = (i / 8) * (568.0 / 16.0);
UIView *rhombus = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];
rhombus.center = CGPointMake(x, y);
rhombus.transform = CGAffineTransformMakeRotation(M_PI/4.0);
rhombus.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2];
[self.view addSubview:rhombus];
UIView *inner = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 8)];
inner.center = CGPointMake(x, y);
inner.transform = CGAffineTransformMakeRotation(M_PI/4.0);
inner.backgroundColor = [UIColor blackColor];
[self.view addSubview:inner];
}
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end