You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
project-kyoku/src/modes/classicmode/graphics/classictimelinegraphicsmana...

154 lines
4.4 KiB
C++

#include "classictimelinegraphicsmanager.h"
#include "game/classicarrownote.h"
#include <iostream>
ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager(
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),
_back_visibility_offset(static_cast<double>(visibility_offset) / 4.f),
_last_offset(0)
{
_timeline->expire(_first);
_timeline->expire(_last);
}
void ClassicTimelineGraphicsManager::input(kku::GameEvent &&input)
{
switch (input.event.type)
{
default:
break;
case kku::SystemEvent::Type::KeyPress:
{
const auto key_data = std::get<kku::SystemEvent::Key>(input.event.data);
if (key_data.view == kku::SystemEvent::Key::Code::Add)
{
_visibility_offset += 200000;
_back_visibility_offset =
static_cast<double>(_visibility_offset) / 4.f;
}
else if (key_data.view == kku::SystemEvent::Key::Code::Subtract)
{
_visibility_offset -= 200000;
_back_visibility_offset =
static_cast<double>(_visibility_offset) / 4.f;
}
break;
}
}
}
void ClassicTimelineGraphicsManager::display() const
{
// if (nothingToDraw())
// return;
std::cout << "displaying on tl: ";
for (auto it = _first; it != _last; ++it)
{
std::cout << (*it)->getId() << " ";
(*it)->draw(shared_from_this());
}
std::cout << "\n" << std::flush;
}
void ClassicTimelineGraphicsManager::update(const kku::microsec &offset)
{
_last_offset = offset;
fetchLastNote(offset);
fetchFirstNote(offset);
}
void ClassicTimelineGraphicsManager::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;
}
else
{
std::cout << note->getId() << ": remove graphics!\n" << std::flush;
}
}
void ClassicTimelineGraphicsManager::draw(
const ClassicArrowNote *const note) const
{
const double d_visibility_offset =
static_cast<double>(_last_offset + _visibility_offset);
const double d_back_visibility_offset =
static_cast<double>(_last_offset - _back_visibility_offset);
const double span = d_visibility_offset - d_back_visibility_offset;
const double note_span =
static_cast<double>(note->getPerfectOffset()) - d_visibility_offset;
const double percent = note_span / (span / 100.f);
const auto elements = note->getElements();
for (std::size_t i = 0; i < elements.size(); ++i)
{
auto timeline_sprite = _factory->createSprite(elements[i].type);
timeline_sprite->setPosition(
kku::Point{static_cast<int>(850 + 1280.f / 100.f * percent), 700});
timeline_sprite->display();
}
}
bool ClassicTimelineGraphicsManager::nothingToDraw() const noexcept
{
return _timeline->isExpired(_first) || _timeline->isExpired(_last);
}
bool ClassicTimelineGraphicsManager::isVisiblyClose(
const ClassicNote *const note,
const kku::microsec &music_offset) const noexcept
{
const auto &perfect_offset = note->getPerfectOffset();
return ((perfect_offset - _visibility_offset) <= music_offset) ||
((perfect_offset + (_visibility_offset / 4.)) >= music_offset);
}
void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec &offset)
{
// if (nothingToDraw())
// return;
Iterator note_iterator = _first;
while (note_iterator != _timeline->begin() &&
isVisiblyClose(*note_iterator, offset))
{
--note_iterator;
}
_first = note_iterator;
}
void ClassicTimelineGraphicsManager::fetchLastNote(const kku::microsec &offset)
{
Iterator note_iterator = _timeline->getTopNote();
while (!_timeline->isExpired(note_iterator) &&
isVisiblyClose(*note_iterator, offset))
{
if (nothingToDraw())
_first = note_iterator;
++note_iterator;
}
_last = note_iterator;
}