mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-23 16:17:53 -05:00
Redo note positioning
This commit is contained in:
parent
ae76b24a65
commit
140afd3c31
2 changed files with 84 additions and 55 deletions
|
@ -175,8 +175,11 @@ class ChartEditorNoteSprite extends FlxSprite
|
|||
this.x = cursorColumn * ChartEditorState.GRID_SIZE;
|
||||
|
||||
// Notes far in the song will start far down, but the group they belong to will have a high negative offset.
|
||||
// TODO: stepTime doesn't account for fluctuating BPMs.
|
||||
if (this.noteData.stepTime >= 0) this.y = this.noteData.stepTime * ChartEditorState.GRID_SIZE;
|
||||
if (this.noteData.stepTime >= 0)
|
||||
{
|
||||
// noteData.stepTime is a calculated value which accounts for BPM changes
|
||||
this.y = this.noteData.stepTime * ChartEditorState.GRID_SIZE;
|
||||
}
|
||||
|
||||
if (origin != null)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package funkin.ui.debug.charting;
|
||||
|
||||
import funkin.util.SortUtil;
|
||||
import funkin.ui.debug.charting.ChartEditorCommand;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
import funkin.input.TurboKeyHandler;
|
||||
|
@ -172,29 +173,35 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
/**
|
||||
* scrollPosition, converted to steps.
|
||||
* TODO: Handle BPM changes.
|
||||
* NOT dependant on BPM, because the size of a grid square does not change with BPM.
|
||||
*/
|
||||
var scrollPositionInSteps(get, null):Float;
|
||||
var scrollPositionInSteps(get, set):Float;
|
||||
|
||||
function get_scrollPositionInSteps():Float
|
||||
{
|
||||
return scrollPositionInPixels / GRID_SIZE;
|
||||
}
|
||||
|
||||
function set_scrollPositionInSteps(value:Float):Float
|
||||
{
|
||||
scrollPositionInPixels = value * GRID_SIZE;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* scrollPosition, converted to milliseconds.
|
||||
* TODO: Handle BPM changes.
|
||||
* DEPENDANT on BPM, because the duration of a grid square changes with BPM.
|
||||
*/
|
||||
var scrollPositionInMs(get, set):Float;
|
||||
|
||||
function get_scrollPositionInMs():Float
|
||||
{
|
||||
return scrollPositionInSteps * Conductor.stepLengthMs;
|
||||
return Conductor.getStepTimeInMs(scrollPositionInSteps);
|
||||
}
|
||||
|
||||
function set_scrollPositionInMs(value:Float):Float
|
||||
{
|
||||
scrollPositionInPixels = value / Conductor.stepLengthMs;
|
||||
scrollPositionInSteps = Conductor.getTimeInSteps(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -206,11 +213,26 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
var playheadPositionInPixels(default, set):Float;
|
||||
|
||||
var playheadPositionInSteps(get, null):Float;
|
||||
function set_playheadPositionInPixels(value:Float):Float
|
||||
{
|
||||
// Make sure playhead doesn't go outside the song.
|
||||
if (value + scrollPositionInPixels < 0) value = -scrollPositionInPixels;
|
||||
if (value + scrollPositionInPixels > songLengthInPixels) value = songLengthInPixels - scrollPositionInPixels;
|
||||
|
||||
this.playheadPositionInPixels = value;
|
||||
|
||||
// Move the playhead sprite to the correct position.
|
||||
gridPlayhead.y = this.playheadPositionInPixels + (MENU_BAR_HEIGHT + GRID_TOP_PAD);
|
||||
|
||||
return this.playheadPositionInPixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* playheadPosition, converted to steps.
|
||||
* NOT dependant on BPM, because the size of a grid square does not change with BPM.
|
||||
*/
|
||||
var playheadPositionInSteps(get, null):Float;
|
||||
|
||||
function get_playheadPositionInSteps():Float
|
||||
{
|
||||
return playheadPositionInPixels / GRID_SIZE;
|
||||
|
@ -218,60 +240,76 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
/**
|
||||
* playheadPosition, converted to milliseconds.
|
||||
* DEPENDANT on BPM, because the duration of a grid square changes with BPM.
|
||||
*/
|
||||
var playheadPositionInMs(get, null):Float;
|
||||
|
||||
function get_playheadPositionInMs():Float
|
||||
{
|
||||
return playheadPositionInSteps * Conductor.stepLengthMs;
|
||||
return Conductor.getStepTimeInMs(playheadPositionInSteps);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the song's length in PIXELS, same format as scrollPosition.
|
||||
* songLength, in milliseconds.
|
||||
*/
|
||||
var songLengthInPixels(get, default):Int;
|
||||
@:isVar var songLengthInMs(get, set):Float;
|
||||
|
||||
function get_songLengthInPixels():Int
|
||||
function get_songLengthInMs():Float
|
||||
{
|
||||
if (songLengthInPixels <= 0) return 1000;
|
||||
if (songLengthInMs <= 0) return 1000;
|
||||
return songLengthInMs;
|
||||
}
|
||||
|
||||
return songLengthInPixels;
|
||||
function set_songLengthInMs(value:Float):Float
|
||||
{
|
||||
this.songLengthInMs = value;
|
||||
|
||||
// Make sure playhead doesn't go outside the song.
|
||||
if (playheadPositionInMs > songLengthInMs) playheadPositionInMs = songLengthInMs;
|
||||
|
||||
return this.songLengthInMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* songLength, converted to steps.
|
||||
* TODO: Handle BPM changes.
|
||||
* Dependant on BPM, because the size of a grid square does not change with BPM but the length of a beat does.
|
||||
*/
|
||||
var songLengthInSteps(get, set):Float;
|
||||
|
||||
function get_songLengthInSteps():Float
|
||||
{
|
||||
return songLengthInPixels / GRID_SIZE;
|
||||
return Conductor.getTimeInSteps(songLengthInMs);
|
||||
}
|
||||
|
||||
function set_songLengthInSteps(value:Float):Float
|
||||
{
|
||||
songLengthInPixels = Std.int(value * GRID_SIZE);
|
||||
// Getting a reasonable result from setting songLengthInSteps requires that Conductor.mapBPMChanges be called first.
|
||||
songLengthInMs = Conductor.getStepTimeInMs(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* songLength, converted to milliseconds.
|
||||
* TODO: Handle BPM changes.
|
||||
* This is the song's length in PIXELS, same format as scrollPosition.
|
||||
* Dependant on BPM, because the size of a grid square does not change with BPM but the length of a beat does.
|
||||
*/
|
||||
var songLengthInMs(get, set):Float;
|
||||
var songLengthInPixels(get, set):Int;
|
||||
|
||||
function get_songLengthInMs():Float
|
||||
function get_songLengthInPixels():Int
|
||||
{
|
||||
return songLengthInSteps * Conductor.stepLengthMs;
|
||||
return Std.int(songLengthInSteps * GRID_SIZE);
|
||||
}
|
||||
|
||||
function set_songLengthInMs(value:Float):Float
|
||||
function set_songLengthInPixels(value:Int):Int
|
||||
{
|
||||
songLengthInSteps = Conductor.getTimeInSteps(audioInstTrack.length);
|
||||
songLengthInSteps = value / GRID_SIZE;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current theme used by the editor.
|
||||
* Dictates the appearance of many UI elements.
|
||||
* Currently hardcoded to just Light and Dark.
|
||||
*/
|
||||
var currentTheme(default, set):ChartEditorTheme = null;
|
||||
|
||||
function set_currentTheme(value:ChartEditorTheme):ChartEditorTheme
|
||||
|
@ -1667,7 +1705,8 @@ class ChartEditorState extends HaxeUIState
|
|||
// The song position of the cursor, in steps.
|
||||
var cursorFractionalStep:Float = cursorY / GRID_SIZE / (16 / noteSnapQuant);
|
||||
var cursorStep:Int = Std.int(Math.floor(cursorFractionalStep));
|
||||
var cursorMs:Float = cursorStep * Conductor.stepLengthMs * (16 / noteSnapQuant);
|
||||
var cursorMs:Float = Conductor.getStepTimeInMs(cursorStep);
|
||||
trace('${cursorFractionalStep} ${cursorStep} ${cursorMs}');
|
||||
// The direction value for the column at the cursor.
|
||||
var cursorColumn:Int = Math.floor(cursorX / GRID_SIZE);
|
||||
if (cursorColumn < 0) cursorColumn = 0;
|
||||
|
@ -1705,7 +1744,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// We released the mouse. Select the notes in the box.
|
||||
var cursorFractionalStepStart:Float = cursorYStart / GRID_SIZE;
|
||||
var cursorStepStart:Int = Math.floor(cursorFractionalStepStart);
|
||||
var cursorMsStart:Float = cursorStepStart * Conductor.stepLengthMs;
|
||||
var cursorMsStart:Float = Conductor.getStepTimeInMs(cursorStepStart);
|
||||
var cursorColumnBase:Int = Math.floor(cursorX / GRID_SIZE);
|
||||
var cursorColumnBaseStart:Int = Math.floor(cursorXStart / GRID_SIZE);
|
||||
|
||||
|
@ -1877,12 +1916,13 @@ class ChartEditorState extends HaxeUIState
|
|||
{
|
||||
// Handle extending the note as you drag.
|
||||
|
||||
// Since use Math.floor and stepLengthMs here, the hold notes will be beat snapped.
|
||||
var dragLengthSteps:Float = Math.floor((cursorMs - currentPlaceNoteData.time) / Conductor.stepLengthMs);
|
||||
// TODO: This should be beat snapped?
|
||||
var dragLengthSteps:Float = Conductor.getTimeInSteps(cursorMs) - currentPlaceNoteData.stepTime;
|
||||
|
||||
// Without this, the newly placed note feels too short compared to the user's input.
|
||||
var INCREMENT:Float = 1.0;
|
||||
var dragLengthMs:Float = (dragLengthSteps + INCREMENT) * Conductor.stepLengthMs;
|
||||
// TODO: Make this not busted with BPM changes
|
||||
var dragLengthMs:Float = Math.floor(dragLengthSteps + INCREMENT) * Conductor.stepLengthMs;
|
||||
|
||||
// TODO: Add and update some sort of preview?
|
||||
|
||||
|
@ -2187,7 +2227,7 @@ class ChartEditorState extends HaxeUIState
|
|||
}
|
||||
|
||||
// Get the position the note should be at.
|
||||
var noteTimePixels:Float = noteData.time / Conductor.stepLengthMs * GRID_SIZE;
|
||||
var noteTimePixels:Float = noteData.stepTime * GRID_SIZE;
|
||||
|
||||
// Make sure the note appears when scrolling up.
|
||||
var modifiedViewAreaTop = viewAreaTop - GRID_SIZE;
|
||||
|
@ -2209,11 +2249,11 @@ class ChartEditorState extends HaxeUIState
|
|||
noteSprite.x += renderedNotes.x;
|
||||
noteSprite.y += renderedNotes.y;
|
||||
|
||||
// TODO: Replace this with SustainTrail.
|
||||
if (noteSprite.noteData.length > 0)
|
||||
{
|
||||
// If the note is a hold, we need to make sure it's long enough.
|
||||
var noteLengthMs:Float = noteSprite.noteData.length;
|
||||
var noteLengthSteps:Float = (noteLengthMs / Conductor.stepLengthMs);
|
||||
var noteLengthSteps:Float = noteSprite.noteData.stepLength;
|
||||
var lastNoteSprite:ChartEditorNoteSprite = noteSprite;
|
||||
|
||||
while (noteLengthSteps > 0)
|
||||
|
@ -2252,7 +2292,7 @@ class ChartEditorState extends HaxeUIState
|
|||
}
|
||||
|
||||
// Get the position the event should be at.
|
||||
var eventTimePixels:Float = eventData.time / Conductor.stepLengthMs * GRID_SIZE;
|
||||
var eventTimePixels:Float = eventData.stepTime * GRID_SIZE;
|
||||
|
||||
// Make sure the event appears when scrolling up.
|
||||
var modifiedViewAreaTop = viewAreaTop - GRID_SIZE;
|
||||
|
@ -2264,7 +2304,7 @@ class ChartEditorState extends HaxeUIState
|
|||
// Get an event sprite from the pool.
|
||||
// If we can reuse a deleted event, do so.
|
||||
// If a new event is needed, call buildEventSprite.
|
||||
var eventSprite:ChartEditorEventSprite = renderedEvents.recycle(() -> new ChartEditorEventSprite(this));
|
||||
var eventSprite:ChartEditorEventSprite = renderedEvents.recycle(() -> new ChartEditorEventSprite(this), false, true);
|
||||
eventSprite.parentState = this;
|
||||
|
||||
// The event sprite handles animation playback and positioning.
|
||||
|
@ -2655,7 +2695,7 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
function handleNotePreview():Void
|
||||
{
|
||||
//
|
||||
// TODO: Finish this.
|
||||
if (notePreviewDirty)
|
||||
{
|
||||
notePreviewDirty = false;
|
||||
|
@ -2924,25 +2964,6 @@ class ChartEditorState extends HaxeUIState
|
|||
return this.scrollPositionInPixels;
|
||||
}
|
||||
|
||||
function get_playheadPositionInPixels():Float
|
||||
{
|
||||
return this.playheadPositionInPixels;
|
||||
}
|
||||
|
||||
function set_playheadPositionInPixels(value:Float):Float
|
||||
{
|
||||
// Make sure playhead doesn't go outside the song.
|
||||
if (value + scrollPositionInPixels < 0) value = -scrollPositionInPixels;
|
||||
if (value + scrollPositionInPixels > songLengthInPixels) value = songLengthInPixels - scrollPositionInPixels;
|
||||
|
||||
this.playheadPositionInPixels = value;
|
||||
|
||||
// Move the playhead sprite to the correct position.
|
||||
gridPlayhead.y = this.playheadPositionInPixels + (MENU_BAR_HEIGHT + GRID_TOP_PAD);
|
||||
|
||||
return this.playheadPositionInPixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an instrumental from an absolute file path, replacing the current instrumental.
|
||||
*
|
||||
|
@ -3102,7 +3123,12 @@ class ChartEditorState extends HaxeUIState
|
|||
Conductor.mapTimeChanges(currentSongMetadata.timeChanges);
|
||||
|
||||
loadInstrumentalFromAsset(Paths.inst(songId));
|
||||
loadVocalsFromAsset(Paths.voices(songId));
|
||||
|
||||
var voiceList:Array<String> = song.getDifficulty(selectedDifficulty).buildVoiceList();
|
||||
for (voicePath in voiceList)
|
||||
{
|
||||
loadVocalsFromAsset(voicePath);
|
||||
}
|
||||
|
||||
NotificationManager.instance.addNotification(
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue