0

リールが回転するスロットマシンのアニメーションを作ろうとしています。これを行うために、私はdrawRectを使用して、UIViewから継承するカスタムクラスで画像を描画しています。nstimerを使用して画像の位置を更新し、[selfsetNeedsDisplay]を呼び出して図面を更新しています。シミュレーターでは非常に見栄えがしますが、デバイスでは非常に遅くなります。自分の描画方法に何か問題があるのか​​、それとももっと良い解決策があるのだろうかと思っていました。

- (void)drawRect:(CGRect)rect
{   
    [image1 drawInRect:CGRectMake(0, image1Position, 98, 80)];
    [image2 drawInRect:CGRectMake(0, image2Position, 98, 80)];
    [image3 drawInRect:CGRectMake(0, image3Position, 98, 80)];
}


- (void)spin
{
    // move each position down by 10 px
    image1Position -= MOVEMENT;
    image2Position -= MOVEMENT;
    image3Position -= MOVEMENT;
    // if any of the position <= -60 reset to 180
    if(image1Position < -50)
    {
        image1Position = 180;
    }
    if(image2Position < -50)
    {
        image2Position = 180;
    }
    if(image3Position < -50)
    {
        image3Position = 180;
    }
    [self setNeedsDisplay];
}

-(void)beginSpinAnimation
{       
    timer = [NSTimer scheduledTimerWithTimeInterval:SCROLL_TIME target:self selector:@selector(spin) userInfo:self repeats:YES];
}

UIScrollViewを使用したCoreAnimationの試み:

- (void) spinToNextReel
{   
    int y = self.contentOffset.y + 80;

    // if the current >= last element reset to first position (-30)
    if(y >= (80 *(elementCount+1) - 30))
    {
        y = -30;
    }

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDuration:SCROLL_TIME];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];

    self.contentOffset = CGPointMake(0, y);

    [UIView commitAnimations];

    if (!isSpinning && targetY == y)
    {
        NSLog(@"target is %d, y is %d", targetY, y);

        if(timer)
        {
            [timer invalidate];
            timer = nil;
        }
        [self playSound];
    }
}
4

2 に答える 2

4

CoreAnimationの研究だと思います。ここでやりたいことをやらせてもらいます。ここで行っていることよりもはるかに高速になります。

遅いということに関しては、drawInRectを呼び出すことは世界で最速のことではありません。SCROLL_TIMEとは何ですか?

于 2010-07-06T00:42:29.183 に答える
2

CoreAnimationを使用したい場合は、はるかに簡単で効率的です。そうは言っても、この方法で手動でアニメーション化しようと主張する場合は、いくつか間違ったことをしていることになります。

  1. 一定の間隔で一定量を移動しようとしないでください。タイマーイベントが遅延する可能性があります。その場合、時間間隔ではなくイベントごとに一定量を移動するため、アニメーションが不均一になります。アニメーション化するたびに実際のタイムスタンプを記録し、それを前のタイムスタンプと比較して、適切なピクセル数を移動する必要があります。これにより、イベントが遅延した場合でも、移動量が均等になります(事実上、フレームをドロップすることになります)。

  2. NSTimerを使用せず、CADisplayLinkを使用してください。これにより、図面がシステムのネイティブリフレッシュレートに関連付けられ、進行中の他の図面と同期されます。

  3. すでに言ったことは知っていますが、CoreAnimationを学び、使用すれば、はるかに幸せになります。

于 2010-07-06T03:10:06.670 に答える