4

我有超过 200 张图像我想在大约 10 秒的空间内制作动画。我尝试animationImages通过将图像加载到数组中然后调用该startAnimating方法来使用。这在模拟器中运行良好,但导致 iPad 崩溃。

我尝试NStimer每 1/25 秒调用一次,并在每次定时器触发时更改图像。这比以前的方法表现更好,它在模拟器中运行良好,但在 iPad 上的(滞后)动画结束时也崩溃了。

有人可以帮助我并告诉我解决这个问题的理想方法吗?谢谢。

原始代码:

- (void) humptyFallingAnim {

    NSString *filename;
    if (humptyImageCounter < 285) {
        filename = [NSString stringWithFormat:@"Humpty Animation HD1.2 png sequence/humpty_HD1.2_%d.png", humptyImageCounter];
            UIImage *someImage = [UIImage imageNamed:filename];
            humptyFalling.image = someImage;
            NSLog(@"loaded image: %d", humptyImageCounter);
        humptyImageCounter++;
    } else {
        NSLog(@"Timer invalidated");
        [humptyTimer invalidate];
        humptyTimer = nil;
    }

}

编辑:一些对我不起作用的新代码

NSString *filename;
    if (humptyImageCounter < 285) {
        filename = [NSString stringWithFormat:@"Humpty Animation HD1.2 png sequence/humpty_HD1.2_%d.png", humptyImageCounter];
        @autoreleasepool {
            UIImage *someImage = [UIImage imageWithContentsOfFile:filename];
            humptyFalling.image = someImage;
            NSLog(@"loaded image: %d", humptyImageCounter);
        }
        humptyImageCounter++;
    } else {
        NSLog(@"Timer invalidated");
        [humptyTimer invalidate];
        humptyTimer = nil;
    }

编辑2:

-(void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    NSLog(@"You shook it!");
    [self.view bringSubviewToFront:imgSnail];
    if (deviceHasBeenShaken == 0) {
        deviceHasBeenShaken = 1;
    }
    humptyTimer = [NSTimer scheduledTimerWithTimeInterval:(1/25) target:self selector:@selector(humptyFallingAnim) userInfo:nil repeats:YES];
    [self moveHumptyPosition];

}
4

4 回答 4

3

不幸的是,这听起来像是 OpenGL ES 的工作。应用程序是游戏吗?

于 2012-07-03T23:48:07.550 回答
3

内存管理 :)。

NSString* somePath;
UIImageView *imageView;
for (i=0;i<200;i++) {
@autoreleasepool {
UIImage *someImage = [UIImage imageWithContentsOfFile:somePath];
imageView.image = someImage; //every time this line is executed, old reference disappears and previous UIImage is discarded
}
}

我的意思是,您必须实现自动释放池并且不要使用 +(UIImage *) imageNamed: 方法,因为它会缓存图像。

更新 让我解释一下。您的问题与内存管理有关。您的应用程序必须有效地使用设备的内存,但您实际上没有。我不知道您的应用程序是如何工作的,但总体思路如上所示。 更新 2让我知道您是否使用 ARC。

更新 3对不起我奇怪的语言,但已经晚了。对不起 :)

于 2012-07-03T23:50:12.540 回答
3

尝试使用CALayer隐式动画。创建图层并循环设置它们的图像,如下所示:

NSMutableArray *allLayers = [NSMutableArray array];
for (int i = 0 ; i != 200 ; i++) {
    CGImageRef image = ...; // Get i-th image from an image source
    CALayer* sub = [CALayer layer];
    sub.contents = (__bridge id)image;
    sub.contentsRect = CGRectMake(...); // Create a rectangle based on the image size
    [self.layer addSublayer:sub];
    [allLayers addObject:sub];
}

现在你可以通过设置它们的属性来隐式地为你的图层设置动画:

for (CALayer *sub in allLayers) {
    sub.position = CGMakePoint(...); // The position to which to move the image
}

完成图层后,将它们从超级视图中删除:

for (CALayer *sub in allLayers) {
    [sub removeFromSuperlayer];
}
于 2012-07-04T00:27:10.980 回答
1

使用cocos2d我的朋友。免得自己头疼。您所说的使用 OpenGLES 效率提高了一百倍。然而,OpenGL 并不复杂,cocos2d 在它之上提供了一个很好的抽象层,因此您只需几行代码就可以完成。

于 2012-07-04T10:07:10.500 回答