2015-09-14 9 views
14

मेरे पास "चरण चयन" दृश्य और एक "गेम" दृश्य है। हालांकि जब उपयोगकर्ता गेम दृश्य शुरू करने के लिए बटन दबाता है तो दबाने और दृश्य के बीच एक देरी होती है (पुराने उपकरणों पर लगभग 2 सेकंड या उससे अधिक)। तो मैंने सोचा कि मुझे लोडिंग दृश्य बनाना चाहिए।cocos2d-x में स्प्राइट एनिमेट करते समय आप एक दृश्य कैसे लोड करते हैं?

तो अभी मैं क्या कर रहा हूँ एक std :: समारोह जो 0.1 सेकंड बुलाया जाता लोड हो रहा है दृश्य दिखाई देता है के बाद मेरे "लोड करने" दृश्य करने के लिए दे रहा है। इस फ़ंक्शन में "गेम" दृश्य शुरू करने के लिए कोड है:

लोडिंग दृश्य बनाने के लिए।

auto loading_scene = LoadingScene::createLoadingScene([stage_course]() { 

    Director::getInstance()->replaceScene(Game::createScene(stage_course->course_id)); 

}); 

Director::getInstance()->replaceScene(loading_scene); 

गेम दृश्य लोड करने के लिए।

void LoadingScene::onEnter() 
{ 
    Node::onEnter(); 

    call_after(0.1, callback_start); 
} 

इसी का परिणाम लोड हो रहा है एक चरित्र चल रहा है की एक सरल एनिमेटेड स्प्राइट के साथ दिखा दृश्य है। सबसे पहले मैंने कॉलबैक से पहले 1.0 सेकंड की देरी के साथ प्रयास किया ताकि यह जांच सके कि स्प्राइट सही तरीके से काम कर रहा है (यह करता है, चरित्र चलता है)। लेकिन कॉलबैक निष्पादित होने पर यह आगे बढ़ता है (जो नया दृश्य लोड करता है) और दृश्य के लोड होने तक लगभग 1-2 सेकंड तक रहता है और उसके बाद प्रस्तुत किया जाता है ..

क्या कोई जानता है कि कैसे रखा जाए दृश्य लोड हो रहा है, जबकि एनिमेटेड स्प्राइट ताकि यह "खेल" दृश्य दिखाए जाने तक कभी नहीं चल रहा है?


संपादित करें:

मैं उपयोग कर रहा हूँ Cocos2d-एक्स 3.8।

मेरे लोड हो रहा है दृश्य अपने init समारोह में निम्न कोड एक एनीमेशन जो एक शिखर चेतन करने के लिए प्रयोग किया जाता है बनाने के लिए है:

// Create the sprite animation 
Animation *animation = Animation::create(); 
for (int i = 0; i < INT16_MAX; i++) 
{ 
    string frame_sprite_name = StringUtils::format("Interface/loading/0_%d.png",i); 

    auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(frame_sprite_name); 

    if (frame) { 
     animation->addSpriteFrame(frame); 
    } else { 
     break; 
    } 
} 

animation->setDelayPerUnit(0.15f); 


Animate *animate = Animate::create(animation); 


// Create a temporal sprite to run the animation 

auto temp_sprite = Sprite::create(); 

temp_sprite->setAnchorPoint(Vec2(0.5,0.5)); 
temp_sprite->setPosition(Vec2(DISPLAY_WIDTH/2.0f,DISPLAY_HEIGHT/2.0f)); 


this->addChild(temp_sprite); 

temp_sprite->runAction(RepeatForever::create(animate)); 

संपादित करें 2:

कारण है कि मेरी खेल दृश्य लोड करने में बहुत अधिक समय लगता है क्योंकि मैं अपने स्टेज को इस तरह की सभी जरूरतों को लोड कर रहा हूं:

// Shared 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(STUDENTS_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(STUDENTS_SPRITE_MAP); 
} 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(OTHERS_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(OTHERS_SPRITE_MAP); 
} 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(INTERFACE_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(INTERFACE_SPRITE_MAP); 
} 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(ZOMBIES_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(ZOMBIES_SPRITE_MAP); 
} 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(PORTRAITS_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(PORTRAITS_SPRITE_MAP); 
} 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(CUTS_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(CUTS_SPRITE_MAP); 
} 

// Exclusive 

if (!SpriteFrameCache::getInstance()->isSpriteFramesWithFileLoaded(TEACHERS_SPRITE_MAP)) { 
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile(TEACHERS_SPRITE_MAP); 
} 

उत्तर

4

इस प्रयास करें:

void HelloWorld::loadTextures1(){ 
    Director::getInstance()->getTextureCache()->addImageAsync("sprites1.png", CC_CALLBACK_1(HelloWorld::loadTextures2, this)); 
} 

void HelloWorld::loadTextures2(Texture2D* texture1){ 
    this->texture1 = texture1; 
    CCLOG("Texture 1 loaded!"); 
    Director::getInstance()->getTextureCache()->addImageAsync("sprites2.png", CC_CALLBACK_1(HelloWorld::loadTextures3, this)); 
} 


void HelloWorld::loadTextures3(Texture2D* texture2){ 
    this->texture2 = texture2; 
    CCLOG("Texture 2 loaded!"); 
    Director::getInstance()->getTextureCache()->addImageAsync("sprites3.png", CC_CALLBACK_1(HelloWorld::allTexturesLoaded, this)); 
} 

void HelloWorld::allTexturesLoaded(Texture2D* texture3){ 
    this->texture3 = texture3; 
    CCLOG("Texture 3 loaded!"); 

    auto cache = SpriteFrameCache::getInstance(); 

    cache->addSpriteFramesWithFile("sprites1.plist", texture1); 
    cache->addSpriteFramesWithFile("sprites2.plist", texture2); 
    cache->addSpriteFramesWithFile("sprites3.plist", texture3); 

    auto scene = GameScene::createScene(); 
    Director::getInstance()->replaceScene(TransitionShrinkGrow::create(.5, scene)); 
} 

यह अतुल्यकालिक रूप से इन 3 बनावट लोड करता है और उसके बाद तुल्यकालिक प्रीलोडेड बनावट के साथ plist फ़ाइलें लोड। अंत में एक छोटा सा फ्रीज है (सिंक्रोनस भाग), लेकिन यह बुरा नहीं है मुझे लगता है। आप SpriteFrameCache में भी गहरी खुदाई कर सकते हैं और इसे अनुकूलित करने का प्रयास कर सकते हैं।

+0

