diff --git a/Project.xml b/Project.xml index 8eb62bb1d..656590aec 100644 --- a/Project.xml +++ b/Project.xml @@ -114,11 +114,8 @@ xsi:schemaLocation="http://lime.openfl.org/project/1.0.4 http://lime.openfl.org/ <haxelib name="openfl" /> <!-- Game engine backend --> <haxelib name="flixel" /> <!-- Game engine --> - <haxedev set="webgl" /> - <haxelib name="flixel-addons" /> <!-- Additional utilities for Flixel --> <haxelib name="hscript" /> <!-- Scripting --> - <haxelib name="flixel-ui" /> <!-- UI framework (DEPRECATED) --> <haxelib name="haxeui-core" /> <!-- UI framework --> <haxelib name="haxeui-flixel" /> <!-- Integrate HaxeUI with Flixel --> <haxelib name="flixel-text-input" /> <!-- Improved text field rendering for HaxeUI --> diff --git a/assets b/assets index 62c4a8203..b57d7f8d3 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 62c4a8203362c1b434de0d376046ebccb96da254 +Subproject commit b57d7f8d308e468f7b0947d4784d0efeca44d9aa diff --git a/hmm.json b/hmm.json index aad0be8cf..d67760882 100644 --- a/hmm.json +++ b/hmm.json @@ -39,8 +39,8 @@ "name": "flxanimate", "type": "git", "dir": null, - "ref": "17e0d59fdbc2b6283a5c0e4df41f1c7f27b71c49", - "url": "https://github.com/FunkinCrew/flxanimate" + "ref": "768740a56b26aa0c072720e0d1236b94afe68e3e", + "url": "https://github.com/Dot-Stuff/flxanimate" }, { "name": "FlxPartialSound", diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 34516dee1..e53499e3c 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -244,11 +244,11 @@ class InitState extends FlxState totalNotesHit: 140, totalNotes: 190 } - // 2000 = loss - // 240 = good - // 230 = great - // 210 = excellent - // 190 = perfect + // 2400 total notes = 7% = LOSS + // 240 total notes = 79% = GOOD + // 230 total notes = 82% = GREAT + // 210 total notes = 91% = EXCELLENT + // 190 total notes = PERFECT }, })); #elseif ANIMDEBUG diff --git a/source/funkin/data/freeplay/player/PlayerRegistry.hx b/source/funkin/data/freeplay/player/PlayerRegistry.hx index 4656a1286..be8730ccd 100644 --- a/source/funkin/data/freeplay/player/PlayerRegistry.hx +++ b/source/funkin/data/freeplay/player/PlayerRegistry.hx @@ -58,8 +58,9 @@ class PlayerRegistry extends BaseRegistry<PlayableCharacter, PlayerData> * @param characterId The stage character ID. * @return The playable character. */ - public function getCharacterOwnerId(characterId:String):Null<String> + public function getCharacterOwnerId(characterId:Null<String>):Null<String> { + if (characterId == null) return null; return ownedCharacterIds[characterId]; } diff --git a/source/funkin/data/stage/StageRegistry.hx b/source/funkin/data/stage/StageRegistry.hx index 1f0504247..7754c380e 100644 --- a/source/funkin/data/stage/StageRegistry.hx +++ b/source/funkin/data/stage/StageRegistry.hx @@ -93,8 +93,8 @@ class StageRegistry extends BaseRegistry<Stage, StageData> public function listBaseGameStageIds():Array<String> { return [ - "mainStage", "spookyMansion", "phillyTrain", "phillyTrainErect", "limoRide", "limoRideErect", "mallXmas", "mallEvil", "school", "schoolEvil", - "tankmanBattlefield", "phillyStreets", "phillyBlazin", + "mainStage", "mainStageErect", "spookyMansion", "phillyTrain", "phillyTrainErect", "limoRide", "limoRideErect", "mallXmas", "mallEvil", "school", + "schoolEvil", "tankmanBattlefield", "phillyStreets", "phillyBlazin", ]; } diff --git a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx index eb331b9c3..049c6e206 100644 --- a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx +++ b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx @@ -4,8 +4,11 @@ import flixel.util.FlxSignal.FlxTypedSignal; import flxanimate.FlxAnimate; import flxanimate.FlxAnimate.Settings; import flxanimate.frames.FlxAnimateFrames; +import flixel.graphics.frames.FlxFrame; +import flixel.system.FlxAssets.FlxGraphicAsset; import openfl.display.BitmapData; import openfl.utils.Assets; +import flixel.math.FlxPoint; /** * A sprite which provides convenience functions for rendering a texture atlas with animations. @@ -25,9 +28,19 @@ class FlxAtlasSprite extends FlxAnimate }; /** - * Signal dispatched when an animation finishes playing. + * Signal dispatched when an animation advances to the next frame. */ - public var onAnimationFinish:FlxTypedSignal<String->Void> = new FlxTypedSignal<String->Void>(); + public var onAnimationFrame:FlxTypedSignal<String->Int->Void> = new FlxTypedSignal(); + + /** + * Signal dispatched when a non-looping animation finishes playing. + */ + public var onAnimationComplete:FlxTypedSignal<String->Void> = new FlxTypedSignal(); + + /** + * Signal dispatched when a looping animation finishes playing + */ + public var onAnimationLoopComplete:FlxTypedSignal<String->Void> = new FlxTypedSignal(); var currentAnimation:String; @@ -44,17 +57,20 @@ class FlxAtlasSprite extends FlxAnimate super(x, y, path, settings); - if (this.anim.curInstance == null) + if (this.anim.stageInstance == null) { throw 'FlxAtlasSprite not initialized properly. Are you sure the path (${path}) exists?'; } - onAnimationFinish.add(cleanupAnimation); + onAnimationComplete.add(cleanupAnimation); // This defaults the sprite to play the first animation in the atlas, // then pauses it. This ensures symbols are intialized properly. this.anim.play(''); this.anim.pause(); + + this.anim.onComplete.add(_onAnimationComplete); + this.anim.onFrame.add(_onAnimationFrame); } /** @@ -62,9 +78,13 @@ class FlxAtlasSprite extends FlxAnimate */ public function listAnimations():Array<String> { - if (this.anim == null) return []; - return this.anim.getFrameLabels(); - // return [""]; + var mainSymbol = this.anim.symbolDictionary[this.anim.stageInstance.symbol.name]; + if (mainSymbol == null) + { + FlxG.log.error('FlxAtlasSprite does not have its main symbol!'); + return []; + } + return mainSymbol.getFrameLabels().map(keyFrame -> keyFrame.name).filterNull(); } /** @@ -107,12 +127,11 @@ class FlxAtlasSprite extends FlxAnimate * @param restart Whether to restart the animation if it is already playing. * @param ignoreOther Whether to ignore all other animation inputs, until this one is done playing * @param loop Whether to loop the animation + * @param startFrame The frame to start the animation on * NOTE: `loop` and `ignoreOther` are not compatible with each other! */ - public function playAnimation(id:String, restart:Bool = false, ignoreOther:Bool = false, ?loop:Bool = false):Void + public function playAnimation(id:String, restart:Bool = false, ignoreOther:Bool = false, loop:Bool = false, startFrame:Int = 0):Void { - if (loop == null) loop = false; - // Skip if not allowed to play animations. if ((!canPlayOtherAnims && !ignoreOther)) return; @@ -128,7 +147,7 @@ class FlxAtlasSprite extends FlxAnimate else { // Resume animation if it's paused. - anim.play('', false, false); + anim.play('', restart, false, startFrame); } } else @@ -141,31 +160,27 @@ class FlxAtlasSprite extends FlxAnimate } } - anim.callback = function(_, frame:Int) { - var offset = loop ? 0 : -1; - - var frameLabel = anim.getFrameLabel(id); - if (frame == (frameLabel.duration + offset) + frameLabel.index) + anim.onComplete.removeAll(); + anim.onComplete.add(function() { + if (loop) { - if (loop) - { - playAnimation(id, true, false, true); - } - else - { - onAnimationFinish.dispatch(id); - } + onAnimationLoopComplete.dispatch(id); + this.anim.play(id, restart, false, startFrame); + this.currentAnimation = id; } - }; - - anim.onComplete = function() { - onAnimationFinish.dispatch(id); - }; + else + { + onAnimationComplete.dispatch(id); + } + }); // Prevent other animations from playing if `ignoreOther` is true. if (ignoreOther) canPlayOtherAnims = false; // Move to the first frame of the animation. + // goToFrameLabel(id); + trace('Playing animation $id'); + this.anim.play(id, restart, false, startFrame); goToFrameLabel(id); this.currentAnimation = id; } @@ -175,6 +190,24 @@ class FlxAtlasSprite extends FlxAnimate super.update(elapsed); } + /** + * Returns true if the animation has finished playing. + * Never true if animation is configured to loop. + */ + public function isAnimationFinished():Bool + { + return this.anim.finished; + } + + /** + * Returns true if the animation has reached the last frame. + * Can be true even if animation is configured to loop. + */ + public function isLoopComplete():Bool + { + return (anim.reversed && anim.curFrame == 0 || !(anim.reversed) && (anim.curFrame) >= (anim.length - 1)); + } + /** * Stops the current animation. */ @@ -219,4 +252,76 @@ class FlxAtlasSprite extends FlxAnimate // this.currentAnimation = null; this.anim.pause(); } + + function _onAnimationFrame(frame:Int):Void + { + if (currentAnimation != null) + { + onAnimationFrame.dispatch(currentAnimation, frame); + if (isLoopComplete()) onAnimationLoopComplete.dispatch(currentAnimation); + } + } + + function _onAnimationComplete():Void + { + if (currentAnimation != null) + { + onAnimationComplete.dispatch(currentAnimation); + } + } + + var prevFrames:Map<Int, FlxFrame> = []; + + public function replaceFrameGraphic(index:Int, ?graphic:FlxGraphicAsset):Void + { + if (graphic == null || !Assets.exists(graphic)) + { + var prevFrame:Null<FlxFrame> = prevFrames.get(index); + if (prevFrame == null) return; + + prevFrame.copyTo(frames.getByIndex(index)); + return; + } + + var prevFrame:FlxFrame = prevFrames.get(index) ?? frames.getByIndex(index).copyTo(); + prevFrames.set(index, prevFrame); + + var frame = FlxG.bitmap.add(graphic).imageFrame.frame; + frame.copyTo(frames.getByIndex(index)); + + // Additional sizing fix. + @:privateAccess + if (true) + { + var frame = frames.getByIndex(index); + frame.tileMatrix[0] = prevFrame.frame.width / frame.frame.width; + frame.tileMatrix[3] = prevFrame.frame.height / frame.frame.height; + } + } + + public function getBasePosition():Null<FlxPoint> + { + var stagePos = new FlxPoint(anim.stageInstance.matrix.tx, anim.stageInstance.matrix.ty); + var instancePos = new FlxPoint(anim.curInstance.matrix.tx, anim.curInstance.matrix.ty); + var firstElement = anim.curSymbol.timeline?.get(0)?.get(0)?.get(0); + if (firstElement == null) return instancePos; + var firstElementPos = new FlxPoint(firstElement.matrix.tx, firstElement.matrix.ty); + + return instancePos + firstElementPos; + } + + public function getPivotPosition():Null<FlxPoint> + { + return anim.curInstance.symbol.transformationPoint; + } + + public override function destroy():Void + { + for (prevFrameId in prevFrames.keys()) + { + replaceFrameGraphic(prevFrameId, null); + } + + super.destroy(); + } } diff --git a/source/funkin/modding/base/ScriptedFlxUIState.hx b/source/funkin/modding/base/ScriptedFlxUIState.hx deleted file mode 100644 index c58fc294f..000000000 --- a/source/funkin/modding/base/ScriptedFlxUIState.hx +++ /dev/null @@ -1,8 +0,0 @@ -package funkin.modding.base; - -/** - * A script that can be tied to an FlxUIState. - * Create a scripted class that extends FlxUIState to use this. - */ -@:hscriptClass -class ScriptedFlxUIState extends flixel.addons.ui.FlxUIState implements HScriptedClass {} diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index c2d9d42b3..b1ff69a3a 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -70,6 +70,8 @@ class ResultState extends MusicBeatSubState delay:Float }> = []; + var playerCharacterId:Null<String>; + var rankBg:FunkinSprite; final cameraBG:FunkinCamera; final cameraScroll:FunkinCamera; @@ -164,7 +166,7 @@ class ResultState extends MusicBeatSubState add(soundSystem); // Fetch playable character data. Default to BF on the results screen if we can't find it. - var playerCharacterId:Null<String> = PlayerRegistry.instance.getCharacterOwnerId(params.characterId); + playerCharacterId = PlayerRegistry.instance.getCharacterOwnerId(params.characterId); var playerCharacter:Null<PlayableCharacter> = PlayerRegistry.instance.fetchEntry(playerCharacterId ?? 'bf'); trace('Got playable character: ${playerCharacter?.getName()}'); @@ -189,7 +191,7 @@ class ResultState extends MusicBeatSubState if (!(animData.looped ?? true)) { // Animation is not looped. - animation.onAnimationFinish.add((_name:String) -> { + animation.onAnimationComplete.add((_name:String) -> { if (animation != null) { animation.anim.pause(); @@ -198,7 +200,7 @@ class ResultState extends MusicBeatSubState } else if (animData.loopFrameLabel != null) { - animation.onAnimationFinish.add((_name:String) -> { + animation.onAnimationComplete.add((_name:String) -> { if (animation != null) { animation.playAnimation(animData.loopFrameLabel ?? ''); // unpauses this anim, since it's on PlayOnce! @@ -207,7 +209,7 @@ class ResultState extends MusicBeatSubState } else if (animData.loopFrame != null) { - animation.onAnimationFinish.add((_name:String) -> { + animation.onAnimationComplete.add((_name:String) -> { if (animation != null) { animation.anim.curFrame = animData.loopFrame ?? 0; @@ -742,6 +744,7 @@ class ResultState extends MusicBeatSubState FlxG.switchState(FreeplayState.build( { { + character: playerCharacterId ?? "bf", fromResults: { oldRank: Scoring.calculateRank(params?.prevScoreData), @@ -799,8 +802,9 @@ typedef ResultsStateParams = /** * The character ID for the song we just played. + * @default `bf` */ - var characterId:String; + var ?characterId:String; /** * Whether the displayed score is a new highscore diff --git a/source/funkin/play/character/AnimateAtlasCharacter.hx b/source/funkin/play/character/AnimateAtlasCharacter.hx index ed58b92b5..32a4e765c 100644 --- a/source/funkin/play/character/AnimateAtlasCharacter.hx +++ b/source/funkin/play/character/AnimateAtlasCharacter.hx @@ -109,8 +109,6 @@ class AnimateAtlasCharacter extends BaseCharacter var loop:Bool = animData.looped; this.mainSprite.playAnimation(prefix, restart, ignoreOther, loop); - - animFinished = false; } public override function hasAnimation(name:String):Bool @@ -124,17 +122,17 @@ class AnimateAtlasCharacter extends BaseCharacter */ public override function isAnimationFinished():Bool { - return animFinished; + return mainSprite.isAnimationFinished(); } function loadAtlasSprite():FlxAtlasSprite { trace('[ATLASCHAR] Loading sprite atlas for ${characterId}.'); - var sprite:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas(_data.assetPath, 'shared')); + var sprite:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas(_data.assetPath)); - sprite.onAnimationFinish.removeAll(); - sprite.onAnimationFinish.add(this.onAnimationFinished); + // sprite.onAnimationComplete.removeAll(); + sprite.onAnimationComplete.add(this.onAnimationFinished); return sprite; } @@ -152,7 +150,6 @@ class AnimateAtlasCharacter extends BaseCharacter // Make the game hold on the last frame. this.mainSprite.cleanupAnimation(prefix); // currentAnimName = null; - animFinished = true; // Fallback to idle! // playAnimation('idle', true, false); @@ -165,6 +162,11 @@ class AnimateAtlasCharacter extends BaseCharacter this.mainSprite = sprite; + // This forces the atlas to recalcuate its width and height + this.mainSprite.alpha = 0.0001; + this.mainSprite.draw(); + this.mainSprite.alpha = 1.0; + var feetPos:FlxPoint = feetPosition; this.updateHitbox(); diff --git a/source/funkin/play/character/MultiSparrowCharacter.hx b/source/funkin/play/character/MultiSparrowCharacter.hx index 41c96fbfa..e23afe18c 100644 --- a/source/funkin/play/character/MultiSparrowCharacter.hx +++ b/source/funkin/play/character/MultiSparrowCharacter.hx @@ -62,7 +62,7 @@ class MultiSparrowCharacter extends BaseCharacter } } - var texture:FlxAtlasFrames = Paths.getSparrowAtlas(_data.assetPath, 'shared'); + var texture:FlxAtlasFrames = Paths.getSparrowAtlas(_data.assetPath); if (texture == null) { @@ -76,7 +76,7 @@ class MultiSparrowCharacter extends BaseCharacter for (asset in assetList) { - var subTexture:FlxAtlasFrames = Paths.getSparrowAtlas(asset, 'shared'); + var subTexture:FlxAtlasFrames = Paths.getSparrowAtlas(asset); // If we don't do this, the unused textures will be removed as soon as they're loaded. if (subTexture == null) diff --git a/source/funkin/play/character/PackerCharacter.hx b/source/funkin/play/character/PackerCharacter.hx index 22edbe339..5d004606c 100644 --- a/source/funkin/play/character/PackerCharacter.hx +++ b/source/funkin/play/character/PackerCharacter.hx @@ -30,7 +30,7 @@ class PackerCharacter extends BaseCharacter { trace('[PACKERCHAR] Loading spritesheet ${_data.assetPath} for ${characterId}'); - var tex:FlxFramesCollection = Paths.getPackerAtlas(_data.assetPath, 'shared'); + var tex:FlxFramesCollection = Paths.getPackerAtlas(_data.assetPath); if (tex == null) { trace('Could not load Packer sprite: ${_data.assetPath}'); diff --git a/source/funkin/play/character/SparrowCharacter.hx b/source/funkin/play/character/SparrowCharacter.hx index 81d98b138..eacf799d8 100644 --- a/source/funkin/play/character/SparrowCharacter.hx +++ b/source/funkin/play/character/SparrowCharacter.hx @@ -33,7 +33,7 @@ class SparrowCharacter extends BaseCharacter { trace('[SPARROWCHAR] Loading spritesheet ${_data.assetPath} for ${characterId}'); - var tex:FlxFramesCollection = Paths.getSparrowAtlas(_data.assetPath, 'shared'); + var tex:FlxFramesCollection = Paths.getSparrowAtlas(_data.assetPath); if (tex == null) { trace('Could not load Sparrow sprite: ${_data.assetPath}'); diff --git a/source/funkin/ui/charSelect/CharSelectPlayer.hx b/source/funkin/ui/charSelect/CharSelectPlayer.hx index 9322369ba..9052c60e9 100644 --- a/source/funkin/ui/charSelect/CharSelectPlayer.hx +++ b/source/funkin/ui/charSelect/CharSelectPlayer.hx @@ -9,7 +9,7 @@ class CharSelectPlayer extends FlxAtlasSprite { super(x, y, Paths.animateAtlas("charSelect/bfChill")); - onAnimationFinish.add(function(animLabel:String) { + onAnimationComplete.add(function(animLabel:String) { switch (animLabel) { case "slidein": diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 14a5b36e0..8b1f050f5 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -600,7 +600,7 @@ class CharSelectSubState extends MusicBeatSubState playerChill.visible = false; playerChillOut.visible = true; playerChillOut.anim.goToFrameLabel("slideout"); - playerChillOut.anim.callback = (_, frame:Int) -> { + playerChillOut.onAnimationFrame.add((_, frame:Int) -> { if (frame == playerChillOut.anim.getFrameLabel("slideout").index + 1) { playerChill.visible = true; @@ -612,7 +612,7 @@ class CharSelectSubState extends MusicBeatSubState playerChillOut.switchChar(value); playerChillOut.visible = false; } - }; + }); return value; } diff --git a/source/funkin/ui/debug/anim/DebugBoundingState.hx b/source/funkin/ui/debug/anim/DebugBoundingState.hx index 04784a5b7..7bb42c89e 100644 --- a/source/funkin/ui/debug/anim/DebugBoundingState.hx +++ b/source/funkin/ui/debug/anim/DebugBoundingState.hx @@ -1,33 +1,26 @@ package funkin.ui.debug.anim; +import flixel.addons.display.FlxBackdrop; import flixel.addons.display.FlxGridOverlay; -import flixel.addons.ui.FlxInputText; -import flixel.addons.ui.FlxUIDropDownMenu; import flixel.FlxCamera; import flixel.FlxSprite; import flixel.FlxState; -import flixel.graphics.frames.FlxAtlasFrames; import flixel.graphics.frames.FlxFrame; import flixel.group.FlxGroup; import flixel.math.FlxPoint; import flixel.text.FlxText; import flixel.util.FlxColor; -import flixel.util.FlxSpriteUtil; -import flixel.util.FlxTimer; -import funkin.audio.FunkinSound; import funkin.input.Cursor; import funkin.play.character.BaseCharacter; import funkin.play.character.CharacterData; import funkin.play.character.CharacterData.CharacterDataParser; -import funkin.play.character.SparrowCharacter; import funkin.ui.mainmenu.MainMenuState; import funkin.util.MouseUtil; import funkin.util.SerializerUtil; import funkin.util.SortUtil; import haxe.ui.components.DropDown; -import haxe.ui.core.Component; +import haxe.ui.containers.dialogs.CollapsibleDialog; import haxe.ui.core.Screen; -import haxe.ui.events.ItemEvent; import haxe.ui.events.UIEvent; import haxe.ui.RuntimeComponentBuilder; import lime.utils.Assets as LimeAssets; @@ -36,9 +29,6 @@ import openfl.events.Event; import openfl.events.IOErrorEvent; import openfl.geom.Rectangle; import openfl.net.FileReference; -import openfl.net.URLLoader; -import openfl.net.URLRequest; -import openfl.utils.ByteArray; using flixel.util.FlxSpriteUtil; @@ -55,10 +45,10 @@ class DebugBoundingState extends FlxState TODAY'S TO-DO - Cleaner UI */ - var bg:FlxSprite; + var bg:FlxBackdrop; var fileInfo:FlxText; - var txtGrp:FlxGroup; + var txtGrp:FlxTypedGroup<FlxText>; var hudCam:FlxCamera; @@ -66,16 +56,23 @@ class DebugBoundingState extends FlxState var spriteSheetView:FlxGroup; var offsetView:FlxGroup; - var animDropDownMenu:FlxUIDropDownMenu; var dropDownSetup:Bool = false; var onionSkinChar:FlxSprite; var txtOffsetShit:FlxText; - var uiStuff:Component; + var offsetEditorDialog:CollapsibleDialog; + var offsetAnimationDropdown:DropDown; var haxeUIFocused(get, default):Bool = false; + var currentAnimationName(get, never):String; + + function get_currentAnimationName():String + { + return offsetAnimationDropdown?.value?.id ?? "idle"; + } + function get_haxeUIFocused():Bool { // get the screen position, according to the HUD camera, temp default to FlxG.camera juuust in case? @@ -87,46 +84,35 @@ class DebugBoundingState extends FlxState { Paths.setCurrentLevel('week1'); - // lv. - // lv.onChange = function(e:UIEvent) - // { - // trace(e.type); - // // trace(e.data.curView); - // // var item:haxe.ui.core.ItemRenderer = cast e.target; - // trace(e.target); - // // if (e.type == "change") - // // { - // // curView = cast e.data; - // // } - // }; - hudCam = new FlxCamera(); hudCam.bgColor.alpha = 0; - bg = FlxGridOverlay.create(10, 10); - // bg = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.GREEN); - - bg.scrollFactor.set(); + bg = new FlxBackdrop(FlxGridOverlay.createGrid(10, 10, FlxG.width, FlxG.height, true, 0xffe7e6e6, 0xffd9d5d5)); add(bg); // we are setting this as the default draw camera only temporarily, to trick haxeui FlxG.cameras.add(hudCam); var str = Paths.xml('ui/animation-editor/offset-editor-view'); - uiStuff = RuntimeComponentBuilder.fromAsset(str); + offsetEditorDialog = cast RuntimeComponentBuilder.fromAsset(str); - // uiStuff.findComponent("btnViewSpriteSheet").onClick = _ -> curView = SPRITESHEET; - var dropdown:DropDown = cast uiStuff.findComponent("swapper"); - dropdown.onChange = function(e:UIEvent) { + // offsetEditorDialog.findComponent("btnViewSpriteSheet").onClick = _ -> curView = SPRITESHEET; + var viewDropdown:DropDown = offsetEditorDialog.findComponent("swapper", DropDown); + viewDropdown.onChange = function(e:UIEvent) { trace(e.type); curView = cast e.data.curView; trace(e.data); // trace(e.data); }; - uiStuff.cameras = [hudCam]; + offsetAnimationDropdown = offsetEditorDialog.findComponent("animationDropdown", DropDown); - add(uiStuff); + offsetEditorDialog.cameras = [hudCam]; + + add(offsetEditorDialog); + + // Anchor to the right side by default + // offsetEditorDialog.x = FlxG.width - offsetEditorDialog.width; // sets the default camera back to FlxG.camera, since we set it to hudCamera for haxeui stuf FlxG.cameras.setDefaultDrawTarget(FlxG.camera, true); @@ -159,7 +145,7 @@ class DebugBoundingState extends FlxState generateOutlines(tex.frames); - txtGrp = new FlxGroup(); + txtGrp = new FlxTypedGroup<FlxText>(); txtGrp.cameras = [hudCam]; spriteSheetView.add(txtGrp); @@ -168,64 +154,6 @@ class DebugBoundingState extends FlxState addInfo('Height', bf.height); spriteSheetView.add(swagOutlines); - - FlxG.stage.window.onDropFile.add(function(path:String) { - // WACKY ASS TESTING SHIT FOR WEB FILE LOADING?? - #if web - var swagList:FileList = cast path; - - var objShit = js.html.URL.createObjectURL(swagList.item(0)); - trace(objShit); - - var funnysound = new FunkinSound().loadStream('https://cdn.discordapp.com/attachments/767500676166451231/817821618251759666/Flutter.mp3', false, false, - null, function() { - trace('LOADED SHIT??'); - }); - - funnysound.volume = 1; - funnysound.play(); - - var urlShit = new URLLoader(new URLRequest(objShit)); - - new FlxTimer().start(3, function(tmr:FlxTimer) { - // music lol! - if (urlShit.dataFormat == BINARY) - { - // var daSwagBytes:ByteArray = urlShit.data; - - // FlxG.sound.playMusic(); - - // trace('is binary!!'); - } - trace(urlShit.dataFormat); - }); - - // remove(bf); - // FlxG.bitmap.removeByKey(Paths.image('characters/temp')); - // Assets.cache.clear(); - - // bf.loadGraphic(objShit); - // add(bf); - - // trace(swagList.item(0).name); - // var urlShit = js.html.URL.createObjectURL(path); - #end - - #if sys - trace("DROPPED FILE FROM: " + Std.string(path)); - var newPath = "./" + Paths.image('characters/temp'); - File.copy(path, newPath); - - var swag = Paths.image('characters/temp'); - - if (bf != null) remove(bf); - FlxG.bitmap.removeByKey(Paths.image('characters/temp')); - Assets.cache.clear(); - - bf.loadGraphic(Paths.image('characters/temp')); - add(bf); - #end - }); } function generateOutlines(frameShit:Array<FlxFrame>):Void @@ -260,15 +188,9 @@ class DebugBoundingState extends FlxState txtOffsetShit = new FlxText(20, 20, 0, "", 20); txtOffsetShit.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); txtOffsetShit.cameras = [hudCam]; + txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; offsetView.add(txtOffsetShit); - animDropDownMenu = new FlxUIDropDownMenu(0, 0, FlxUIDropDownMenu.makeStrIdLabelArray(['weed'], true)); - animDropDownMenu.cameras = [hudCam]; - // Move to bottom right corner - animDropDownMenu.x = FlxG.width - animDropDownMenu.width - 20; - animDropDownMenu.y = FlxG.height - animDropDownMenu.height - 20; - offsetView.add(animDropDownMenu); - var characters:Array<String> = CharacterDataParser.listCharacterIds(); characters = characters.filter(function(charId:String) { var char = CharacterDataParser.fetchCharacterData(charId); @@ -276,7 +198,7 @@ class DebugBoundingState extends FlxState }); characters.sort(SortUtil.alphabetically); - var charDropdown:DropDown = cast uiStuff.findComponent('characterDropdown'); + var charDropdown:DropDown = offsetEditorDialog.findComponent('characterDropdown', DropDown); for (char in characters) { charDropdown.dataSource.add({text: char}); @@ -289,32 +211,47 @@ class DebugBoundingState extends FlxState public var mouseOffset:FlxPoint = FlxPoint.get(0, 0); public var oldPos:FlxPoint = FlxPoint.get(0, 0); + public var movingCharacter:Bool = false; function mouseOffsetMovement() { if (swagChar != null) { - if (FlxG.mouse.justPressed) + if (FlxG.mouse.justPressed && !haxeUIFocused) { + movingCharacter = true; mouseOffset.set(FlxG.mouse.x - -swagChar.animOffsets[0], FlxG.mouse.y - -swagChar.animOffsets[1]); } + if (!movingCharacter) return; + if (FlxG.mouse.pressed) { swagChar.animOffsets = [(FlxG.mouse.x - mouseOffset.x) * -1, (FlxG.mouse.y - mouseOffset.y) * -1]; - swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, swagChar.animOffsets); + swagChar.animationOffsets.set(offsetAnimationDropdown.value.id, swagChar.animOffsets); txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets; + txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; + } + + if (FlxG.mouse.justReleased) + { + movingCharacter = false; } } } function addInfo(str:String, value:Dynamic) { - var swagText:FlxText = new FlxText(10, 10 + (28 * txtGrp.length)); + var swagText:FlxText = new FlxText(10, FlxG.height - 32); swagText.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); swagText.scrollFactor.set(); + + for (text in txtGrp.members) + { + text.y -= swagText.height; + } txtGrp.add(swagText); swagText.text = str + ": " + Std.string(value); @@ -345,14 +282,14 @@ class DebugBoundingState extends FlxState { if (FlxG.keys.justPressed.ONE) { - var lv:DropDown = cast uiStuff.findComponent("swapper"); + var lv:DropDown = offsetEditorDialog.findComponent("swapper", DropDown); lv.selectedIndex = 0; curView = SPRITESHEET; } if (FlxG.keys.justReleased.TWO) { - var lv:DropDown = cast uiStuff.findComponent("swapper"); + var lv:DropDown = offsetEditorDialog.findComponent("swapper", DropDown); lv.selectedIndex = 1; curView = ANIMATIONS; if (swagChar != null) @@ -368,12 +305,14 @@ class DebugBoundingState extends FlxState spriteSheetView.visible = true; offsetView.visible = false; offsetView.active = false; + offsetAnimationDropdown.visible = false; case ANIMATIONS: spriteSheetView.visible = false; offsetView.visible = true; offsetView.active = true; + offsetAnimationDropdown.visible = true; offsetControls(); - if (!haxeUIFocused) mouseOffsetMovement(); + mouseOffsetMovement(); } if (FlxG.keys.justPressed.H) hudCam.visible = !hudCam.visible; @@ -395,24 +334,36 @@ class DebugBoundingState extends FlxState { if (FlxG.keys.justPressed.RBRACKET || FlxG.keys.justPressed.E) { - if (Std.parseInt(animDropDownMenu.selectedId) + 1 <= animDropDownMenu.length) - animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) - + 1); + if (offsetAnimationDropdown.selectedIndex + 1 <= offsetAnimationDropdown.dataSource.size) + { + offsetAnimationDropdown.selectedIndex += 1; + } else - animDropDownMenu.selectedId = Std.string(0); - playCharacterAnimation(animDropDownMenu.selectedId, true); + { + offsetAnimationDropdown.selectedIndex = 0; + } + trace(offsetAnimationDropdown.selectedIndex); + trace(offsetAnimationDropdown.dataSource.size); + trace(offsetAnimationDropdown.value); + trace(currentAnimationName); + playCharacterAnimation(currentAnimationName, true); } if (FlxG.keys.justPressed.LBRACKET || FlxG.keys.justPressed.Q) { - if (Std.parseInt(animDropDownMenu.selectedId) - 1 >= 0) animDropDownMenu.selectedId = Std.string(Std.parseInt(animDropDownMenu.selectedId) - 1); + if (offsetAnimationDropdown.selectedIndex - 1 >= 0) + { + offsetAnimationDropdown.selectedIndex -= 1; + } else - animDropDownMenu.selectedId = Std.string(animDropDownMenu.length - 1); - playCharacterAnimation(animDropDownMenu.selectedId, true); + { + offsetAnimationDropdown.selectedIndex = offsetAnimationDropdown.dataSource.size - 1; + } + playCharacterAnimation(currentAnimationName, true); } // Keyboards controls for general WASD "movement" - // modifies the animDropDownMenu so that it's properly updated and shit - // and then it's just played and updated from the animDropDownMenu callback, which is set in the loadAnimShit() function probabbly + // modifies the animDrooffsetAnimationDropdownpDownMenu so that it's properly updated and shit + // and then it's just played and updated from the offsetAnimationDropdown callback, which is set in the loadAnimShit() function probabbly if (FlxG.keys.justPressed.W || FlxG.keys.justPressed.S || FlxG.keys.justPressed.D || FlxG.keys.justPressed.A) { var suffix:String = ''; @@ -425,18 +376,19 @@ class DebugBoundingState extends FlxState if (FlxG.keys.justPressed.A) targetLabel = 'singLEFT$suffix'; if (FlxG.keys.justPressed.D) targetLabel = 'singRIGHT$suffix'; - if (targetLabel != animDropDownMenu.selectedLabel) + if (targetLabel != currentAnimationName) { + offsetAnimationDropdown.value = {id: targetLabel, text: targetLabel}; + // Play the new animation if the IDs are the different. // Override the onion skin. - animDropDownMenu.selectedLabel = targetLabel; - playCharacterAnimation(animDropDownMenu.selectedId, true); + playCharacterAnimation(currentAnimationName, true); } else { // Replay the current animation if the IDs are the same. // Don't override the onion skin. - playCharacterAnimation(animDropDownMenu.selectedId, false); + playCharacterAnimation(currentAnimationName, false); } } @@ -448,16 +400,20 @@ class DebugBoundingState extends FlxState // Plays the idle animation if (FlxG.keys.justPressed.SPACE) { - animDropDownMenu.selectedLabel = 'idle'; - playCharacterAnimation(animDropDownMenu.selectedId, true); + offsetAnimationDropdown.value = {id: 'idle', text: 'idle'}; + + playCharacterAnimation(currentAnimationName, true); } // Playback the animation - if (FlxG.keys.justPressed.ENTER) playCharacterAnimation(animDropDownMenu.selectedId, false); + if (FlxG.keys.justPressed.ENTER) + { + playCharacterAnimation(currentAnimationName, false); + } if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.UP || FlxG.keys.justPressed.DOWN) { - var animName = animDropDownMenu.selectedLabel; + var animName = currentAnimationName; var coolValues:Array<Float> = swagChar.animationOffsets.get(animName).copy(); var multiplier:Int = 5; @@ -471,10 +427,11 @@ class DebugBoundingState extends FlxState else if (FlxG.keys.justPressed.UP) coolValues[1] += 1 * multiplier; else if (FlxG.keys.justPressed.DOWN) coolValues[1] -= 1 * multiplier; - swagChar.animationOffsets.set(animDropDownMenu.selectedLabel, coolValues); + swagChar.animationOffsets.set(currentAnimationName, coolValues); swagChar.playAnimation(animName); txtOffsetShit.text = 'Offset: ' + coolValues; + txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; trace(animName); } @@ -529,7 +486,7 @@ class DebugBoundingState extends FlxState swagChar = CharacterDataParser.fetchCharacter(char); swagChar.x = 100; swagChar.y = 100; - // swagChar.debugMode = true; + swagChar.debug = true; offsetView.add(swagChar); if (swagChar == null || swagChar.frames == null) @@ -554,11 +511,25 @@ class DebugBoundingState extends FlxState trace(swagChar.animationOffsets[i]); } - animDropDownMenu.setData(FlxUIDropDownMenu.makeStrIdLabelArray(characterAnimNames, true)); - animDropDownMenu.callback = function(str:String) { - playCharacterAnimation(str, true); - }; + offsetAnimationDropdown.dataSource.clear(); + + for (charAnim in characterAnimNames) + { + trace('Adding ${charAnim} to HaxeUI dropdown'); + offsetAnimationDropdown.dataSource.add({id: charAnim, text: charAnim}); + } + + offsetAnimationDropdown.selectedIndex = 0; + + trace('Added ${offsetAnimationDropdown.dataSource.size} to HaxeUI dropdown'); + + offsetAnimationDropdown.onChange = function(event:UIEvent) { + trace('Selected animation ${event?.data?.id}'); + playCharacterAnimation(event.data.id, true); + } + txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets; + txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; dropDownSetup = true; } @@ -575,11 +546,13 @@ class DebugBoundingState extends FlxState onionSkinChar.alpha = 0.6; } - var animName = characterAnimNames[Std.parseInt(str)]; + // var animName = characterAnimNames[Std.parseInt(str)]; + var animName = str; swagChar.playAnimation(animName, true); // trace(); trace(swagChar.animationOffsets.get(animName)); txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets; + txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height; } var _file:FileReference; diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 09a06661d..ebfbe5eac 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -5699,7 +5699,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // TODO: Rework asset system so we can remove this jank. switch (currentSongStage) { - case 'mainStage': + case 'mainStage' | 'mainStageErect': PlayStatePlaylist.campaignId = 'week1'; case 'spookyMansion' | 'spookyMansionErect': PlayStatePlaylist.campaignId = 'week2'; diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index 49c588722..36dba0054 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -37,6 +37,7 @@ class AlbumRoll extends FlxSpriteGroup } var newAlbumArt:FlxAtlasSprite; + var albumTitle:FunkinSprite; var difficultyStars:DifficultyStars; var _exitMovers:Null<FreeplayState.ExitMoverData>; @@ -59,24 +60,27 @@ class AlbumRoll extends FlxSpriteGroup { super(); - newAlbumArt = new FlxAtlasSprite(0, 0, Paths.animateAtlas("freeplay/albumRoll/freeplayAlbum")); + newAlbumArt = new FlxAtlasSprite(640, 350, Paths.animateAtlas("freeplay/albumRoll/freeplayAlbum")); newAlbumArt.visible = false; - newAlbumArt.onAnimationFinish.add(onAlbumFinish); + newAlbumArt.onAnimationComplete.add(onAlbumFinish); add(newAlbumArt); difficultyStars = new DifficultyStars(140, 39); difficultyStars.visible = false; add(difficultyStars); + + buildAlbumTitle("freeplay/albumRoll/volume1-text"); + albumTitle.visible = false; } function onAlbumFinish(animName:String):Void { // Play the idle animation for the current album. - newAlbumArt.playAnimation(animNames.get('$albumId-idle'), false, false, true); - - // End on the last frame and don't continue until playAnimation is called again. - // newAlbumArt.anim.pause(); + if (animName != "idle") + { + // newAlbumArt.playAnimation('idle', true); + } } /** @@ -104,6 +108,12 @@ class AlbumRoll extends FlxSpriteGroup return; }; + // Update the album art. + var albumGraphic = Paths.image(albumData.getAlbumArtAssetKey()); + newAlbumArt.replaceFrameGraphic(0, albumGraphic); + + buildAlbumTitle(albumData.getAlbumTitleAssetKey()); + applyExitMovers(); refresh(); @@ -146,19 +156,57 @@ class AlbumRoll extends FlxSpriteGroup */ public function playIntro():Void { + albumTitle.visible = false; newAlbumArt.visible = true; - newAlbumArt.playAnimation(animNames.get('$albumId-active'), false, false, false); + newAlbumArt.playAnimation('intro', true); difficultyStars.visible = false; new FlxTimer().start(0.75, function(_) { - // showTitle(); + showTitle(); showStars(); + albumTitle.animation.play('switch'); }); } public function skipIntro():Void { - newAlbumArt.playAnimation(animNames.get('$albumId-trans'), false, false, false); + // Weird workaround + newAlbumArt.playAnimation('switch', true); + albumTitle.animation.play('switch'); + } + + public function showTitle():Void + { + albumTitle.visible = true; + } + + public function buildAlbumTitle(assetKey:String):Void + { + if (albumTitle != null) + { + remove(albumTitle); + albumTitle = null; + } + + albumTitle = FunkinSprite.createSparrow(925, 500, assetKey); + albumTitle.visible = albumTitle.frames != null && newAlbumArt.visible; + albumTitle.animation.addByPrefix('idle', 'idle0', 24, true); + albumTitle.animation.addByPrefix('switch', 'switch0', 24, false); + add(albumTitle); + + albumTitle.animation.finishCallback = (function(name) { + if (name == 'switch') albumTitle.animation.play('idle'); + }); + albumTitle.animation.play('idle'); + + albumTitle.zIndex = 1000; + + if (_exitMovers != null) _exitMovers.set([albumTitle], + { + x: FlxG.width, + speed: 0.4, + wait: 0 + }); } public function setDifficultyStars(?difficulty:Int):Void diff --git a/source/funkin/ui/freeplay/FreeplayDJ.hx b/source/funkin/ui/freeplay/FreeplayDJ.hx index 72eddd0ca..317a52308 100644 --- a/source/funkin/ui/freeplay/FreeplayDJ.hx +++ b/source/funkin/ui/freeplay/FreeplayDJ.hx @@ -43,7 +43,7 @@ class FreeplayDJ extends FlxAtlasSprite super(x, y, playableCharData.getAtlasPath()); - anim.callback = function(name, number) { + onAnimationFrame.add(function(name, number) { if (name == playableCharData.getAnimationPrefix('cartoon')) { if (number == playableCharData.getCartoonSoundClickFrame()) @@ -55,12 +55,12 @@ class FreeplayDJ extends FlxAtlasSprite runTvLogic(); } } - }; + }); FlxG.debugger.track(this); FlxG.console.registerObject("dj", this); - anim.onComplete = onFinishAnim; + onAnimationComplete.add(onFinishAnim); FlxG.console.registerFunction("freeplayCartoon", function() { currentState = Cartoon; @@ -96,7 +96,7 @@ class FreeplayDJ extends FlxAtlasSprite var animPrefix = playableCharData.getAnimationPrefix('idle'); if (getCurrentAnimation() != animPrefix) { - playFlashAnimation(animPrefix, true); + playFlashAnimation(animPrefix, true, false, true); } if (getCurrentAnimation() == animPrefix && this.isLoopFinished()) @@ -120,7 +120,7 @@ class FreeplayDJ extends FlxAtlasSprite if (getCurrentAnimation() != animPrefix) playFlashAnimation('Boyfriend DJ fist pump', false); if (getCurrentAnimation() == animPrefix && anim.curFrame >= 4) { - anim.play("Boyfriend DJ fist pump", true, false, 0); + playAnimation("Boyfriend DJ fist pump", true, false, false, 0); } case FistPump: @@ -135,9 +135,12 @@ class FreeplayDJ extends FlxAtlasSprite timeIdling = 0; case Cartoon: var animPrefix = playableCharData.getAnimationPrefix('cartoon'); - if (animPrefix == null) { + if (animPrefix == null) + { currentState = IdleEasterEgg; - } else { + } + else + { if (getCurrentAnimation() != animPrefix) playFlashAnimation(animPrefix, true); timeIdling = 0; } @@ -145,6 +148,7 @@ class FreeplayDJ extends FlxAtlasSprite // I shit myself. } + #if debug if (FlxG.keys.pressed.CONTROL) { if (FlxG.keys.justPressed.LEFT) @@ -167,16 +171,17 @@ class FreeplayDJ extends FlxAtlasSprite this.offsetY += FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); } - if (FlxG.keys.justPressed.SPACE) + if (FlxG.keys.justPressed.C) { currentState = (currentState == Idle ? Cartoon : Idle); } } + #end } - function onFinishAnim():Void + function onFinishAnim(name:String):Void { - var name = anim.curSymbol.name; + // var name = anim.curSymbol.name; if (name == playableCharData.getAnimationPrefix('intro')) { @@ -220,7 +225,7 @@ class FreeplayDJ extends FlxAtlasSprite // runTvLogic(); } trace('Replay idle: ${frame}'); - anim.play(playableCharData.getAnimationPrefix('cartoon'), true, false, frame); + playAnimation(playableCharData.getAnimationPrefix('cartoon'), true, false, false, frame); // trace('Finished confirm'); } else @@ -266,7 +271,7 @@ class FreeplayDJ extends FlxAtlasSprite function loadCartoon() { cartoonSnd = FunkinSound.load(Paths.sound(getRandomFlashToon()), 1.0, false, true, true, function() { - anim.play("Boyfriend DJ watchin tv OG", true, false, 60); + playAnimation("Boyfriend DJ watchin tv OG", true, false, false, 60); }); // Fade out music to 40% volume over 1 second. @@ -304,13 +309,13 @@ class FreeplayDJ extends FlxAtlasSprite public function pumpFist():Void { currentState = FistPump; - anim.play("Boyfriend DJ fist pump", true, false, 4); + playAnimation("Boyfriend DJ fist pump", true, false, false, 4); } public function pumpFistBad():Void { currentState = FistPump; - anim.play("Boyfriend DJ loss reaction 1", true, false, 4); + playAnimation("Boyfriend DJ loss reaction 1", true, false, false, 4); } override public function getCurrentAnimation():String @@ -319,9 +324,9 @@ class FreeplayDJ extends FlxAtlasSprite return this.anim.curSymbol.name; } - public function playFlashAnimation(id:String, ?Force:Bool = false, ?Reverse:Bool = false, ?Frame:Int = 0):Void + public function playFlashAnimation(id:String, Force:Bool = false, Reverse:Bool = false, Loop:Bool = false, Frame:Int = 0):Void { - anim.play(id, Force, Reverse, Frame); + playAnimation(id, Force, Reverse, Loop, Frame); applyAnimOffset(); } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 690e3b910..03eb12ead 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1,7 +1,6 @@ package funkin.ui.freeplay; import flixel.addons.transition.FlxTransitionableState; -import flixel.addons.ui.FlxInputText; import flixel.FlxCamera; import flixel.FlxSprite; import flixel.group.FlxGroup; @@ -1795,7 +1794,7 @@ class FreeplayState extends MusicBeatSubState confirmGlow.visible = true; confirmGlow2.visible = true; - backingTextYeah.anim.play("BF back card confirm raw", false, false, 0); + backingTextYeah.playAnimation("BF back card confirm raw", false, false, false, 0); confirmGlow2.alpha = 0; confirmGlow.alpha = 0;