|
|
|
@ -4,21 +4,25 @@
|
|
|
|
|
#include "classicflyinganimationscenario.h"
|
|
|
|
|
#include "classicdyinganimationscenario.h"
|
|
|
|
|
|
|
|
|
|
ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
|
|
|
|
Type type, const Coordinates& coord, const std::unique_ptr<ClassicGraphicsManager> &manager) :
|
|
|
|
|
Note(perfect_offset),
|
|
|
|
|
_coordinates(coord),
|
|
|
|
|
_evaluator(intervals, _perfect_offset),
|
|
|
|
|
_keys({sf::Keyboard::W, sf::Keyboard::Up}),
|
|
|
|
|
ClassicNote::ClassicNote(ClassicNoteInitializer &&init, const std::unique_ptr<ClassicGraphicsManager> &manager) :
|
|
|
|
|
Note(init.perfect_offset),
|
|
|
|
|
_evaluator(init.intervals, _perfect_offset),
|
|
|
|
|
_graphics_manager(manager),
|
|
|
|
|
_type(type),
|
|
|
|
|
_state(State::NONE)
|
|
|
|
|
{
|
|
|
|
|
_animations[State::NONE] = nullptr;
|
|
|
|
|
_animations[State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
|
|
|
|
|
_animations[State::ACTIVE] = _animations[State::FLYING];
|
|
|
|
|
_animations[State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
|
|
|
|
|
_animations[State::DEAD] = nullptr;
|
|
|
|
|
_elements.resize(init.elements.size());
|
|
|
|
|
for (std::size_t i = 0; i < _elements.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
_elements[i].keys = init.elements[i].keys;
|
|
|
|
|
_elements[i].coordinates = init.elements[i].coordinates;
|
|
|
|
|
_elements[i].type = init.elements[i].type;
|
|
|
|
|
|
|
|
|
|
_elements[i].animations[State::NONE] = nullptr;
|
|
|
|
|
_elements[i].animations[State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
|
|
|
|
|
_elements[i].animations[State::ACTIVE] = _elements[i].animations[State::FLYING];
|
|
|
|
|
_elements[i].animations[State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
|
|
|
|
|
_elements[i].animations[State::DEAD] = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClassicNote::isActive() const
|
|
|
|
@ -28,9 +32,14 @@ bool ClassicNote::isActive() const
|
|
|
|
|
|
|
|
|
|
void ClassicNote::putToGame(const microsec &music_offset)
|
|
|
|
|
{
|
|
|
|
|
_graphics_manager->initGraphics(this);
|
|
|
|
|
_state = State::FLYING;
|
|
|
|
|
_animations[_state]->launch(_sprite, music_offset, offset());
|
|
|
|
|
|
|
|
|
|
for (auto& element : _elements)
|
|
|
|
|
{
|
|
|
|
|
element.sprite = _graphics_manager->getSprite(element.type);
|
|
|
|
|
element.sprite->setCoordinates(element.coordinates, 0., 9.);
|
|
|
|
|
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ClassicNote::isInGame() const
|
|
|
|
@ -47,68 +56,82 @@ bool ClassicNote::isExpired() const
|
|
|
|
|
|
|
|
|
|
void ClassicNote::update(const microsec& music_offset)
|
|
|
|
|
{
|
|
|
|
|
switch (_state)
|
|
|
|
|
{
|
|
|
|
|
default: return;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case State::FLYING:
|
|
|
|
|
if (_evaluator.isActive(music_offset))
|
|
|
|
|
_state = State::ACTIVE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case State::DYING:
|
|
|
|
|
if (_animations[_state]->isDone())
|
|
|
|
|
_state = State::DEAD;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case State::ACTIVE:
|
|
|
|
|
if (!_evaluator.isActive(music_offset))
|
|
|
|
|
switch (_state)
|
|
|
|
|
{
|
|
|
|
|
_state = State::DYING;
|
|
|
|
|
_animations[_state]->launch(_sprite, music_offset, offset());
|
|
|
|
|
default: return;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case State::FLYING:
|
|
|
|
|
if (_evaluator.isActive(music_offset))
|
|
|
|
|
_state = State::ACTIVE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case State::DYING:
|
|
|
|
|
if (_elements[0].animations[_state]->isDone())
|
|
|
|
|
_state = State::DEAD;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case State::ACTIVE:
|
|
|
|
|
if (!_evaluator.isActive(music_offset))
|
|
|
|
|
{
|
|
|
|
|
_state = State::DYING;
|
|
|
|
|
for (auto& element : _elements)
|
|
|
|
|
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_animations[_state])
|
|
|
|
|
_animations[_state]->update(music_offset);
|
|
|
|
|
for (auto& element : _elements)
|
|
|
|
|
if (element.animations[_state])
|
|
|
|
|
element.animations[_state]->update(music_offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicNote::input(PlayerInput&& inputdata)
|
|
|
|
|
{
|
|
|
|
|
auto grade = ClassicNote::Grade::BAD;
|
|
|
|
|
|
|
|
|
|
if (std::find(_keys.begin(), _keys.end(), inputdata.event.key.code) != _keys.end())
|
|
|
|
|
bool input_valid = std::any_of(_elements.begin(), _elements.end(),
|
|
|
|
|
[inputdata=inputdata](auto& element)
|
|
|
|
|
{
|
|
|
|
|
if (element.pressed)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
auto key_iterator = std::find(element.keys.begin(), element.keys.end(), inputdata.event.key.code);
|
|
|
|
|
bool found_key = key_iterator != element.keys.end();
|
|
|
|
|
if (found_key)
|
|
|
|
|
{
|
|
|
|
|
element.pressed = true;
|
|
|
|
|
element.pressed_as = inputdata.event.key.code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return found_key;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
bool all_pressed = std::all_of(_elements.begin(), _elements.end(),
|
|
|
|
|
[](const auto& element)
|
|
|
|
|
{
|
|
|
|
|
return element.pressed;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (all_pressed)
|
|
|
|
|
grade = _evaluator.calculatePrecision(inputdata.timestamp);
|
|
|
|
|
|
|
|
|
|
_state = State::DYING;
|
|
|
|
|
_animations[_state]->launch(_sprite, inputdata.timestamp, offset());
|
|
|
|
|
if (all_pressed || !input_valid)
|
|
|
|
|
{
|
|
|
|
|
_state = State::DYING;
|
|
|
|
|
for (auto& element : _elements)
|
|
|
|
|
element.animations[_state]->launch(element.sprite, inputdata.timestamp, offset());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<ClassicSprite> ClassicNote::sprite() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return _sprite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicNote::setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept
|
|
|
|
|
{
|
|
|
|
|
_sprite = sprite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Coordinates& ClassicNote::getCoordinates() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return _coordinates;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Type ClassicNote::type() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return _type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ClassicNote::draw() const
|
|
|
|
|
{
|
|
|
|
|
_graphics_manager->draw(this);
|
|
|
|
|
for (std::size_t i = 0; i < _elements.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i >= 1)
|
|
|
|
|
_graphics_manager->drawLine(_elements[i-1].sprite->trailCoordinates(), _elements[i].sprite->trailCoordinates());
|
|
|
|
|
_graphics_manager->draw(_elements[i].sprite);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|