Update every columns's color up to the current one instead of trying to be efficient
This commit is contained in:
parent
1b72bc0a50
commit
114527fb4d
2
TODO.md
2
TODO.md
@ -13,6 +13,8 @@
|
|||||||
- Density Graph
|
- Density Graph
|
||||||
- White line
|
- White line
|
||||||
- Cursor
|
- Cursor
|
||||||
|
- Fix some columns not being hit
|
||||||
|
- mouse clicks highlights don't fade away
|
||||||
|
|
||||||
## Results Screen
|
## Results Screen
|
||||||
|
|
||||||
|
@ -76,6 +76,8 @@ sources = [
|
|||||||
'src/Screens/MusicSelect/Resources.cpp',
|
'src/Screens/MusicSelect/Resources.cpp',
|
||||||
'src/Screens/MusicSelect/SongInfo.hpp',
|
'src/Screens/MusicSelect/SongInfo.hpp',
|
||||||
'src/Screens/MusicSelect/SongInfo.cpp',
|
'src/Screens/MusicSelect/SongInfo.cpp',
|
||||||
|
'src/Screens/Gameplay/Drawables/Cursor.hpp',
|
||||||
|
'src/Screens/Gameplay/Drawables/Cursor.cpp',
|
||||||
'src/Screens/Gameplay/Gameplay.hpp',
|
'src/Screens/Gameplay/Gameplay.hpp',
|
||||||
'src/Screens/Gameplay/Gameplay.cpp',
|
'src/Screens/Gameplay/Gameplay.cpp',
|
||||||
'src/Screens/Gameplay/PreciseMusic.hpp',
|
'src/Screens/Gameplay/PreciseMusic.hpp',
|
||||||
|
@ -76,18 +76,7 @@ namespace Data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sf::Time Chart::get_last_event_timing() const {
|
sf::Time Chart::get_last_event_timing() const {
|
||||||
if (notes.empty()) {
|
return get_time_bounds_from_notes().end;
|
||||||
return sf::Time::Zero;
|
|
||||||
} else {
|
|
||||||
const auto& last_note = *std::max_element(
|
|
||||||
notes.begin(),
|
|
||||||
notes.end(),
|
|
||||||
[](const Data::Note& a, const Data::Note& b) -> bool {
|
|
||||||
return a.timing+a.duration < b.timing+b.duration;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return last_note.timing + last_note.duration;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeBounds Data::Chart::get_time_bounds_from_notes() const {
|
TimeBounds Data::Chart::get_time_bounds_from_notes() const {
|
||||||
|
@ -17,7 +17,7 @@ namespace Data {
|
|||||||
std::set<Note> notes;
|
std::set<Note> notes;
|
||||||
std::size_t resolution;
|
std::size_t resolution;
|
||||||
// get the time at which the very last scorable event happens
|
// get the time at which the very last scorable event happens
|
||||||
// (i.e. including long note releases)
|
// (i.e. note tap or long note release)
|
||||||
sf::Time get_last_event_timing() const;
|
sf::Time get_last_event_timing() const;
|
||||||
// get the time interval covered by the notes, including offset zero
|
// get the time interval covered by the notes, including offset zero
|
||||||
TimeBounds get_time_bounds_from_notes() const;
|
TimeBounds get_time_bounds_from_notes() const;
|
||||||
|
@ -41,8 +41,10 @@ namespace Data {
|
|||||||
return Judgement::Great;
|
return Judgement::Great;
|
||||||
} else if (delta_abs < sf::milliseconds(162)) {
|
} else if (delta_abs < sf::milliseconds(162)) {
|
||||||
return Judgement::Good;
|
return Judgement::Good;
|
||||||
} else {
|
} else if (delta_abs < sf::milliseconds(533)) {
|
||||||
return Judgement::Poor;
|
return Judgement::Poor;
|
||||||
|
} else {
|
||||||
|
return Judgement::Miss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,7 @@ namespace Data {
|
|||||||
if (m.openFromFile(*song.full_audio_path())) {
|
if (m.openFromFile(*song.full_audio_path())) {
|
||||||
time_bounds += {sf::Time::Zero, m.getDuration()};
|
time_bounds += {sf::Time::Zero, m.getDuration()};
|
||||||
}
|
}
|
||||||
|
time_bounds.end += sf::seconds(1);
|
||||||
return time_bounds;
|
return time_bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +55,11 @@ namespace Data {
|
|||||||
const Data::Song& song;
|
const Data::Song& song;
|
||||||
const std::string& difficulty;
|
const std::string& difficulty;
|
||||||
|
|
||||||
// get the total play time for this chart :
|
// Get the total play interval for this chart :
|
||||||
// if there's no audio and no notes, one second starting at sf::Time::Zero
|
// if there's no audio and no notes, returns a one second inteval starting at sf::Time::Zero
|
||||||
// else the start bounds is either zero or the first note if for some reason it happens before 0s
|
// otherwise the start bound is either zero or the first note if for some reason it happens before 0s
|
||||||
// and the end bound is either the end of the song of the last timing event if a note or the
|
// and the end bound is either the end of the song of the last timing event if a note or the
|
||||||
// release of a long note happen after the audio ends
|
// release of a long note happens after the audio ends
|
||||||
TimeBounds get_time_bounds() const;
|
TimeBounds get_time_bounds() const;
|
||||||
|
|
||||||
bool operator==(const SongDifficulty &other) const {
|
bool operator==(const SongDifficulty &other) const {
|
||||||
|
@ -36,7 +36,7 @@ namespace Drawables {
|
|||||||
);
|
);
|
||||||
m_vertex_array.insert(m_vertex_array.end(), bar.begin(), bar.end());
|
m_vertex_array.insert(m_vertex_array.end(), bar.begin(), bar.end());
|
||||||
}
|
}
|
||||||
target.draw(m_vertex_array.data(), m_vertex_array.size(), sf::Quads);
|
target.draw(m_vertex_array.data(), m_vertex_array.size(), sf::Quads, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<sf::Vertex, 4> make_solid_quad(const sf::FloatRect& rect, const sf::Color& color) {
|
std::array<sf::Vertex, 4> make_solid_quad(const sf::FloatRect& rect, const sf::Color& color) {
|
||||||
|
@ -56,8 +56,14 @@ namespace Drawables {
|
|||||||
115.f
|
115.f
|
||||||
};
|
};
|
||||||
for (auto &¬e : chart.notes) {
|
for (auto &¬e : chart.notes) {
|
||||||
auto index = static_cast<unsigned int>(ticks_to_column.transform(note.timing.asSeconds()));
|
auto index = static_cast<std::size_t>(ticks_to_column.transform(note.timing.asSeconds()));
|
||||||
d.at(index) += 1;
|
d.at(index) += 1;
|
||||||
|
if (note.duration > sf::Time::Zero) {
|
||||||
|
auto long_note_end_index = static_cast<std::size_t>(
|
||||||
|
ticks_to_column.transform((note.timing+note.duration).asSeconds())
|
||||||
|
);
|
||||||
|
d.at(long_note_end_index) += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::replace_if(
|
std::replace_if(
|
||||||
d.begin(),
|
d.begin(),
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include <imgui-sfml/imgui-SFML.h>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
|
||||||
namespace Drawables {
|
namespace Drawables {
|
||||||
|
|
||||||
DensityLineGrade judgement_to_density_line_grade(Data::Judgement judge) {
|
DensityLineGrade judgement_to_density_line_grade(Data::Judgement judge) {
|
||||||
switch (judge) {
|
switch (judge) {
|
||||||
case Data::Judgement::Perfect:
|
case Data::Judgement::Perfect:
|
||||||
@ -52,56 +53,11 @@ namespace Drawables {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Toolkit::AffineTransform<float> get_seconds_to_column_transform_from_notes(const Data::Chart& chart) {
|
|
||||||
auto time_bounds = chart.get_time_bounds_from_notes();
|
|
||||||
// only one timing point
|
|
||||||
if (time_bounds.start == time_bounds.end) {
|
|
||||||
// give one extra second
|
|
||||||
return Toolkit::AffineTransform<float>(
|
|
||||||
time_bounds.start.asSeconds(),
|
|
||||||
(time_bounds.start + sf::seconds(1)).asSeconds(),
|
|
||||||
0.f,
|
|
||||||
115.f
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// at least two timing points
|
|
||||||
return Toolkit::AffineTransform<float>(
|
|
||||||
time_bounds.start.asSeconds(),
|
|
||||||
time_bounds.end.asSeconds(),
|
|
||||||
0.f,
|
|
||||||
115.f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toolkit::AffineTransform<float> get_seconds_to_column_transform(const Data::SongDifficulty& sd) {
|
Toolkit::AffineTransform<float> get_seconds_to_column_transform(const Data::SongDifficulty& sd) {
|
||||||
auto chart = sd.song.get_chart(sd.difficulty);
|
auto bounds = sd.get_time_bounds();
|
||||||
if (not chart) {
|
|
||||||
throw std::invalid_argument("Song "+sd.song.title+" has no '"+sd.difficulty+"' chart");
|
|
||||||
}
|
|
||||||
// no notes, no need to return something useful
|
|
||||||
if (chart->notes.empty()) {
|
|
||||||
return Toolkit::AffineTransform<float>(0.f, 1.f, 0.f, 115.f);
|
|
||||||
}
|
|
||||||
// no audio
|
|
||||||
if (not sd.song.audio) {
|
|
||||||
return get_seconds_to_column_transform_from_notes(*chart);
|
|
||||||
}
|
|
||||||
sf::Music m;
|
|
||||||
// can't open audio
|
|
||||||
if (not m.openFromFile(*sd.song.full_audio_path())) {
|
|
||||||
return get_seconds_to_column_transform_from_notes(*chart);
|
|
||||||
}
|
|
||||||
// both notes and audio exist
|
|
||||||
auto time_bounds = chart->get_time_bounds_from_notes();
|
|
||||||
return Toolkit::AffineTransform<float>(
|
return Toolkit::AffineTransform<float>(
|
||||||
time_bounds.start.asSeconds(),
|
bounds.start.asSeconds(),
|
||||||
sf::microseconds(
|
bounds.end.asSeconds(),
|
||||||
std::max(
|
|
||||||
time_bounds.end.asMicroseconds(),
|
|
||||||
m.getDuration().asMicroseconds()
|
|
||||||
)
|
|
||||||
).asSeconds(),
|
|
||||||
0.f,
|
0.f,
|
||||||
115.f
|
115.f
|
||||||
);
|
);
|
||||||
@ -148,19 +104,21 @@ namespace Drawables {
|
|||||||
for (size_t i = 0; i < index_of_first_vertex_of_each_column.size(); i++) {
|
for (size_t i = 0; i < index_of_first_vertex_of_each_column.size(); i++) {
|
||||||
m_densities.at(i).first_vertex = std::next(it, index_of_first_vertex_of_each_column.at(i));
|
m_densities.at(i).first_vertex = std::next(it, index_of_first_vertex_of_each_column.at(i));
|
||||||
}
|
}
|
||||||
first_non_played_density = m_densities.begin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GradedDensityGraph::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
void GradedDensityGraph::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||||
states.transform *= getTransform();
|
states.transform *= getTransform();
|
||||||
target.draw(&m_vertex_array[0], m_vertex_array.size(), sf::Quads, states);
|
target.draw(&m_vertex_array[0], m_vertex_array.size(), sf::Quads, states);
|
||||||
|
if (debug) {
|
||||||
|
draw_debug();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GradedDensityGraph::update(const sf::Time& music_time) {
|
void GradedDensityGraph::update(const sf::Time& music_time) {
|
||||||
const auto float_column = m_seconds_to_column.transform(music_time.asSeconds());
|
const auto float_column = m_seconds_to_column.transform(music_time.asSeconds());
|
||||||
const auto current_column = static_cast<std::size_t>(float_column);
|
const auto current_column = static_cast<std::size_t>(float_column);
|
||||||
const auto current_column_it = std::next(m_densities.begin(), current_column);
|
const auto current_column_it = std::next(m_densities.begin(), current_column);
|
||||||
for (auto it = first_non_played_density; it != current_column_it; ++it) {
|
for (auto it = m_densities.begin(); it != current_column_it; ++it) {
|
||||||
auto color = grade_to_color(it->grade);
|
auto color = grade_to_color(it->grade);
|
||||||
auto next = std::next(it);
|
auto next = std::next(it);
|
||||||
std::vector<sf::Vertex>::iterator next_vertex_it;
|
std::vector<sf::Vertex>::iterator next_vertex_it;
|
||||||
@ -173,7 +131,6 @@ namespace Drawables {
|
|||||||
vertex_it->color = color;
|
vertex_it->color = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first_non_played_density = current_column_it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GradedDensityGraph::update_grades(const Data::Judgement& judge, const sf::Time& timing) {
|
void GradedDensityGraph::update_grades(const Data::Judgement& judge, const sf::Time& timing) {
|
||||||
@ -183,11 +140,31 @@ namespace Drawables {
|
|||||||
current_grade = merge_grades(current_grade, judgement_to_density_line_grade(judge));
|
current_grade = merge_grades(current_grade, judgement_to_density_line_grade(judge));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
sf::FloatRect GradedDensityGraph::getLocalBounds() const {
|
||||||
|
return sf::FloatRect({0, 0}, {(115*5)-1, 39});
|
||||||
|
}
|
||||||
|
|
||||||
namespace Toolkit {
|
sf::FloatRect GradedDensityGraph::getGlobalBounds() const {
|
||||||
template<>
|
return getTransform().transformRect(getLocalBounds());
|
||||||
void set_origin_normalized(Drawables::GradedDensityGraph& s, float x, float y) {
|
}
|
||||||
s.setOrigin(x*574.f, y*39.f);
|
|
||||||
|
void Drawables::GradedDensityGraph::draw_debug() const {
|
||||||
|
if (ImGui::Begin("GradedDensityGraph")) {
|
||||||
|
auto orig_x = ImGui::GetCursorPosX();
|
||||||
|
auto pos = ImGui::GetCursorPos();
|
||||||
|
for (size_t line = 0; line < m_densities.size(); line++) {
|
||||||
|
const auto& graded_density = m_densities.at(line);
|
||||||
|
auto color = grade_to_color(graded_density.grade);
|
||||||
|
for (size_t column = 0; column < graded_density.density; column++) {
|
||||||
|
ImGui::SetCursorPos(pos);
|
||||||
|
ImGui::DrawRectFilled({{0,0}, {4,4}}, color);
|
||||||
|
pos.x += 5;
|
||||||
|
}
|
||||||
|
pos.x = orig_x;
|
||||||
|
pos.y += 5;
|
||||||
|
}
|
||||||
|
ImGui::Dummy({8*5, 115*5});
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "../Data/GradedNote.hpp"
|
#include "../Data/GradedNote.hpp"
|
||||||
#include "../Data/Song.hpp"
|
#include "../Data/Song.hpp"
|
||||||
#include "../Toolkit/AffineTransform.hpp"
|
#include "../Toolkit/AffineTransform.hpp"
|
||||||
#include "../Toolkit/Cache.hpp"
|
#include "../Toolkit/Debuggable.hpp"
|
||||||
#include "../Toolkit/SFMLHelpers.hpp"
|
#include "../Toolkit/SFMLHelpers.hpp"
|
||||||
#include "DensityGraph.hpp"
|
#include "DensityGraph.hpp"
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ namespace Drawables {
|
|||||||
ComboBreak,
|
ComboBreak,
|
||||||
NonGraded
|
NonGraded
|
||||||
};
|
};
|
||||||
|
|
||||||
DensityLineGrade judgement_to_density_line_grade(Data::Judgement judge);
|
DensityLineGrade judgement_to_density_line_grade(Data::Judgement judge);
|
||||||
DensityLineGrade merge_grades(DensityLineGrade current, DensityLineGrade _new);
|
DensityLineGrade merge_grades(DensityLineGrade current, DensityLineGrade _new);
|
||||||
sf::Color grade_to_color(DensityLineGrade grade);
|
sf::Color grade_to_color(DensityLineGrade grade);
|
||||||
@ -35,27 +35,24 @@ namespace Drawables {
|
|||||||
std::vector<sf::Vertex>::iterator first_vertex;
|
std::vector<sf::Vertex>::iterator first_vertex;
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper functions for GradedDensityGraph
|
// helper function for GradedDensityGraph
|
||||||
Toolkit::AffineTransform<float> get_seconds_to_column_transform_from_notes(const Data::Chart& chart);
|
|
||||||
Toolkit::AffineTransform<float> get_seconds_to_column_transform(const Data::SongDifficulty& sd);
|
Toolkit::AffineTransform<float> get_seconds_to_column_transform(const Data::SongDifficulty& sd);
|
||||||
|
|
||||||
class GradedDensityGraph : public sf::Drawable, public sf::Transformable {
|
class GradedDensityGraph : public sf::Drawable, public sf::Transformable, public Toolkit::Debuggable {
|
||||||
public:
|
public:
|
||||||
explicit GradedDensityGraph(const DensityGraph& density_graph, const Data::SongDifficulty& sd);
|
explicit GradedDensityGraph(const DensityGraph& density_graph, const Data::SongDifficulty& sd);
|
||||||
// Set verticies colors for density columns that have already been played
|
// Set verticies colors for density columns that have already been played
|
||||||
void update(const sf::Time& music_time);
|
void update(const sf::Time& music_time);
|
||||||
// Update stored grades according to the recieved judgement
|
// Update stored grades according to the recieved judgement
|
||||||
void update_grades(const Data::Judgement& judge, const sf::Time& timing);
|
void update_grades(const Data::Judgement& judge, const sf::Time& timing);
|
||||||
|
sf::FloatRect getLocalBounds() const;
|
||||||
|
sf::FloatRect getGlobalBounds() const;
|
||||||
|
|
||||||
|
void draw_debug() const;
|
||||||
private:
|
private:
|
||||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
std::array<GradedDensity, 115> m_densities;
|
std::array<GradedDensity, 115> m_densities;
|
||||||
std::vector<sf::Vertex> m_vertex_array;
|
std::vector<sf::Vertex> m_vertex_array;
|
||||||
std::array<GradedDensity, 115>::iterator first_non_played_density;
|
|
||||||
Toolkit::AffineTransform<float> m_seconds_to_column;
|
Toolkit::AffineTransform<float> m_seconds_to_column;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace Toolkit {
|
|
||||||
template<>
|
|
||||||
void set_origin_normalized(Drawables::GradedDensityGraph& s, float x, float y);
|
|
||||||
}
|
}
|
37
src/Screens/Gameplay/Drawables/Cursor.cpp
Normal file
37
src/Screens/Gameplay/Drawables/Cursor.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "Cursor.hpp"
|
||||||
|
|
||||||
|
namespace Drawables {
|
||||||
|
Cursor::Cursor() {
|
||||||
|
m_vertex_array = {
|
||||||
|
sf::Vertex{
|
||||||
|
sf::Vector2f(1.f, 0.f),
|
||||||
|
sf::Color::White
|
||||||
|
},
|
||||||
|
sf::Vertex{
|
||||||
|
sf::Vector2f(1.f, 1.f),
|
||||||
|
sf::Color::White
|
||||||
|
},
|
||||||
|
sf::Vertex{
|
||||||
|
sf::Vector2f(0.f, 1.f),
|
||||||
|
sf::Color::Transparent
|
||||||
|
},
|
||||||
|
sf::Vertex{
|
||||||
|
sf::Vector2f(0.f, 0.f),
|
||||||
|
sf::Color::Transparent
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::FloatRect Cursor::getLocalBounds() const {
|
||||||
|
return sf::FloatRect{{0.f,0.f}, {1.f,1.f}};
|
||||||
|
}
|
||||||
|
|
||||||
|
sf::FloatRect Cursor::getGlobalBounds() const {
|
||||||
|
return getTransform().transformRect(getLocalBounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cursor::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||||
|
states.transform *= getTransform();
|
||||||
|
target.draw(&m_vertex_array[0], m_vertex_array.size(), sf::Quads, states);
|
||||||
|
}
|
||||||
|
}
|
18
src/Screens/Gameplay/Drawables/Cursor.hpp
Normal file
18
src/Screens/Gameplay/Drawables/Cursor.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
namespace Drawables {
|
||||||
|
// Small thingy that scrolls atop the graded density graph to indicate how far we are in the song
|
||||||
|
class Cursor : public sf::Drawable, public sf::Transformable {
|
||||||
|
public:
|
||||||
|
Cursor();
|
||||||
|
sf::FloatRect getLocalBounds() const;
|
||||||
|
sf::FloatRect getGlobalBounds() const;
|
||||||
|
private:
|
||||||
|
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
|
std::array<sf::Vertex, 4> m_vertex_array;
|
||||||
|
};
|
||||||
|
}
|
@ -154,13 +154,20 @@ namespace Gameplay {
|
|||||||
window.draw(line);
|
window.draw(line);
|
||||||
|
|
||||||
// Density Graph
|
// Density Graph
|
||||||
Toolkit::set_origin_normalized(graded_density_graph, 0.5f, 1.f);
|
Toolkit::set_local_origin_normalized(graded_density_graph, 0.5f, 1.f);
|
||||||
graded_density_graph.setScale(get_screen_width()/768.f, get_screen_width()/768.f);
|
graded_density_graph.setScale(get_screen_width()/768.f, get_screen_width()/768.f);
|
||||||
graded_density_graph.setPosition(get_screen_width()*0.5f,423.f/768.f*get_screen_width());
|
graded_density_graph.setPosition(get_screen_width()*0.5f,423.f/768.f*get_screen_width());
|
||||||
window.draw(graded_density_graph);
|
window.draw(graded_density_graph);
|
||||||
|
|
||||||
// Cursor on the density graph
|
// Cursor on the density graph
|
||||||
|
Toolkit::set_local_origin_normalized(cursor, 1.f, 0.f);
|
||||||
|
auto bounds = graded_density_graph.getGlobalBounds();
|
||||||
|
cursor.setScale(bounds.height, bounds.height);
|
||||||
|
cursor.setPosition(
|
||||||
|
bounds.left+music_time_to_progression.transform(music_time.asSeconds())*bounds.width,
|
||||||
|
bounds.top
|
||||||
|
);
|
||||||
|
window.draw(cursor);
|
||||||
|
|
||||||
|
|
||||||
// Draw Combo
|
// Draw Combo
|
||||||
@ -448,6 +455,7 @@ namespace Gameplay {
|
|||||||
switch (*key) {
|
switch (*key) {
|
||||||
case sf::Keyboard::F12:
|
case sf::Keyboard::F12:
|
||||||
debug = not debug;
|
debug = not debug;
|
||||||
|
graded_density_graph.debug = not graded_density_graph.debug;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -487,6 +495,12 @@ namespace Gameplay {
|
|||||||
score.update(judgement);
|
score.update(judgement);
|
||||||
graded_density_graph.update_grades(judgement, note.timing);
|
graded_density_graph.update_grades(judgement, note.timing);
|
||||||
if (Data::judgement_breaks_combo(judgement)) {
|
if (Data::judgement_breaks_combo(judgement)) {
|
||||||
|
// If we've broken combo at the begining of a long we also missed the end
|
||||||
|
if (note.duration > sf::Time::Zero) {
|
||||||
|
note.long_release = Data::TimedJudgement{sf::Time::Zero, Data::Judgement::Miss};
|
||||||
|
score.update(Data::Judgement::Miss);
|
||||||
|
graded_density_graph.update_grades(Data::Judgement::Miss, note.timing+note.duration);
|
||||||
|
}
|
||||||
combo = 0;
|
combo = 0;
|
||||||
} else {
|
} else {
|
||||||
combo++;
|
combo++;
|
||||||
@ -538,6 +552,11 @@ namespace Gameplay {
|
|||||||
note.tap_judgement = timed_judgement;
|
note.tap_judgement = timed_judgement;
|
||||||
score.update(Data::Judgement::Miss);
|
score.update(Data::Judgement::Miss);
|
||||||
graded_density_graph.update_grades(Data::Judgement::Miss, note.timing);
|
graded_density_graph.update_grades(Data::Judgement::Miss, note.timing);
|
||||||
|
if (note.duration > sf::Time::Zero) {
|
||||||
|
note.long_release = timed_judgement;
|
||||||
|
score.update(Data::Judgement::Miss);
|
||||||
|
graded_density_graph.update_grades(Data::Judgement::Miss, note.timing+note.duration);
|
||||||
|
}
|
||||||
combo = 0;
|
combo = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,7 +569,7 @@ namespace Gameplay {
|
|||||||
(note.duration > sf::Time::Zero)
|
(note.duration > sf::Time::Zero)
|
||||||
and (note.timing + note.duration < music_time)
|
and (note.timing + note.duration < music_time)
|
||||||
and note.tap_judgement.has_value()
|
and note.tap_judgement.has_value()
|
||||||
and note.tap_judgement->judgement != Data::Judgement::Miss
|
and not Data::judgement_breaks_combo(note.tap_judgement->judgement)
|
||||||
and (not note.long_release.has_value())
|
and (not note.long_release.has_value())
|
||||||
) {
|
) {
|
||||||
auto timed_judgement = Data::TimedJudgement{sf::Time::Zero, Data::Judgement::Perfect};
|
auto timed_judgement = Data::TimedJudgement{sf::Time::Zero, Data::Judgement::Perfect};
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "AbstractMusic.hpp"
|
#include "AbstractMusic.hpp"
|
||||||
#include "Resources.hpp"
|
#include "Resources.hpp"
|
||||||
#include "TimedEventsQueue.hpp"
|
#include "TimedEventsQueue.hpp"
|
||||||
|
#include "Drawables/Cursor.hpp"
|
||||||
|
|
||||||
namespace Gameplay {
|
namespace Gameplay {
|
||||||
class Screen : public Toolkit::Debuggable, public HoldsResources {
|
class Screen : public Toolkit::Debuggable, public HoldsResources {
|
||||||
@ -49,7 +50,7 @@ namespace Gameplay {
|
|||||||
const Resources::LNMarker& ln_marker;
|
const Resources::LNMarker& ln_marker;
|
||||||
std::unique_ptr<AbstractMusic> music;
|
std::unique_ptr<AbstractMusic> music;
|
||||||
Drawables::GradedDensityGraph graded_density_graph;
|
Drawables::GradedDensityGraph graded_density_graph;
|
||||||
std::array<sf::Vertex, 4> cursor;
|
Drawables::Cursor cursor;
|
||||||
// maps music time to [0, 1]
|
// maps music time to [0, 1]
|
||||||
Toolkit::AffineTransform<float> music_time_to_progression;
|
Toolkit::AffineTransform<float> music_time_to_progression;
|
||||||
|
|
||||||
|
29
test/imgui-sfml-demo.cpp
Normal file
29
test/imgui-sfml-demo.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include <imgui-sfml/imgui-SFML.h>
|
||||||
|
|
||||||
|
#include <SFML/Graphics/RenderWindow.hpp>
|
||||||
|
#include <SFML/System/Clock.hpp>
|
||||||
|
#include <SFML/Window/Event.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
sf::RenderWindow window(sf::VideoMode(640, 480), "imgui-sfml-demo");
|
||||||
|
window.setVerticalSyncEnabled(true);
|
||||||
|
ImGui::SFML::Init(window);
|
||||||
|
window.resetGLStates(); // call it if you only draw ImGui. Otherwise not needed.
|
||||||
|
sf::Clock deltaClock;
|
||||||
|
while (window.isOpen()) {
|
||||||
|
sf::Event event;
|
||||||
|
while (window.pollEvent(event)) {
|
||||||
|
ImGui::SFML::ProcessEvent(event);
|
||||||
|
if (event.type == sf::Event::Closed) {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SFML::Update(window, deltaClock.restart());
|
||||||
|
window.clear(sf::Color::Transparent); // fill background with color
|
||||||
|
ImGui::ShowDemoWindow();
|
||||||
|
ImGui::SFML::Render(window);
|
||||||
|
window.display();
|
||||||
|
}
|
||||||
|
ImGui::SFML::Shutdown();
|
||||||
|
}
|
@ -1,5 +1,21 @@
|
|||||||
test_files = []
|
test_files = []
|
||||||
|
|
||||||
|
imgui_demo = executable(
|
||||||
|
'imgui_demo.out',
|
||||||
|
[
|
||||||
|
'imgui-sfml-demo.cpp',
|
||||||
|
'../include/imgui/imgui.cpp',
|
||||||
|
'../include/imgui/imgui_demo.cpp',
|
||||||
|
'../include/imgui/imgui_draw.cpp',
|
||||||
|
'../include/imgui/imgui_widgets.cpp',
|
||||||
|
'../include/imgui-sfml/imgui-SFML.cpp'
|
||||||
|
],
|
||||||
|
dependencies : dependencies,
|
||||||
|
include_directories: inc
|
||||||
|
)
|
||||||
|
|
||||||
|
test('Able to build imgui demo', imgui_demo)
|
||||||
|
|
||||||
foreach test_file : test_files
|
foreach test_file : test_files
|
||||||
test_executable = executable(
|
test_executable = executable(
|
||||||
test_file+'.out',
|
test_file+'.out',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user