0

私はゲームエンジンに取り組んでいますが、かなり不可解な動作に遭遇しました。かなり単純だと思いますが、先に進む前に理解したいと思います。

UIImageView複数のアニメーション化されたスプライトのサポートをサブクラス化し、追加しました。コントロールも機能していますが、奇妙な動作が見られます。キャラクターが上または左に歩くと、アニメーションがフレームをスキップし、速く動いているように見えます。右または下に移動すると遅くなり、正しい 3 つのフレームが表示されます。

コールスタック全体を調べましたが、わかりません。何が起こるかは次のとおりです。

  • ユーザーが仮想ジョイパッドをタップします。
  • ゲーム コントローラのビュー コントローラが通知をディスパッチします。
  • メイン プレイヤー スプライトが通知を受け取ります。
  • スプライトはデリゲートに、移動したい場所に移動できるかどうかを尋ねます。
  • 実際に許可されている場合、スプライトは指定された距離を移動します。

スプライトの移動コードは次のようになります。

//  Move in a direction
- (void)moveInDirection:(MBSpriteMovementDirection)direction distanceInTiles:(NSInteger)distanceInTiles withCompletion:(void (^)())completion{

CGRect oldFrame = [self frame];
CGSize tileDimensions = CGSizeZero;

tileDimensions = [[self movementDataSource] tileSizeInPoints];

if (tileDimensions.height == 0 && tileDimensions.width == 0) {

    NSLog(@"The tile dimensions for the movement method are zero. Did you forget to set a data source?\nI can't do anything with this steaming pile of variables. I'm outta here!");

    return;
}

CGPoint tileCoordinates = CGPointMake(oldFrame.origin.x/tileDimensions.width, oldFrame.origin.y/tileDimensions.height);

//  Calculate the new position
if (direction == MBSpriteMovementDirectionLeft || direction == MBSpriteMovementDirectionRight) {
    oldFrame.origin.x += (tileDimensions.width * distanceInTiles);
    tileCoordinates.x += distanceInTiles;
}else{
    oldFrame.origin.y += (tileDimensions.height * distanceInTiles);
    tileCoordinates.y += distanceInTiles;
}

if (![[self movementDelegate] sprite:self canMoveToCoordinates:tileCoordinates]) {
    [self resetMovementState];
    if(completion){
        completion();
    }
    return;
}

[self startAnimating];

[UIView animateWithDuration:distanceInTiles*[self movementTimeScaleFactor] delay:0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState animations:^{

    [self setFrame:oldFrame];
}
                 completion:^(BOOL finished) {
                     //  Perform whatever the callback warrants
                     if(completion){
                         completion();
                     }
                     [self resetMovementState];
                 }];
}

方向 (のMBSpriteMovementtypedef NSUInteger) が上または左の場合、distanceInTilesは負の整数です。正しい距離が計算されるのですが、なぜかダウンとライトが遅いように感じます。上/左に移動するとフレームがスキップされると確信しています。

理由はありますか?

(これはオープン ソース プロジェクトであり、こちらの GitHub にあります。)

4

1 に答える 1

1

UIViewアニメーション ルーチンに与えられる期間が負でないことを確認する必要があります。これは、次の関数を使用して簡単に実現できfabsます。

NSTimeInterval animationDuration = fabs(distanceInTiles*[self movementTimeScaleFactor]);

[UIView animateWithDuration:animationDuration
                      delay:0
                    options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState
                 animations:^{
                    //...
                 }];
于 2012-10-11T00:32:56.633 に答える