forked from NaiJi/project-kyoku
Add new abstraction Context
Implement GameContext and move all logic from ClassicArrowNote to thereselection
parent
f1d24460a6
commit
14c201e28d
@ -0,0 +1,43 @@
|
||||
#include "game/classicarrownote.h"
|
||||
#include "classicmode/context.h"
|
||||
|
||||
ClassicArrowNote::ClassicArrowNote(Init&& init) :
|
||||
ClassicNote(init.perfect_offset),
|
||||
_evaluator(init.intervals, init.perfect_offset),
|
||||
_context(init.context)
|
||||
{
|
||||
_elements.resize(init.elements.size());
|
||||
|
||||
for (std::size_t i = 0; i < _elements.size(); ++i)
|
||||
{
|
||||
_elements[i].keys = init.elements[i].keys;
|
||||
_elements[i].position = init.elements[i].position;
|
||||
_elements[i].type = init.elements[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassicArrowNote::isActive(const kku::microsec& offset) const
|
||||
{
|
||||
return _evaluator.isActive(offset)
|
||||
&& _state != State::DYING;
|
||||
}
|
||||
|
||||
void ClassicArrowNote::update(const kku::microsec &music_offset)
|
||||
{
|
||||
_context->update(this, music_offset);
|
||||
}
|
||||
|
||||
void ClassicArrowNote::input(kku::GameEvent&& input)
|
||||
{
|
||||
_context->input(this, std::move(input));
|
||||
}
|
||||
|
||||
std::vector<ArrowElement>& ClassicArrowNote::getElements()
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
auto ClassicArrowNote::calculatePrecision(const kku::microsec& offset) const -> Grade
|
||||
{
|
||||
return _evaluator.calculatePrecision(offset);
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
#include "gamecontext.h"
|
||||
#include "game/classicarrownote.h"
|
||||
#include "game/holdmanager.h"
|
||||
#include "graphics/animations/classicanimationscenario.h"
|
||||
|
||||
GameContext::GameContext(HoldManager *hold_manager, ClassicGraphicsManager *graphics_manager) :
|
||||
_hold_manager(hold_manager),
|
||||
_graphics_manager(graphics_manager)
|
||||
{}
|
||||
|
||||
void GameContext::input(ClassicArrowNote *note, kku::GameEvent&& input) const
|
||||
{
|
||||
auto grade = ClassicArrowNote::Grade::BAD;
|
||||
auto& elements = note->getElements();
|
||||
|
||||
bool input_valid = std::any_of(elements.begin(), elements.end(),
|
||||
[input=input](auto& element)
|
||||
{
|
||||
if (element.pressed)
|
||||
return false;
|
||||
|
||||
const auto code = std::get<kku::SystemEvent::Key>(input.event.data).view;
|
||||
auto key_iterator = std::find(element.keys.begin(), element.keys.end(), code);
|
||||
|
||||
bool found_key = key_iterator != element.keys.end();
|
||||
if (found_key)
|
||||
{
|
||||
element.pressed = true;
|
||||
element.pressed_as = code;
|
||||
}
|
||||
|
||||
return found_key;
|
||||
});
|
||||
|
||||
bool all_pressed = std::all_of(elements.begin(), elements.end(),
|
||||
[](const auto& element)
|
||||
{
|
||||
return element.pressed;
|
||||
});
|
||||
|
||||
if (all_pressed)
|
||||
{
|
||||
grade = note->calculatePrecision(input.timestamp);
|
||||
if (note->isHold())
|
||||
_hold_manager->emplace(note);
|
||||
}
|
||||
|
||||
if (all_pressed || !input_valid)
|
||||
{
|
||||
note->setState(ClassicArrowNote::State::DYING);
|
||||
for (auto& element : elements)
|
||||
element.animations[note->getState()]->launch(element.sprite, input.timestamp, note->getPerfectOffset());
|
||||
}
|
||||
|
||||
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
||||
}
|
||||
|
||||
void GameContext::update(ClassicArrowNote *note, const kku::microsec& music_offset) const
|
||||
{
|
||||
auto& elements = note->getElements();
|
||||
|
||||
switch (note->getState())
|
||||
{
|
||||
default: return;
|
||||
break;
|
||||
|
||||
case ClassicArrowNote::State::FLYING:
|
||||
if (!note->isActive(music_offset) && music_offset > note->getPerfectOffset())
|
||||
{
|
||||
note->setState(ClassicArrowNote::State::DYING);
|
||||
for (auto& element : elements)
|
||||
element.animations[note->getState()]->launch(element.sprite, music_offset, note->getPerfectOffset());
|
||||
}
|
||||
break;
|
||||
|
||||
case ClassicArrowNote::State::DYING:
|
||||
if (elements[0].animations[note->getState()]->isDone())
|
||||
note->setState(ClassicArrowNote::State::DEAD);
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto& element : elements)
|
||||
if (element.animations[note->getState()])
|
||||
element.animations[note->getState()]->update(music_offset);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "classicmode/context.h"
|
||||
|
||||
class HoldManager;
|
||||
class ClassicGraphicsManager;
|
||||
|
||||
class GameContext : public Context
|
||||
{
|
||||
public:
|
||||
explicit GameContext(HoldManager *hold_manager, ClassicGraphicsManager *graphics_manager);
|
||||
|
||||
virtual void input(ClassicArrowNote *note, kku::GameEvent&& input) const override;
|
||||
virtual void update(ClassicArrowNote *note, const kku::microsec &music_offset) const override;
|
||||
|
||||
private:
|
||||
HoldManager * const _hold_manager;
|
||||
ClassicGraphicsManager * const _graphics_manager;
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/time.h"
|
||||
#include "core/gameevent.h"
|
||||
|
||||
class ClassicArrowNote;
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
virtual ~Context() = default;
|
||||
|
||||
virtual void input(ClassicArrowNote *note, kku::GameEvent&& input) const = 0;
|
||||
virtual void update(ClassicArrowNote *note, const kku::microsec &music_offset) const = 0;
|
||||
};
|
Loading…
Reference in New Issue