forked from NaiJi/project-kyoku
Untie dependecies and make them more abstract
This commit is contained in:
parent
5b7076ac1c
commit
a028773fe8
|
@ -1,11 +1,11 @@
|
||||||
#ifndef APPLICATION_H
|
#ifndef APPLICATION_H
|
||||||
#define APPLICATION_H
|
#define APPLICATION_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
#include <SFML/Window/Keyboard.hpp>
|
#include <SFML/Window/Keyboard.hpp>
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
|
||||||
#include "timeline.h"
|
|
||||||
#include "note.h"
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
class Application
|
class Application
|
||||||
|
@ -19,7 +19,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RenderWindow _game_window;
|
sf::RenderWindow _game_window;
|
||||||
std::unique_ptr<Timeline> _timeline;
|
|
||||||
std::shared_ptr<Game> _game;
|
std::shared_ptr<Game> _game;
|
||||||
|
|
||||||
void exec();
|
void exec();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define GAME_H
|
#define GAME_H
|
||||||
|
|
||||||
#include <SFML/Graphics/RenderWindow.hpp>
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
#include <SFML/Window/Event.hpp>
|
#include "inputtype.h"
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
|
@ -11,9 +11,9 @@ public:
|
||||||
|
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
|
|
||||||
virtual void input(const sf::Event& event) = 0;
|
virtual void input(PlayerInput&& inputdata) = 0;
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
virtual void draw(sf::RenderWindow& window) const = 0;
|
virtual void draw() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GAME_H
|
#endif // GAME_H
|
||||||
|
|
|
@ -2,19 +2,14 @@
|
||||||
#define INPUTTYPE_H
|
#define INPUTTYPE_H
|
||||||
|
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
using microsec = sf::Int64;
|
||||||
|
|
||||||
class InputType
|
struct PlayerInput
|
||||||
{
|
{
|
||||||
public:
|
microsec timestamp;
|
||||||
explicit InputType(const microsec& timestamp);
|
sf::Event event;
|
||||||
virtual ~InputType() = 0;
|
|
||||||
|
|
||||||
const microsec& timestamp() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
microsec _timestamp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INPUTTYPE_H
|
#endif // INPUTTYPE_H
|
||||||
|
|
|
@ -4,19 +4,21 @@
|
||||||
#include <SFML/System/Clock.hpp>
|
#include <SFML/System/Clock.hpp>
|
||||||
#include <SFML/Graphics/Drawable.hpp>
|
#include <SFML/Graphics/Drawable.hpp>
|
||||||
|
|
||||||
|
#include "inputtype.h"
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
using microsec = sf::Int64;
|
||||||
|
|
||||||
class Note : public sf::Drawable
|
class Note
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Note(microsec perfect_offset) :
|
explicit Note(microsec perfect_offset) :
|
||||||
_perfect_offset(perfect_offset) {}
|
_perfect_offset(perfect_offset) {}
|
||||||
virtual ~Note() = default;
|
virtual ~Note() = default;
|
||||||
|
|
||||||
virtual bool isActive() const = 0;
|
|
||||||
virtual bool isActive(const microsec& music_offset) const = 0;
|
virtual bool isActive(const microsec& music_offset) const = 0;
|
||||||
virtual void update(const microsec& music_offset) = 0;
|
virtual void update(const microsec& music_offset) = 0;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
|
virtual void input(PlayerInput&& inputdata) = 0;
|
||||||
|
virtual void draw() const = 0;
|
||||||
|
|
||||||
virtual void putToGame(const microsec &offset) = 0;
|
virtual void putToGame(const microsec &offset) = 0;
|
||||||
virtual bool isExpired() const = 0;
|
virtual bool isExpired() const = 0;
|
||||||
|
|
|
@ -62,7 +62,7 @@ private:
|
||||||
* V0 is PERFECT SCORE and the last V represents the worst
|
* V0 is PERFECT SCORE and the last V represents the worst
|
||||||
* grades which is death of note by expiration */
|
* grades which is death of note by expiration */
|
||||||
|
|
||||||
const std::vector<microsec>& _intervals;
|
const std::vector<microsec> _intervals;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PRECISIONEVALUATOR_H
|
#endif // PRECISIONEVALUATOR_H
|
||||||
|
|
|
@ -7,17 +7,22 @@
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
using microsec = sf::Int64;
|
||||||
|
|
||||||
|
class Note;
|
||||||
|
|
||||||
class Timeline
|
class Timeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
using Iterator = std::vector<Note*>::const_iterator;
|
||||||
|
|
||||||
virtual ~Timeline() = default;
|
virtual ~Timeline() = default;
|
||||||
|
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
virtual void run() = 0;
|
virtual void run(std::vector<Note*>&& notes, const microsec& visibility) = 0;
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
virtual microsec currentMusicOffset() const = 0;
|
virtual microsec currentMusicOffset() const = 0;
|
||||||
virtual void drawVisibleNotes(sf::RenderWindow& window) const = 0;
|
virtual void drawVisibleNotes() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIMELINE_H
|
#endif // TIMELINE_H
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "inputtype.h"
|
||||||
|
|
||||||
#include "classicgame/classicgame.h"
|
#include "classicgame/classicgame.h"
|
||||||
#include <SFML/Graphics/Color.hpp>
|
#include "classicgame/classicgraphicsmanager.h"
|
||||||
#include <SFML/Window/Event.hpp>
|
|
||||||
#include <SFML/Window/ContextSettings.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <future>
|
|
||||||
|
|
||||||
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f);
|
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f);
|
||||||
|
|
||||||
Application::Application() :
|
Application::Application() :
|
||||||
_game_window({1280, 720}, "Test", sf::Style::Default ),
|
_game_window({1280, 720}, "Test", sf::Style::Default),
|
||||||
_game(std::make_unique<ClassicGame>())
|
_game(std::make_unique<ClassicGame>(std::make_unique<ClassicGraphicsManager>(_game_window)))
|
||||||
{
|
{
|
||||||
_game_window.setFramerateLimit(60);
|
_game_window.setFramerateLimit(60);
|
||||||
_game_window.setKeyRepeatEnabled(false);
|
_game_window.setKeyRepeatEnabled(false);
|
||||||
|
@ -65,7 +63,7 @@ void Application::input()
|
||||||
case sf::Event::KeyReleased:
|
case sf::Event::KeyReleased:
|
||||||
if (event.key.code == sf::Keyboard::Escape)
|
if (event.key.code == sf::Keyboard::Escape)
|
||||||
_game_window.close();
|
_game_window.close();
|
||||||
_game->input(event);
|
_game->input(PlayerInput{0, event});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -82,6 +80,6 @@ void Application::update()
|
||||||
void Application::draw()
|
void Application::draw()
|
||||||
{
|
{
|
||||||
_game_window.clear();
|
_game_window.clear();
|
||||||
_game->draw(_game_window);
|
_game->draw();
|
||||||
_game_window.display();
|
_game_window.display();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ enum class Action
|
||||||
COUNT
|
COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Button
|
enum class Type
|
||||||
{
|
{
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
#include "classicgame.h"
|
#include "classicgame.h"
|
||||||
#include "classicinputtype.h"
|
|
||||||
#include "classictimeline.h"
|
#include "classictimeline.h"
|
||||||
#include "classicgraphicsmanager.h"
|
#include "classicmapcreator.h"
|
||||||
#include "spritecontainer.h"
|
|
||||||
#include "classicnote.h"
|
#include "classicnote.h"
|
||||||
|
|
||||||
ClassicGame::ClassicGame() :
|
ClassicGame::ClassicGame(std::unique_ptr<ClassicGraphicsManager>&& manager) :
|
||||||
_timeline(std::make_unique<ClassicTimeline>()),
|
_timeline(std::make_unique<ClassicTimeline>()),
|
||||||
_graphics_manager(std::make_unique<ClassicGraphicsManager>())
|
_graphics_manager(std::move(manager))
|
||||||
{
|
{
|
||||||
_slap_buffer.loadFromFile("very-final-slap.wav");
|
_slap_buffer.loadFromFile("very-final-slap.wav");
|
||||||
_slap.setBuffer(_slap_buffer);
|
_slap.setBuffer(_slap_buffer);
|
||||||
|
@ -15,40 +13,40 @@ ClassicGame::ClassicGame() :
|
||||||
|
|
||||||
_keys_to_buttons =
|
_keys_to_buttons =
|
||||||
{
|
{
|
||||||
{sf::Keyboard::Up, Button::UP}, // Load from settings
|
{sf::Keyboard::Up, Type::UP}, // Load from settings
|
||||||
{sf::Keyboard::Right, Button::RIGHT},
|
{sf::Keyboard::Right, Type::RIGHT},
|
||||||
{sf::Keyboard::Down, Button::DOWN},
|
{sf::Keyboard::Down, Type::DOWN},
|
||||||
{sf::Keyboard::Left, Button::LEFT},
|
{sf::Keyboard::Left, Type::LEFT},
|
||||||
|
|
||||||
{sf::Keyboard::W, Button::UP},
|
{sf::Keyboard::W, Type::UP},
|
||||||
{sf::Keyboard::D, Button::RIGHT},
|
{sf::Keyboard::D, Type::RIGHT},
|
||||||
{sf::Keyboard::S, Button::DOWN},
|
{sf::Keyboard::S, Type::DOWN},
|
||||||
{sf::Keyboard::A, Button::LEFT},
|
{sf::Keyboard::A, Type::LEFT},
|
||||||
|
|
||||||
{sf::Keyboard::E, Button::SLIDER_RIGHT},
|
{sf::Keyboard::E, Type::SLIDER_RIGHT},
|
||||||
{sf::Keyboard::Q, Button::SLIDER_LEFT}
|
{sf::Keyboard::Q, Type::SLIDER_LEFT}
|
||||||
};
|
};
|
||||||
|
|
||||||
_buttons_to_pressed_actions=
|
_buttons_to_pressed_actions=
|
||||||
{
|
{
|
||||||
{Button::UP, Action::PRESS_UP},
|
{Type::UP, Action::PRESS_UP},
|
||||||
{Button::RIGHT, Action::PRESS_RIGHT},
|
{Type::RIGHT, Action::PRESS_RIGHT},
|
||||||
{Button::DOWN, Action::PRESS_DOWN},
|
{Type::DOWN, Action::PRESS_DOWN},
|
||||||
{Button::LEFT, Action::PRESS_LEFT},
|
{Type::LEFT, Action::PRESS_LEFT},
|
||||||
|
|
||||||
{Button::SLIDER_RIGHT, Action::PRESS_SLIDER_RIGHT},
|
{Type::SLIDER_RIGHT, Action::PRESS_SLIDER_RIGHT},
|
||||||
{Button::SLIDER_LEFT, Action::PRESS_SLIDER_LEFT}
|
{Type::SLIDER_LEFT, Action::PRESS_SLIDER_LEFT}
|
||||||
};
|
};
|
||||||
|
|
||||||
_buttons_to_released_actions=
|
_buttons_to_released_actions=
|
||||||
{
|
{
|
||||||
{Button::UP, Action::RELEASE_UP},
|
{Type::UP, Action::RELEASE_UP},
|
||||||
{Button::RIGHT, Action::RELEASE_RIGHT},
|
{Type::RIGHT, Action::RELEASE_RIGHT},
|
||||||
{Button::DOWN, Action::RELEASE_DOWN},
|
{Type::DOWN, Action::RELEASE_DOWN},
|
||||||
{Button::LEFT, Action::RELEASE_LEFT},
|
{Type::LEFT, Action::RELEASE_LEFT},
|
||||||
|
|
||||||
{Button::SLIDER_RIGHT, Action::RELEASE_SLIDER_RIGHT},
|
{Type::SLIDER_RIGHT, Action::RELEASE_SLIDER_RIGHT},
|
||||||
{Button::SLIDER_LEFT, Action::RELEASE_SLIDER_LEFT}
|
{Type::SLIDER_LEFT, Action::RELEASE_SLIDER_LEFT}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,60 +55,42 @@ ClassicGame::~ClassicGame()
|
||||||
|
|
||||||
void ClassicGame::run()
|
void ClassicGame::run()
|
||||||
{
|
{
|
||||||
_timeline->fetchVisibleNotes(_graphics_manager);
|
ClassicMapCreator creator(_graphics_manager);
|
||||||
_timeline->run();
|
auto beatmap = creator.createBeatmap("aa");
|
||||||
|
_timeline->run(std::move(beatmap.notes), beatmap.visibility_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::input(const sf::Event& event)
|
void ClassicGame::input(PlayerInput&& inputdata)
|
||||||
{
|
{
|
||||||
Action new_action = Action::NONE;
|
inputdata.timestamp = _timeline->currentMusicOffset();
|
||||||
microsec timestamp = _timeline->currentMusicOffset();
|
|
||||||
|
|
||||||
switch (event.type)
|
switch (inputdata.event.type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
{
|
|
||||||
if (_keys_to_buttons.find(event.key.code) != _keys_to_buttons.end())
|
|
||||||
new_action = getActionKeyPressed(_keys_to_buttons[event.key.code]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case sf::Event::KeyReleased:
|
case sf::Event::KeyReleased:
|
||||||
{
|
{
|
||||||
if (_keys_to_buttons.find(event.key.code) != _keys_to_buttons.end())
|
auto note = _timeline->getActiveNote();
|
||||||
new_action = getActionKeyReleased(_keys_to_buttons[event.key.code]);
|
|
||||||
|
if (!_timeline->isExpired(note))
|
||||||
|
{
|
||||||
|
(*note)->input(std::move(inputdata));
|
||||||
|
_slap.play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto note = _timeline->getActiveNote();
|
|
||||||
|
|
||||||
if (!_timeline->isExpired(note))
|
|
||||||
{
|
|
||||||
(*note)->input(ClassicInputType(timestamp, new_action));
|
|
||||||
_slap.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Action ClassicGame::getActionKeyPressed(Button button) const
|
|
||||||
{
|
|
||||||
return _buttons_to_pressed_actions.at(button);
|
|
||||||
}
|
|
||||||
|
|
||||||
Action ClassicGame::getActionKeyReleased(Button button) const
|
|
||||||
{
|
|
||||||
return _buttons_to_released_actions.at(button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::update()
|
void ClassicGame::update()
|
||||||
{
|
{
|
||||||
_timeline->update();
|
_timeline->update();
|
||||||
_timeline->fetchVisibleNotes(_graphics_manager);
|
_timeline->fetchVisibleNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::draw(sf::RenderWindow& window) const
|
void ClassicGame::draw() const
|
||||||
{
|
{
|
||||||
_timeline->drawVisibleNotes(window);
|
_timeline->drawVisibleNotes();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,36 +2,30 @@
|
||||||
#define CLASSICGAME_H
|
#define CLASSICGAME_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "classicactions.h"
|
#include "classicactions.h"
|
||||||
#include "spritecontainer.h"
|
|
||||||
#include <SFML/Audio/SoundBuffer.hpp>
|
#include <SFML/Audio/SoundBuffer.hpp>
|
||||||
#include <SFML/Audio/Sound.hpp>
|
#include <SFML/Audio/Sound.hpp>
|
||||||
|
|
||||||
class ClassicTimeline;
|
class ClassicTimeline;
|
||||||
class ClassicSprite;
|
|
||||||
class ClassicGraphicsManager;
|
class ClassicGraphicsManager;
|
||||||
|
|
||||||
class ClassicGame final : public Game
|
class ClassicGame final : public Game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ClassicGame();
|
explicit ClassicGame(std::unique_ptr<ClassicGraphicsManager>&& manager);
|
||||||
virtual ~ClassicGame() override;
|
virtual ~ClassicGame() override;
|
||||||
|
|
||||||
virtual void run() override;
|
virtual void run() override;
|
||||||
|
|
||||||
virtual void input(const sf::Event& event) override;
|
virtual void input(PlayerInput &&inputdata) override;
|
||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void draw(sf::RenderWindow &window) const override;
|
virtual void draw() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<sf::Keyboard::Key, Button> _keys_to_buttons;
|
std::map<sf::Keyboard::Key, Type> _keys_to_buttons;
|
||||||
std::map<Button, Action> _buttons_to_pressed_actions;
|
std::map<Type, Action> _buttons_to_pressed_actions;
|
||||||
std::map<Button, Action> _buttons_to_released_actions;
|
std::map<Type, Action> _buttons_to_released_actions;
|
||||||
|
|
||||||
Action getActionKeyPressed(Button button) const;
|
|
||||||
Action getActionKeyReleased(Button button) const;
|
|
||||||
|
|
||||||
std::unique_ptr<ClassicTimeline> _timeline;
|
std::unique_ptr<ClassicTimeline> _timeline;
|
||||||
std::unique_ptr<ClassicGraphicsManager> _graphics_manager;
|
std::unique_ptr<ClassicGraphicsManager> _graphics_manager;
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
#include "classicgraphicsmanager.h"
|
#include "classicgraphicsmanager.h"
|
||||||
#include "classicnote.h"
|
#include "classicnote.h"
|
||||||
|
|
||||||
ClassicGraphicsManager::ClassicGraphicsManager() :
|
ClassicGraphicsManager::ClassicGraphicsManager(sf::RenderTarget& target) :
|
||||||
_sprite_container({Action::PRESS_UP, Action::PRESS_DOWN,
|
_sprite_container({Type::UP, Type::DOWN,
|
||||||
Action::PRESS_LEFT, Action::PRESS_RIGHT},
|
Type::LEFT, Type::RIGHT},
|
||||||
std::make_unique<ClassicSpriteFactory>("VeraMono.ttf"))
|
std::make_unique<ClassicSpriteFactory>("VeraMono.ttf")),
|
||||||
|
_render_target(target)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void ClassicGraphicsManager::initSprite(ClassicNote* note)
|
void ClassicGraphicsManager::initSprite(ClassicNote* note)
|
||||||
{
|
{
|
||||||
const auto action_type = note->action();
|
note->setSprite(_sprite_container.getSprite(note->type()));
|
||||||
note->setSprite(_sprite_container.getSprite(action_type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGraphicsManager::resetSprite(ClassicNote* note)
|
void ClassicGraphicsManager::resetSprite(ClassicNote* note)
|
||||||
{
|
{
|
||||||
_sprite_container.resetSprite(note->sprite(), note->action());
|
_sprite_container.resetSprite(note->sprite(), note->type());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicGraphicsManager::draw(const ClassicNote *note)
|
||||||
|
{
|
||||||
|
_render_target.draw(*note->sprite());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,21 @@
|
||||||
#include "spritecontainer.h"
|
#include "spritecontainer.h"
|
||||||
#include "classicspritefactory.h"
|
#include "classicspritefactory.h"
|
||||||
|
|
||||||
|
#include <SFML/Graphics/RenderTarget.hpp>
|
||||||
|
|
||||||
class ClassicSprite;
|
class ClassicSprite;
|
||||||
class ClassicNote;
|
class ClassicNote;
|
||||||
|
|
||||||
class ClassicGraphicsManager
|
class ClassicGraphicsManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ClassicGraphicsManager();
|
explicit ClassicGraphicsManager(sf::RenderTarget& target);
|
||||||
|
|
||||||
void initSprite(ClassicNote* note);
|
void initSprite(ClassicNote* note);
|
||||||
void resetSprite(ClassicNote* note);
|
void resetSprite(ClassicNote* note);
|
||||||
|
void draw(const ClassicNote *note);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpriteContainer<Action, ClassicSpriteFactory, ClassicSprite> _sprite_container;
|
SpriteContainer<Type, ClassicSpriteFactory, ClassicSprite> _sprite_container;
|
||||||
|
sf::RenderTarget& _render_target;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#include "classicinputtype.h"
|
|
||||||
|
|
||||||
ClassicInputType::ClassicInputType(const microsec& timestamp, Action action) :
|
|
||||||
InputType(timestamp),
|
|
||||||
_action(action)
|
|
||||||
{}
|
|
||||||
|
|
||||||
ClassicInputType::~ClassicInputType()
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool ClassicInputType::operator==(const Action& comparing_action) const
|
|
||||||
{
|
|
||||||
return _action == comparing_action;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicInputType::operator==(const ClassicInputType& comparing_action) const
|
|
||||||
{
|
|
||||||
return _action == comparing_action._action
|
|
||||||
&& _button == comparing_action._button;
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
#ifndef CLASSICINPUTTYPE_H
|
|
||||||
#define CLASSICINPUTTYPE_H
|
|
||||||
|
|
||||||
#include "classicactions.h"
|
|
||||||
#include "inputtype.h"
|
|
||||||
|
|
||||||
class ClassicInputType : public InputType
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit ClassicInputType(const microsec& timestamp, Action action);
|
|
||||||
virtual ~ClassicInputType() override;
|
|
||||||
|
|
||||||
bool operator==(const Action& comparing_action) const;
|
|
||||||
bool operator==(const ClassicInputType& comparing_action) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Action _action;
|
|
||||||
Button _button;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLASSICINPUTTYPE_H
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "classicmapcreator.h"
|
||||||
|
#include "classicnote.h"
|
||||||
|
|
||||||
|
ClassicMapCreator::ClassicMapCreator(const std::unique_ptr<ClassicGraphicsManager>& manager) :
|
||||||
|
_graphics_manager(manager)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Beatmap ClassicMapCreator::createBeatmap(const std::string& filepath) const
|
||||||
|
{
|
||||||
|
(void) filepath;
|
||||||
|
|
||||||
|
microsec starting_beat_offset = 352162;
|
||||||
|
int amount_of_beats = 209;
|
||||||
|
microsec interval = 1412162;
|
||||||
|
microsec tempo_interval = interval / 2;
|
||||||
|
microsec note_input_offset = 412162 / 3;
|
||||||
|
microsec bpm_iterator = starting_beat_offset;
|
||||||
|
microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
||||||
|
|
||||||
|
std::vector<microsec> input_intervals = {note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
|
||||||
|
std::vector<Note*> notes;
|
||||||
|
input_intervals.shrink_to_fit();
|
||||||
|
|
||||||
|
bpm_iterator += tempo_interval;
|
||||||
|
|
||||||
|
float x = 90.;
|
||||||
|
|
||||||
|
while (bpm_iterator < bpm_end)
|
||||||
|
{
|
||||||
|
notes.emplace_back(new ClassicNote(input_intervals, bpm_iterator, Type::UP, {x, 390.}, _graphics_manager));
|
||||||
|
bpm_iterator += tempo_interval;
|
||||||
|
x += 70;
|
||||||
|
|
||||||
|
if (x >= 1200)
|
||||||
|
x = 90.;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {std::move(notes), note_input_offset * 12};
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef CLASSICMAPCREATOR_H
|
||||||
|
#define CLASSICMAPCREATOR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "note.h"
|
||||||
|
#include "classicgraphicsmanager.h"
|
||||||
|
|
||||||
|
struct Beatmap
|
||||||
|
{
|
||||||
|
std::vector<Note*> notes;
|
||||||
|
microsec visibility_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClassicMapCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ClassicMapCreator(const std::unique_ptr<ClassicGraphicsManager>& manager);
|
||||||
|
|
||||||
|
Beatmap createBeatmap(const std::string& filepath) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::unique_ptr<ClassicGraphicsManager>& _graphics_manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CLASSICMAPCREATOR_H
|
|
@ -4,20 +4,15 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
||||||
Action action, const Coordinates& coord) :
|
Type type, const Coordinates& coord, const std::unique_ptr<ClassicGraphicsManager> &manager) :
|
||||||
Note(perfect_offset),
|
Note(perfect_offset),
|
||||||
_coordinates(coord),
|
_coordinates(coord),
|
||||||
_evaluator(intervals, _perfect_offset),
|
_evaluator(intervals, _perfect_offset),
|
||||||
_action(action),
|
_graphics_manager(manager),
|
||||||
_appearance_time(0),
|
_is_expired(true),
|
||||||
_current_state(ClassicNoteState::NONE)
|
_type(type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool ClassicNote::isActive() const
|
|
||||||
{
|
|
||||||
return _states.at(_current_state)->value() == ClassicNoteState::ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClassicNote::isActive(const microsec &music_offset) const
|
bool ClassicNote::isActive(const microsec &music_offset) const
|
||||||
{
|
{
|
||||||
return _evaluator.isActive(music_offset);
|
return _evaluator.isActive(music_offset);
|
||||||
|
@ -25,47 +20,36 @@ bool ClassicNote::isActive(const microsec &music_offset) const
|
||||||
|
|
||||||
void ClassicNote::putToGame(const microsec &music_offset)
|
void ClassicNote::putToGame(const microsec &music_offset)
|
||||||
{
|
{
|
||||||
_appearance_time = music_offset; // To animation manager
|
_is_expired = false;
|
||||||
_trail_path_percent = ((_perfect_offset - _appearance_time) * 0.01);
|
_graphics_manager->initSprite(this); (void) music_offset;
|
||||||
|
//_appearance_time = music_offset; // To animation manager
|
||||||
_current_state = ClassicNoteState::FLYING;
|
//_trail_path_percent = ((_perfect_offset - _appearance_time) * 0.01);
|
||||||
_states.at(_current_state)->onEntering(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClassicNote::isExpired() const
|
bool ClassicNote::isExpired() const
|
||||||
{
|
{
|
||||||
return _states.at(_current_state)->value() == ClassicNoteState::NONE;
|
return _is_expired;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicNote::update(const microsec& music_offset)
|
void ClassicNote::update(const microsec& music_offset)
|
||||||
{
|
{
|
||||||
auto next_state = _states.at(_current_state)->update(this, music_offset);
|
bool is_not_active_anymore = (!_is_expired && !isActive(music_offset));
|
||||||
if (next_state != _current_state)
|
|
||||||
{
|
|
||||||
_current_state = next_state;
|
|
||||||
_states.at(_current_state)->onEntering(this);
|
|
||||||
|
|
||||||
|
if (is_not_active_anymore)
|
||||||
|
{
|
||||||
|
_graphics_manager->resetSprite(this);
|
||||||
|
_is_expired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ClassicNote::input(ClassicInputType&& input_data) -> Grade
|
void ClassicNote::input(PlayerInput&& inputdata)
|
||||||
{
|
{
|
||||||
auto grade = ClassicNote::Grade::BAD;
|
auto grade = ClassicNote::Grade::BAD;
|
||||||
|
|
||||||
if (input_data == _action)
|
if (std::find(_keys.begin(), _keys.end(), inputdata.event.key.code) != _keys.end())
|
||||||
grade = _evaluator.calculatePrecision(input_data.timestamp());
|
grade = _evaluator.calculatePrecision(inputdata.timestamp);
|
||||||
|
|
||||||
_current_state = ClassicNoteState::DYING;
|
|
||||||
_states.at(_current_state)->onEntering(this);
|
|
||||||
|
|
||||||
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
||||||
|
|
||||||
return grade;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action ClassicNote::action() const
|
|
||||||
{
|
|
||||||
return _action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClassicSprite> ClassicNote::sprite() const noexcept
|
std::shared_ptr<ClassicSprite> ClassicNote::sprite() const noexcept
|
||||||
|
@ -82,3 +66,13 @@ const Coordinates& ClassicNote::getCoordinates() const noexcept
|
||||||
{
|
{
|
||||||
return _coordinates;
|
return _coordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type ClassicNote::type() const noexcept
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicNote::draw() const
|
||||||
|
{
|
||||||
|
_graphics_manager->draw(this);
|
||||||
|
}
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
#include "note.h"
|
#include "note.h"
|
||||||
#include "precisionevaluator.h"
|
#include "precisionevaluator.h"
|
||||||
#include "classicinputtype.h"
|
#include "classicgraphicsmanager.h"
|
||||||
#include "classicnotestate/classicnotestate.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -33,35 +32,31 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
explicit ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
||||||
Action action, const Coordinates& coord);
|
Type type, const Coordinates& coord,
|
||||||
|
const std::unique_ptr<ClassicGraphicsManager>& manager);
|
||||||
virtual ~ClassicNote() = default;
|
virtual ~ClassicNote() = default;
|
||||||
|
|
||||||
virtual bool isActive() const override;
|
|
||||||
virtual bool isActive(const microsec &music_offset) const override;
|
virtual bool isActive(const microsec &music_offset) const override;
|
||||||
virtual void update(const microsec &music_offset) override;
|
virtual void update(const microsec &music_offset) override;
|
||||||
|
virtual void input(PlayerInput&& inputdata) override;
|
||||||
virtual void putToGame(const microsec &music_offset) override;
|
virtual void putToGame(const microsec &music_offset) override;
|
||||||
virtual bool isExpired() const override;
|
virtual bool isExpired() const override;
|
||||||
|
virtual void draw() const override;
|
||||||
|
|
||||||
Grade input(ClassicInputType&& input_data);
|
Type type() const noexcept;
|
||||||
Action action() const;
|
|
||||||
|
|
||||||
std::shared_ptr<ClassicSprite> sprite() const noexcept;
|
std::shared_ptr<ClassicSprite> sprite() const noexcept;
|
||||||
void saveAppearanceTime(const microsec& music_offset);
|
|
||||||
void setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept;
|
void setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept;
|
||||||
const Coordinates& getCoordinates() const noexcept;
|
const Coordinates& getCoordinates() const noexcept;
|
||||||
|
|
||||||
const microsec& getApearanceTime() const { return _appearance_time; }
|
|
||||||
const float& getOneTrailPercent() const { return _trail_path_percent; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Coordinates _coordinates;
|
const Coordinates _coordinates;
|
||||||
const PrecisionEvaluator<Grade> _evaluator;
|
const PrecisionEvaluator<Grade> _evaluator;
|
||||||
const Action _action;
|
|
||||||
|
|
||||||
|
const std::unique_ptr<ClassicGraphicsManager>& _graphics_manager;
|
||||||
std::shared_ptr<ClassicSprite> _sprite;
|
std::shared_ptr<ClassicSprite> _sprite;
|
||||||
microsec _appearance_time;
|
|
||||||
float _trail_path_percent; //100% for sprite falling trajectory
|
|
||||||
|
|
||||||
std::array<std::shared_ptr<ClassicNoteState>, ClassicNoteState::COUNT> _states;
|
bool _is_expired;
|
||||||
ClassicNoteState::Value _current_state;
|
std::array<sf::Keyboard::Key, 2> _keys;
|
||||||
|
const Type _type;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include "classicnoteactivestate.h"
|
|
||||||
#include "../classicnote.h"
|
|
||||||
#include "../classicsprite.h"
|
|
||||||
|
|
||||||
auto ClassicNoteActiveState::value() const -> Value
|
|
||||||
{
|
|
||||||
return Value::ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ClassicNoteActiveState::update(const ClassicNote* note, const microsec& offset) -> Value
|
|
||||||
{
|
|
||||||
float i;
|
|
||||||
auto update_time = offset - note->getApearanceTime(); // This all will be inside ::update
|
|
||||||
i = update_time / note->getOneTrailPercent() * 0.01; // of an animation object
|
|
||||||
|
|
||||||
const auto& coordinates = note->getCoordinates();
|
|
||||||
const auto& sprite = note->sprite();
|
|
||||||
float xa = getPt( coordinates.x + 20. , coordinates.x + 90. , i );
|
|
||||||
float ya = getPt( coordinates.y - 600. , coordinates.y - 150. , i );
|
|
||||||
float xb = getPt( coordinates.x + 90. , coordinates.x , i );
|
|
||||||
float yb = getPt( coordinates.y - 150. , coordinates.y , i );
|
|
||||||
|
|
||||||
sprite->update(getPt( xa , xb , i ), getPt( ya , yb , i ));
|
|
||||||
if (i >= 1)
|
|
||||||
{
|
|
||||||
sprite->trailFade();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!note->isActive(offset))
|
|
||||||
return Value::DYING;
|
|
||||||
|
|
||||||
return value();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int ClassicNoteActiveState::getPt(float n1, float n2, float perc) const
|
|
||||||
{
|
|
||||||
float diff = n2 - n1;
|
|
||||||
return n1 + (diff * perc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicNoteActiveState::onEntering(const ClassicNote* note)
|
|
||||||
{
|
|
||||||
(void)note;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#ifndef CLASSICNOTEACTIVESTATE_H
|
|
||||||
#define CLASSICNOTEACTIVESTATE_H
|
|
||||||
|
|
||||||
#include "classicnotestate.h"
|
|
||||||
|
|
||||||
class ClassicNoteActiveState : public ClassicNoteState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Value value() const override;
|
|
||||||
virtual Value update(const ClassicNote* note, const microsec& offset) override;
|
|
||||||
virtual void onEntering(const ClassicNote* note) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline constexpr int getPt(float n1 , float n2 , float perc) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLASSICNOTEACTIVESTATE_H
|
|
|
@ -1,26 +0,0 @@
|
||||||
#include "classicnotedyingstate.h"
|
|
||||||
#include "../classicnote.h"
|
|
||||||
#include "../classicsprite.h"
|
|
||||||
|
|
||||||
auto ClassicNoteDyingState::value() const -> Value
|
|
||||||
{
|
|
||||||
return Value::DYING;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ClassicNoteDyingState::update(const ClassicNote* note, const microsec& offset) -> Value
|
|
||||||
{
|
|
||||||
(void) offset;
|
|
||||||
const auto& sprite = note->sprite();
|
|
||||||
|
|
||||||
sprite->update();
|
|
||||||
if (sprite->isDead())
|
|
||||||
return Value::NONE;
|
|
||||||
|
|
||||||
return value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicNoteDyingState::onEntering(const ClassicNote* note)
|
|
||||||
{
|
|
||||||
note->sprite()->pulse();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef CLASSICNOTEDYINGSTATE_H
|
|
||||||
#define CLASSICNOTEDYINGSTATE_H
|
|
||||||
|
|
||||||
#include "classicnotestate.h"
|
|
||||||
|
|
||||||
class ClassicNoteDyingState : public ClassicNoteState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Value value() const override;
|
|
||||||
virtual Value update(const ClassicNote* note, const microsec& offset) override;
|
|
||||||
virtual void onEntering(const ClassicNote* note) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLASSICNOTEDYINGSTATE_H
|
|
|
@ -1,49 +0,0 @@
|
||||||
#include "classicnoteflyingstate.h"
|
|
||||||
#include "../classicnote.h"
|
|
||||||
#include "../classicsprite.h"
|
|
||||||
|
|
||||||
auto ClassicNoteFlyingState::value() const -> Value
|
|
||||||
{
|
|
||||||
return Value::FLYING;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ClassicNoteFlyingState::update(const ClassicNote* note, const microsec& offset) -> Value
|
|
||||||
{
|
|
||||||
float i;
|
|
||||||
auto update_time = offset - note->getApearanceTime(); // This all will be inside ::update
|
|
||||||
i = update_time / note->getOneTrailPercent() * 0.01; // of an animation object
|
|
||||||
|
|
||||||
const auto& coordinates = note->getCoordinates();
|
|
||||||
const auto& sprite = note->sprite();
|
|
||||||
float xa = getPt( coordinates.x + 20. , coordinates.x + 90. , i );
|
|
||||||
float ya = getPt( coordinates.y - 600. , coordinates.y - 150. , i );
|
|
||||||
float xb = getPt( coordinates.x + 90. , coordinates.x , i );
|
|
||||||
float yb = getPt( coordinates.y - 150. , coordinates.y , i );
|
|
||||||
|
|
||||||
sprite->update(getPt( xa , xb , i ), getPt( ya , yb , i ));
|
|
||||||
if (i >= 1)
|
|
||||||
{
|
|
||||||
sprite->trailFade();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note->isActive(offset))
|
|
||||||
return Value::ACTIVE;
|
|
||||||
|
|
||||||
return value();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int ClassicNoteFlyingState::getPt(float n1, float n2, float perc) const
|
|
||||||
{
|
|
||||||
float diff = n2 - n1;
|
|
||||||
return n1 + (diff * perc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicNoteFlyingState::onEntering(const ClassicNote* note)
|
|
||||||
{
|
|
||||||
const auto& coordinates = note->getCoordinates();
|
|
||||||
const auto& sprite = note->sprite();
|
|
||||||
|
|
||||||
sprite->setCoordinates(coordinates.x, coordinates.y,
|
|
||||||
coordinates.x + 20, coordinates.y - 600);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#ifndef CLASSICNOTEFLYINGSTATE_H
|
|
||||||
#define CLASSICNOTEFLYINGSTATE_H
|
|
||||||
|
|
||||||
#include "classicnotestate.h"
|
|
||||||
|
|
||||||
class ClassicNoteFlyingState : public ClassicNoteState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Value value() const override;
|
|
||||||
virtual Value update(const ClassicNote* note, const microsec& offset) override;
|
|
||||||
virtual void onEntering(const ClassicNote* note) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline constexpr int getPt(float n1 , float n2 , float perc) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLASSICNOTEFLYINGSTATE_H
|
|
|
@ -1,20 +0,0 @@
|
||||||
#include "classicnotenonestate.h"
|
|
||||||
#include "../classicnote.h"
|
|
||||||
#include "../classicsprite.h"
|
|
||||||
|
|
||||||
auto ClassicNoteNoneState::value() const -> Value
|
|
||||||
{
|
|
||||||
return Value::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ClassicNoteNoneState::update(const ClassicNote* note, const microsec& offset) -> Value
|
|
||||||
{
|
|
||||||
(void) offset;
|
|
||||||
(void) note;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicNoteNoneState::onEntering(const ClassicNote* note)
|
|
||||||
{
|
|
||||||
note->sprite()->reset();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef CLASSICNOTENONESTATE_H
|
|
||||||
#define CLASSICNOTENONESTATE_H
|
|
||||||
|
|
||||||
#include "classicnotestate.h"
|
|
||||||
|
|
||||||
class ClassicNoteNoneState : public ClassicNoteState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Value value() const override;
|
|
||||||
virtual Value update(const ClassicNote* note, const microsec& offset) override;
|
|
||||||
virtual void onEntering(const ClassicNote* note) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLASSICNOTENONESTATE_H
|
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef CLASSICNOTESTATE_H
|
|
||||||
#define CLASSICNOTESTATE_H
|
|
||||||
|
|
||||||
#include <SFML/System/Clock.hpp>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
|
||||||
|
|
||||||
class ClassicNote;
|
|
||||||
|
|
||||||
class ClassicNoteState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Value
|
|
||||||
{
|
|
||||||
NONE,
|
|
||||||
DYING,
|
|
||||||
FLYING,
|
|
||||||
ACTIVE,
|
|
||||||
|
|
||||||
COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual Value value() const = 0;
|
|
||||||
virtual Value update(const ClassicNote* note, const microsec& offset) = 0;
|
|
||||||
virtual void onEntering(const ClassicNote* note) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CLASSICNOTESTATE_H
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "classicinputtype.h"
|
#include "classicactions.h"
|
||||||
#include "classicsprite.h"
|
#include "classicsprite.h"
|
||||||
|
|
||||||
class ClassicSpriteFactory
|
class ClassicSpriteFactory
|
||||||
|
@ -12,25 +12,25 @@ public:
|
||||||
_font.loadFromFile(font_filename);
|
_font.loadFromFile(font_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<ClassicSprite> create(Action action)
|
inline std::shared_ptr<ClassicSprite> create(Type type)
|
||||||
{
|
{
|
||||||
sf::RectangleShape sprite;
|
sf::RectangleShape sprite;
|
||||||
sprite.setSize({20.f, 20.f});
|
sprite.setSize({20.f, 20.f});
|
||||||
switch (action)
|
switch (type)
|
||||||
{
|
{
|
||||||
case Action::PRESS_UP:
|
case Type::UP:
|
||||||
sprite.setFillColor(sf::Color(255, 0, 0));
|
sprite.setFillColor(sf::Color(255, 0, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Action::PRESS_DOWN:
|
case Type::DOWN:
|
||||||
sprite.setFillColor(sf::Color(0, 255, 0));
|
sprite.setFillColor(sf::Color(0, 255, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Action::PRESS_LEFT:
|
case Type::LEFT:
|
||||||
sprite.setFillColor(sf::Color(0, 0, 255));
|
sprite.setFillColor(sf::Color(0, 0, 255));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Action::PRESS_RIGHT:
|
case Type::RIGHT:
|
||||||
sprite.setFillColor(sf::Color(255, 0, 255));
|
sprite.setFillColor(sf::Color(255, 0, 255));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
#include <iostream>
|
#include "note.h"
|
||||||
#include "classicactions.h"
|
|
||||||
#include "classictimeline.h"
|
#include "classictimeline.h"
|
||||||
#include "classicnote.h"
|
#include <iostream>
|
||||||
#include "spritecontainer.h"
|
|
||||||
#include "classicgraphicsmanager.h"
|
|
||||||
|
|
||||||
#include <SFML/Graphics/RenderTarget.hpp>
|
|
||||||
|
|
||||||
ClassicTimeline::ClassicTimeline()
|
ClassicTimeline::ClassicTimeline()
|
||||||
{
|
{
|
||||||
|
@ -17,40 +12,19 @@ ClassicTimeline::ClassicTimeline()
|
||||||
|
|
||||||
_music.openFromFile(song_filename);
|
_music.openFromFile(song_filename);
|
||||||
_music.setVolume(10);
|
_music.setVolume(10);
|
||||||
|
}
|
||||||
|
|
||||||
microsec starting_beat_offset = 352162;
|
void ClassicTimeline::run(std::vector<Note*>&& notes, const microsec& visibility)
|
||||||
int amount_of_beats = 209;
|
{
|
||||||
microsec interval = 1412162;
|
_visibility_offset = visibility;
|
||||||
microsec tempo_interval = interval / 2;
|
_timeline = std::move(notes);
|
||||||
microsec note_input_offset = 412162 / 3;
|
|
||||||
microsec bpm_iterator = starting_beat_offset;
|
|
||||||
microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
|
||||||
_visibility_offset = note_input_offset * 12;
|
|
||||||
|
|
||||||
_input_intervals = {note_input_offset / 3, note_input_offset / 3 * 2, note_input_offset};
|
|
||||||
|
|
||||||
bpm_iterator += tempo_interval;
|
|
||||||
|
|
||||||
float x = 90.;
|
|
||||||
|
|
||||||
while (bpm_iterator < bpm_end)
|
|
||||||
{
|
|
||||||
_timeline.emplace_back(new ClassicNote(_input_intervals, bpm_iterator, Action::PRESS_UP, {x, 390.}));
|
|
||||||
bpm_iterator += tempo_interval;
|
|
||||||
x += 70;
|
|
||||||
|
|
||||||
if (x >= 1200)
|
|
||||||
x = 90.;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_top_note = _timeline.begin();
|
||||||
expire(_first_visible_note);
|
expire(_first_visible_note);
|
||||||
expire(_last_visible_note);
|
expire(_last_visible_note);
|
||||||
expire(_active_note);
|
expire(_active_note);
|
||||||
_top_note = _timeline.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassicTimeline::run()
|
fetchVisibleNotes();
|
||||||
{
|
|
||||||
_music.play();
|
_music.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,32 +43,33 @@ void ClassicTimeline::clear()
|
||||||
|
|
||||||
void ClassicTimeline::update()
|
void ClassicTimeline::update()
|
||||||
{
|
{
|
||||||
checkCurrentActiveNote();
|
const auto& music_offset = currentMusicOffset();
|
||||||
checkForNextActiveNote();
|
checkCurrentActiveNote(music_offset);
|
||||||
updateVisibleSprites(currentMusicOffset());
|
checkForNextActiveNote(music_offset);
|
||||||
|
updateVisibleSprites(music_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::checkCurrentActiveNote()
|
void ClassicTimeline::checkCurrentActiveNote(const microsec& music_offset)
|
||||||
{
|
{
|
||||||
if (isExpired(_active_note))
|
if (isExpired(_active_note))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto note = *_active_note;
|
auto note = *_active_note;
|
||||||
|
|
||||||
if (!note->isActive())
|
if (!note->isActive(music_offset))
|
||||||
{
|
{
|
||||||
expire(_active_note);
|
expire(_active_note);
|
||||||
++_top_note;
|
++_top_note;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::checkForNextActiveNote()
|
void ClassicTimeline::checkForNextActiveNote(const microsec& music_offset)
|
||||||
{
|
{
|
||||||
if (!isExpired(_active_note))
|
if (!isExpired(_active_note))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto top_note = *_top_note;
|
auto top_note = *_top_note;
|
||||||
if (top_note->isActive())
|
if (top_note->isActive(music_offset))
|
||||||
_active_note = _top_note;
|
_active_note = _top_note;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,14 +110,14 @@ bool ClassicTimeline::isVisiblyClose(const Iterator& iterator, const microsec& m
|
||||||
return ((*iterator)->offset() - _visibility_offset) <= music_offset;
|
return ((*iterator)->offset() - _visibility_offset) <= music_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::fetchVisibleNotes(const std::unique_ptr<ClassicGraphicsManager>& graphics_manager)
|
void ClassicTimeline::fetchVisibleNotes()
|
||||||
{
|
{
|
||||||
const microsec music_offset = currentMusicOffset();
|
const microsec music_offset = currentMusicOffset();
|
||||||
initGraphicsForNewNotes(graphics_manager, music_offset);
|
findLastVisibleNote(music_offset);
|
||||||
discardGraphicsForDeadNotes(graphics_manager);
|
findFirstVisibleNote();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::initGraphicsForNewNotes(const std::unique_ptr<ClassicGraphicsManager>& graphics_manager, const microsec &music_offset)
|
void ClassicTimeline::findLastVisibleNote(const microsec &music_offset)
|
||||||
{
|
{
|
||||||
Iterator note_iterator = _top_note;
|
Iterator note_iterator = _top_note;
|
||||||
while (isVisiblyClose(note_iterator, music_offset))
|
while (isVisiblyClose(note_iterator, music_offset))
|
||||||
|
@ -152,11 +127,8 @@ void ClassicTimeline::initGraphicsForNewNotes(const std::unique_ptr<ClassicGraph
|
||||||
|
|
||||||
auto note = *note_iterator;
|
auto note = *note_iterator;
|
||||||
|
|
||||||
if (!note->sprite())
|
if (note->isExpired())
|
||||||
{
|
|
||||||
graphics_manager->initSprite(note);
|
|
||||||
note->putToGame(music_offset);
|
note->putToGame(music_offset);
|
||||||
}
|
|
||||||
|
|
||||||
++note_iterator;
|
++note_iterator;
|
||||||
}
|
}
|
||||||
|
@ -164,7 +136,7 @@ void ClassicTimeline::initGraphicsForNewNotes(const std::unique_ptr<ClassicGraph
|
||||||
_last_visible_note = note_iterator;
|
_last_visible_note = note_iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::discardGraphicsForDeadNotes(const std::unique_ptr<ClassicGraphicsManager>& graphics_manager)
|
void ClassicTimeline::findFirstVisibleNote()
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
return;
|
return;
|
||||||
|
@ -174,11 +146,7 @@ void ClassicTimeline::discardGraphicsForDeadNotes(const std::unique_ptr<ClassicG
|
||||||
{
|
{
|
||||||
auto note = *note_iterator;
|
auto note = *note_iterator;
|
||||||
if (note->isExpired())
|
if (note->isExpired())
|
||||||
{
|
|
||||||
graphics_manager->resetSprite(note);
|
|
||||||
|
|
||||||
++_first_visible_note;
|
++_first_visible_note;
|
||||||
}
|
|
||||||
|
|
||||||
++note_iterator;
|
++note_iterator;
|
||||||
}
|
}
|
||||||
|
@ -189,15 +157,15 @@ bool ClassicTimeline::nothingToDraw() const noexcept
|
||||||
return isExpired(_first_visible_note);
|
return isExpired(_first_visible_note);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::drawVisibleNotes(sf::RenderWindow &window) const
|
void ClassicTimeline::drawVisibleNotes() const
|
||||||
{
|
{
|
||||||
if (nothingToDraw())
|
if (nothingToDraw())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::for_each(_first_visible_note, _last_visible_note,
|
std::for_each(_first_visible_note, _last_visible_note,
|
||||||
[&window](const auto& note)
|
[](const auto& note)
|
||||||
{
|
{
|
||||||
window.draw(*note);
|
note->draw();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "timeline.h"
|
||||||
|
|
||||||
|
#include <SFML/Audio/Music.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "timeline.h"
|
|
||||||
#include <SFML/Audio/Music.hpp>
|
|
||||||
|
|
||||||
class ClassicGraphicsManager;
|
class Note;
|
||||||
class ClassicNote;
|
|
||||||
|
|
||||||
class ClassicTimeline : public Timeline
|
class ClassicTimeline : public Timeline
|
||||||
{
|
{
|
||||||
|
@ -14,17 +14,15 @@ public:
|
||||||
explicit ClassicTimeline();
|
explicit ClassicTimeline();
|
||||||
virtual ~ClassicTimeline();
|
virtual ~ClassicTimeline();
|
||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void run() override;
|
virtual void run(std::vector<Note*>&& notes, const microsec& visibility) override;
|
||||||
virtual void clear() override;
|
virtual void clear() override;
|
||||||
|
|
||||||
virtual microsec currentMusicOffset() const override;
|
virtual microsec currentMusicOffset() const override;
|
||||||
virtual void drawVisibleNotes(sf::RenderWindow& window) const override;
|
virtual void drawVisibleNotes() const override;
|
||||||
|
|
||||||
void fetchVisibleNotes(const std::unique_ptr<ClassicGraphicsManager>& graphics_manager);
|
void fetchVisibleNotes();
|
||||||
void initGraphicsForNewNotes(const std::unique_ptr<ClassicGraphicsManager>& graphics_manager, const microsec& music_offset);
|
void findLastVisibleNote(const microsec& music_offset);
|
||||||
void discardGraphicsForDeadNotes(const std::unique_ptr<ClassicGraphicsManager>& graphics_manager);
|
void findFirstVisibleNote();
|
||||||
|
|
||||||
using Iterator = std::vector<ClassicNote*>::const_iterator;
|
|
||||||
|
|
||||||
Iterator getActiveNote() noexcept;
|
Iterator getActiveNote() noexcept;
|
||||||
|
|
||||||
|
@ -33,14 +31,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<microsec> _input_intervals;
|
std::vector<microsec> _input_intervals;
|
||||||
std::vector<ClassicNote*> _timeline;
|
std::vector<Note*> _timeline;
|
||||||
microsec _visibility_offset;
|
microsec _visibility_offset;
|
||||||
|
|
||||||
sf::Music _music;
|
sf::Music _music;
|
||||||
|
|
||||||
void updateVisibleSprites(const microsec& music_offset);
|
void updateVisibleSprites(const microsec& music_offset);
|
||||||
void checkCurrentActiveNote();
|
void checkCurrentActiveNote(const microsec& music_offset);
|
||||||
void checkForNextActiveNote();
|
void checkForNextActiveNote(const microsec& music_offset);
|
||||||
bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const;
|
bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const;
|
||||||
inline bool nothingToDraw() const noexcept;
|
inline bool nothingToDraw() const noexcept;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#include "inputtype.h"
|
|
||||||
|
|
||||||
InputType::InputType(const microsec ×tamp) :
|
|
||||||
_timestamp(timestamp)
|
|
||||||
{}
|
|
||||||
|
|
||||||
InputType::~InputType()
|
|
||||||
{}
|
|
||||||
|
|
||||||
const microsec& InputType::timestamp() const
|
|
||||||
{
|
|
||||||
return _timestamp;
|
|
||||||
}
|
|
|
@ -1,8 +1,5 @@
|
||||||
#include <iostream>
|
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Application app;
|
Application app;
|
||||||
|
|
Loading…
Reference in New Issue