मुझे लगता है कि यह सबसे अच्छा तरीका है, अन्य प्रकार के उत्तर क्या कहते हैं लेकिन उदाहरण कोड के लिए धन्यवाद समझने में आसान है। मुझे लगता है कि मैं प्रत्येक दृश्य स्थिर प्रति दृश्य प्रकार में स्प्राइट शीट की आवश्यकता के बारे में जानकारी बना सकता हूं और इसके आधार पर सभी आवश्यक रूप से लोड कर सकता हूं। फिर मैं अपने अधिकांश दृश्यों के लिए इसका उपयोग कर सकता हूं। धन्यवाद। (मुझे नहीं पता था कि मैं बनावट लोड कर सकता हूं और उसके बाद इसे स्प्राइटफ्रेम कैश के साथ जोड़ सकता हूं। मैंने सोचा था कि 'addSpriteFramesWithFile' स्क्रैच से सबकुछ फिर से बनाएगा, इसलिए मैंने नहीं सोचा था कि मैं addImageAsync विधि का उपयोग कर सकता हूं। – Pochi

1

मुझे पता नहीं है कि cocos2d-x इस विशेष रूप से अच्छी तरह से समर्थन करता है:

सीएसएलओडर वर्तमान थ्रेड पर दृश्य लोड करता है ताकि यह एनीमेशन लूप को समाप्त होने तक अवरुद्ध कर दे।

चिकनी एनिमेशन प्राप्त करने के लिए छलबल CSLoader काम कर रहा है यह पुनर्संशोधित करने की आवश्यकता होगी या तो * एक कार्यकर्ता सूत्र में चलाने के लिए - कौन (पिछली बार मैंने देखा) के रूप में किसी भी रेफरी ली गई वस्तु अगर आतंक लिए जा रहा है कठिन होने जा रहा है यह मुख्य कोको थ्रेड पर नहीं बनाया गया है। फ्रेम को एनिमेट करने की अनुमति देने के लिए * डिस्पैचर/रनलोप पर अक्सर कॉलआउट करने के लिए। मैंने cocostudio :: CSLoader कोड को यह देखने के लिए नहीं देखा है कि यह कितना सक्षम होगा ... यह निश्चित रूप से बॉक्स को इसका समर्थन नहीं करता है।

वैकल्पिक विकल्प जो आपको प्राप्त करना मुश्किल हो सकता है, आपको बस भाग में दृश्य तोड़ना है - जिनमें से प्रत्येक को जल्दी से लोड किया जा सकता है, इसलिए कोई स्पष्ट भार देरी नहीं होती है।

+0

दृश्यों को टुकड़ों में तोड़कर आपका क्या मतलब है? – Pochi

+0

उम्मीद है कि पूरा दृश्य एक बार में सभी दिखाई नहीं दे रहा है। प्रारंभिक रूप से अदृश्य बिट्स को बाद में लोड करें, जब उनकी आवश्यकता हो। –

+1

मैं बिल्कुल वैसा ही समस्या है :(एक ही रास्ता मैंने पाया, मैन्युअल कोकोस स्टूडियो CSLoader का उपयोग कर withoud लोड स्प्राइट है बुला: \t ऑटो TexureCache = निदेशक :: getInstance() -> getTextureCache(); TexureCache-> addImageAsync (" मेनमेनूस्क्रीन/पृष्ठभूमि.png ", CC_CALLBACK_1 (जीएस_लोडिंग :: लोडिंग कॉलबैक, यह)); – finalpets

1

मैं क्रिस के कहने से सहमत हूं, विशेष रूप से काम बंद करना या चीजों को तोड़ना।

यह सच है, Cocos2d-x बहु सूत्रण के लिए नहीं बनाया गया है, तो यही कारण है कि आप एक update कॉलबैक कि केवल काम की एक छोटी राशि करता लागू करने की आवश्यकता इंतजार कर रहा है जब तक अगले runloop इंजन प्रस्तुत करने के लिए अनुमति देने के लिए है, तो।

मेरी इच्छा है कि मैं लोडिंग समस्याओं को हल करने में आपकी सहायता कर सकूं, लेकिन जो कोड आप दिखा रहे हैं वह केवल एनिमेशन लोड करने के लिए है, जो वास्तव में समस्या नहीं है। हमें उस कोड को देखने की ज़रूरत है जो धीरे-धीरे कुछ व्यावहारिक समाधान प्रदान करने के कारण हो रही है।

+0

मुझे लगता है कि खेल में मंदी दृश्य इस तथ्य से आता है कि मैं 6 या 7 स्प्राइट मैप्स लोड कर रहा हूं। लेकिन मुझे नहीं लगता कि मैं उनमें से कुछ को लोड नहीं कर सकता क्योंकि मैं उन सभी का उपयोग कर रहा हूं, और जब मैं उपयोगकर्ता खेल रहा हूं तो मैं मंदी नहीं करना चाहता वास्तव में उम्मीद थी कि किसी को यह पता चल जाएगा कि ऐसा करने के तरीके के साथ कैसे आया था या नहीं। कुछ ऐसा जो दिमाग में आता है वह लोडिंग दृश्य पर क्षैतिज रूप से spritemaps लोड करता है लेकिन मुझे पता नहीं है कि यह संभव है। मुझे याद है कि बनावट को अतुल्यकालिक रूप से लोड किया जा सकता है लेकिन spritemaps के बारे में पता नहीं है। – Pochi

+0

@ चेकिस मैंने कभी नहीं कहा कि उनमें से कुछ लोड करें और दृश्य शुरू करें। आपको डेटा का हिस्सा लोड करना चाहिए, और अगले रनलोप को लोड करना जारी रखने की प्रतीक्षा करें। एक बार जब आप सब कुछ लोड कर लेते हैं, तो ** ** आप वास्तविक दृश्य में संक्रमण करते हैं। दोबारा, यह महत्वपूर्ण है कि आप इस तथ्य के बारे में जानते हों कि समय क्या ले रहा है, और हमें संभावित समाधान सुझाए जाने के लिए उस कोड को देखने की आवश्यकता है। – Mazyod

संबंधित मुद्दे

 संबंधित मुद्दे