2015-12-20 10 views
2

У меня есть контейнер объектов:Как анимировать через контейнер для windows.draw()?

std::vector<sf::Drawable> gameObjects; 

Моя цель состоит в перебирать эти объекты и сделать их:

for (auto it : gameObjects) 
{ 
    window.draw(*it); 
} 

Вы можете предположить, эти методы уже реализованы. Что я подразумеваю под «анимацией»: я хочу, чтобы эти объекты рисовались по одному, а не сразу сразу.

void Run::render() 
{ 
    window.clear(colorWindow); 

    for (auto it : gameObjects) 
    { 
     window.draw(*it); 
    } 

    window.display();  
} 

То есть, каждый рендер() нарисовывает дополнительный объект в контейнере. Вы знаете, как я могу это сделать? Заранее спасибо.


редактировать: Я пытался что-то нетрадиционное - я не думаю, что это хорошая практика, но это работает:

int count = 0; 
int countReset = 1; 

...

while (countReset > count) 
{ 
    objects.at(count++).draw(window); 

} 
countReset++; 
count = 0; 

ответ

1

Используйте статический счетчик для вашего индекс в списке объектов. Измерьте время и увеличьте счетчик, если истек период времени. Итак, следующий раз нарисован следующий объект в списке.

#include <chrono> 

void Run::render() 
{ 
    // actual time 
    std::chrono::high_resolution_clock::time_point actTime = std::chrono::high_resolution_clock::now(); 

    // remember time 
    static bool init = false; 
    std::chrono::high_resolution_clock::time_point lastTime; 
    if (!init) 
    { 
     lastTime = actTime; 
     init = true; 
    } 

    // delta time 
    long microseconds = std::chrono::duration_cast<std::chrono::duration<long, std::micro> >(actTime - lastTime).count(); 
    double deltaTms = ((double)microseconds)/1000.0; 

    window.clear(colorWindow); 

    static size_t actObjInx = 0; 
    window.draw(gameObjects[actObjInx]); 

    // increment object index if time period has elapsed 
    if (deltaTms > 100.0) // 0.1 seconds 
    { 
     lastTime = actTime; 

     actObjInx ++; 
     if (actObjInx == gameObjects.size()) 
      actObjInx = 0; 
    } 

    window.display(); 
} 
+0

Это будет оживлять быстрее, тем быстрее мой процессор/графический процессор может отображать ... на современных процессорах, это будет просто дикое мерцание. – nvoigt

+0

@nvoigt Вам нужно измерить прошедшее время с момента последнего вызова Run :: render. Только приращение 'actObjInx', если достигнут порог времени. В данный момент я приведу вам пример. – Rabbid76

2

Вы не должны принимать решения об игре в своем рендеринге. У вас должен быть метод обновления где-нибудь, который принимает решения о том, как ввод и время влияют на ваш игровой мир. Рендеринг должен делать только одно: рендеринг. Никаких решений, никаких манипуляций с данными.

Вы можете, например, использовать составной класс, чтобы указать, какой объект должен быть нарисован, или вы можете получить свой собственный базовый класс из sf :: Drawable и реализовать метод bool IsVisible() const;. В любом случае, решение, если оно нарисовано производится в другом месте, рендеринг только для выполнения команд, что делают именно:

struct MaybeDrawn 
{ 
    bool IsVisible; 
    sf::Drawable Object;  
}; 

...

std::vector<MaybeDrawn> gameObjects; 

...

void Run::render() 
{ 
    window.clear(colorWindow); 

    for (auto it : gameObjects) 
    { 
     if(it->IsVisible) 
     { 
      window.draw(it->Object); 
     } 
    } 

    window.display();  
} 

Ваше решение, как и когда устанавливать bool на true должно произойти в вашем методе Update/ChangeWorld. Возможно, вы хотите посмотреть here для общего описания того, как структурировать игру и как построить таймер.

В качестве альтернативы, вы можете оставить свою программу такой, какой она есть, и вставить и/или удалить из своего вектора в свой метод принятия решений.

 Смежные вопросы

  • Нет связанных вопросов^_^