forked from NaiJi/project-kyoku
Turn ArrowNote into a template with T for note element
parent
70d3284eeb
commit
41541e0757
@ -1,101 +0,0 @@
|
|||||||
#include "classicmocknote.h"
|
|
||||||
#include "graphics/classicscenegraphicsmanager.h"
|
|
||||||
#include "graphics/animations/classicanimationscenario.h"
|
|
||||||
#include "editor/selectionmanager.h"
|
|
||||||
|
|
||||||
ClassicMockNote::ClassicMockNote(ArrowNoteInitializer&& init, const std::shared_ptr<SelectionManager<ClassicMockNote>>& selection_manager) :
|
|
||||||
ClassicNote(std::move(init.initializer)),
|
|
||||||
_selection_manager(selection_manager)
|
|
||||||
{
|
|
||||||
_elements.resize(init.elements.size());
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < _elements.size(); ++i)
|
|
||||||
{
|
|
||||||
_elements[i].position = init.elements[i].element.position;
|
|
||||||
_elements[i].type = init.elements[i].element.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicMockNote::isActive(const kku::microsec &offset) const
|
|
||||||
{
|
|
||||||
(void)offset;
|
|
||||||
return _state != State::DEAD
|
|
||||||
&& _state != State::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicMockNote::input(kku::GameEvent&& input)
|
|
||||||
{
|
|
||||||
switch (input.event.type)
|
|
||||||
{
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kku::SystemEvent::Type::MousePress:
|
|
||||||
{
|
|
||||||
bool selection_changed = false;
|
|
||||||
std::size_t amount_selected = 0;
|
|
||||||
|
|
||||||
const auto position = std::get<kku::SystemEvent::Mouse>(input.event.data).position;
|
|
||||||
for (auto& element : _elements)
|
|
||||||
{
|
|
||||||
if (element.sprite->getRectangle()->contains(position))
|
|
||||||
{
|
|
||||||
element.selected = !element.selected;
|
|
||||||
selection_changed = true;
|
|
||||||
if (element.selected)
|
|
||||||
++amount_selected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selection_changed)
|
|
||||||
{
|
|
||||||
if (amount_selected > 0)
|
|
||||||
_selection_manager->fetch(this);
|
|
||||||
else
|
|
||||||
_selection_manager->remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicMockNote::update(const kku::microsec& music_offset)
|
|
||||||
{
|
|
||||||
switch (_state)
|
|
||||||
{
|
|
||||||
default: return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::FLYING:
|
|
||||||
if (music_offset >= getPerfectOffset())
|
|
||||||
{
|
|
||||||
_state = State::DYING;
|
|
||||||
for (auto& element : _elements)
|
|
||||||
element.animations[_state]->launch(element.sprite, music_offset, getPerfectOffset());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::DYING:
|
|
||||||
if (_elements[0].animations[_state]->isDone())
|
|
||||||
_state = State::DEAD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& element : _elements)
|
|
||||||
if (element.animations[_state])
|
|
||||||
element.animations[_state]->update(music_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<MockElement>& ClassicMockNote::getElements()
|
|
||||||
{
|
|
||||||
return _elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicMockNote::deselect()
|
|
||||||
{
|
|
||||||
for (auto& element : _elements)
|
|
||||||
element.selected = false;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "classicmode/classicnote.h"
|
|
||||||
|
|
||||||
#include "mockelement.h"
|
|
||||||
#include "classicmode/arrownoteinitializer.h"
|
|
||||||
#include "selectionmanager.h"
|
|
||||||
|
|
||||||
class ClassicMockNote : public ClassicNote
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit ClassicMockNote(ArrowNoteInitializer&& init, const std::shared_ptr<SelectionManager<ClassicMockNote>>& selection_manager);
|
|
||||||
virtual ~ClassicMockNote() = default;
|
|
||||||
|
|
||||||
virtual bool isActive(const kku::microsec& offset) const override;
|
|
||||||
virtual void update(const kku::microsec &music_offset) override;
|
|
||||||
virtual void input(kku::GameEvent&& input) override;
|
|
||||||
|
|
||||||
std::vector<MockElement>& getElements();
|
|
||||||
void deselect();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::shared_ptr<SelectionManager<ClassicMockNote>> _selection_manager;
|
|
||||||
std::vector<MockElement> _elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
using MockElements = std::vector<MockElement>;
|
|
@ -1,124 +0,0 @@
|
|||||||
#include "classicarrownote.h"
|
|
||||||
#include "graphics/animations/classicanimationscenario.h"
|
|
||||||
#include "holdmanager.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
ClassicArrowNote::ClassicArrowNote(ArrowNoteInitializer&& init, const std::shared_ptr<HoldManager>& hold_manager) :
|
|
||||||
ClassicNote(std::move(init.initializer)),
|
|
||||||
_evaluator(init.initializer.intervals, _perfect_offset),
|
|
||||||
_hold_manager(hold_manager),
|
|
||||||
_is_hold(init.hold)
|
|
||||||
{
|
|
||||||
_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].element.position;
|
|
||||||
_elements[i].type = init.elements[i].element.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicArrowNote::isActive(const kku::microsec& offset) const
|
|
||||||
{
|
|
||||||
return _evaluator.isActive(offset)
|
|
||||||
&& _state != State::DYING;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicArrowNote::input(kku::GameEvent&& input)
|
|
||||||
{
|
|
||||||
auto grade = Grade::BAD;
|
|
||||||
|
|
||||||
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 = allElementsPressed();
|
|
||||||
|
|
||||||
if (all_pressed)
|
|
||||||
{
|
|
||||||
grade = _evaluator.calculatePrecision(input.timestamp);
|
|
||||||
if (isHold())
|
|
||||||
_hold_manager->emplace(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_pressed || !input_valid)
|
|
||||||
{
|
|
||||||
_state = State::DYING;
|
|
||||||
for (auto& element : _elements)
|
|
||||||
element.animations[_state]->launch(element.sprite, input.timestamp, getPerfectOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicArrowNote::update(const kku::microsec& music_offset)
|
|
||||||
{
|
|
||||||
switch (_state)
|
|
||||||
{
|
|
||||||
default: return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::FLYING:
|
|
||||||
if (!_evaluator.isActive(music_offset) && music_offset > getPerfectOffset())
|
|
||||||
{
|
|
||||||
_state = State::DYING;
|
|
||||||
for (auto& element : _elements)
|
|
||||||
element.animations[_state]->launch(element.sprite, music_offset, getPerfectOffset());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case State::DYING:
|
|
||||||
if (_elements[0].animations[_state]->isDone())
|
|
||||||
_state = State::DEAD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& element : _elements)
|
|
||||||
if (element.animations[_state])
|
|
||||||
element.animations[_state]->update(music_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicArrowNote::allElementsPressed() const
|
|
||||||
{
|
|
||||||
return std::all_of(_elements.begin(), _elements.end(),
|
|
||||||
[](const auto& element)
|
|
||||||
{
|
|
||||||
return element.pressed;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicArrowNote::isPressedAs(kku::SystemEvent::Key::Code key) const
|
|
||||||
{
|
|
||||||
return std::any_of(_elements.begin(), _elements.end(),
|
|
||||||
[key](const auto& element)
|
|
||||||
{
|
|
||||||
return key == element.pressed_as;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicArrowNote::isHold() const
|
|
||||||
{
|
|
||||||
return _is_hold;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ArrowElement>& ClassicArrowNote::getElements()
|
|
||||||
{
|
|
||||||
return _elements;
|
|
||||||
}
|
|
@ -1,22 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "classicarrownote.h"
|
||||||
|
#include "game/arrowelement.h"
|
||||||
#include "core/gameevent.h"
|
#include "core/gameevent.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class ClassicArrowNote;
|
|
||||||
class ClassicGraphicsManager;
|
class ClassicGraphicsManager;
|
||||||
|
|
||||||
class HoldManager
|
class HoldManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void emplace(ClassicArrowNote* note);
|
void emplace(ClassicArrowNote<ArrowElement>* note);
|
||||||
void checkRelease(kku::SystemEvent::Key::Code released_key);
|
void checkRelease(kku::SystemEvent::Key::Code released_key);
|
||||||
|
|
||||||
void drawHoldBar();
|
void drawHoldBar();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ClassicArrowNote*> _notes_on_hold;
|
std::vector<ClassicArrowNote<ArrowElement>*> _notes_on_hold;
|
||||||
std::shared_ptr<ClassicGraphicsManager> _graphics_manager;
|
std::shared_ptr<ClassicGraphicsManager> _graphics_manager;
|
||||||
};
|
};
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "classicmode/elementinitializer.h"
|
|
||||||
|
|
||||||
struct ArrowElementInitializer
|
|
||||||
{
|
|
||||||
ElementInitializer element;
|
|
||||||
std::array<kku::SystemEvent::Key::Code, 2> keys;
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "classicmode/noteinitializer.h"
|
|
||||||
#include "arrowelementinitializer.h"
|
|
||||||
|
|
||||||
struct ArrowNoteInitializer
|
|
||||||
{
|
|
||||||
NoteInitializer initializer;
|
|
||||||
bool hold = false;
|
|
||||||
|
|
||||||
std::vector<ArrowElementInitializer> elements;
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "classicactions.h"
|
|
||||||
#include "core/gameevent.h"
|
|
||||||
#include "core/point.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct ElementInitializer
|
|
||||||
{
|
|
||||||
Type type = Type::NONE;
|
|
||||||
|
|
||||||
kku::Point position;
|
|
||||||
std::vector<kku::Point> falling_curve_interpolation;
|
|
||||||
};
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "core/time.h"
|
|
||||||
|
|
||||||
struct NoteInitializer
|
|
||||||
{
|
|
||||||
std::vector<kku::microsec> intervals;
|
|
||||||
kku::microsec perfect_offset = 0;
|
|
||||||
};
|
|
Loading…
Reference in New Issue