forked from NaiJi/project-kyoku
Rework Timeline to work fine with scrolling and note insertion
This commit is contained in:
parent
ebf736a0bb
commit
581e1fe6a4
|
@ -13,6 +13,7 @@ public:
|
||||||
virtual void input(PlayerInput&& inputdata) = 0;
|
virtual void input(PlayerInput&& inputdata) = 0;
|
||||||
virtual void update(UpdateData&& updatedata) = 0;
|
virtual void update(UpdateData&& updatedata) = 0;
|
||||||
virtual void draw() const = 0;
|
virtual void draw() const = 0;
|
||||||
|
virtual void recalculate(const microsec& timestamp) = 0;
|
||||||
|
|
||||||
inline void setBPMSections(const std::set<BPMSection, BPMSectionCompt>& sections) noexcept
|
inline void setBPMSections(const std::set<BPMSection, BPMSectionCompt>& sections) noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ public:
|
||||||
_perfect_offset(perfect_offset) {}
|
_perfect_offset(perfect_offset) {}
|
||||||
virtual ~Note() = default;
|
virtual ~Note() = default;
|
||||||
|
|
||||||
virtual bool isActive() const = 0;
|
virtual bool isActive(const microsec& offset) const = 0;
|
||||||
virtual void update(const microsec& music_offset) = 0;
|
virtual void update(const microsec& music_offset) = 0;
|
||||||
virtual void draw() const = 0;
|
virtual void draw() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "tools/mathutils.h"
|
#include "tools/mathutils.h"
|
||||||
#include "core/note.h"
|
#include "core/note.h"
|
||||||
|
@ -18,15 +19,46 @@ public:
|
||||||
|
|
||||||
typedef typename std::set<TNote*>::const_iterator Iterator;
|
typedef typename std::set<TNote*>::const_iterator Iterator;
|
||||||
|
|
||||||
|
void recalculate(const microsec& offset)
|
||||||
|
{
|
||||||
|
_current_offset = offset;
|
||||||
|
expire(_first_visible_note);
|
||||||
|
expire(_last_visible_note);
|
||||||
|
expire(_top_note);
|
||||||
|
|
||||||
|
if (!_timeline.empty())
|
||||||
|
{
|
||||||
|
Iterator head_iterator = _timeline.begin();
|
||||||
|
|
||||||
|
while (!isExpired(head_iterator))
|
||||||
|
{
|
||||||
|
if ((*head_iterator)->offset() >= offset)
|
||||||
|
{
|
||||||
|
Iterator pre_head = head_iterator;
|
||||||
|
--pre_head;
|
||||||
|
|
||||||
|
_top_note = !isExpired(pre_head) && (*pre_head)->isActive(offset)
|
||||||
|
? pre_head
|
||||||
|
: head_iterator;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++head_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isExpired(_top_note))
|
||||||
|
_top_note = _timeline.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchVisibleNotes();
|
||||||
|
}
|
||||||
|
|
||||||
void setNotes(const std::set<TNote*, NotePtrCompt>& notes, const microsec& visibility)
|
void setNotes(const std::set<TNote*, NotePtrCompt>& notes, const microsec& visibility)
|
||||||
{
|
{
|
||||||
_visibility_offset = visibility;
|
_visibility_offset = visibility;
|
||||||
_timeline = std::move(notes);
|
_timeline = std::move(notes);
|
||||||
|
|
||||||
_top_note = _timeline.begin();
|
recalculate(_current_offset);
|
||||||
expire(_first_visible_note);
|
|
||||||
expire(_last_visible_note);
|
|
||||||
expire(_active_note);
|
|
||||||
|
|
||||||
if (isExpired(_top_note))
|
if (isExpired(_top_note))
|
||||||
return;
|
return;
|
||||||
|
@ -37,13 +69,16 @@ public:
|
||||||
void insertNote(TNote* note)
|
void insertNote(TNote* note)
|
||||||
{
|
{
|
||||||
_top_note = _timeline.insert(note).first;
|
_top_note = _timeline.insert(note).first;
|
||||||
|
recalculate(_current_offset);
|
||||||
update(_current_offset);
|
update(_current_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertNotes(const std::set<TNote*, NotePtrCompt>& notes)
|
void insertNotes(const std::set<TNote*, NotePtrCompt>& notes)
|
||||||
{
|
{
|
||||||
_timeline.insert(notes.begin(), notes.end());
|
_timeline.insert(notes.begin(), notes.end());
|
||||||
|
recalculate(_current_offset);
|
||||||
update(_current_offset);
|
update(_current_offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear()
|
inline void clear()
|
||||||
|
@ -57,13 +92,7 @@ public:
|
||||||
void update(const microsec& offset)
|
void update(const microsec& offset)
|
||||||
{
|
{
|
||||||
_current_offset = offset;
|
_current_offset = offset;
|
||||||
|
updateTopNote(_current_offset);
|
||||||
if (isExpired(_top_note))
|
|
||||||
return;
|
|
||||||
|
|
||||||
checkTopNote(_current_offset);
|
|
||||||
checkCurrentActiveNote();
|
|
||||||
checkForNextActiveNote();
|
|
||||||
updateVisibleSprites(_current_offset);
|
updateVisibleSprites(_current_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,9 +112,6 @@ public:
|
||||||
|
|
||||||
void findLastVisibleNote(const microsec& music_offset)
|
void findLastVisibleNote(const microsec& music_offset)
|
||||||
{
|
{
|
||||||
if (isExpired(_top_note))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Iterator note_iterator = _top_note;
|
Iterator note_iterator = _top_note;
|
||||||
while (!isExpired(note_iterator) && isVisiblyClose(note_iterator, music_offset))
|
while (!isExpired(note_iterator) && isVisiblyClose(note_iterator, music_offset))
|
||||||
{
|
{
|
||||||
|
@ -113,15 +139,34 @@ public:
|
||||||
{
|
{
|
||||||
auto note = *note_iterator;
|
auto note = *note_iterator;
|
||||||
if (note->shouldRemove())
|
if (note->shouldRemove())
|
||||||
|
{
|
||||||
++_first_visible_note;
|
++_first_visible_note;
|
||||||
|
}
|
||||||
|
|
||||||
++note_iterator;
|
++note_iterator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Iterator getActiveNote() noexcept
|
Iterator getActiveNote(const microsec& music_offset) noexcept
|
||||||
{
|
{
|
||||||
return _active_note;
|
Iterator return_note = _timeline.end();
|
||||||
|
|
||||||
|
auto note_iterator = _top_note;
|
||||||
|
while (!isExpired(note_iterator))
|
||||||
|
{
|
||||||
|
const auto& note = *note_iterator;
|
||||||
|
if (note->isActive(music_offset))
|
||||||
|
{
|
||||||
|
return_note = note_iterator;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (note->offset() > music_offset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
++note_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return return_note;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Iterator getNoteBy(const microsec& music_offset) noexcept
|
inline Iterator getNoteBy(const microsec& music_offset) noexcept
|
||||||
|
@ -133,12 +178,12 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isExpired(const Iterator& iterator) const
|
inline bool isExpired(const Iterator& iterator) const noexcept
|
||||||
{
|
{
|
||||||
return iterator == _timeline.end();
|
return iterator == _timeline.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void expire(Iterator& iterator)
|
inline void expire(Iterator& iterator) noexcept
|
||||||
{
|
{
|
||||||
iterator = _timeline.end();
|
iterator = _timeline.end();
|
||||||
}
|
}
|
||||||
|
@ -148,6 +193,16 @@ private:
|
||||||
microsec _visibility_offset;
|
microsec _visibility_offset;
|
||||||
microsec _current_offset;
|
microsec _current_offset;
|
||||||
|
|
||||||
|
inline void updateTopNote(const microsec& music_offset) noexcept
|
||||||
|
{
|
||||||
|
if ((*_top_note)->offset() < music_offset //
|
||||||
|
&& _top_note == _first_visible_note // Maybe simplify
|
||||||
|
&& !(*_top_note)->isActive(music_offset)) //
|
||||||
|
{
|
||||||
|
++_top_note;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updateVisibleSprites(const microsec& music_offset)
|
void updateVisibleSprites(const microsec& music_offset)
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
|
@ -160,40 +215,7 @@ private:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkCurrentActiveNote()
|
inline bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept
|
||||||
{
|
|
||||||
if (isExpired(_active_note))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto note = *_active_note;
|
|
||||||
|
|
||||||
if (!note->isActive())
|
|
||||||
{
|
|
||||||
expire(_active_note);
|
|
||||||
++_top_note;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkTopNote(const microsec& offset)
|
|
||||||
{
|
|
||||||
if (isExpired(_top_note) || !isExpired(_active_note))
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((*_top_note)->offset() < offset)
|
|
||||||
++_top_note;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkForNextActiveNote()
|
|
||||||
{
|
|
||||||
if (!isExpired(_active_note))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto top_note = *_top_note;
|
|
||||||
if (top_note->isActive())
|
|
||||||
_active_note = _top_note;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const
|
|
||||||
{
|
{
|
||||||
return ((*iterator)->offset() - _visibility_offset) <= music_offset;
|
return ((*iterator)->offset() - _visibility_offset) <= music_offset;
|
||||||
}
|
}
|
||||||
|
@ -203,22 +225,7 @@ private:
|
||||||
return isExpired(_first_visible_note);
|
return isExpired(_first_visible_note);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Difference between top and active note is that
|
|
||||||
* top note is the note handling input right now
|
|
||||||
* OR it's the closest note from current music offset
|
|
||||||
* position, not necessarily active. A note stops being top only
|
|
||||||
* after dying or being tapped by player, even if it's already
|
|
||||||
* past her perfect offset.
|
|
||||||
*
|
|
||||||
* Meanwhile active note is the note which is currently handling
|
|
||||||
* player input for grade.
|
|
||||||
*
|
|
||||||
* An active note is always top note but a top note
|
|
||||||
* is not always active note.
|
|
||||||
* */
|
|
||||||
|
|
||||||
Iterator _top_note;
|
Iterator _top_note;
|
||||||
Iterator _active_note;
|
|
||||||
Iterator _last_visible_note;
|
Iterator _last_visible_note;
|
||||||
Iterator _first_visible_note;
|
Iterator _first_visible_note;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,23 +12,20 @@ ClassicEditor::ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager)
|
||||||
|
|
||||||
std::set<MockClassicNote*, NotePtrCompt> _set = {};
|
std::set<MockClassicNote*, NotePtrCompt> _set = {};
|
||||||
|
|
||||||
for (int i = 1; i < 5; ++i)
|
|
||||||
{
|
|
||||||
NoteInitializer init;
|
NoteInitializer init;
|
||||||
init.context = &_context;
|
init.context = &_context;
|
||||||
init.intervals = {};
|
init.intervals = {};
|
||||||
init.perfect_offset = basic_offset + (500000 * i);
|
init.perfect_offset = basic_offset + (500000 * 20);
|
||||||
|
|
||||||
ElementInitializer elem_init;
|
ElementInitializer elem_init;
|
||||||
elem_init.type = _selected_type;
|
elem_init.type = _selected_type;
|
||||||
elem_init.coordinates = Coordinates{ 700 - (i * 120), 550 };
|
elem_init.coordinates = Coordinates{ 700 - (5 * 120), 550 };
|
||||||
elem_init.falling_curve_interpolation = {};
|
elem_init.falling_curve_interpolation = {};
|
||||||
|
|
||||||
MockArrowNoteInitializer mock_init;
|
MockArrowNoteInitializer mock_init;
|
||||||
mock_init.elements = {elem_init};
|
mock_init.elements = {elem_init};
|
||||||
mock_init.initializer = init;
|
mock_init.initializer = init;
|
||||||
_set.insert(new MockClassicNote(std::move(mock_init)));
|
_set.insert(new MockClassicNote(std::move(mock_init)));
|
||||||
}
|
|
||||||
|
|
||||||
_timeline.setNotes(_set, 1648648);
|
_timeline.setNotes(_set, 1648648);
|
||||||
}
|
}
|
||||||
|
@ -89,6 +86,11 @@ void ClassicEditor::draw() const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassicEditor::recalculate(const microsec& timestamp)
|
||||||
|
{
|
||||||
|
_timeline.recalculate(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
void ClassicEditor::selectNoteType(Type type) noexcept
|
void ClassicEditor::selectNoteType(Type type) noexcept
|
||||||
{
|
{
|
||||||
_selected_type = type;
|
_selected_type = type;
|
||||||
|
|
|
@ -17,6 +17,7 @@ public:
|
||||||
virtual void input(PlayerInput&& inputdata) override;
|
virtual void input(PlayerInput&& inputdata) override;
|
||||||
virtual void update(UpdateData&& updatedata) override;
|
virtual void update(UpdateData&& updatedata) override;
|
||||||
virtual void draw() const override;
|
virtual void draw() const override;
|
||||||
|
virtual void recalculate(const microsec& timestamp) override;
|
||||||
|
|
||||||
void selectNoteType(Type type) noexcept;
|
void selectNoteType(Type type) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,9 @@ MockClassicNote::MockClassicNote(MockArrowNoteInitializer&& init) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MockClassicNote::isActive() const
|
bool MockClassicNote::isActive(const microsec& offset) const
|
||||||
{
|
{
|
||||||
return _state != State::DEAD
|
return offset == Note::offset();
|
||||||
&& _state != State::NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MockClassicNote::isInGame() const
|
bool MockClassicNote::isInGame() const
|
||||||
|
@ -44,21 +43,20 @@ bool MockClassicNote::isInGame() const
|
||||||
|
|
||||||
bool MockClassicNote::shouldRemove() const
|
bool MockClassicNote::shouldRemove() const
|
||||||
{
|
{
|
||||||
return _state == State::DEAD;
|
return _state == State::DEAD
|
||||||
|
|| _state == State::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MockClassicNote::putToGame(const microsec &music_offset)
|
void MockClassicNote::putToGame(const microsec &music_offset)
|
||||||
{
|
{
|
||||||
_state = State::FLYING;
|
_state = State::FLYING; (void)music_offset;
|
||||||
|
|
||||||
std::cout << "Put to game " << this << ": " << music_offset << '\n';
|
|
||||||
|
|
||||||
for (auto& element : _elements)
|
for (auto& element : _elements)
|
||||||
{
|
{
|
||||||
element.sprite = _context->graphics_manager->getSprite(element.type);
|
element.sprite = _context->graphics_manager->getSprite(element.type);
|
||||||
element.sprite->setCoordinates(element.coordinates);
|
element.sprite->setCoordinates(element.coordinates);
|
||||||
element.sprite->setTrailCoordinates(Coordinates(0.f, 9.f));
|
element.sprite->setTrailCoordinates(Coordinates(0.f, 9.f));
|
||||||
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
element.animations[_state]->launch(element.sprite, offset() - 1648648, offset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
explicit MockClassicNote(MockArrowNoteInitializer&& init);
|
explicit MockClassicNote(MockArrowNoteInitializer&& init);
|
||||||
virtual ~MockClassicNote() override = default;
|
virtual ~MockClassicNote() override = default;
|
||||||
|
|
||||||
virtual bool isActive() const override final;
|
virtual bool isActive(const microsec& offset) const override final;
|
||||||
virtual bool isInGame() const override final;
|
virtual bool isInGame() const override final;
|
||||||
virtual bool shouldRemove() const override final;
|
virtual bool shouldRemove() const override final;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ ClassicArrowNote::ClassicArrowNote(ArrowNoteInitializer&& init) :
|
||||||
// Animations will be injected into note.
|
// Animations will be injected into note.
|
||||||
_elements[i].animations[State::NONE] = nullptr;
|
_elements[i].animations[State::NONE] = nullptr;
|
||||||
_elements[i].animations[State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
|
_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::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
|
||||||
_elements[i].animations[State::DEAD] = nullptr;
|
_elements[i].animations[State::DEAD] = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -100,9 +99,11 @@ void ClassicArrowNote::update(const microsec& music_offset)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case State::FLYING:
|
case State::FLYING:
|
||||||
if (_evaluator.isActive(music_offset)) {
|
if (!_evaluator.isActive(music_offset) && music_offset > offset())
|
||||||
_state = State::ACTIVE;
|
{
|
||||||
|
_state = State::DYING;
|
||||||
|
for (auto& element : _elements)
|
||||||
|
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -110,15 +111,6 @@ void ClassicArrowNote::update(const microsec& music_offset)
|
||||||
if (_elements[0].animations[_state]->isDone())
|
if (_elements[0].animations[_state]->isDone())
|
||||||
_state = State::DEAD;
|
_state = State::DEAD;
|
||||||
break;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& element : _elements)
|
for (auto& element : _elements)
|
||||||
|
@ -138,7 +130,7 @@ bool ClassicArrowNote::allElementsPressed() const
|
||||||
bool ClassicArrowNote::isPressedAs(sf::Keyboard::Key key) const
|
bool ClassicArrowNote::isPressedAs(sf::Keyboard::Key key) const
|
||||||
{
|
{
|
||||||
return std::any_of(_elements.begin(), _elements.end(),
|
return std::any_of(_elements.begin(), _elements.end(),
|
||||||
[key=key](const auto& element)
|
[key](const auto& element)
|
||||||
{
|
{
|
||||||
return key == element.pressed_as;
|
return key == element.pressed_as;
|
||||||
});
|
});
|
||||||
|
|
|
@ -73,7 +73,7 @@ void ClassicGame::input(PlayerInput&& inputdata)
|
||||||
|
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
{
|
{
|
||||||
auto note_it = _timeline.getActiveNote();
|
auto note_it = _timeline.getActiveNote(inputdata.timestamp);
|
||||||
|
|
||||||
if (!_timeline.isExpired(note_it))
|
if (!_timeline.isExpired(note_it))
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,15 +14,15 @@ ClassicNote::ClassicNote(NoteInitializer &&init) :
|
||||||
_context(init.context)
|
_context(init.context)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool ClassicNote::isActive() const
|
bool ClassicNote::isActive(const microsec& offset) const
|
||||||
{
|
{
|
||||||
return _state == State::ACTIVE;
|
return _evaluator.isActive(offset)
|
||||||
|
&& _state != State::DYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicNote::isInGame() const
|
bool ClassicNote::isInGame() const
|
||||||
{
|
{
|
||||||
return _state == State::FLYING
|
return _state == State::FLYING
|
||||||
|| _state == State::ACTIVE
|
|
||||||
|| _state == State::DYING;
|
|| _state == State::DYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ public:
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
FLYING,
|
FLYING,
|
||||||
ACTIVE,
|
|
||||||
DYING,
|
DYING,
|
||||||
DEAD
|
DEAD
|
||||||
};
|
};
|
||||||
|
@ -32,7 +31,7 @@ public:
|
||||||
explicit ClassicNote(NoteInitializer&& init);
|
explicit ClassicNote(NoteInitializer&& init);
|
||||||
virtual ~ClassicNote() override = default;
|
virtual ~ClassicNote() override = default;
|
||||||
|
|
||||||
virtual bool isActive() const override final;
|
virtual bool isActive(const microsec& offset) const override final;
|
||||||
virtual bool isInGame() const override final;
|
virtual bool isInGame() const override final;
|
||||||
virtual bool shouldRemove() const override final;
|
virtual bool shouldRemove() const override final;
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,6 @@ EditorState::~EditorState()
|
||||||
|
|
||||||
void EditorState::input(const sf::Event& event)
|
void EditorState::input(const sf::Event& event)
|
||||||
{
|
{
|
||||||
if (event.key.code == sf::Keyboard::Space && event.type == sf::Event::KeyReleased)
|
|
||||||
_music.isPaused() ? _music.play() : _music.pause();
|
|
||||||
|
|
||||||
_group->input(event);
|
_group->input(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,8 +153,13 @@ void EditorState::enter()
|
||||||
|
|
||||||
callbacks.onInput = [&editor, &music](const sf::Event& event)
|
callbacks.onInput = [&editor, &music](const sf::Event& event)
|
||||||
{
|
{
|
||||||
if (event.type == sf::Event::MouseWheelScrolled)
|
if (event.key.code == sf::Keyboard::Space && event.type == sf::Event::KeyReleased)
|
||||||
|
music.isPaused() ? music.play() : music.pause();
|
||||||
|
else if (event.type == sf::Event::MouseWheelScrolled)
|
||||||
|
{
|
||||||
music.moveOffset(event.mouseWheelScroll.delta > 0 ? 500000 : -500000);
|
music.moveOffset(event.mouseWheelScroll.delta > 0 ? 500000 : -500000);
|
||||||
|
editor->recalculate(music.fetchOffset());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
editor->input(PlayerInput{music.fetchOffset(), event});
|
editor->input(PlayerInput{music.fetchOffset(), event});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue