1

我在 Cocos2d 中遇到横向滚动问题。情况是,我有一个包含多个其他精灵的精灵,称为动作。用户可以水平来回滑动以滚动浏览多个动作。现在发生的事情是它非常生涩,似乎滞后并且不是平滑的滚动,而是非常波涛汹涌。不知道问题是什么,我试图改变动画的时间,但这似乎不起作用。

- (void)translateInventoryForSwipe:(int)xTranslationValue {

  NSArray* tempArray = [NSArray arrayWithArray:self.slotsCenterCoordinates];
  [self.slotsCenterCoordinates removeAllObjects];

  for (NSNumber* i in tempArray) {

    NSNumber* newXCoordinate = [NSNumber numberWithInt:[i intValue] + xTranslationValue];
    [self.slotsCenterCoordinates addObject:newXCoordinate];
  }

  [self updatePositionOfActionsInInventory];
}

此方法从父视图中获取两次触摸的 delta x。(当前触摸减去上一个触摸)这将设置滚动视图中所有动作的中心坐标。

- (void)updatePositionOfActionsInInventory {

  for (int inventoryCounter = 0; inventoryCounter < self.inventorySize; inventoryCounter++) {

    FFAction* action = [self.actions objectAtIndex:inventoryCounter];
    if (action != self.actionBeingDragged)
      [self placeAction:action atIndex:inventoryCounter];
  }
  self.tempAction = nil;
}

- (void)placeAction:(FFAction*)action atIndex:(int)index {

  const float yCenterCoordinate = self.boundingBox.size.height/2;

  NSNumber* xCenterCoordinate = [self.slotsCenterCoordinates objectAtIndex:index];
  CGPoint centerPointForActionAtIndex = ccp([xCenterCoordinate floatValue], yCenterCoordinate);
  CCAction* updatePositionAction = [CCMoveTo actionWithDuration:0.03f position:centerPointForActionAtIndex];
  if ([action.view numberOfRunningActions] == 0 || self.tempAction == action) {

    [action.view runAction:updatePositionAction];
    [action.view released];
  }
}

这部分来自处理触摸的父精灵:

  CGPoint currentTouch = [self convertTouchToNodeSpace:touch];
  CGPoint previousTouch = [touch previousLocationInView:[touch view]];
  int translationPoint = currentTouch.x - previousTouch.x;
  [self.inventory translateInventoryForSwipe:translationPoint withPoint:currentTouch];

然后设置模仿滚动效果的动作坐标。我不确定它在哪里引起了生涩的动作,但如果有人对这种情况有任何帮助,那就太棒了!

4

1 回答 1

0

假设您的代码中的所有复杂性都不是必需的,这里有几个方面需要考虑,我将一一介绍。

首先,内存分配很昂贵,而且每次调用translateInventoryForSwipe:. 创建一个全新的 NSArray 并重新填充 self.slotsCenterCoordinates。相反,您应该迭代动作精灵并一一重新定位它们。

这将我们带到第二个方面,即使用 CCAction 来移动精灵。为每个精灵创建一个新的 CCAction,由于内存分配再次导致延迟。CCAction 被创建,即使它不会被使用。此外,动作的使用可能是延迟的主要原因,因为在前一个动作完成之前不会接受新动作。更好的方法是直接通过 delta 重新定位精灵,而不是分配用于重新定位的动作。translateInventoryForSwipe:由于调用的频率很高,因此不需要该操作即可获得平稳的移动。

您还应该考虑使用 float 而不是 int 将 delta 值发送到方法。触摸坐标是浮动的,尤其是在视网膜设备上,这很重要,因为两个像素的距离是 0.5f。

基于这些方面,这里是一个固定方法的模板。这是未经测试的,所以可能有错误。另外,我假设 action.view 是实际的精灵,因为动作是在那里分配的。

- (void)translateInventoryForSwipe:(float)xTranslationValue {
    for (FFAction *action in self.actions) {
        if (action == self.actionBeingDragged)
            continue;
        // Position the items manually
        float xCoordinate = action.view.position.x + xTranslationValue;
        float yCoordinate = self.boundingBox.size.height/2;
        action.view.position = ccp(xCoordinate, yCoordinate);
    }
}
于 2013-11-24T20:31:12.777 回答