project-kyoku/modes/classicmode/game/classicgraphicsmanager.cpp

133 lines
3.8 KiB
C++
Raw Normal View History

2021-12-21 18:07:19 +01:00
#include "classicgraphicsmanager.h"
#include "graphics/classicsprite.h"
#include "graphics/classicflyinganimationscenario.h"
#include "graphics/classicdyinganimationscenario.h"
2021-12-21 18:07:19 +01:00
ClassicGraphicsManager::ClassicGraphicsManager(Timeline<ClassicNote> &timeline, const microsec& visibility_offset) :
_sprite_container({Type::UP, Type::DOWN,
Type::LEFT, Type::RIGHT},
std::make_unique<ClassicSpriteFactory>()),
_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<ClassicArrowNote::ArrowElement>& 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);
}
2021-12-21 18:07:19 +01:00
}
sf::VertexArray ClassicGraphicsManager::makeLine(const Coordinates& c1, const Coordinates& c2) const
2021-12-21 18:07:19 +01:00
{
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<ClassicArrowNote::ArrowElement>& 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<ClassicFlyingAnimationScenario>();
element.animations[ClassicArrowNote::State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
element.animations[ClassicArrowNote::State::DEAD] = nullptr;
element.animations[ClassicArrowNote::State::FLYING]->launch(element.sprite, range.begin, range.end);
}
2021-12-21 18:07:19 +01:00
}
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)
2021-12-21 18:07:19 +01:00
{
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()});
}
2021-12-21 18:07:19 +01:00
++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;
2021-12-21 18:07:19 +01:00
}