forked from NaiJi/project-kyoku
Finish test basic implementation for ClassEditor
This commit is contained in:
parent
0b1acd7697
commit
43e09a6db1
|
@ -118,6 +118,15 @@ public:
|
||||||
return _active_note;
|
return _active_note;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Iterator getNoteBy(const microsec& music_offset) noexcept
|
||||||
|
{
|
||||||
|
return std::find_if(_timeline.begin(), _timeline.end(),
|
||||||
|
[music_offset](const auto& note)
|
||||||
|
{
|
||||||
|
return note->offset() == music_offset;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
inline bool isExpired(const Iterator& iterator) const
|
inline bool isExpired(const Iterator& iterator) const
|
||||||
{
|
{
|
||||||
return iterator == _timeline.end();
|
return iterator == _timeline.end();
|
||||||
|
|
|
@ -1,21 +1,65 @@
|
||||||
#include "classiceditor.h"
|
#include "classiceditor.h"
|
||||||
|
|
||||||
ClassicEditor::ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager)
|
ClassicEditor::ClassicEditor(std::shared_ptr<ClassicGraphicsManager>&& manager) :
|
||||||
|
_graphics_manager(manager),
|
||||||
|
_selected_type(Type::UP)
|
||||||
{
|
{
|
||||||
|
_context.graphics_manager = _graphics_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::input(PlayerInput&& inputdata)
|
void ClassicEditor::input(PlayerInput&& inputdata)
|
||||||
{
|
{
|
||||||
|
const auto& event = inputdata.event;
|
||||||
|
const auto offset = _music.fetchOffset();
|
||||||
|
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Event::MouseButtonPressed:
|
||||||
|
{
|
||||||
|
const auto note = _timeline.getNoteBy(offset);
|
||||||
|
if (_timeline.isExpired(note))
|
||||||
|
{
|
||||||
|
NoteInitializer init;
|
||||||
|
init.context = &_context;
|
||||||
|
init.intervals = {};
|
||||||
|
init.perfect_offset = offset;
|
||||||
|
|
||||||
|
ElementInitializer elem_init;
|
||||||
|
elem_init.type = _selected_type;
|
||||||
|
elem_init.coordinates = Coordinates{ event.mouseButton.x, event.mouseButton.y };
|
||||||
|
elem_init.falling_curve_interpolation = {};
|
||||||
|
|
||||||
|
MockArrowNoteInitializer mock_init;
|
||||||
|
mock_init.elements = {elem_init};
|
||||||
|
mock_init.initializer = init;
|
||||||
|
|
||||||
|
_timeline.insertNote(new MockClassicNote(std::move(mock_init)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::update(const sf::Time& dt)
|
void ClassicEditor::update(const sf::Time& dt)
|
||||||
{
|
{
|
||||||
|
(void)dt;
|
||||||
|
// TODO!!!
|
||||||
|
|
||||||
|
_timeline.update(_music.fetchOffset());
|
||||||
|
_timeline.fetchVisibleNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicEditor::draw() const
|
void ClassicEditor::draw() const
|
||||||
{
|
{
|
||||||
|
_timeline.drawVisibleNotes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicEditor::selectNoteType(Type type) noexcept
|
||||||
|
{
|
||||||
|
_selected_type = type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "core/editor.h"
|
#include "core/editor.h"
|
||||||
#include "tools/music.h"
|
|
||||||
#include "core/timeline.h"
|
#include "core/timeline.h"
|
||||||
|
#include "tools/music.h"
|
||||||
|
|
||||||
|
#include "mockclassicnote.h"
|
||||||
|
|
||||||
class ClassicGraphicsManager;
|
class ClassicGraphicsManager;
|
||||||
|
|
||||||
|
@ -16,9 +19,14 @@ public:
|
||||||
virtual void update(const sf::Time& dt) override;
|
virtual void update(const sf::Time& dt) override;
|
||||||
virtual void draw() const override;
|
virtual void draw() const override;
|
||||||
|
|
||||||
|
void selectNoteType(Type type) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Music _music;
|
Music _music;
|
||||||
|
Context _context;
|
||||||
|
|
||||||
std::shared_ptr<ClassicGraphicsManager> _graphics_manager;
|
std::shared_ptr<ClassicGraphicsManager> _graphics_manager;
|
||||||
Timeline<ClassicNote> _timeline;
|
Timeline<MockClassicNote> _timeline;
|
||||||
|
|
||||||
|
Type _selected_type;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,93 @@
|
||||||
#include "mockclassicnote.h"
|
#include "mockclassicnote.h"
|
||||||
|
#include "graphics/classicgraphicsmanager.h"
|
||||||
|
|
||||||
|
// Replace with interface by dependency injection
|
||||||
|
#include "graphics/classicflyinganimationscenario.h"
|
||||||
|
#include "graphics/classicdyinganimationscenario.h"
|
||||||
|
//
|
||||||
|
|
||||||
|
// A LOT OF CODE DUPLICATES game/arrowclassicnote, DO SOMETHING D:<
|
||||||
|
|
||||||
MockClassicNote::MockClassicNote(MockArrowNoteInitializer&& init) :
|
MockClassicNote::MockClassicNote(MockArrowNoteInitializer&& init) :
|
||||||
Note(init.initializer)
|
Note(init.initializer.perfect_offset),
|
||||||
|
_state(State::NONE),
|
||||||
|
_context(init.initializer.context)
|
||||||
{
|
{
|
||||||
|
_elements.resize(init.elements.size());
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < _elements.size(); ++i)
|
||||||
|
{
|
||||||
|
_elements[i].coordinates = init.elements[i].coordinates;
|
||||||
|
_elements[i].type = init.elements[i].type;
|
||||||
|
|
||||||
|
// Animations will be injected into note.
|
||||||
|
_elements[i].animations[State::NONE] = nullptr;
|
||||||
|
_elements[i].animations[State::FLYING] = std::make_shared<ClassicFlyingAnimationScenario>();
|
||||||
|
_elements[i].animations[State::DYING] = std::make_shared<ClassicDyingAnimationScenario>();
|
||||||
|
_elements[i].animations[State::DEAD] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MockClassicNote::isActive() const
|
||||||
|
{
|
||||||
|
return _state != State::DEAD
|
||||||
|
&& _state != State::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MockClassicNote::isInGame() const
|
||||||
|
{
|
||||||
|
return _state == State::FLYING
|
||||||
|
|| _state == State::DYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MockClassicNote::shouldRemove() const
|
||||||
|
{
|
||||||
|
return _state == State::DEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MockClassicNote::putToGame(const microsec &music_offset)
|
||||||
|
{
|
||||||
|
_state = State::FLYING;
|
||||||
|
|
||||||
|
for (auto& element : _elements)
|
||||||
|
{
|
||||||
|
element.sprite = _context->graphics_manager->getSprite(element.type);
|
||||||
|
element.sprite->setCoordinates(element.coordinates);
|
||||||
|
element.sprite->setTrailCoordinates(Coordinates(0.f, 9.f));
|
||||||
|
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MockClassicNote::update(const microsec &music_offset)
|
||||||
|
{
|
||||||
|
switch (_state)
|
||||||
|
{
|
||||||
|
default: return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case State::FLYING:
|
||||||
|
if (music_offset > offset())
|
||||||
|
_state = State::DYING;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MockClassicNote::draw() const
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < _elements.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i >= 1)
|
||||||
|
_context->graphics_manager->drawLine(_elements[i-1].sprite->trailCoordinates(), _elements[i].sprite->trailCoordinates());
|
||||||
|
|
||||||
|
_context->graphics_manager->draw(_elements[i].sprite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "core/note.h"
|
#include "core/note.h"
|
||||||
#include "initializers/mockarrownoteinitializer.h"
|
#include "initializers/mockarrownoteinitializer.h"
|
||||||
|
|
||||||
|
class ClassicSprite;
|
||||||
|
class ClassicAnimationScenario;
|
||||||
|
|
||||||
class MockClassicNote : public Note
|
class MockClassicNote : public Note
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -17,13 +23,29 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit MockClassicNote(MockArrowNoteInitializer&& init);
|
explicit MockClassicNote(MockArrowNoteInitializer&& init);
|
||||||
virtual ~MockClassicNote() = default;
|
virtual ~MockClassicNote() override = default;
|
||||||
|
|
||||||
virtual bool isActive() const override final;
|
virtual bool isActive() 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;
|
||||||
|
|
||||||
virtual void putToGame(const microsec &music_offset) override = 0;
|
virtual void putToGame(const microsec &music_offset) override final;
|
||||||
virtual void update(const microsec &music_offset) override = 0;
|
virtual void update(const microsec &music_offset) override final;
|
||||||
virtual void draw() const override = 0;
|
virtual void draw() const override final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct MockElement
|
||||||
|
{
|
||||||
|
std::shared_ptr<ClassicSprite> sprite;
|
||||||
|
std::array<std::shared_ptr<ClassicAnimationScenario>, 4> animations;
|
||||||
|
Type type = Type::NONE;
|
||||||
|
|
||||||
|
Coordinates coordinates;
|
||||||
|
std::vector<Coordinates> falling_curve_interpolation;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<MockElement> _elements;
|
||||||
|
|
||||||
|
State _state;
|
||||||
|
const Context *_context;
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,9 +15,9 @@ ClassicArrowNote::ClassicArrowNote(ArrowNoteInitializer&& init) :
|
||||||
|
|
||||||
for (std::size_t i = 0; i < _elements.size(); ++i)
|
for (std::size_t i = 0; i < _elements.size(); ++i)
|
||||||
{
|
{
|
||||||
_elements[i].keys = init.elements[i].element.keys;
|
_elements[i].keys = init.elements[i].keys;
|
||||||
_elements[i].coordinates = init.elements[i].element.coordinates;
|
_elements[i].coordinates = init.elements[i].element.coordinates;
|
||||||
_elements[i].type = init.elements[i].type;
|
_elements[i].type = init.elements[i].element.type;
|
||||||
|
|
||||||
// Animations will be injected into note.
|
// Animations will be injected into note.
|
||||||
_elements[i].animations[State::NONE] = nullptr;
|
_elements[i].animations[State::NONE] = nullptr;
|
||||||
|
@ -36,7 +36,7 @@ void ClassicArrowNote::putToGame(const microsec &music_offset)
|
||||||
{
|
{
|
||||||
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({0., 9.});
|
element.sprite->setTrailCoordinates(Coordinates( 0.f, 9.f ));
|
||||||
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
element.animations[_state]->launch(element.sprite, music_offset, offset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,16 +38,16 @@ auto classic::createBeatmap(const std::string& filepath, const Context &context)
|
||||||
init.hold = false;
|
init.hold = false;
|
||||||
init.initializer.context = &context;
|
init.initializer.context = &context;
|
||||||
|
|
||||||
element.element.coordinates = {x, 390.};
|
element.element.coordinates = Coordinates(x, 390.f);
|
||||||
element.element.falling_curve_interpolation = {};
|
element.element.falling_curve_interpolation = {};
|
||||||
element.element.keys = {sf::Keyboard::W, sf::Keyboard::Up};
|
element.keys = {sf::Keyboard::W, sf::Keyboard::Up};
|
||||||
element.type = Type::UP;
|
element.element.type = Type::UP;
|
||||||
|
|
||||||
if (counter == 0)
|
if (counter == 0)
|
||||||
{
|
{
|
||||||
init.hold = true;
|
init.hold = true;
|
||||||
element.element.keys = {sf::Keyboard::D, sf::Keyboard::Right};
|
element.keys = {sf::Keyboard::D, sf::Keyboard::Right};
|
||||||
element.type = Type::RIGHT;
|
element.element.type = Type::RIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
--counter;
|
--counter;
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ClassicNote(NoteInitializer&& init);
|
explicit ClassicNote(NoteInitializer&& init);
|
||||||
virtual ~ClassicNote() = default;
|
virtual ~ClassicNote() override = default;
|
||||||
|
|
||||||
virtual bool isActive() const override final;
|
virtual bool isActive() const override final;
|
||||||
virtual bool isInGame() const override final;
|
virtual bool isInGame() const override final;
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "classicmode/elementinitializer.h"
|
#include "classicmode/elementinitializer.h"
|
||||||
#include "classicmode/classicactions.h"
|
|
||||||
|
|
||||||
struct ArrowElementInitializer
|
struct ArrowElementInitializer
|
||||||
{
|
{
|
||||||
ElementInitializer element;
|
ElementInitializer element;
|
||||||
|
|
||||||
Type type = Type::NONE;
|
|
||||||
std::array<sf::Keyboard::Key, 2> keys;
|
std::array<sf::Keyboard::Key, 2> keys;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ void ClassicDyingAnimationScenario::launch(const std::shared_ptr<ClassicSprite>
|
||||||
|
|
||||||
_sprite->setColor(sf::Color(140, 140, 140));
|
_sprite->setColor(sf::Color(140, 140, 140));
|
||||||
_sprite->setTrailColor(sf::Color(0, 0, 0, 0));
|
_sprite->setTrailColor(sf::Color(0, 0, 0, 0));
|
||||||
_sprite->setTrailCoordinates({0, 0});
|
_sprite->setTrailCoordinates(Coordinates(0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicDyingAnimationScenario::update(const microsec& music_offset)
|
void ClassicDyingAnimationScenario::update(const microsec& music_offset)
|
||||||
|
|
|
@ -28,7 +28,7 @@ void ClassicFlyingAnimationScenario::update(const microsec& music_offset)
|
||||||
float xb = getPoint( crd.x + 90. , crd.x , i );
|
float xb = getPoint( crd.x + 90. , crd.x , i );
|
||||||
float yb = getPoint( crd.y - 150. , crd.y , i );
|
float yb = getPoint( crd.y - 150. , crd.y , i );
|
||||||
|
|
||||||
_sprite->setTrailCoordinates({getPoint( xa , xb , i ), getPoint( ya , yb , i )});
|
_sprite->setTrailCoordinates(Coordinates(getPoint( xa , xb , i ), getPoint( ya , yb , i )));
|
||||||
|
|
||||||
bool pastPerfectScore = (i >= 1);
|
bool pastPerfectScore = (i >= 1);
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,12 @@ void ClassicSprite::setTrailCoordinates(const Coordinates &coordinates)
|
||||||
|
|
||||||
Coordinates ClassicSprite::coordinates() const
|
Coordinates ClassicSprite::coordinates() const
|
||||||
{
|
{
|
||||||
return {_shape.getPosition().x, _shape.getPosition().y};
|
return Coordinates(_shape.getPosition().x, _shape.getPosition().y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Coordinates ClassicSprite::trailCoordinates() const
|
Coordinates ClassicSprite::trailCoordinates() const
|
||||||
{
|
{
|
||||||
return {_trail.getPosition().x, _trail.getPosition().y};
|
return Coordinates(_trail.getPosition().x, _trail.getPosition().y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSprite::setColor(const sf::Color& color)
|
void ClassicSprite::setColor(const sf::Color& color)
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class ClassicGraphicsManager;
|
||||||
|
class HoldManager;
|
||||||
|
|
||||||
|
struct Context
|
||||||
|
{
|
||||||
|
std::shared_ptr<ClassicGraphicsManager> graphics_manager;
|
||||||
|
std::shared_ptr<HoldManager> hold_manager;
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "classicactions.h"
|
||||||
#include "core/inputtype.h"
|
#include "core/inputtype.h"
|
||||||
#include "tools/mathutils.h"
|
#include "tools/mathutils.h"
|
||||||
|
|
||||||
|
@ -7,6 +8,7 @@
|
||||||
|
|
||||||
struct ElementInitializer
|
struct ElementInitializer
|
||||||
{
|
{
|
||||||
|
Type type = Type::NONE;
|
||||||
Coordinates coordinates;
|
Coordinates coordinates;
|
||||||
std::vector<Coordinates> falling_curve_interpolation;
|
std::vector<Coordinates> falling_curve_interpolation;
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ Application::Application() :
|
||||||
EditorState::Callbacks editor_callbacks = {[&](){ popState(); }};
|
EditorState::Callbacks editor_callbacks = {[&](){ popState(); }};
|
||||||
|
|
||||||
const auto main_menu = std::make_shared<MainMenu>(_game_window, std::move(callbacks), _font_holder);
|
const auto main_menu = std::make_shared<MainMenu>(_game_window, std::move(callbacks), _font_holder);
|
||||||
const auto game_state = std::make_shared<GameState>(_game_window, classic::init(_game_window), GameState::Callbacks());
|
const auto game_state = std::make_shared<GameState>(_game_window, classic::initGame(_game_window), GameState::Callbacks());
|
||||||
const auto editor = std::make_shared<EditorState>(_game_window, std::move(editor_callbacks), std::make_unique<Music>(), _font_holder);
|
const auto editor = std::make_shared<EditorState>(_game_window, std::move(editor_callbacks), std::make_unique<Music>(), _font_holder);
|
||||||
|
|
||||||
_states[GUIState::Tag::MAIN_MENU] = main_menu;
|
_states[GUIState::Tag::MAIN_MENU] = main_menu;
|
||||||
|
|
|
@ -99,7 +99,7 @@ void EditorState::enter()
|
||||||
|
|
||||||
menu_bar->setVisibility(true);
|
menu_bar->setVisibility(true);
|
||||||
|
|
||||||
auto editor_widget = std::make_unique<EditorWidget>(_edito)
|
//auto editor_widget = std::make_unique<EditorWidget>(_edito)
|
||||||
|
|
||||||
_group = std::make_shared<Group>();
|
_group = std::make_shared<Group>();
|
||||||
_group->addChild(menu_bar);
|
_group->addChild(menu_bar);
|
||||||
|
|
|
@ -4,17 +4,29 @@ using microsec = long long;
|
||||||
|
|
||||||
struct Coordinates
|
struct Coordinates
|
||||||
{
|
{
|
||||||
float x = 0.;
|
float x;
|
||||||
float y = 0.;
|
float y;
|
||||||
|
|
||||||
|
constexpr inline explicit Coordinates() noexcept :
|
||||||
|
x(0.), y(0.)
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr inline explicit Coordinates(int x, int y) noexcept :
|
||||||
|
x(x), y(y)
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr inline explicit Coordinates(float x, float y) noexcept :
|
||||||
|
x(x), y(y)
|
||||||
|
{}
|
||||||
|
|
||||||
constexpr inline Coordinates operator+(const Coordinates& right) const noexcept
|
constexpr inline Coordinates operator+(const Coordinates& right) const noexcept
|
||||||
{
|
{
|
||||||
return {right.x + x, right.y + y};
|
return Coordinates{right.x + x, right.y + y};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline Coordinates operator-(const Coordinates& right) const noexcept
|
constexpr inline Coordinates operator-(const Coordinates& right) const noexcept
|
||||||
{
|
{
|
||||||
return {right.x - x, right.y - y};
|
return Coordinates{right.x - x, right.y - y};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void moveBy(float x, float y) noexcept
|
inline void moveBy(float x, float y) noexcept
|
||||||
|
|
Loading…
Reference in New Issue