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/classicgame/classicnotemanager.cpp

142 lines
4.5 KiB
C++

#include "classicnotemanager.h"
#include "classicsprite.h"
#include "classicgraphicsmanager.h"
// Replace with interface by dependency injection
#include "classicflyinganimationscenario.h"
#include "classicdyinganimationscenario.h"
//
ClassicNoteManager::ClassicNoteManager(const std::shared_ptr<ClassicGraphicsManager>& manager) :
_graphics_manager(manager)
{}
ClassicNoteManager::~ClassicNoteManager()
{}
bool ClassicNoteManager::isActive(const ClassicNote* note) const
{
return note->state == ClassicNoteState::ACTIVE;
}
void ClassicNoteManager::putToGame(ClassicNote* note, const microsec &music_offset)
{
note->state = ClassicNoteState::FLYING;
for (auto& element : note->elements)
{
element.sprite = _graphics_manager->getSprite(element.type);
element.sprite->setCoordinates(element.coordinates, 0., 9.);
element.animations[note->state]->launch(element.sprite, music_offset, note->evaluator.offset());
}
}
bool ClassicNoteManager::isInGame(const ClassicNote* note) const
{
return note->state == ClassicNoteState::FLYING
|| note->state == ClassicNoteState::ACTIVE
|| note->state == ClassicNoteState::DYING;
}
bool ClassicNoteManager::shouldRemove(const ClassicNote* note) const
{
return note->state == ClassicNoteState::DEAD;
}
void ClassicNoteManager::update(ClassicNote* note, const microsec& music_offset)
{
switch (note->state)
{
default: return;
break;
case ClassicNoteState::FLYING:
if (note->evaluator.isActive(music_offset))
note->state = ClassicNoteState::ACTIVE;
break;
case ClassicNoteState::DYING:
if (note->elements[0].animations[note->state]->isDone())
note->state = ClassicNoteState::DEAD;
break;
case ClassicNoteState::ACTIVE:
if (!note->evaluator.isActive(music_offset))
{
note->state = ClassicNoteState::DYING;
for (auto& element : note->elements)
element.animations[note->state]->launch(element.sprite, music_offset, note->evaluator.offset());
}
break;
}
for (auto& element : note->elements)
if (element.animations[note->state])
element.animations[note->state]->update(music_offset);
}
void ClassicNoteManager::input(ClassicNote* note, PlayerInput&& inputdata)
{
auto grade = ClassicGrade::BAD;
bool input_valid = std::any_of(note->elements.begin(), note->elements.end(),
[inputdata=inputdata](auto& element)
{
if (element.pressed)
return false;
auto key_iterator = std::find(element.available_keys.begin(), element.available_keys.end(), inputdata.event.key.code);
bool found_key = key_iterator != element.available_keys.end();
if (found_key)
{
element.pressed = true;
element.pressed_as = inputdata.event.key.code;
}
return found_key;
});
bool all_pressed = allElementsPressed(note);
if (all_pressed)
grade = note->evaluator.calculatePrecision(inputdata.timestamp);
if (all_pressed || !input_valid)
{
note->state = ClassicNoteState::DYING;
for (auto& element : note->elements)
element.animations[note->state]->launch(element.sprite, inputdata.timestamp, note->evaluator.offset());
}
std::cout << "User input: " << static_cast<int>(grade) << "\n";
}
void ClassicNoteManager::draw(const ClassicNote* note) const
{
for (std::size_t i = 0; i < note->elements.size(); ++i)
{
if (i >= 1)
_graphics_manager->drawLine(note->elements[i-1].sprite->trailCoordinates(), note->elements[i].sprite->trailCoordinates());
_graphics_manager->draw(note->elements[i].sprite);
}
}
bool ClassicNoteManager::allElementsPressed(const ClassicNote* note) const
{
return std::all_of(note->elements.begin(), note->elements.end(),
[](const auto& element)
{
return element.pressed;
});
}
bool ClassicNoteManager::isPressedAs(const ClassicNote* note, sf::Keyboard::Key key) const
{
return std::any_of(note->elements.begin(), note->elements.end(),
[key=key](const auto& element)
{
return key == element.pressed_as;
});
}