2015-09-14 19 views
14

Tôi có cảnh "chọn giai đoạn" và cảnh "trò chơi". Tuy nhiên khi người dùng nhấn nút để bắt đầu cảnh trò chơi, có sự chậm trễ giữa cảnh báo và cảnh hiển thị (khoảng 2 giây trở lên trên các thiết bị cũ). Vì vậy, những gì tôi nghĩ là tôi nên tạo ra một cảnh tải.Làm thế nào để bạn tải một cảnh trong khi hoạt hình một sprite trong cocos2d-x?

Vì vậy, những gì tôi đang làm ngay bây giờ là đi qua để "tải" tôi cảnh một std :: chức năng mà được gọi là 0,1 giây sau khi cảnh bốc xuất hiện. Chức năng này có mã để bắt đầu cảnh "trò chơi" như sau:

Để tạo cảnh tải.

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

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

}); 

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

Để tải cảnh trò chơi.

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

    call_after(0.1, callback_start); 
} 

Kết quả là cảnh tải hiển thị bằng hình động đơn giản của ký tự đang chạy. Lúc đầu, tôi đã thử với một sự chậm trễ là 1,0 giây trước khi gọi lại để kiểm tra xem sprite có đang hoạt động đúng không (nó hoạt động, ký tự chạy). Nhưng nó dừng di chuyển khi gọi lại được thực hiện (một trong đó tải các cảnh mới) và vẫn như thế này trong khoảng 1-2 giây cho đến khi cảnh đã tải và sau đó được trình bày ..

Có ai biết làm thế nào để giữ sprite hoạt hình trong khi cảnh đang tải để nó không bao giờ ngừng chạy cho đến khi cảnh "game" được hiển thị?


Edit:

Tôi đang sử dụng cocos2d-x-3.8.

cảnh tải của tôi có đoạn mã sau trong hàm init của nó để tạo ra một hình ảnh động được sử dụng để animate một chóp:

// 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)); 

Chỉnh sửa 2:

Lý do tại sao trò chơi của tôi cảnh mất quá nhiều thời gian để tải là bởi vì tôi đang tải tất cả các spritemaps sân khấu của tôi cần như thế này:

// 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); 
} 

Trả lời

4

Hãy thử điều này:

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)); 
} 

Nó tải không đồng bộ những 3 textures và sau đó tải đồng bộ các file plist với kết cấu tải trước. Có một chút đóng băng vào cuối (phần đồng bộ), nhưng nó không phải là xấu tôi nghĩ. Bạn cũng có thể đào sâu hơn vào SpriteFrameCache và cố gắng tối ưu hóa nó.

+0

Tôi đoán đây là cách tiếp cận tốt nhất, đó là những gì các câu trả lời khác nói nhưng dễ hiểu hơn nhờ mã ví dụ. Tôi đoán tôi có thể làm cho các thông tin về những gì sprite tờ là cần thiết trong mỗi cảnh tĩnh cho mỗi loại cảnh và đệ quy tải tất cả cần thiết dựa trên nó. Sau đó, tôi có thể sử dụng điều này cho hầu hết các cảnh của tôi. cảm ơn. (Tôi không biết tôi có thể tải các kết cấu và sau đó liên kết nó với bộ nhớ cache spriteframe như thế này.Tôi nghĩ rằng 'addSpriteFramesWithFile' sẽ tạo lại tất cả mọi thứ từ đầu vì vậy tôi đã không nghĩ rằng tôi có thể sử dụng phương pháp addImageAsync. – Pochi

1

Tôi không biết rằng cocos2d-x hỗ trợ điều này đặc biệt tốt:

CSLoader tải cảnh trên chuỗi hiện tại để nó chặn vòng hoạt ảnh cho đến khi kết thúc.

Để đạt được hình ảnh động mượt mà, CSLoader đang hoạt động, cần phải được cấu trúc lại hoặc * để chạy trong chuỗi công nhân - Sẽ khó khăn (lần gần đây nhất) nó không được tạo trên sợi coco chính. * để gọi chú thích thường xuyên đến Dispatcher/runloop để cho phép khung hoạt ảnh. Tôi havn't nhìn vào cocostudio :: CSLoader mã để xem như thế nào amenable nó sẽ được này ... nó chắc chắn dường như không hỗ trợ này ra khỏi hộp.

Cách thay thế khó có thể đạt được là chỉ đơn giản là phá vỡ cảnh của bạn thành các khối - mỗi phần có thể được tải nhanh để không có sự chậm trễ tải rõ ràng.

+0

Bạn có ý gì khi chia nhỏ cảnh thành các phần? – Pochi

+0

Hy vọng rằng toàn cảnh không thể nhìn thấy tất cả cùng một lúc. Tải các bit vô hình ban đầu sau này, khi chúng cần thiết. –

+1

tôi có chính xác cùng một vấn đề: (cách duy nhất tôi tìm thấy là tải sprites thủ công bằng cách sử dụng cocos studio CSLoader, gọi: \t tự động TexureCache = Director :: getInstance() -> getTextureCache(); TexureCache-> addImageAsync (" MainMenuScreen/Background.png ", CC_CALLBACK_1 (GS_Loading :: LoadingCallback, điều này)); – finalpets

1

Tôi đồng ý với những gì Chris đang nói, cụ thể là tải công việc hoặc chia nhỏ mọi thứ thành nhiều phần.

Đúng vậy, Cocos2d-x không được thiết kế để đa luồng, vì vậy đó là lý do tại sao bạn cần thực hiện gọi lại update chỉ một lượng nhỏ công việc, sau đó đợi cho đến lần chạy tiếp theo để cho phép công cụ hiển thị.

Tôi ước tôi có thể giúp bạn giải quyết vấn đề tải, nhưng mã bạn đang hiển thị chỉ để tải hình động, điều này thực sự không phải là vấn đề. Chúng ta cần xem mã đang làm chậm tốc độ cung cấp một số giải pháp thực tế.

+0

Tôi nghĩ rằng sự suy giảm trong trò chơi cảnh đến từ thực tế là tôi đang tải 6 hoặc 7 bản đồ sprite.Nhưng tôi không nghĩ rằng tôi có thể chọn không tải một số người trong số họ kể từ im sử dụng tất cả, và tôi không muốn có chậm lại trong khi người dùng đang chơi Đã thực sự hy vọng một ai đó biết làm thế nào hoặc đã đi với một cách để làm điều này.Một cái gì đó mà nói đến cái tâm là tải các spritemaps không đồng bộ trên cảnh tải nhưng tôi không biết nếu điều đó là có thể. Tôi nhớ đã thấy rằng các kết cấu có thể được nạp không đồng bộ nhưng không biết về spritemaps. – Pochi

+0

@Chiquis Tôi không bao giờ nói tải một số người trong số họ và bắt đầu hiện trường. Bạn nên tải một phần dữ liệu và chờ cho vòng lặp tiếp theo tiếp tục tải. Khi bạn tải mọi thứ, ** sau đó ** bạn chuyển sang cảnh thực tế. Một lần nữa, điều quan trọng ở đây là bạn biết một thực tế thời gian là gì, và chúng ta cần xem mã đó để đề xuất các giải pháp khả thi. – Mazyod

Các vấn đề liên quan