3

画面上の任意のパスに沿ってその位置を変更するために、単一のレイヤーを正常にアニメーション化しています。私は今、このアニメーションを複数回複製して、何かが角を曲がっているような錯覚を与えようとしています。コードをCATransaction内に配置し、ループの反復ごとに開始位置をインクリメントするループに配置し、ループの後にCATransactionをコミットしました。コードがループしていない場合(つまり、1つのレイヤーだけがアニメーション化されている場合)、アニメーションの最後にすべてのレイヤーが表示されます(アニメーションの最後にアニメーションの最後でデリゲートがそれらを削除する前に、animationDidStopで表示される効果は同じです)。 )。

私が書いたコードは次のようになります。

NSArray* path = [board caclulatePath:s];
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:([path count] * 0.25)] forKey:kCATransactionAnimationDuration];
    for (int i = 0; i < 20; i++)
    {
        CALayer* laserLayer = [CALayer layer];
        laserLayer.bounds = CGRectMake(s.frame.origin.x, s.frame.origin.y + (10*i), 20, 10);
        laserLayer.position = CGPointMake(s.frame.origin.x + (s.frame.size.width / 2), s.frame.origin.y + (s.frame.size.height / 2) + (10*i));
        laserLayer.contents = (id)[UIImage imageNamed:@"Laser.png"].CGImage;
        [self.layer addSublayer:laserLayer];

        CAKeyframeAnimation* anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        anim.values = path;
        anim.duration = ([path count] * 0.25);
        anim.removedOnCompletion = NO;
        anim.delegate = self;
        anim.rotationMode = kCAAnimationRotateAuto;
        [anim setValue:@"Fire" forKey:@"Action"];
        [anim setValue:laserLayer forKey:@"Layer"];
        [laserLayer addAnimation:anim forKey:nil];
    }
    [CATransaction commit];

ここで、[board caclulatePath:s]は、CGPointを表すNSValueのNSArray*を返します。

自分が求めている効果をどのように達成できますか(同じパスをたどるlaser.pngの複数のコピーはどれですか)?[Laser.pngは20pxx20pxの赤い正方形です];

4

2 に答える 2

2

実際の問題は、各レイヤーが同時に同じパスをたどっていたということでした...解決策は、iがインクリメントされた(someSmallFractionOfTime * i)の遅延後に各レイヤー/アニメーションを起動することでした。

だから私はアニメーション部分を新しい関数/メソッド/メッセージとして抽出しました(それが何と呼ばれていても)

- (void) kickoffLaserAnimationWithPath: (NSArray *) path  {
CGPoint start = [(NSValue*)[path objectAtIndex:0] CGPointValue];
CALayer* laserLayer = [CALayer layer];
laserLayer.bounds = CGRectMake(start.x, start.y, 20, 10);
laserLayer.position = CGPointMake(start.x, start.y);
laserLayer.contents = (id)[UIImage imageNamed:@"Laser.png"].CGImage;
[self.layer addSublayer:laserLayer];

CAKeyframeAnimation* anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.values = path;
anim.duration = ([path count] * laserSpeed);
anim.removedOnCompletion = NO;
anim.delegate = self;
anim.rotationMode = kCAAnimationRotateAuto;
[anim setValue:@"Fire" forKey:@"Action"];
[anim setValue:laserLayer forKey:@"Layer"];
[laserLayer addAnimation:anim forKey:nil];
isAnimating = YES;

}

そして、次のようにループ内でそれを呼び出しました:

NSArray* path = [board caclulatePath:s];
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:([path count] * laserSpeed)] forKey:kCATransactionAnimationDuration];
    float numBetweenPoints = (float)((float)s.frame.size.height / (float)10) * 2;
    float delay = (laserSpeed / numBetweenPoints);
    for (int i = 0; i < [path count]; i++)
    {
        [self performSelector:@selector(kickoffLaserAnimationWithPath:) withObject:path afterDelay:(delay*i)];

    }
    [CATransaction commit];

出来上がり...

于 2011-07-29T10:59:46.033 に答える
1

CAAnimationGroupを見てください。それはあなたの問題に合うかもしれないと思います。

于 2011-07-29T08:52:37.980 に答える