Added bottom bar labels. Delayed start of MIDI glyphs.
This commit is contained in:
parent
0133fc9f14
commit
a092de9d35
@ -14,23 +14,27 @@ namespace
|
||||
constexpr int LANE_COUNT = 12;
|
||||
constexpr int MAX_INSTRUMENT_TYPES = 8;
|
||||
constexpr int MAX_GAMEPADS = 4;
|
||||
constexpr float HIT_WINDOW_PX = 80.0f;
|
||||
constexpr float RECEPTOR_HEIGHT = 100.0f;
|
||||
constexpr float RECEPTOR_HEIGHT = 150.0f;
|
||||
constexpr float SCROLL_PX_PER_SEC = 350.0f;
|
||||
constexpr float LEAD_OFFSET_SECONDS = 3.0f;
|
||||
|
||||
const int GAMEPAD_BUTTONS[LANE_COUNT] = {
|
||||
GAMEPAD_BUTTON_LEFT_FACE_LEFT,
|
||||
GAMEPAD_BUTTON_LEFT_FACE_UP,
|
||||
GAMEPAD_BUTTON_LEFT_FACE_RIGHT,
|
||||
GAMEPAD_BUTTON_LEFT_FACE_DOWN,
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_LEFT,
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_UP,
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_RIGHT,
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_DOWN,
|
||||
GAMEPAD_BUTTON_LEFT_TRIGGER_2,
|
||||
GAMEPAD_BUTTON_LEFT_TRIGGER_1,
|
||||
GAMEPAD_BUTTON_RIGHT_TRIGGER_1,
|
||||
GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
|
||||
GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Left
|
||||
GAMEPAD_BUTTON_LEFT_FACE_UP, // Up
|
||||
GAMEPAD_BUTTON_LEFT_FACE_RIGHT, // Right
|
||||
GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Down
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // X
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_UP, // Y
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // B
|
||||
GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // A
|
||||
GAMEPAD_BUTTON_LEFT_TRIGGER_2, // LT
|
||||
GAMEPAD_BUTTON_LEFT_TRIGGER_1, // LB
|
||||
GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // RB
|
||||
GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // RT
|
||||
};
|
||||
|
||||
const char* const GAMEPAD_BUTTON_LABELS[LANE_COUNT] = {
|
||||
"<", "^", ">", "v", "X", "Y", "B", "A", "LT", "LB", "RB", "RT",
|
||||
};
|
||||
|
||||
const int KEY_KEYS[LANE_COUNT] = {
|
||||
@ -187,8 +191,10 @@ public:
|
||||
std::vector<Glyph*> spawned;
|
||||
std::unordered_set<Glyph*> completed_notes;
|
||||
float song_time = 0.0f;
|
||||
float chart_time_offset = 0.0f;
|
||||
int score = 0;
|
||||
int combo = 0;
|
||||
float upper_bar_y = 0.0f;
|
||||
float hit_line_y = 0.0f;
|
||||
float lane_width = 0.0f;
|
||||
float screen_width = 0.0f;
|
||||
@ -222,6 +228,10 @@ public:
|
||||
{
|
||||
StopMusicStream(music);
|
||||
PlayMusicStream(music);
|
||||
if (chart_time_offset < 0.0f)
|
||||
{
|
||||
SeekMusicStream(music, -chart_time_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,6 +272,7 @@ public:
|
||||
font = font_manager->get_font("Roboto");
|
||||
screen_width = static_cast<float>(GetScreenWidth());
|
||||
screen_height = static_cast<float>(GetScreenHeight());
|
||||
upper_bar_y = screen_height - RECEPTOR_HEIGHT;
|
||||
hit_line_y = screen_height - RECEPTOR_HEIGHT / 2.0f;
|
||||
lane_width = screen_width / LANE_COUNT;
|
||||
for (int slot = 0; slot < MAX_INSTRUMENT_TYPES; slot++)
|
||||
@ -277,6 +288,13 @@ public:
|
||||
}
|
||||
}
|
||||
chart = load_chart(GHHB_CHART_PATH);
|
||||
float first_note_time = 0.0f;
|
||||
if (!chart.empty())
|
||||
{
|
||||
first_note_time = chart.front().time;
|
||||
float lead_seconds = (hit_line_y - 60.0f) / SCROLL_PX_PER_SEC;
|
||||
chart_time_offset = lead_seconds + LEAD_OFFSET_SECONDS - first_note_time;
|
||||
}
|
||||
background = add_game_object<Background>();
|
||||
background->add_tag("background");
|
||||
}
|
||||
@ -318,10 +336,15 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
float glyph_y(const Glyph& n) const
|
||||
{
|
||||
return hit_line_y - (n.time + chart_time_offset - song_time) * SCROLL_PX_PER_SEC;
|
||||
}
|
||||
|
||||
bool is_note_hittable(const Glyph& n) const
|
||||
{
|
||||
float y = n.y_position(song_time, hit_line_y);
|
||||
return fabsf(y - hit_line_y) <= HIT_WINDOW_PX;
|
||||
float y = glyph_y(n);
|
||||
return y >= upper_bar_y && y <= hit_line_y;
|
||||
}
|
||||
|
||||
void consume_note(Glyph* n)
|
||||
@ -363,12 +386,13 @@ public:
|
||||
float last_note_time = 0.0f;
|
||||
for (const auto& n : chart)
|
||||
{
|
||||
if (n.time > last_note_time)
|
||||
float t = n.time + chart_time_offset;
|
||||
if (t > last_note_time)
|
||||
{
|
||||
last_note_time = n.time;
|
||||
last_note_time = t;
|
||||
}
|
||||
}
|
||||
float note_exit_seconds = HIT_WINDOW_PX / SCROLL_PX_PER_SEC;
|
||||
float note_exit_seconds = (hit_line_y - upper_bar_y) / SCROLL_PX_PER_SEC;
|
||||
if (song_time >= last_note_time + note_exit_seconds + RESULTS_DELAY_AFTER_LAST_NOTE)
|
||||
{
|
||||
game_ended = true;
|
||||
@ -384,7 +408,7 @@ public:
|
||||
}
|
||||
bool already = std::find_if(spawned.begin(), spawned.end(),
|
||||
[&n](Glyph* p) { return p == &n; }) != spawned.end();
|
||||
if (!already && song_time >= n.time - lead_seconds)
|
||||
if (!already && song_time >= n.time + chart_time_offset - lead_seconds)
|
||||
{
|
||||
spawned.push_back(&n);
|
||||
}
|
||||
@ -393,7 +417,7 @@ public:
|
||||
for (auto it = spawned.begin(); it != spawned.end();)
|
||||
{
|
||||
Glyph* n = *it;
|
||||
float y = n->y_position(song_time, hit_line_y);
|
||||
float y = glyph_y(*n);
|
||||
if (y > hit_line_y)
|
||||
{
|
||||
miss_flash_timer[n->lane] = MISS_FLASH_DURATION;
|
||||
@ -443,7 +467,7 @@ public:
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float y = n->y_position(song_time, hit_line_y);
|
||||
float y = glyph_y(*n);
|
||||
float d = fabsf(y - hit_line_y);
|
||||
if (d < best_dist)
|
||||
{
|
||||
@ -483,9 +507,8 @@ public:
|
||||
DrawLineEx(Vector2{cx, 0}, Vector2{cx, screen_height}, 2.0f, Color{70, 70, 90, 255});
|
||||
}
|
||||
|
||||
float receptor_top = screen_height - RECEPTOR_HEIGHT;
|
||||
DrawRectangle(0,
|
||||
static_cast<int>(receptor_top),
|
||||
static_cast<int>(upper_bar_y),
|
||||
static_cast<int>(screen_width),
|
||||
static_cast<int>(RECEPTOR_HEIGHT),
|
||||
Color{60, 60, 100, 255});
|
||||
@ -495,7 +518,7 @@ public:
|
||||
{
|
||||
float alpha = 180.0f * (hit_flash_timer[lane] / PRESS_FLASH_DURATION);
|
||||
DrawRectangle(static_cast<int>(lane * lane_width),
|
||||
static_cast<int>(receptor_top),
|
||||
static_cast<int>(upper_bar_y),
|
||||
static_cast<int>(lane_width),
|
||||
static_cast<int>(RECEPTOR_HEIGHT),
|
||||
Color{80, 255, 120, static_cast<unsigned char>(alpha)});
|
||||
@ -504,7 +527,7 @@ public:
|
||||
{
|
||||
float alpha = 180.0f * (press_flash_timer[lane] / PRESS_FLASH_DURATION);
|
||||
DrawRectangle(static_cast<int>(lane * lane_width),
|
||||
static_cast<int>(receptor_top),
|
||||
static_cast<int>(upper_bar_y),
|
||||
static_cast<int>(lane_width),
|
||||
static_cast<int>(RECEPTOR_HEIGHT),
|
||||
Color{255, 255, 255, static_cast<unsigned char>(alpha)});
|
||||
@ -513,17 +536,30 @@ public:
|
||||
{
|
||||
float alpha = 200.0f * (miss_flash_timer[lane] / MISS_FLASH_DURATION);
|
||||
DrawRectangle(static_cast<int>(lane * lane_width),
|
||||
static_cast<int>(receptor_top),
|
||||
static_cast<int>(upper_bar_y),
|
||||
static_cast<int>(lane_width),
|
||||
static_cast<int>(RECEPTOR_HEIGHT),
|
||||
Color{255, 80, 80, static_cast<unsigned char>(alpha)});
|
||||
}
|
||||
}
|
||||
DrawLineEx(Vector2{0, upper_bar_y}, Vector2{screen_width, upper_bar_y}, 3.0f, WHITE);
|
||||
DrawLineEx(Vector2{0, hit_line_y}, Vector2{screen_width, hit_line_y}, 3.0f, WHITE);
|
||||
|
||||
const float button_label_font_size = 28.0f;
|
||||
const float button_label_y = hit_line_y + 18.0f;
|
||||
for (int lane = 0; lane < LANE_COUNT; lane++)
|
||||
{
|
||||
const char* label = GAMEPAD_BUTTON_LABELS[lane];
|
||||
float label_w = MeasureTextEx(font, label, button_label_font_size, 1).x;
|
||||
float cx = lane_center_x(lane);
|
||||
DrawTextEx(font, label,
|
||||
{cx - label_w / 2.0f, button_label_y},
|
||||
button_label_font_size, 1, Color{220, 220, 240, 255});
|
||||
}
|
||||
|
||||
for (Glyph* n : spawned)
|
||||
{
|
||||
float y = n->y_position(song_time, hit_line_y);
|
||||
float y = glyph_y(*n);
|
||||
if (y < -40.0f || y > screen_height + 40.0f)
|
||||
{
|
||||
continue;
|
||||
@ -539,8 +575,8 @@ public:
|
||||
|
||||
std::string score_text = "Score: " + std::to_string(score) + " Combo: " + std::to_string(combo);
|
||||
DrawTextEx(font, score_text.c_str(), {20, 16}, 28, 1, WHITE);
|
||||
DrawTextEx(font, "Arrows / D-pad / X Y A B / LB LT RB RT: hit when note reaches white line",
|
||||
{20, receptor_top - 28}, 18, 1, Color{200, 200, 200, 255});
|
||||
DrawTextEx(font, "Arrows / D-pad / X Y A B / LB LT RB RT: hit when note is between the two white lines",
|
||||
{20, upper_bar_y - 28}, 18, 1, Color{200, 200, 200, 255});
|
||||
|
||||
if (game_ended)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user