我正在开发一款使用cocos2d-x的游戏,我在ipad 1等旧设备上遇到问题,因为大型场景需要花费大量时间才能加载。 所以场景转换可能需要几秒钟,因此我试图实现一个忙碌的"在加载新场景时场景转换之间的动画。 我使用IOS上的MBProgressHUD和android上的ProgressDialog实现了这个。 我决定不想立即开始显示这个动画,而是我可以安排动画在场景转换开始后1-2秒开始,这样在较新的设备上动画将根本不会显示。 最初我做的是这个:
- (void) showProgressDialog: (int) runWithoutDelay
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showProgressDialogAfterDelay) object:nil];
shouldShow = YES;
if (runWithoutDelay){
[self showProgressDialogAfterDelay];
}
else{
[self performSelector:@selector(showProgressDialogAfterDelay) withObject:nil afterDelay:delay];
}
}
- (void) showProgressDialogAfterDelay
{
if (shouldShow){
isShown = YES;
[progressHUD show:YES];
}
}
如果我通过场景转换部分,我只需将shouldShow标志设置为false并且不会启动动画。 问题是因为cocos2d-x场景转换是在主\ ui线程中完成的,有时而不是在2秒后调用show方法,它需要6-8秒才能被调用,有时它甚至在我设置后调用标志为假。 据我所知,这是因为performSelector(我也尝试过NSTimer)都是通过将调用放在线程运行循环队列中而在同一个线程上运行。 我需要像performSelectorInBackground那样需要延迟的东西,所以我尝试使用dispatch_after(尽管我仍然没有弄清楚如何取消它,因为我需要取消之前的计划,当我创建一个新计划时)这看起来更多准确地根据Xcode的日志,但即使日志说该方法在被安排后2秒正好被调用,时间将花费5-8秒来显示,有时根本不会显示。 据我所知,并纠正我,如果我错了,这是因为MBProgressHUD更改为UI必须发生在主\ UI线程上,所以即使我在后台线程上调用[ProgressHUD show:YES]实际更新UI被安排在主线程上以某种方式执行,并且由于它被卡在cocos2d-x上,它只在场景转换完成后才开始显示,而且为时已晚。
有什么方法可以解决这个问题吗?我可以以某种方式安排它以延迟开始但是在我想要的时候显示它吗?
我不明白的是,如果我毫不拖延地启动它,即使主线程忙于cocos2d-x处理,动画也能顺利运行而不会卡住。
答案 0 :(得分:2)
我以某种方式解决了这个问题!
创建一个常规方法,您将调用progressHUD并调用第二个
创建第二种方法,用于执行耗时的工作(加载视图)
在主线程上执行该方法
样品:
-(void)callHUD {
[progressHUD show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[progressHUD dismiss];
});
});
}
-(void)loadView {
//Perform your segue or transition which needs to load
}
希望能帮到你一点点。