diff --git a/assets/songs/json/mary.json b/assets/songs/json/mary.json index bf07e33..e30839b 100644 --- a/assets/songs/json/mary.json +++ b/assets/songs/json/mary.json @@ -55,6 +55,9 @@ }, "name": "Melody 2", "notes": [ + {"duration": 0.5, "durationTicks": 480, "midi": 64, "name": "E4", "ticks": 0, "time": 0, "velocity": 0.7874015748031497}, + {"duration": 0.5, "durationTicks": 480, "midi": 62, "name": "D4", "ticks": 480, "time": 0.5, "velocity": 0.7874015748031497}, + {"duration": 0.5, "durationTicks": 480, "midi": 60, "name": "C4", "ticks": 960, "time": 1, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 62, "name": "D4", "ticks": 1440, "time": 1.5, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 64, "name": "E4", "ticks": 1920, "time": 2, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 64, "name": "E4", "ticks": 2400, "time": 2.5, "velocity": 0.7874015748031497}, @@ -75,6 +78,8 @@ }, "name": "Melody 3", "notes": [ + {"duration": 0.5, "durationTicks": 480, "midi": 62, "name": "D4", "ticks": 480, "time": 0.5, "velocity": 0.7874015748031497}, + {"duration": 0.5, "durationTicks": 480, "midi": 60, "name": "C4", "ticks": 960, "time": 1, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 62, "name": "D4", "ticks": 3840, "time": 4, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 62, "name": "D4", "ticks": 4320, "time": 4.5, "velocity": 0.7874015748031497}, {"duration": 1, "durationTicks": 960, "midi": 62, "name": "D4", "ticks": 4800, "time": 5, "velocity": 0.7874015748031497} @@ -94,6 +99,7 @@ }, "name": "Melody 4", "notes": [ + {"duration": 0.5, "durationTicks": 480, "midi": 60, "name": "C4", "ticks": 960, "time": 1, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 64, "name": "E4", "ticks": 5760, "time": 6, "velocity": 0.7874015748031497}, {"duration": 0.5, "durationTicks": 480, "midi": 67, "name": "G4", "ticks": 6240, "time": 6.5, "velocity": 0.7874015748031497}, {"duration": 1, "durationTicks": 960, "midi": 67, "name": "G4", "ticks": 6720, "time": 7, "velocity": 0.7874015748031497} diff --git a/src/samples/ghhb_game.h b/src/samples/ghhb_game.h index dd99116..c0420d8 100644 --- a/src/samples/ghhb_game.h +++ b/src/samples/ghhb_game.h @@ -18,6 +18,7 @@ constexpr int MAX_GAMEPADS = 4; constexpr int MAX_INSTRUMENT_TYPES = MAX_GAMEPADS; constexpr float RECEPTOR_HEIGHT = 150.0f; constexpr float HIT_ZONE_MARGIN = 20.0f; +constexpr float SIMULTANEOUS_NOTE_Y_TOLERANCE = 2.0f; constexpr float SCROLL_PX_PER_SEC = 350.0f; constexpr float LEAD_OFFSET_SECONDS = 3.0f; @@ -500,6 +501,10 @@ public: { continue; } + if (!lane_pressed_by_instrument_owner(lane, n->instrument_slot)) + { + continue; + } float y = glyph_y(*n); float d = fabsf(y - hit_line_y); if (d < best_dist) @@ -510,12 +515,9 @@ public: } if (best != nullptr) { - if (lane_pressed_by_instrument_owner(lane, best->instrument_slot)) - { - consume_note(best); - } + consume_note(best); } - else if (is_lane_pressed(lane)) + else { combo = 0; score = std::max(0, score - 25); @@ -595,6 +597,7 @@ public: button_label_font_size, 1, Color{220, 220, 240, 255}); } + std::vector> by_lane(static_cast(LANE_COUNT)); for (Glyph* n : spawned) { float y = glyph_y(*n); @@ -602,13 +605,45 @@ public: { continue; } - float cx = lane_center_x(n->lane); - Color fill = INSTRUMENT_COLORS[n->instrument_slot]; - Color edge = Color{static_cast(std::min(255, fill.r + 35)), - static_cast(std::min(255, fill.g + 50)), - static_cast(std::min(255, fill.b + 50)), 255}; - DrawCircle(static_cast(cx), static_cast(y), 22, fill); - DrawCircleLines(static_cast(cx), static_cast(y), 22, edge); + by_lane[static_cast(n->lane)].push_back(n); + } + for (int lane = 0; lane < LANE_COUNT; lane++) + { + std::vector& list = by_lane[static_cast(lane)]; + std::sort(list.begin(), list.end(), + [this](Glyph* a, Glyph* b) { return glyph_y(*a) < glyph_y(*b); }); + float left_base = lane * lane_width; + for (size_t i = 0; i < list.size();) + { + size_t j = i; + float y0 = glyph_y(*list[i]); + while (j < list.size() && + glyph_y(*list[j]) - y0 <= SIMULTANEOUS_NOTE_Y_TOLERANCE) + { + j++; + } + int group_count = static_cast(j - i); + float slice_width = lane_width / static_cast(group_count); + float glyph_height = lane_width / 2.0f; + for (int k = 0; k < group_count; k++) + { + Glyph* n = list[i + static_cast(k)]; + float y = glyph_y(*n); + float left = left_base + k * slice_width; + float top = y - glyph_height / 2.0f; + Color fill = INSTRUMENT_COLORS[n->instrument_slot]; + Color edge = Color{ + static_cast(std::min(255, fill.r + 35)), + static_cast(std::min(255, fill.g + 50)), + static_cast(std::min(255, fill.b + 50)), 255}; + DrawRectangle(static_cast(left), static_cast(top), + static_cast(slice_width), + static_cast(glyph_height), fill); + DrawRectangleLinesEx( + Rectangle{left, top, slice_width, glyph_height}, 2.0f, edge); + } + i = j; + } } std::string score_text = "Score: " + std::to_string(score) + " Combo: " + std::to_string(combo);