project-kyoku/src/modes/classicmode/graphics/classicscenegraphicsmanager...

199 lines
5.9 KiB
C++
Raw Normal View History

2022-05-17 00:22:18 -04:00
#include "classicscenegraphicsmanager.h"
2022-05-17 19:47:47 -04:00
#include "game/classicarrownote.h"
2022-05-17 00:22:18 -04:00
2022-05-25 22:13:13 -04:00
#include <iostream>
2022-05-17 00:22:18 -04:00
ClassicSceneGraphicsManager::ClassicSceneGraphicsManager(const std::shared_ptr<kku::Timeline<ClassicNote>>& timeline,
const std::shared_ptr<ClassicGraphicsFactory>& factory,
const kku::microsec& visibility_offset) :
ClassicGraphicsManager(visibility_offset),
_sprite_container({Type::UP, Type::DOWN,
Type::LEFT, Type::RIGHT},
factory),
_factory(factory),
_timeline(timeline)
{
_timeline->expire(_first);
_timeline->expire(_last);
}
void ClassicSceneGraphicsManager::input(kku::GameEvent&& input)
{
if (nothingToDraw())
return;
for (auto it = _first; it != _last; ++it)
{
(*it)->input(std::move(input));
}
}
void ClassicSceneGraphicsManager::display() const
{
if (nothingToDraw())
return;
for (auto it = _first; it != _last; ++it)
{
2022-05-25 22:13:13 -04:00
const auto note = *it;
if (note->getState() != ClassicNote::State::DEAD)
note->draw(shared_from_this());
2022-05-17 00:22:18 -04:00
}
}
void ClassicSceneGraphicsManager::update(const kku::microsec &offset)
2022-05-17 00:22:18 -04:00
{
fetchLastNote(offset);
fetchFirstNote(offset);
updateVisibleNotes(offset);
}
void ClassicSceneGraphicsManager::update(const kku::microsec& offset, ClassicArrowNote* note)
{
bool hasGraphics = (note->getElements()[0].sprite != nullptr);
2022-05-25 22:13:13 -04:00
if (isVisiblyClose(note, offset) && !hasGraphics)
{
std::cout << note->getId() << ": set graphics!\n" << std::flush;
setGraphics(note->getElements(), kku::TimeRange{note->getPerfectOffset() - _visibility_offset, note->getPerfectOffset()});
2022-05-25 22:13:13 -04:00
}
else
{
std::cout << note->getId() << ": remove graphics!\n" << std::flush;
removeGraphics(note->getElements());
}
}
void ClassicSceneGraphicsManager::draw(const std::vector<ArrowElement>& elements) const
2022-05-17 00:22:18 -04:00
{
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->trailPosition();
//const auto c2 = sprite->trailPosition();
//_render_target->draw(makeLine(c1, c2));
}
sprite->display();
}
}
void ClassicSceneGraphicsManager::setGraphics(std::vector<ArrowElement>& elements, kku::TimeRange&& range)
{
for (auto& element : elements)
{
element.sprite = _sprite_container.getSprite(element.type);
element.sprite->setPosition(element.position);
element.sprite->setTrailPosition(kku::Point( 0.f, 9.f ));
element.animations[ClassicNote::State::NONE] = nullptr;
element.animations[ClassicNote::State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
element.animations[ClassicNote::State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
element.animations[ClassicNote::State::DEAD] = nullptr;
element.animations[ClassicNote::State::FLYING]->launch(element.sprite, range.begin, range.end);
}
}
2022-05-25 22:13:13 -04:00
void ClassicSceneGraphicsManager::removeGraphics(std::vector<ArrowElement>& elements)
{
for (auto& element : elements)
{
_sprite_container.resetSprite(element.sprite, element.type);
element.sprite = nullptr;
element.animations[ClassicNote::State::NONE] = nullptr;
element.animations[ClassicNote::State::FLYING] = nullptr;
element.animations[ClassicNote::State::DYING] = nullptr;
element.animations[ClassicNote::State::DEAD] = nullptr;
}
}
2022-05-17 00:22:18 -04:00
bool ClassicSceneGraphicsManager::nothingToDraw() const noexcept
{
return _timeline->isExpired(_first)
|| _timeline->isExpired(_last);
}
bool ClassicSceneGraphicsManager::isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept
2022-05-17 00:22:18 -04:00
{
return (note->getPerfectOffset() - _visibility_offset) <= music_offset;
2022-05-17 00:22:18 -04:00
}
void ClassicSceneGraphicsManager::fetchFirstNote(const kku::microsec& offset)
{
if (nothingToDraw())
return;
if (offset < (*_first)->getPerfectOffset())
{
Iterator note_iterator = _first;
while (note_iterator != _timeline->begin() && isVisiblyClose(*note_iterator, offset))
2022-05-17 00:22:18 -04:00
{
--note_iterator;
}
_first = note_iterator;
auto note = *_first;
const auto state = note->getState();
if (state != ClassicNote::State::FLYING
&& state != ClassicNote::State::DYING
&& state != ClassicNote::State::INITIAL
2022-05-17 00:22:18 -04:00
&& offset <= note->getPerfectOffset())
{
note->setState(ClassicNote::State::INITIAL);
2022-05-17 00:22:18 -04:00
}
}
else
{
Iterator note_iterator = _first;
while (note_iterator != _last)
{
auto note = *note_iterator;
if (note->getState() == ClassicNote::State::DEAD)
{
// note->removeGraphics(this);
++_first;
}
++note_iterator;
}
}
}
void ClassicSceneGraphicsManager::fetchLastNote(const kku::microsec& offset)
{
Iterator note_iterator = _timeline->getTopNote();
while (!_timeline->isExpired(note_iterator) && isVisiblyClose(*note_iterator, offset))
2022-05-17 00:22:18 -04:00
{
if (nothingToDraw())
_first = note_iterator;
auto note = *note_iterator;
const auto state = note->getState();
if (state != ClassicNote::State::FLYING
&& state != ClassicNote::State::DYING
&& state != ClassicNote::State::INITIAL
2022-05-17 00:22:18 -04:00
&& offset <= note->getPerfectOffset())
{
note->setState(ClassicNote::State::INITIAL);
2022-05-17 00:22:18 -04:00
}
++note_iterator;
}
_last = note_iterator;
}
void ClassicSceneGraphicsManager::updateVisibleNotes(const kku::microsec& offset)
{
for (auto it = _first; it != _last; ++it)
(*it)->update(offset);
}