mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-04-10 22:34:17 +00:00
Fix for BPM changes, plus working on hold note rendering
This commit is contained in:
parent
c56517f94f
commit
16e3bfe85e
|
@ -316,7 +316,8 @@ class Conductor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultStep += Math.floor((ms - lastTimeChange.timeStamp) / stepLengthMs);
|
var resultFractionalStep:Float = (ms - lastTimeChange.timeStamp) / stepLengthMs;
|
||||||
|
resultStep += resultFractionalStep; // Math.floor();
|
||||||
|
|
||||||
return resultStep;
|
return resultStep;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,6 @@ class ChartEditorNoteSprite extends FlxSprite
|
||||||
*/
|
*/
|
||||||
public var noteStyle(get, null):String;
|
public var noteStyle(get, null):String;
|
||||||
|
|
||||||
/**
|
|
||||||
* This note is the previous sprite in a sustain chain.
|
|
||||||
*/
|
|
||||||
public var parentNoteSprite(default, set):ChartEditorNoteSprite = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This note is the next sprite in a sustain chain.
|
|
||||||
*/
|
|
||||||
public var childNoteSprite(default, set):ChartEditorNoteSprite = null;
|
|
||||||
|
|
||||||
public function new(parent:ChartEditorState)
|
public function new(parent:ChartEditorState)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
@ -124,14 +114,6 @@ class ChartEditorNoteSprite extends FlxSprite
|
||||||
|
|
||||||
if (this.noteData == null)
|
if (this.noteData == null)
|
||||||
{
|
{
|
||||||
// Disown parent.
|
|
||||||
this.parentNoteSprite = null;
|
|
||||||
if (this.childNoteSprite != null)
|
|
||||||
{
|
|
||||||
// Kill all children and disown them.
|
|
||||||
this.childNoteSprite.noteData = null;
|
|
||||||
this.childNoteSprite = null;
|
|
||||||
}
|
|
||||||
this.kill();
|
this.kill();
|
||||||
return this.noteData;
|
return this.noteData;
|
||||||
}
|
}
|
||||||
|
@ -170,71 +152,22 @@ class ChartEditorNoteSprite extends FlxSprite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentNoteSprite == null)
|
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.
|
||||||
|
if (this.noteData.stepTime >= 0)
|
||||||
{
|
{
|
||||||
this.x = cursorColumn * ChartEditorState.GRID_SIZE;
|
// noteData.stepTime is a calculated value which accounts for BPM changes
|
||||||
|
var stepTime:Float = this.noteData.stepTime;
|
||||||
// Notes far in the song will start far down, but the group they belong to will have a high negative offset.
|
var roundedStepTime:Float = Math.floor(stepTime + 0.01); // Add epsilon to fix rounding issues
|
||||||
if (this.noteData.stepTime >= 0)
|
this.y = roundedStepTime * ChartEditorState.GRID_SIZE;
|
||||||
{
|
|
||||||
// noteData.stepTime is a calculated value which accounts for BPM changes
|
|
||||||
this.y = this.noteData.stepTime * ChartEditorState.GRID_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (origin != null)
|
|
||||||
{
|
|
||||||
this.x += origin.x;
|
|
||||||
this.y += origin.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If this is a hold note, we need to adjust the position to be centered.
|
|
||||||
if (parentNoteSprite.parentNoteSprite == null)
|
|
||||||
{
|
|
||||||
this.x = parentNoteSprite.x;
|
|
||||||
this.x += (ChartEditorState.GRID_SIZE / 2);
|
|
||||||
this.x -= this.width / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.x = parentNoteSprite.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.y = parentNoteSprite.y;
|
|
||||||
if (parentNoteSprite.parentNoteSprite == null)
|
|
||||||
{
|
|
||||||
this.y += parentNoteSprite.height / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.y += parentNoteSprite.height - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function set_parentNoteSprite(value:ChartEditorNoteSprite):ChartEditorNoteSprite
|
|
||||||
{
|
|
||||||
this.parentNoteSprite = value;
|
|
||||||
|
|
||||||
if (this.parentNoteSprite != null)
|
|
||||||
{
|
|
||||||
this.noteData = this.parentNoteSprite.noteData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.parentNoteSprite;
|
if (origin != null)
|
||||||
}
|
|
||||||
|
|
||||||
function set_childNoteSprite(value:ChartEditorNoteSprite):ChartEditorNoteSprite
|
|
||||||
{
|
|
||||||
this.childNoteSprite = value;
|
|
||||||
|
|
||||||
if (this.parentNoteSprite != null)
|
|
||||||
{
|
{
|
||||||
this.noteData = this.parentNoteSprite.noteData;
|
this.x += origin.x;
|
||||||
|
this.y += origin.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.childNoteSprite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_noteStyle():String
|
function get_noteStyle():String
|
||||||
|
@ -247,7 +180,6 @@ class ChartEditorNoteSprite extends FlxSprite
|
||||||
{
|
{
|
||||||
// Decide whether to display a note or a sustain.
|
// Decide whether to display a note or a sustain.
|
||||||
var baseAnimationName:String = 'tap';
|
var baseAnimationName:String = 'tap';
|
||||||
if (this.parentNoteSprite != null) baseAnimationName = (this.childNoteSprite != null) ? 'hold' : 'holdEnd';
|
|
||||||
|
|
||||||
// Play the appropriate animation for the type, direction, and skin.
|
// Play the appropriate animation for the type, direction, and skin.
|
||||||
var animationName:String = '${baseAnimationName}${this.noteData.getDirectionName()}${this.noteStyle}';
|
var animationName:String = '${baseAnimationName}${this.noteData.getDirectionName()}${this.noteStyle}';
|
||||||
|
@ -260,17 +192,6 @@ class ChartEditorNoteSprite extends FlxSprite
|
||||||
{
|
{
|
||||||
case 'tap':
|
case 'tap':
|
||||||
this.setGraphicSize(0, ChartEditorState.GRID_SIZE);
|
this.setGraphicSize(0, ChartEditorState.GRID_SIZE);
|
||||||
case 'hold':
|
|
||||||
if (parentNoteSprite.parentNoteSprite == null)
|
|
||||||
{
|
|
||||||
this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), Std.int(ChartEditorState.GRID_SIZE / 2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), ChartEditorState.GRID_SIZE);
|
|
||||||
}
|
|
||||||
case 'holdEnd':
|
|
||||||
this.setGraphicSize(Std.int(ChartEditorState.GRID_SIZE / 2), Std.int(ChartEditorState.GRID_SIZE / 2));
|
|
||||||
}
|
}
|
||||||
this.updateHitbox();
|
this.updateHitbox();
|
||||||
|
|
||||||
|
@ -294,11 +215,4 @@ class ChartEditorNoteSprite extends FlxSprite
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBaseNoteSprite()
|
|
||||||
{
|
|
||||||
if (this.parentNoteSprite == null) return this;
|
|
||||||
else
|
|
||||||
return this.parentNoteSprite;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package funkin.ui.debug.charting;
|
package funkin.ui.debug.charting;
|
||||||
|
|
||||||
|
import funkin.graphics.rendering.SustainTrail;
|
||||||
import funkin.util.SortUtil;
|
import funkin.util.SortUtil;
|
||||||
import funkin.ui.debug.charting.ChartEditorCommand;
|
import funkin.ui.debug.charting.ChartEditorCommand;
|
||||||
import flixel.input.keyboard.FlxKey;
|
import flixel.input.keyboard.FlxKey;
|
||||||
|
@ -944,6 +945,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
*/
|
*/
|
||||||
var renderedNotes:FlxTypedSpriteGroup<ChartEditorNoteSprite>;
|
var renderedNotes:FlxTypedSpriteGroup<ChartEditorNoteSprite>;
|
||||||
|
|
||||||
|
var renderedHoldNotes:FlxTypedSpriteGroup<SustainTrail>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sprite group containing the song events.
|
* The sprite group containing the song events.
|
||||||
* Only displays a subset of the data from `currentSongChartEventData`,
|
* Only displays a subset of the data from `currentSongChartEventData`,
|
||||||
|
@ -1706,7 +1709,6 @@ class ChartEditorState extends HaxeUIState
|
||||||
var cursorFractionalStep:Float = cursorY / GRID_SIZE / (16 / noteSnapQuant);
|
var cursorFractionalStep:Float = cursorY / GRID_SIZE / (16 / noteSnapQuant);
|
||||||
var cursorStep:Int = Std.int(Math.floor(cursorFractionalStep));
|
var cursorStep:Int = Std.int(Math.floor(cursorFractionalStep));
|
||||||
var cursorMs:Float = Conductor.getStepTimeInMs(cursorStep);
|
var cursorMs:Float = Conductor.getStepTimeInMs(cursorStep);
|
||||||
trace('${cursorFractionalStep} ${cursorStep} ${cursorMs}');
|
|
||||||
// The direction value for the column at the cursor.
|
// The direction value for the column at the cursor.
|
||||||
var cursorColumn:Int = Math.floor(cursorX / GRID_SIZE);
|
var cursorColumn:Int = Math.floor(cursorX / GRID_SIZE);
|
||||||
if (cursorColumn < 0) cursorColumn = 0;
|
if (cursorColumn < 0) cursorColumn = 0;
|
||||||
|
@ -1858,8 +1860,7 @@ class ChartEditorState extends HaxeUIState
|
||||||
{
|
{
|
||||||
if (highlightedNote != null)
|
if (highlightedNote != null)
|
||||||
{
|
{
|
||||||
// Handle the case of clicking on a sustain piece.
|
// TODO: Handle the case of clicking on a sustain piece.
|
||||||
highlightedNote = highlightedNote.getBaseNoteSprite();
|
|
||||||
// Control click to select/deselect an individual note.
|
// Control click to select/deselect an individual note.
|
||||||
if (isNoteSelected(highlightedNote.noteData))
|
if (isNoteSelected(highlightedNote.noteData))
|
||||||
{
|
{
|
||||||
|
@ -2055,8 +2056,7 @@ class ChartEditorState extends HaxeUIState
|
||||||
|
|
||||||
if (highlightedNote != null)
|
if (highlightedNote != null)
|
||||||
{
|
{
|
||||||
// Handle the case of clicking on a sustain piece.
|
// TODO: Handle the case of clicking on a sustain piece.
|
||||||
highlightedNote = highlightedNote.getBaseNoteSprite();
|
|
||||||
// Remove the note.
|
// Remove the note.
|
||||||
performCommand(new RemoveNotesCommand([highlightedNote.noteData]));
|
performCommand(new RemoveNotesCommand([highlightedNote.noteData]));
|
||||||
}
|
}
|
||||||
|
@ -2167,18 +2167,18 @@ class ChartEditorState extends HaxeUIState
|
||||||
// Kill the note sprite and recycle it.
|
// Kill the note sprite and recycle it.
|
||||||
noteSprite.noteData = null;
|
noteSprite.noteData = null;
|
||||||
}
|
}
|
||||||
else if (noteSprite.noteData.length > 0 && (noteSprite.parentNoteSprite == null && noteSprite.childNoteSprite == null))
|
// else if (noteSprite.noteData.length > 0 && (noteSprite.parentNoteSprite == null && noteSprite.childNoteSprite == null))
|
||||||
{
|
// {
|
||||||
// Note was extended.
|
// // Note was extended.
|
||||||
// Kill the note sprite and recycle it.
|
// // Kill the note sprite and recycle it.
|
||||||
noteSprite.noteData = null;
|
// noteSprite.noteData = null;
|
||||||
}
|
// }
|
||||||
else if (noteSprite.noteData.length == 0 && (noteSprite.parentNoteSprite != null || noteSprite.childNoteSprite != null))
|
// else if (noteSprite.noteData.length == 0 && (noteSprite.parentNoteSprite != null || noteSprite.childNoteSprite != null))
|
||||||
{
|
// {
|
||||||
// Note was shortened.
|
// // Note was shortened.
|
||||||
// Kill the note sprite and recycle it.
|
// // Kill the note sprite and recycle it.
|
||||||
noteSprite.noteData = null;
|
// noteSprite.noteData = null;
|
||||||
}
|
// }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Note is already displayed and should remain displayed.
|
// Note is already displayed and should remain displayed.
|
||||||
|
@ -2252,30 +2252,34 @@ class ChartEditorState extends HaxeUIState
|
||||||
// TODO: Replace this with SustainTrail.
|
// TODO: Replace this with SustainTrail.
|
||||||
if (noteSprite.noteData.length > 0)
|
if (noteSprite.noteData.length > 0)
|
||||||
{
|
{
|
||||||
|
var holdNoteSprite:SustainTrail = renderedHoldNotes.recycle(() -> new SustainTrail(this));
|
||||||
|
|
||||||
|
var noteLengthPixels:Float = noteSprite.noteData.stepLength * GRID_SIZE;
|
||||||
|
|
||||||
// If the note is a hold, we need to make sure it's long enough.
|
// If the note is a hold, we need to make sure it's long enough.
|
||||||
var noteLengthSteps:Float = noteSprite.noteData.stepLength;
|
// var noteLengthSteps:Float = ;
|
||||||
var lastNoteSprite:ChartEditorNoteSprite = noteSprite;
|
// var lastNoteSprite:ChartEditorNoteSprite = noteSprite;
|
||||||
|
//
|
||||||
while (noteLengthSteps > 0)
|
// while (noteLengthSteps > 0)
|
||||||
{
|
// {
|
||||||
if (noteLengthSteps <= 1.0)
|
// if (noteLengthSteps <= 1.0)
|
||||||
{
|
// {
|
||||||
// Last note in the hold.
|
// // Last note in the hold.
|
||||||
// TODO: We may need to make it shorter and clip it visually.
|
// // TODO: We may need to make it shorter and clip it visually.
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var nextNoteSprite:ChartEditorNoteSprite = renderedNotes.recycle(ChartEditorNoteSprite);
|
// var nextNoteSprite:ChartEditorNoteSprite = renderedNotes.recycle(ChartEditorNoteSprite);
|
||||||
nextNoteSprite.parentState = this;
|
// nextNoteSprite.parentState = this;
|
||||||
nextNoteSprite.parentNoteSprite = lastNoteSprite;
|
// nextNoteSprite.parentNoteSprite = lastNoteSprite;
|
||||||
lastNoteSprite.childNoteSprite = nextNoteSprite;
|
// lastNoteSprite.childNoteSprite = nextNoteSprite;
|
||||||
|
//
|
||||||
lastNoteSprite = nextNoteSprite;
|
// lastNoteSprite = nextNoteSprite;
|
||||||
|
//
|
||||||
noteLengthSteps -= 1;
|
// noteLengthSteps -= 1;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Make sure the last note sprite shows the end cap properly.
|
// // Make sure the last note sprite shows the end cap properly.
|
||||||
lastNoteSprite.childNoteSprite = null;
|
// lastNoteSprite.childNoteSprite = null;
|
||||||
|
|
||||||
// var noteLengthPixels:Float = (noteLengthMs / Conductor.stepLengthMs + 1) * GRID_SIZE;
|
// var noteLengthPixels:Float = (noteLengthMs / Conductor.stepLengthMs + 1) * GRID_SIZE;
|
||||||
// add(new FlxSprite(noteSprite.x, noteSprite.y - renderedNotes.y + noteLengthPixels).makeGraphic(40, 2, 0xFFFF0000));
|
// add(new FlxSprite(noteSprite.x, noteSprite.y - renderedNotes.y + noteLengthPixels).makeGraphic(40, 2, 0xFFFF0000));
|
||||||
|
@ -2326,7 +2330,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
// Recycle selection squares if possible.
|
// Recycle selection squares if possible.
|
||||||
for (noteSprite in renderedNotes.members)
|
for (noteSprite in renderedNotes.members)
|
||||||
{
|
{
|
||||||
if (isNoteSelected(noteSprite.noteData) && noteSprite.parentNoteSprite == null)
|
// TODO: Handle selection of hold notes.
|
||||||
|
if (isNoteSelected(noteSprite.noteData))
|
||||||
{
|
{
|
||||||
var selectionSquare:FlxSprite = renderedSelectionSquares.recycle(buildSelectionSquare);
|
var selectionSquare:FlxSprite = renderedSelectionSquares.recycle(buildSelectionSquare);
|
||||||
|
|
||||||
|
@ -2833,11 +2838,13 @@ class ChartEditorState extends HaxeUIState
|
||||||
// Assume notes are sorted by time.
|
// Assume notes are sorted by time.
|
||||||
for (noteData in currentSongChartNoteData)
|
for (noteData in currentSongChartNoteData)
|
||||||
{
|
{
|
||||||
|
// Check for notes between the old and new song positions.
|
||||||
|
|
||||||
if (noteData.time < oldSongPosition) // Note is in the past.
|
if (noteData.time < oldSongPosition) // Note is in the past.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (noteData.time >= newSongPosition) // Note is in the future.
|
if (noteData.time > newSongPosition) // Note is in the future.
|
||||||
return;
|
return; // Assume all notes are also in the future.
|
||||||
|
|
||||||
// Note was just hit.
|
// Note was just hit.
|
||||||
|
|
||||||
|
@ -3122,6 +3129,8 @@ class ChartEditorState extends HaxeUIState
|
||||||
Conductor.forceBPM(null); // Disable the forced BPM.
|
Conductor.forceBPM(null); // Disable the forced BPM.
|
||||||
Conductor.mapTimeChanges(currentSongMetadata.timeChanges);
|
Conductor.mapTimeChanges(currentSongMetadata.timeChanges);
|
||||||
|
|
||||||
|
sortChartData();
|
||||||
|
|
||||||
loadInstrumentalFromAsset(Paths.inst(songId));
|
loadInstrumentalFromAsset(Paths.inst(songId));
|
||||||
|
|
||||||
var voiceList:Array<String> = song.getDifficulty(selectedDifficulty).buildVoiceList();
|
var voiceList:Array<String> = song.getDifficulty(selectedDifficulty).buildVoiceList();
|
||||||
|
|
Loading…
Reference in a new issue