【问题标题】:Why is my UIView animation working differently?为什么我的 UIView 动画效果不同?
【发布时间】:2012-10-10 20:36:39
【问题描述】:

我正在处理a game engine,我遇到了一个相当莫名其妙的行为。我敢肯定这很简单,但我想在继续之前弄清楚。

我继承了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 的typedef)是向上或向左,distanceInTiles 是一个负整数。计算了正确的距离,但由于某种原因,向下和向右似乎更慢。我确定它在向上/向左移动时确实会跳过一帧。

知道为什么吗?

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

【问题讨论】:

  • 你没有显示移动代码。
  • 事实上,我愿意。 [UIView animateWithDuration... 就是那个代码。 startMoving 实际上类似于UITableView beginUpdates
  • 对不起,屏幕外...
  • 只需下载完整项目的 zip。我找不到“MBDialogTree”。
  • @S.P.感谢您指出。文件在那里,但 xcodeproj 没有更新。它现在应该构建。

标签: iphone cocos2d-iphone uikit game-engine


【解决方案1】:

您需要确保为UIView 动画例程指定的持续时间是非负数。这可以通过fabs 函数轻松完成:

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

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

【讨论】:

  • 经过一番测试,这就是问题所在!我实际上更喜欢将 distanceInTiles 放在 abs() 方法中,因为它是唯一的负值,但我想这样做可能更安全你的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多