1

我已经在 Cocos2D 中开发一款游戏大约 3 年了,它利用透明背景来显示 UIView。这样做的原因是让视差背景仍然像 Cocos2D 进行场景转换一样运行。

当我更新到 iOS 7 时,我遇到了一个新问题。结合以下情况会出现减速:

- 仅当视差背景的帧位置发生变化时。

- 如果我摧毁一个发射小精灵和粒子效果的敌人。

所以这是这两件事的结合,它只是有时会发生。发生减速时,帧速率的调试值不会下降。如果我加载一个新场景,它会恢复正常。有时当我摧毁另一个敌人时,减速也会消失。

我的视差 UIView 中有代码,几乎可以运行游戏中的每一帧。我将问题总结为一行:

-(void)updateImagePosWithPos:(CGPoint)pos{ // in game

    // create vel based on last currentPos minus new pos

    CGPoint vel = CGPointMake(currentPos.x-pos.x, currentPos.y-pos.y);

    // init variables tmpVel and tempTotalImages

    CGPoint tmpVel = CGPointZero;

    int tmpTotalImages = 0;

    // create indexLayerArr

    NSMutableArray *indexLayerArr = [NSMutableArray array];

    // for every parallax layer, add the number of images horizontally minus 1 to indexLayerArr

    for (int j=0; j<totalLayers; ++j){

        [indexLayerArr addObject:[NSNumber numberWithInt:[[totalImagesArr objectAtIndex:j] intValue]-1]];

    }

    int i = 0;


    for (UIImageView *imageView in self.subviews) {

        CGRect tmpRect = CGRectZero;

        NSMutableArray *tmpRectArr = [rectContainer objectAtIndex:imageView.tag];

        float speed = 0.00;


        tmpTotalImages = [[totalImagesArr objectAtIndex:imageView.tag] intValue];

        speed = [[speedArr objectAtIndex:imageView.tag] floatValue];

        tmpVel = CGPointMake(vel.x*speed, vel.y*speed);

        i = [[indexLayerArr objectAtIndex:imageView.tag] intValue];

        tmpRect = [[tmpRectArr objectAtIndex:i] CGRectValue];


        if(tmpRect.origin.x - tmpVel.x > wins.width){

            tmpRect.origin.x -= (tmpTotalImages)*tmpRect.size.width;

        }
        else if(tmpRect.origin.x - tmpVel.x < -tmpRect.size.width){

            tmpRect.origin.x += (tmpTotalImages)*tmpRect.size.width;

        }

        tmpRect.origin.x -= tmpVel.x;
        tmpRect.origin.y += tmpVel.y;

        [tmpRectArr replaceObjectAtIndex:i withObject:[NSValue valueWithCGRect:tmpRect]];


        imageView.frame = [[tmpRectArr objectAtIndex:i] CGRectValue]; // <-- slow down cause



        i--;

        [indexLayerArr replaceObjectAtIndex:imageView.tag withObject:[NSNumber numberWithInt:i]];


    }

    currentPos = CGPointMake(pos.x, pos.y);

}

见注释行 imageView.frame = [[tmpRectArr objectAtIndex:i] CGRectValue];

因此,如果我将这条线注释掉,问题将永远不会发生。如果我保留这条线并且不更改 tempRect 的值,那么问题也不会发生。

看起来 iOS 7 在更改 UIImageView 的框架位置时存在问题,但只是有时。只是想知道我可以使用哪些其他替代品?还是我在 iOS 7 中做错了什么?

4

1 回答 1

0

不是解决您的问题的方法,而是解决方法。我将从可能需要最多代码更改的那个开始。

  1. 您实际上不必拥有 UIView 来保持背景与过渡。相反,如果你完全在 cocos2d 中实现背景(作为场景的一部分),你可以实现相同的效果,而不是替换场景,而是将图层转换进出。大部分场景转换使用同样适用于节点的动作。

  2. 使用cocos2d节点实现后台,并有一个父节点作为后台节点的容器(即“层”)。您可以对该节点执行以下两项操作之一:

    一个。编辑 CCDirectorIOS 的代码并添加对您的后台节点的引用。在 drawScene 方法中,在所有其他节点之前更新节点,方法是调用visitbefore 的背景节点[_runningScene visit]

    湾。过渡到新场景时,要么从当前场景中移除背景节点并将其添加到新场景中,要么创建具有所有相同设置的背景副本并将其添加到新场景中。确保副本以与原件完全相同的状态开始。尽管由于动画的性质(即移动/翻转/缩放),这不适用于大多数过渡。

  3. 如果您需要在过渡运行时为背景设置动画,有一个简单的技巧。在具有全局生命周期的非 CCNode 对象(即 AppDelegate)上安排更新。然后手动将更新发送到应在转换期间继续更新其状态的所有节点,并且仅在转换期间。

您可以像这样在非节点对象上注册更新:

[_director.scheduler scheduleUpdateForTarget:self priority:0 paused:NO];

即使在场景转换期间也会调用此更新方法。或者,也应该可以通过更改节点的paused状态来继续更新节点,从而恢复调度程序和操作,或者通过覆盖 paused 属性或通过在发生转换时显式取消暂停特定节点。

于 2013-11-17T20:22:38.080 回答