我有一個「加載屏幕」與「加載欄」。這個加載屏幕從我的服務器獲取圖像並將它們加載到CCSprites,因此我將在其他屏幕中使用它們。在加載屏幕下載圖像並創建CCSprites時,我希望我的加載欄能夠更新它的UI。 LoadingBar是一個CCNode子類。我知道我應該使用線程來更新用戶界面,但問題是(據我所知)Cocos2D節點不是線程安全的,所以當我使用下面的代碼時,它確實更新了用戶界面,但隨後精靈確實不加載:Cocos2D更新UI與線程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{
// go do something asynchronous...
dispatch_async(dispatch_get_main_queue(), ^{
// update UI
});
});
我試過很多東西,但是我不能解決這個問題。請幫助:)
這裏是一個讓我LoadingBar更新代碼:
-(void)makeStep{
int actualPersentage = 100 * (numSteps - numStepsToGo + 1)/numSteps;
int objectAtIndex = MAX(0, numSteps - numStepsToGo);
persentageLabel.string = [NSString stringWithFormat:@"%i%% %@", actualPersentage, [steps objectAtIndex:objectAtIndex]];
[frontground setTextureRect:CGRectMake(0, 0, frontground.textureRect.size.width + (200/numSteps), 40)];
frontground.position = ccp(initialPosition + (frontground.contentSize.width/2) - (background.contentSize.width/2), frontground.position.y);
numStepsToGo --;
if(numStepsToGo == 0){
[frontground setTextureRect:CGRectMake(0, 0, 200, 40)];
persentageLabel.string = [NSString stringWithFormat:@"All loaded correctly!"];
}
}
基本上我有一個背景灰色矩形背景和一個綠色的(frontground)認爲,「填充」的背景每次調用makeStep。
下面是代碼示例,其中我分析JSON和在我的LoadingBar應該更新:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{
...
CCSprite *ssButtonStart = [self getSpriteFromUrl:[startScreenData objectForKey:@"SSimg_button_start"]];
CCSprite *ssButtonExit = [self getSpriteFromUrl:[startScreenData objectForKey:@"SSimg_button_exit"]];
CCSprite *ssBackground = [self getSpriteFromUrl:[startScreenData objectForKey:@"SSimg_background"]];
self.gameProperties.slBackground = ssBackground;
self.gameProperties.slButtonExit = ssButtonExit;
self.gameProperties.slButtonStart = ssButtonStart;
NSLog(@"Start Screen Loading done!");
dispatch_async(dispatch_get_main_queue(), ^{
[self updateStep];
});
...
dispatch_async(dispatch_get_main_queue(), ^{
[self updateStep];
});
//Etc.
代碼,我得到的圖像,並轉換成CCSprite:
-(CCSprite*)getSpriteFromUrl:(NSString*)stringUrl{
__block NSData *imageData;
__block CCSprite *sprite;
imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:stringUrl]];
//NSLog(@"string imageData: %@", imageData);
UIImageView *imView = [[UIImageView alloc] initWithImage:[UIImage imageWithData: imageData]];
dispatch_async(dispatch_get_main_queue(), ^{
CCTexture2D *texture = [[CCTexture2D alloc] initWithCGImage:imView.image.CGImage resolutionType:kCCResolutionUnknown];
if(texture != nil){
sprite = [[CCSprite alloc] init];
sprite = [[CCSprite alloc] initWithTexture:texture];
}else{
[self showError:@"Some textures didn't load correctly. Please try again!"];
}
// update UI
});
return sprite;
}
我使用的是iOS 7和Cocos2D 2.0
您應該更新主線程上的欄。而是將圖像下載到後臺線程。 NSData或NSURLRequest甚至包含異步方法。然後,當您完成下載圖像時,在主線程上創建CCSprites作爲最後一步。無論如何,精靈必須在主線程上創建。 – LearnCocos2D 2014-09-03 08:21:19
謝謝你的回答。我已經嘗試了你的建議,但沒有成功。我使用已更改的代碼和獲取圖像的方法更新問題。你能告訴我我錯在哪裏嗎? – aramusss 2014-09-03 09:09:48
解決!在getSpriteFromUrl中獲得每個精靈之後,我睡了一覺。代碼是'[NSThread sleepForTimeInterval:0.2];'。希望它能幫助其他人! – aramusss 2014-09-03 09:56:39