我想要实现一个降雪动画,用户可以按下一个按钮,为降雪增加风效果。 我有以下代码,可以使雪下降,但是当添加风效果时,下面的雪会减慢,没有风效果。
SnowFallView,它具有制作雪和风效果的方法。有三个关键功能:
-(void)createFlakes {
srandomdev();
self.flakesArray = [[NSMutableArray alloc] initWithCapacity:self.flakesCount];
for (int i=0; i < self.flakesCount; i++) {
// generate image
NSString *imageFileName = @"snow.png";
UIImage *flakeImg = [UIImage imageNamed:imageFileName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:flakeImg];
imageView.userInteractionEnabled = NO;
[self.flakesArray addObject:imageView];
[self addSubview:imageView];
}
}
-(void) startToSnow {
static BOOL isFirst = YES;
int ctr = 1;
if (!self.flakesArray)
[self createFlakes];
self.backgroundColor = [UIColor clearColor];
CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation"];
theAnimation.repeatCount = 1e100;
theAnimation.autoreverses = NO;
for (UIImageView *v in self.flakesArray) {
CGPoint p;
p.x = (Float32)(rand()%(int)self.frame.size.width);
p.y = self.frame.size.height+v.frame.size.height*(ctr<4?1:isFirst?(rand()%20):(rand()%20+5));
CGPoint startPoint;
startPoint.x = p.x;
startPoint.y = -p.y;
float timeInterval = ((Float32)(self.animationDurationMax-self.animationDurationMin)*(Float32)random()/(Float32)RAND_MAX);
theAnimation.duration = timeInterval+self.animationDurationMin;
theAnimation.fromValue = [NSValue valueWithCGPoint:startPoint];
CGPoint endPoint;
endPoint.y = self.frame.size.height;
endPoint.x = p.x;
if (!endPointArray) {
endPointArray = [[NSMutableArray alloc] init];
}
[endPointArray addObject:[NSValue valueWithCGPoint:endPoint]];
theAnimation.toValue = [NSValue valueWithCGPoint:endPoint];
float spd = (v.frame.size.height/(51.0-(Float32)(rand()%7))*kFallSpeed)/6.0;
theAnimation.speed = (rand()%2)?spd:spd*1.5;
if (!animationArray) {
animationArray = [[NSMutableArray alloc] init];
}
[animationArray addObject:[theAnimation copy]];
[v.layer addAnimation:theAnimation forKey:@"transform.translation"];
}
isFirst = NO;
}
-(void)windLeft:(BOOL)left
{
CABasicAnimation *theAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation"];
theAnimation.repeatCount = 1e100;
theAnimation.autoreverses = NO;
NSInteger index = 0;
for (UIImageView *v in self.flakesArray) {
CGPoint startPoint;
CGRect currentFrame = [v.layer.presentationLayer frame];
startPoint.x = currentFrame.origin.x;
startPoint.y = currentFrame.origin.y;
NSLog(@"x:%f,y:%f",startPoint.x, startPoint.y);
CABasicAnimation *previousAnimation = [animationArray objectAtIndex:index];
theAnimation.duration = previousAnimation.duration;
theAnimation.fromValue = [NSValue valueWithCGPoint:startPoint];
CGPoint endPoint = [[endPointArray objectAtIndex:index] CGPointValue];
CGPoint newEndPoint;
newEndPoint.y = endPoint.y;
if (left)
newEndPoint.x = endPoint.x - 100;
else
newEndPoint.x = endPoint.x + 100;
theAnimation.toValue = [NSValue valueWithCGPoint:endPoint];
theAnimation.speed = previousAnimation.speed;
[animationArray replaceObjectAtIndex:index withObject:[theAnimation copy]];
[v.layer removeAnimationForKey:@"transform.translation"];
[v.layer addAnimation:theAnimation forKey:@"transform.translation"];
index++;
}
}
在主视图中,我使用以下代码调用
IBOutlet UIView *snowFallView; //for snow flake view
IBOutlet UIButton *windButton;
SnowFallView *sfv;
在viewDidLoad方法
中sfv = [[SnowFallView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
sfv.flakesCount = 20;
[snowFallView addSubview:sfv];
[snowFallView addSubview:windButton];
[sfv startToSnow];
当用户点击按钮添加风效果时
- (IBAction)pushWind: (id)sender
{
[sfv windLeft:YES];
}