212 lines
6.1 KiB
C++
212 lines
6.1 KiB
C++
#include "classicscenegraphicsmanager.h"
|
|
#include "game/classicarrownote.h"
|
|
|
|
#include <iostream>
|
|
|
|
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)
|
|
{
|
|
const auto note = *it;
|
|
if (note->getState() != ClassicNote::State::DEAD)
|
|
note->draw(shared_from_this());
|
|
}
|
|
}
|
|
|
|
void ClassicSceneGraphicsManager::update(const kku::microsec &offset)
|
|
{
|
|
fetchLastNote(offset);
|
|
fetchFirstNote(offset);
|
|
|
|
updateVisibleNotes(offset);
|
|
}
|
|
|
|
void ClassicSceneGraphicsManager::update(const kku::microsec &offset,
|
|
ClassicArrowNote *note)
|
|
{
|
|
bool hasGraphics = (note->getElements()[0].sprite != nullptr);
|
|
|
|
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()});
|
|
}
|
|
else
|
|
{
|
|
std::cout << note->getId() << ": remove graphics!\n" << std::flush;
|
|
removeGraphics(note->getElements());
|
|
}
|
|
}
|
|
|
|
void ClassicSceneGraphicsManager::draw(const ClassicArrowNote *const note) const
|
|
{
|
|
const auto elements = note->getElements();
|
|
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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
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
|
|
{
|
|
return (note->getPerfectOffset() - _visibility_offset) <= music_offset;
|
|
}
|
|
|
|
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))
|
|
{
|
|
--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 &&
|
|
offset <= note->getPerfectOffset())
|
|
{
|
|
note->setState(ClassicNote::State::INITIAL);
|
|
}
|
|
}
|
|
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))
|
|
{
|
|
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 &&
|
|
offset <= note->getPerfectOffset())
|
|
{
|
|
note->setState(ClassicNote::State::INITIAL);
|
|
}
|
|
|
|
++note_iterator;
|
|
}
|
|
|
|
_last = note_iterator;
|
|
}
|
|
|
|
void ClassicSceneGraphicsManager::updateVisibleNotes(
|
|
const kku::microsec &offset)
|
|
{
|
|
for (auto it = _first; it != _last; ++it)
|
|
(*it)->update(offset);
|
|
}
|