Iphone 为什么我的UIView动画工作方式不同?

Iphone 为什么我的UIView动画工作方式不同?,iphone,cocos2d-iphone,uikit,game-engine,Iphone,Cocos2d Iphone,Uikit,Game Engine,我正在工作,我遇到了一个相当令人困惑的行为。我相信这很简单,但我想在继续之前弄清楚 我已经将UIImageView子类化,并添加了对多个动画精灵的支持。我的控件也在工作,但我看到了一种奇怪的行为。当我的角色向上或向左行走时,动画跳过一帧,并且似乎移动得更快。向右或向下移动会变慢,并显示正确的三帧 我已经检查了我的整个调用堆栈,但我想不出来。下面是发生的情况: 用户轻触虚拟操纵手柄 游戏控制器视图控制器发送通知 主玩家精灵在通知中拾取 精灵询问代理是否允许其移动到想要移动的位置 如果确实允许精灵

我正在工作,我遇到了一个相当令人困惑的行为。我相信这很简单,但我想在继续之前弄清楚

我已经将
UIImageView
子类化,并添加了对多个动画精灵的支持。我的控件也在工作,但我看到了一种奇怪的行为。当我的角色向上或向左行走时,动画跳过一帧,并且似乎移动得更快。向右或向下移动会变慢,并显示正确的三帧

我已经检查了我的整个调用堆栈,但我想不出来。下面是发生的情况:

  • 用户轻触虚拟操纵手柄
  • 游戏控制器视图控制器发送通知
  • 主玩家精灵在通知中拾取
  • 精灵询问代理是否允许其移动到想要移动的位置
  • 如果确实允许精灵移动,它会在给定的距离内移动
精灵移动代码如下所示:

//  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];
                 }];
}
如果
MBSpriteMovement
方向(类型定义为
NSUInteger
)为向上或向左,
distanceInTiles
为负整数。计算出正确的距离,但由于某种原因,向下和向右的距离似乎较慢。我敢肯定它在向上/向左移动时会跳过一帧

知道为什么吗


(这是一个开源项目,可以找到。)

您需要确保提供给
UIView
动画例程的持续时间是非负的。这可以通过
fabs
功能轻松实现:

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

[UIView animateWithDuration:animationDuration
                      delay:0
                    options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState
                 animations:^{
                    //...
                 }];

你没有显示动作代码。事实上,我有<代码>[UIView animateWithDuration…就是这个代码。startMoving实际上类似于
UITableView BeginUpdate
。很抱歉,那是屏幕上的内容…只需下载完整项目的zip文件。我找不到“MBDialogTree”@S.P.谢谢你指出。文件在那里,但是xcodeproj没有更新。它现在应该可以构建了。经过一点测试,这就是问题所在!实际上我更喜欢在
abs()
方法中只放distanceInTiles,因为它是唯一的负值,但我想用你的方式做会更安全。