#include "classicgraphicsmanager.h" #include "graphics/classicsprite.h" #include "graphics/classicflyinganimationscenario.h" #include "graphics/classicdyinganimationscenario.h" ClassicGraphicsManager::ClassicGraphicsManager(Timeline &timeline, const microsec& visibility_offset) : _sprite_container({Type::UP, Type::DOWN, Type::LEFT, Type::RIGHT}, std::make_unique()), _timeline(&timeline), _visibility_offset(visibility_offset) { _timeline->expire(_first); _timeline->expire(_last); } void ClassicGraphicsManager::draw(sf::RenderTarget& target, sf::RenderStates states) const { if (nothingToDraw()) return; for (auto it = _first; it != _last; ++it) { (*it)->draw(this, target, states); } } void ClassicGraphicsManager::draw(const std::vector& elements, sf::RenderTarget& target, sf::RenderStates states) const { for (std::size_t i = 0; i < elements.size(); ++i) { const auto& sprite = elements[i].sprite; if (i >= 1) { const auto& neighbor_sprite = elements[i - 1].sprite; const auto c1 = neighbor_sprite->trailCoordinates(); const auto c2 = sprite->trailCoordinates(); target.draw(makeLine(c1, c2)); } target.draw(*sprite, states); } } sf::VertexArray ClassicGraphicsManager::makeLine(const Coordinates& c1, const Coordinates& c2) const { sf::VertexArray line(sf::LinesStrip, 2); line[0].color = sf::Color::Yellow; line[0].position = {c1.x + 10, c1.y}; line[1].color = sf::Color::Blue; line[1].position = {c2.x + 10, c2.y}; return line; } void ClassicGraphicsManager::setGraphics(std::vector& elements, TimeRange &&range) { for (auto& element : elements) { element.sprite = _sprite_container.getSprite(element.type); element.sprite->setCoordinates(element.coordinates); element.sprite->setTrailCoordinates(Coordinates( 0.f, 9.f )); element.animations[ClassicArrowNote::State::NONE] = nullptr; element.animations[ClassicArrowNote::State::FLYING] = std::make_shared(); element.animations[ClassicArrowNote::State::DYING] = std::make_shared(); element.animations[ClassicArrowNote::State::DEAD] = nullptr; element.animations[ClassicArrowNote::State::FLYING]->launch(element.sprite, range.begin, range.end); } } void ClassicGraphicsManager::update(const microsec &offset) { fetchLastNote(offset); fetchFirstNote(offset); } void ClassicGraphicsManager::fetchFirstNote(const microsec& offset) { (void)offset; // ???? if (nothingToDraw()) return; Iterator note_iterator = _first; while (note_iterator != _last) { auto note = *note_iterator; if (note->shouldRemove()) ++_first; ++note_iterator; } } void ClassicGraphicsManager::fetchLastNote(const microsec& offset) { Iterator note_iterator = _timeline->getTopNote(); while (!_timeline->isExpired(note_iterator) && isVisiblyClose(note_iterator, offset)) { if (nothingToDraw()) _first = note_iterator; auto note = *note_iterator; if (!note->isInGame()) { note->putToGame(); note->setGraphics(this, TimeRange{offset, note->offset()}); } ++note_iterator; } _last = note_iterator; } bool ClassicGraphicsManager::nothingToDraw() const noexcept { return _timeline->isExpired(_first) || _timeline->isExpired(_last); } bool ClassicGraphicsManager::isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept { return ((*iterator)->offset() - _visibility_offset) <= music_offset; }