diff --git a/.gitignore b/.gitignore index d4aba58ac..b2fe731ea 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ APIStuff.hx dump/ export/ -RECOVER_*.fla \ No newline at end of file +RECOVER_*.fla +shitAudio/ diff --git a/art b/art index 1656bea53..d1aa2c6e8 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit 1656bea5370c65879aaeb323e329f403c78071c5 +Subproject commit d1aa2c6e81c0ddff8af3d6aac4700590cc5b0ef4 diff --git a/assets b/assets index 7bc9407e0..4ee0c341f 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7bc9407e0e8141a643605ff4514ba63169cc41e2 +Subproject commit 4ee0c341fd213017b98314d47d28f08b8e1d4289 diff --git a/hmm.json b/hmm.json index aa032fb75..3f420ac48 100644 --- a/hmm.json +++ b/hmm.json @@ -32,7 +32,7 @@ "name": "flxanimate", "type": "git", "dir": null, - "ref": "a9136359271cae6ea3016b7fd9023c5c42562933", + "ref": "dd2903f7dc7024335b981edf2a770760cec912e1", "url": "https://github.com/ninjamuffin99/flxanimate" }, { diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx index 6cd353233..3ae32c2e4 100644 --- a/source/funkin/FreeplayState.hx +++ b/source/funkin/FreeplayState.hx @@ -1,5 +1,6 @@ package funkin; +import funkin.shaderslmfao.HSVShader; import funkin.ui.StickerSubState; import flash.text.TextField; import flixel.FlxCamera; @@ -12,6 +13,7 @@ import flixel.addons.ui.FlxInputText; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup; import flixel.group.FlxSpriteGroup; +import flixel.system.debug.watch.Tracker.TrackerProfile; import flixel.input.touch.FlxTouch; import flixel.math.FlxAngle; import flixel.math.FlxMath; @@ -21,6 +23,7 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.util.FlxColor; import funkin.data.song.SongRegistry; +import funkin.data.level.LevelRegistry; import flixel.util.FlxSpriteUtil; import flixel.util.FlxTimer; import funkin.Controls.Control; @@ -29,6 +32,7 @@ import funkin.freeplayStuff.DJBoyfriend; import funkin.freeplayStuff.FreeplayScore; import funkin.freeplayStuff.LetterSort; import funkin.freeplayStuff.SongMenuItem; +import funkin.freeplayStuff.DifficultyStars; import funkin.play.HealthIcon; import funkin.play.PlayState; import funkin.shaderslmfao.AngleMask; @@ -38,6 +42,7 @@ import funkin.play.PlayStatePlaylist; import funkin.play.song.Song; import lime.app.Future; import lime.utils.Assets; +import funkin.graphics.adobeanimate.FlxAtlasSprite; class FreeplayState extends MusicBeatSubState { @@ -69,6 +74,7 @@ class FreeplayState extends MusicBeatSubState var grpSongs:FlxTypedGroup; var grpCapsules:FlxTypedGroup; + var curCapsule:SongMenuItem; var curPlaying:Bool = false; var dj:DJBoyfriend; @@ -114,44 +120,33 @@ class FreeplayState extends MusicBeatSubState #if debug isDebug = true; - addSong('Test', 'tutorial', 'bf-pixel'); - addSong('Pyro', 'weekend1', 'darnell'); + // addSong('Test', 'tutorial', 'bf-pixel'); + // addSong('Pyro', 'weekend1', 'darnell'); #end - var initSonglist = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); + // var initSonglist = CoolUtil.coolTextFile(Paths.txt('freeplaySonglist')); - for (i in 0...initSonglist.length) - { - songs.push(new FreeplaySongData(initSonglist[i], 'tutorial', 'gf')); - } + // for (i in 0...initSonglist.length) + // { + // songs.push(new FreeplaySongData(initSonglist[i], 'tutorial', 'gf')); + // } if (FlxG.sound.music != null) { if (!FlxG.sound.music.playing) FlxG.sound.playMusic(Paths.music('freakyMenu/freakyMenu')); } - // if (StoryMenuState.weekUnlocked[2] || isDebug) - addWeek(['Bopeebo', 'Fresh', 'Dadbattle'], 'week1', ['dad']); - - // if (StoryMenuState.weekUnlocked[2] || isDebug) - addWeek(['Spookeez', 'South', 'Monster'], 'week2', ['spooky', 'spooky', 'monster']); - - // if (StoryMenuState.weekUnlocked[3] || isDebug) - addWeek(['Pico', 'Philly-Nice', 'Blammed'], 'week3', ['pico']); - - // if (StoryMenuState.weekUnlocked[4] || isDebug) - addWeek(['Satin-Panties', 'High', 'MILF'], 'week4', ['mom']); - - // if (StoryMenuState.weekUnlocked[5] || isDebug) - addWeek(['Cocoa', 'Eggnog', 'Winter-Horrorland'], 'week5', ['parents-christmas', 'parents-christmas', 'monster-christmas']); - - // if (StoryMenuState.weekUnlocked[6] || isDebug) - addWeek(['Senpai', 'Roses', 'Thorns'], 'week6', ['senpai', 'senpai', 'spirit']); - - // if (StoryMenuState.weekUnlocked[7] || isDebug) - addWeek(['Ugh', 'Guns', 'Stress'], 'week7', ['tankman']); - - addWeek(["Darnell", "lit-up", "2hot", "blazin"], 'weekend1', ['darnell']); + // programmatically adds the songs via LevelRegistry and SongRegistry + for (coolWeek in LevelRegistry.instance.listBaseGameLevelIds()) + { + for (coolSong in LevelRegistry.instance.parseEntryData(coolWeek).songs) + { + var metadata = SongRegistry.instance.parseEntryMetadata(coolSong); + var char = metadata.playData.characters.opponent; + var songName = metadata.songName; + addSong(songName, coolWeek, char); + } + } // LOAD MUSIC @@ -169,7 +164,7 @@ class FreeplayState extends MusicBeatSubState FlxTween.tween(pinkBack, {x: 0}, 0.6, {ease: FlxEase.quartOut}); add(pinkBack); - var orangeBackShit:FlxSprite = new FlxSprite(84, FlxG.height * 0.68).makeGraphic(Std.int(pinkBack.width), 50, 0xFFffd400); + var orangeBackShit:FlxSprite = new FlxSprite(84, 440).makeGraphic(Std.int(pinkBack.width), 75, 0xFFfeda00); add(orangeBackShit); var alsoOrangeLOL:FlxSprite = new FlxSprite(0, orangeBackShit.y).makeGraphic(100, Std.int(orangeBackShit.height), 0xFFffd400); @@ -191,9 +186,11 @@ class FreeplayState extends MusicBeatSubState add(grpTxtScrolls); grpTxtScrolls.visible = false; - var moreWays:BGScrollingText = new BGScrollingText(0, 200, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width); + FlxG.debugger.addTrackerProfile(new TrackerProfile(BGScrollingText, ["x", "y", "speed", "size"])); + + var moreWays:BGScrollingText = new BGScrollingText(0, 160, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width, true, 43); moreWays.funnyColor = 0xFFfff383; - moreWays.speed = 4; + moreWays.speed = 6.8; grpTxtScrolls.add(moreWays); exitMovers.set([moreWays], @@ -202,9 +199,9 @@ class FreeplayState extends MusicBeatSubState speed: 0.4, }); - var funnyScroll:BGScrollingText = new BGScrollingText(0, 250, "BOYFRIEND", FlxG.width / 2); + var funnyScroll:BGScrollingText = new BGScrollingText(0, 220, "BOYFRIEND", FlxG.width / 2, false, 60); funnyScroll.funnyColor = 0xFFff9963; - funnyScroll.speed = -1; + funnyScroll.speed = -3.8; grpTxtScrolls.add(funnyScroll); exitMovers.set([funnyScroll], @@ -215,7 +212,8 @@ class FreeplayState extends MusicBeatSubState wait: 0 }); - var txtNuts:BGScrollingText = new BGScrollingText(0, 300, "PROTECT YO NUTS", FlxG.width / 2); + var txtNuts:BGScrollingText = new BGScrollingText(0, 285, "PROTECT YO NUTS", FlxG.width / 2, true, 43); + txtNuts.speed = 3.5; grpTxtScrolls.add(txtNuts); exitMovers.set([txtNuts], { @@ -223,9 +221,9 @@ class FreeplayState extends MusicBeatSubState speed: 0.4, }); - var funnyScroll2:BGScrollingText = new BGScrollingText(0, 340, "BOYFRIEND", FlxG.width / 2); + var funnyScroll2:BGScrollingText = new BGScrollingText(0, 335, "BOYFRIEND", FlxG.width / 2, false, 60); funnyScroll2.funnyColor = 0xFFff9963; - funnyScroll2.speed = -1.2; + funnyScroll2.speed = -3.8; grpTxtScrolls.add(funnyScroll2); exitMovers.set([funnyScroll2], @@ -234,9 +232,9 @@ class FreeplayState extends MusicBeatSubState speed: 0.5, }); - var moreWays2:BGScrollingText = new BGScrollingText(0, 400, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width); + var moreWays2:BGScrollingText = new BGScrollingText(0, 397, "HOT BLOODED IN MORE WAYS THAN ONE", FlxG.width, true, 43); moreWays2.funnyColor = 0xFFfff383; - moreWays2.speed = 4.4; + moreWays2.speed = 6.8; grpTxtScrolls.add(moreWays2); exitMovers.set([moreWays2], @@ -245,9 +243,9 @@ class FreeplayState extends MusicBeatSubState speed: 0.4 }); - var funnyScroll3:BGScrollingText = new BGScrollingText(0, orangeBackShit.y, "BOYFRIEND", FlxG.width / 2); - funnyScroll3.funnyColor = 0xFFff9963; - funnyScroll3.speed = -0.8; + var funnyScroll3:BGScrollingText = new BGScrollingText(0, orangeBackShit.y + 10, "BOYFRIEND", FlxG.width / 2, 60); + funnyScroll3.funnyColor = 0xFFfea400; + funnyScroll3.speed = -3.8; grpTxtScrolls.add(funnyScroll3); exitMovers.set([funnyScroll3], @@ -256,7 +254,8 @@ class FreeplayState extends MusicBeatSubState speed: 0.3 }); - dj = new DJBoyfriend(0, -100); + // dj = new DJBoyfriend(0, -100); + dj = new DJBoyfriend(640, 366); exitMovers.set([dj], { x: -dj.width * 1.6, @@ -312,6 +311,49 @@ class FreeplayState extends MusicBeatSubState grpDifficulties.group.members[curDifficulty].visible = true; + var albumArt:FlxAtlasSprite = new FlxAtlasSprite(640, 360, Paths.animateAtlas("freeplay/albumRoll")); + albumArt.visible = false; + add(albumArt); + + exitMovers.set([albumArt], + { + x: FlxG.width, + speed: 0.4, + wait: 0 + }); + + var albumTitle:FlxSprite = new FlxSprite(947, 491).loadGraphic(Paths.image('freeplay/albumTitle-fnfvol1')); + var albumArtist:FlxSprite = new FlxSprite(1010, 607).loadGraphic(Paths.image('freeplay/albumArtist-kawaisprite')); + var difficultyStars:DifficultyStars = new DifficultyStars(140, 39); + + difficultyStars.stars.visible = false; + albumTitle.visible = false; + albumArtist.visible = false; + + exitMovers.set([albumTitle], + { + x: FlxG.width, + speed: 0.2, + wait: 0.1 + }); + + exitMovers.set([albumArtist], + { + x: FlxG.width * 1.1, + speed: 0.2, + wait: 0.2 + }); + exitMovers.set([difficultyStars], + { + x: FlxG.width * 1.2, + speed: 0.2, + wait: 0.3 + }); + + add(albumTitle); + add(albumArtist); + add(difficultyStars); + var overhangStuff:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, 64, FlxColor.BLACK); overhangStuff.y -= overhangStuff.height; add(overhangStuff); @@ -355,6 +397,28 @@ class FreeplayState extends MusicBeatSubState txtCompletion.visible = false; add(txtCompletion); + var letterSort:LetterSort = new LetterSort(400, 75); + add(letterSort); + letterSort.visible = false; + + exitMovers.set([letterSort], + { + y: -100, + speed: 0.3 + }); + + letterSort.changeSelectionCallback = (str) -> { + switch (str) + { + case "fav": + generateSongList({filterType: FAVORITE}, true); + case "ALL": + generateSongList(null, true); + default: + generateSongList({filterType: REGEXP, filterData: str}, true); + } + }; + exitMovers.set([fp, txtCompletion, fnfHighscoreSpr], { x: FlxG.width, @@ -362,6 +426,24 @@ class FreeplayState extends MusicBeatSubState }); dj.onIntroDone.add(function() { + // when boyfriend hits dat shiii + // + + albumArt.visible = true; + albumArt.anim.play(""); + albumArt.anim.onComplete = function() { + albumArt.anim.pause(); + }; + + new FlxTimer().start(1, function(_) { + albumTitle.visible = true; + }); + + new FlxTimer().start(35 / 24, function(_) { + albumArtist.visible = true; + difficultyStars.stars.visible = true; + }); + FlxTween.tween(grpDifficulties, {x: 90}, 0.6, {ease: FlxEase.quartOut}); var diffSelLeft = new DifficultySelector(20, grpDifficulties.y - 10, false, controls); @@ -370,33 +452,14 @@ class FreeplayState extends MusicBeatSubState add(diffSelLeft); add(diffSelRight); + letterSort.visible = true; + exitMovers.set([diffSelLeft, diffSelRight], { x: -diffSelLeft.width * 2, speed: 0.26 }); - var letterSort:LetterSort = new LetterSort(300, 100); - add(letterSort); - - exitMovers.set([letterSort], - { - y: -100, - speed: 0.3 - }); - - letterSort.changeSelectionCallback = (str) -> { - switch (str) - { - case "fav": - generateSongList({filterType: FAVORITE}, true); - case "ALL": - generateSongList(null, true); - default: - generateSongList({filterType: STARTSWITH, filterData: str}, true); - } - }; - new FlxTimer().start(1 / 24, function(handShit) { fnfHighscoreSpr.visible = true; fnfFreeplay.visible = true; @@ -409,18 +472,18 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(1.5 / 24, function(bold) { sillyStroke.width = 0; sillyStroke.height = 0; + changeSelection(); }); }); pinkBack.color = 0xFFffd863; - // fnfFreeplay.visible = true; bgDad.visible = true; orangeBackShit.visible = true; alsoOrangeLOL.visible = true; grpTxtScrolls.visible = true; }); - generateSongList(); + generateSongList(null, false); // FlxG.sound.playMusic(Paths.music('title'), 0); // FlxG.sound.music.fadeIn(2, 0, 0.8); @@ -466,9 +529,12 @@ class FreeplayState extends MusicBeatSubState public function generateSongList(?filterStuff:SongFilter, force:Bool = false) { - curSelected = 0; + curSelected = 1; - grpCapsules.clear(); + for (cap in grpCapsules.members) + cap.kill(); + + // grpCapsules.clear(); // var regexp:EReg = regexp; var tempSongs:Array = songs; @@ -477,6 +543,13 @@ class FreeplayState extends MusicBeatSubState { switch (filterStuff.filterType) { + case REGEXP: + // filterStuff.filterData has a string with the first letter of the sorting range, and the second one + // this creates a filter to return all the songs that start with a letter between those two + var filterRegexp = new EReg("^[" + filterStuff.filterData + "].*", "i"); + tempSongs = tempSongs.filter(str -> { + return filterRegexp.match(str.songName); + }); case STARTSWITH: tempSongs = tempSongs.filter(str -> { return str.songName.toLowerCase().startsWith(filterStuff.filterData); @@ -492,54 +565,48 @@ class FreeplayState extends MusicBeatSubState } } + var hsvShader:HSVShader = new HSVShader(); + + var randomCapsule:SongMenuItem = grpCapsules.recycle(SongMenuItem); + randomCapsule.init(FlxG.width, 0, "Random"); + randomCapsule.onConfirm = function() { + trace("RANDOM SELECTED"); + }; + randomCapsule.y = randomCapsule.intendedY(0) + 10; + randomCapsule.targetPos.x = randomCapsule.x; + randomCapsule.alpha = 0.5; + randomCapsule.songText.visible = false; + randomCapsule.favIcon.visible = false; + randomCapsule.initJumpIn(0, force); + randomCapsule.hsvShader = hsvShader; + grpCapsules.add(randomCapsule); + for (i in 0...tempSongs.length) { - var funnyMenu:SongMenuItem = new SongMenuItem(FlxG.width, (i * 150) + 160, tempSongs[i].songName); + var funnyMenu:SongMenuItem = grpCapsules.recycle(SongMenuItem); + funnyMenu.init(FlxG.width, 0, tempSongs[i].songName); + if (tempSongs[i].songCharacter != null) funnyMenu.setCharacter(tempSongs[i].songCharacter); + funnyMenu.onConfirm = function() { + capsuleOnConfirmDefault(funnyMenu); + }; + funnyMenu.y = funnyMenu.intendedY(i + 1) + 10; funnyMenu.targetPos.x = funnyMenu.x; funnyMenu.ID = i; - funnyMenu.alpha = 0.5; + funnyMenu.capsule.alpha = 0.5; funnyMenu.songText.visible = false; funnyMenu.favIcon.visible = tempSongs[i].isFav; - + funnyMenu.hsvShader = hsvShader; // fp.updateScore(0); - var maxTimer:Float = Math.min(i, 4); - - new FlxTimer().start((1 / 24) * maxTimer, function(doShit) { - funnyMenu.doJumpIn = true; - }); - - new FlxTimer().start((0.09 * maxTimer) + 0.85, function(lerpTmr) { - funnyMenu.doLerp = true; - }); - - if (!force) - { - new FlxTimer().start(((0.20 * maxTimer) / (1 + maxTimer)) + 0.75, function(swagShi) { - funnyMenu.songText.visible = true; - funnyMenu.alpha = 1; - }); - } + if (i < 8) funnyMenu.initJumpIn(Math.min(i, 4), force); else - { - funnyMenu.songText.visible = true; - funnyMenu.alpha = 1; - } + funnyMenu.forcePosition(); grpCapsules.add(funnyMenu); - - var songText:Alphabet = new Alphabet(0, (70 * i) + 30, tempSongs[i].songName, true, false); - songText.x += 100; - songText.isMenuItem = true; - songText.targetY = i; - - // grpSongs.add(songText); - - // songText.x += 40; - // DONT PUT X IN THE FIRST PARAMETER OF new ALPHABET() !! - // songText.screenCenter(X); } + FlxG.console.registerFunction("changeSelection", changeSelection); + changeSelection(); changeDiff(); } @@ -830,66 +897,7 @@ class FreeplayState extends MusicBeatSubState { // if (Assets.exists()) - var poop:String = songs[curSelected].songName.toLowerCase(); - - // does not work properly, always just accidentally sets it to normal anyways! - /* if (!Assets.exists(Paths.json(songs[curSelected].songName + '/' + poop))) - { - // defaults to normal if HARD / EASY doesn't exist - // does not account if NORMAL doesn't exist! - FlxG.log.warn("CURRENT DIFFICULTY IS NOT CHARTED, DEFAULTING TO NORMAL!"); - poop = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), 1); - curDifficulty = 1; - }*/ - - PlayStatePlaylist.isStoryMode = false; - var songId:String = songs[curSelected].songName.toLowerCase(); - var targetSong:Song = SongRegistry.instance.fetchEntry(songId); - var targetDifficulty:String = switch (curDifficulty) - { - case 0: - 'easy'; - case 1: - 'normal'; - case 2: - 'hard'; - default: 'normal'; - }; - - // TODO: Implement additional difficulties into the interface properly. - if (FlxG.keys.pressed.E) - { - targetDifficulty = 'erect'; - } - - // TODO: Implement Pico into the interface properly. - var targetCharacter:String = 'bf'; - if (FlxG.keys.pressed.P) - { - targetCharacter = 'pico'; - } - - PlayStatePlaylist.campaignId = songs[curSelected].levelId; - - // Visual and audio effects. - FlxG.sound.play(Paths.sound('confirmMenu')); - dj.confirm(); - - if (targetSong != null) - { - // Load and cache the song's charts. - // TODO: Do this in the loading state. - targetSong.cacheCharts(true); - } - - new FlxTimer().start(1, function(tmr:FlxTimer) { - LoadingState.loadAndSwitchState(new PlayState( - { - targetSong: targetSong, - targetDifficulty: targetDifficulty, - targetCharacter: targetCharacter, - }), true); - }); + grpCapsules.members[curSelected].onConfirm(); } } @@ -941,45 +949,124 @@ class FreeplayState extends MusicBeatSubState } } + function capsuleOnConfirmDefault(cap:SongMenuItem):Void + { + // var poop:String = songs[curSelected].songName.toLowerCase(); + + // does not work properly, always just accidentally sets it to normal anyways! + /* if (!Assets.exists(Paths.json(songs[curSelected].songName + '/' + poop))) + { + // defaults to normal if HARD / EASY doesn't exist + // does not account if NORMAL doesn't exist! + FlxG.log.warn("CURRENT DIFFICULTY IS NOT CHARTED, DEFAULTING TO NORMAL!"); + poop = Highscore.formatSong(songs[curSelected].songName.toLowerCase(), 1); + curDifficulty = 1; + }*/ + + PlayStatePlaylist.isStoryMode = false; + + var songId:String = cap.songTitle.toLowerCase(); + var targetSong:Song = SongRegistry.instance.fetchEntry(songId); + var targetDifficulty:String = switch (curDifficulty) + { + case 0: + 'easy'; + case 1: + 'normal'; + case 2: + 'hard'; + default: 'normal'; + }; + + // TODO: Implement additional difficulties into the interface properly. + if (FlxG.keys.pressed.E) + { + targetDifficulty = 'erect'; + } + + // TODO: Implement Pico into the interface properly. + var targetCharacter:String = 'bf'; + if (FlxG.keys.pressed.P) + { + targetCharacter = 'pico'; + } + + PlayStatePlaylist.campaignId = songs[curSelected].levelId; + + // Visual and audio effects. + FlxG.sound.play(Paths.sound('confirmMenu')); + dj.confirm(); + + // Load and cache the song's charts. + // TODO: Do this in the loading state. + targetSong.cacheCharts(true); + + new FlxTimer().start(1, function(tmr:FlxTimer) { + LoadingState.loadAndSwitchState(new PlayState( + { + targetSong: targetSong, + targetDifficulty: targetDifficulty, + targetCharacter: targetCharacter, + }), true); + }); + } + function changeSelection(change:Int = 0) { // fp.updateScore(12345); - NGio.logEvent('Fresh'); - // NGio.logEvent('Fresh'); FlxG.sound.play(Paths.sound('scrollMenu'), 0.4); + // FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName)); curSelected += change; - if (curSelected < 0) curSelected = grpCapsules.members.length - 1; - if (curSelected >= grpCapsules.members.length) curSelected = 0; + if (curSelected < 0) curSelected = grpCapsules.countLiving() - 1; + if (curSelected >= grpCapsules.countLiving()) curSelected = 0; // selector.y = (70 * curSelected) + 30; // intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); - intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); - intendedCompletion = Highscore.getCompletion(songs[curSelected].songName, curDifficulty); + + if (songs[curSelected] != null) + { + intendedScore = Highscore.getScore(songs[curSelected].songName, curDifficulty); + intendedCompletion = Highscore.getCompletion(songs[curSelected].songName, curDifficulty); + } + else + { + intendedScore = 0; + intendedCompletion = 0; + } + // lerpScore = 0; #if PRELOAD_ALL // FlxG.sound.playMusic(Paths.inst(songs[curSelected].songName), 0); #end - var bullShit:Int = 0; - for (index => capsule in grpCapsules.members) { - capsule.selected = false; + index += 1; - capsule.targetPos.y = ((index - curSelected) * 150) + 160; + capsule.selected = index == curSelected + 1; + + capsule.targetPos.y = capsule.intendedY(index - curSelected); capsule.targetPos.x = 270 + (60 * (Math.sin(index - curSelected))); // capsule.targetPos.x = 320 + (40 * (index - curSelected)); if (index < curSelected) capsule.targetPos.y -= 100; // another 100 for good measure } - if (grpCapsules.members.length > 0) grpCapsules.members[curSelected].selected = true; + if (grpCapsules.countLiving() > 0) + { + if (curSelected == 0) + { + FlxG.sound.playMusic(Paths.music('freeplay/freeplayRandom'), 0); + FlxG.sound.music.fadeIn(2, 0, 0.8); + } + grpCapsules.members[curSelected].selected = true; + } } } @@ -1019,7 +1106,10 @@ class DifficultySelector extends FlxSprite whiteShader.colorSet = true; + scale.x = scale.y = 0.5; + new FlxTimer().start(2 / 24, function(tmr) { + scale.x = scale.y = 1; whiteShader.colorSet = false; updateHitbox(); }); @@ -1035,6 +1125,7 @@ typedef SongFilter = enum abstract FilterType(String) { var STARTSWITH; + var REGEXP; var FAVORITE; var ALL; } diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx index c8c9c79b7..07a15dae1 100644 --- a/source/funkin/Paths.hx +++ b/source/funkin/Paths.hx @@ -49,9 +49,9 @@ class Paths return getPath(file, type, library); } - public static inline function animateAtlas(path:String, library:String) + public static inline function animateAtlas(path:String, ?library:String) { - return getLibraryPathForce('images/$path', library); + return getLibraryPath('images/$path', library); } inline static public function txt(key:String, ?library:String) diff --git a/source/funkin/audio/FlxStreamSound.hx b/source/funkin/audio/FlxStreamSound.hx new file mode 100644 index 000000000..a572ad436 --- /dev/null +++ b/source/funkin/audio/FlxStreamSound.hx @@ -0,0 +1,49 @@ +package funkin.audio; + +import flash.media.Sound; +#if flash11 +import flash.utils.ByteArray; +#end +import flixel.sound.FlxSound; +import flixel.system.FlxAssets.FlxSoundAsset; +import openfl.Assets; +#if (openfl >= "8.0.0") +import openfl.utils.AssetType; +#end + +/** + * a FlxSound that just overrides loadEmbedded to allow for "streamed" sounds to load with better performance! + */ +class FlxStreamSound extends FlxSound +{ + public function new() + { + super(); + } + + override public function loadEmbedded(EmbeddedSound:FlxSoundAsset, Looped:Bool = false, AutoDestroy:Bool = false, ?OnComplete:Void->Void):FlxSound + { + if (EmbeddedSound == null) return this; + + cleanup(true); + + if ((EmbeddedSound is Sound)) + { + _sound = EmbeddedSound; + } + else if ((EmbeddedSound is Class)) + { + _sound = Type.createInstance(EmbeddedSound, []); + } + else if ((EmbeddedSound is String)) + { + if (Assets.exists(EmbeddedSound, AssetType.SOUND) + || Assets.exists(EmbeddedSound, AssetType.MUSIC)) _sound = Assets.getMusic(EmbeddedSound); + else + FlxG.log.error('Could not find a Sound asset with an ID of \'$EmbeddedSound\'.'); + } + + // NOTE: can't pull ID3 info from embedded sound currently + return init(Looped, AutoDestroy, OnComplete); + } +} diff --git a/source/funkin/freeplayStuff/BGScrollingText.hx b/source/funkin/freeplayStuff/BGScrollingText.hx index 9fa6dd49b..586f83822 100644 --- a/source/funkin/freeplayStuff/BGScrollingText.hx +++ b/source/funkin/freeplayStuff/BGScrollingText.hx @@ -7,6 +7,7 @@ import flixel.math.FlxMath; import flixel.text.FlxText; import flixel.util.FlxColor; import flixel.util.FlxSort; +import flixel.util.FlxTimer; // its kinda like marqeee html lol! class BGScrollingText extends FlxSpriteGroup @@ -16,36 +17,53 @@ class BGScrollingText extends FlxSpriteGroup public var widthShit:Float = FlxG.width; public var placementOffset:Float = 20; public var speed:Float = 1; + public var size(default, set):Int = 48; public var funnyColor(default, set):Int = 0xFFFFFFFF; - public function new(x:Float, y:Float, text:String, widthShit:Float = 100) + public function new(x:Float, y:Float, text:String, widthShit:Float = 100, ?bold:Bool = false, ?size:Int = 48) { super(x, y); this.widthShit = widthShit; + if (size != null) this.size = size; grpTexts = new FlxTypedSpriteGroup(); add(grpTexts); - var testText:FlxText = new FlxText(0, 0, 0, text, 48); + var testText:FlxText = new FlxText(0, 0, 0, text, this.size); testText.font = "5by7"; + testText.bold = bold; testText.updateHitbox(); grpTexts.add(testText); - var needed:Int = Math.ceil(widthShit / testText.frameWidth); + var needed:Int = Math.ceil(widthShit / testText.frameWidth) + 1; for (i in 0...needed) { var lmfao:Int = i + 1; - var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, 48); + var coolText:FlxText = new FlxText((lmfao * testText.frameWidth) + (lmfao * 20), 0, 0, text, this.size); + coolText.font = "5by7"; + coolText.bold = bold; coolText.updateHitbox(); grpTexts.add(coolText); } } + function set_size(value:Int):Int + { + if (grpTexts != null) + { + grpTexts.forEach(function(txt:FlxText) { + txt.size = value; + }); + } + this.size = value; + return value; + } + function set_funnyColor(col:Int):Int { grpTexts.forEach(function(txt) { @@ -55,7 +73,7 @@ class BGScrollingText extends FlxSpriteGroup return col; } - override function update(elapsed:Float) + override public function update(elapsed:Float) { for (txt in grpTexts.group) { @@ -66,14 +84,16 @@ class BGScrollingText extends FlxSpriteGroup if (txt.x < -txt.frameWidth) { txt.x = grpTexts.group.members[grpTexts.length - 1].x + grpTexts.group.members[grpTexts.length - 1].frameWidth + placementOffset; + sortTextShit(); } } else { - if (txt.x > widthShit) + if (txt.x > txt.frameWidth * 2) { txt.x = grpTexts.group.members[0].x - grpTexts.group.members[0].frameWidth - placementOffset; + sortTextShit(); } } diff --git a/source/funkin/freeplayStuff/CapsuleText.hx b/source/funkin/freeplayStuff/CapsuleText.hx new file mode 100644 index 000000000..dda687f5e --- /dev/null +++ b/source/funkin/freeplayStuff/CapsuleText.hx @@ -0,0 +1,49 @@ +package funkin.freeplayStuff; + +import openfl.filters.BitmapFilterQuality; +import flixel.text.FlxText; +import flixel.group.FlxSpriteGroup; +import funkin.shaderslmfao.GaussianBlurShader; + +class CapsuleText extends FlxSpriteGroup +{ + public var blurredText:FlxText; + + var whiteText:FlxText; + + public var text(default, set):String; + + public function new(x:Float, y:Float, songTitle:String, size:Float) + { + super(x, y); + + blurredText = initText(songTitle, size); + blurredText.shader = new GaussianBlurShader(1); + whiteText = initText(songTitle, size); + // whiteText.shader = new GaussianBlurShader(0.3); + text = songTitle; + + blurredText.color = 0xFF00ccff; + whiteText.color = 0xFFFFFFFF; + add(blurredText); + add(whiteText); + } + + function initText(songTitle, size:Float):FlxText + { + var text:FlxText = new FlxText(0, 0, 0, songTitle, Std.int(size)); + text.font = "5by7"; + return text; + } + + function set_text(value:String):String + { + blurredText.text = value; + whiteText.text = value; + whiteText.textField.filters = [ + new openfl.filters.GlowFilter(0x00ccff, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM), + // new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW) + ]; + return value; + } +} diff --git a/source/funkin/freeplayStuff/DJBoyfriend.hx b/source/funkin/freeplayStuff/DJBoyfriend.hx index 5bee4129a..ba0ce464d 100644 --- a/source/funkin/freeplayStuff/DJBoyfriend.hx +++ b/source/funkin/freeplayStuff/DJBoyfriend.hx @@ -3,8 +3,12 @@ package funkin.freeplayStuff; import flixel.FlxSprite; import flixel.util.FlxSignal; import funkin.util.assets.FlxAnimationUtil; +import funkin.graphics.adobeanimate.FlxAtlasSprite; +import flixel.system.FlxSound; +import flixel.util.FlxTimer; +import funkin.audio.FlxStreamSound; -class DJBoyfriend extends FlxSprite +class DJBoyfriend extends FlxAtlasSprite { // Represents the sprite's current status. // Without state machines I would have driven myself crazy years ago. @@ -20,20 +24,55 @@ class DJBoyfriend extends FlxSprite // TODO: Switch this class to use SwagSprite instead. public var animOffsets:Map>; - static final SPOOK_PERIOD:Float = 180.0; + var gotSpooked:Bool = false; + + static final SPOOK_PERIOD:Float = 120.0; + static final TV_PERIOD:Float = 180.0; // Time since dad last SPOOKED you. var timeSinceSpook:Float = 0; public function new(x:Float, y:Float) { - super(x, y); + super(x, y, Paths.animateAtlas("freeplay/freeplay-boyfriend", "preload")); animOffsets = new Map>(); - setupAnimations(); + anim.callback = function(name, number) { + switch (name) + { + case "Boyfriend DJ watchin tv OG": + if (number == 85) runTvLogic(); + default: + } + }; - animation.finishCallback = onFinishAnim; + setupAnimations(); + trace(listAnimations()); + + FlxG.debugger.track(this); + FlxG.console.registerObject("dj", this); + + anim.onComplete = onFinishAnim; + + FlxG.console.registerFunction("tv", function() { + currentState = TV; + }); + } + + /* + [remote hand under,boyfriend top head,brim piece,arm cringe l,red lazer,dj arm in,bf fist pump arm,hand raised right,forearm left,fist shaking,bf smile eyes closed face,arm cringe r,bf clenched face,face shrug,boyfriend falling,blue tint 1,shirt sleeve,bf clenched fist,head BF relaxed,blue tint 2,hand down left,blue tint 3,blue tint 4,head less smooshed,blue tint 5,boyfriend freeplay,BF head slight turn,blue tint 6,arm shrug l,blue tint 7,shoulder raised w sleeve,blue tint 8,fist pump face,blue tint 9,foot rested light,hand turnaround,arm chill right,Boyfriend DJ,arm shrug r,head back bf,hat top piece,dad bod,face surprise snap,Boyfriend DJ fist pump,office chair,foot rested right,chest down,office chair upright,body chill,bf dj afk,head mouth open dad,BF Head defalt HAIR BLOWING,hand shrug l,face piece,foot wag,turn table,shoulder up left,turntable lights,boyfriend dj body shirt blowing,body chunk turned,hand down right,dj arm out,hand shrug r,body chest out,rave hand,palm,chill face default,head back semi bf,boyfriend bottom head,DJ arm,shoulder right dad,bf surprise,boyfriend dj body,hs1,Boyfriend DJ watchin tv OG,spinning disk,hs2,arm chill left,boyfriend dj intro,hs3,hs4,chill face extra,hs5,remote hand upright,hs6,pant over table,face surprise,bf arm peace,arm turnaround,bf eyes 1,arm slammed table,eye squit,leg BF,head mid piece,arm backing,arm swoopin in,shoe right lowering,forearm right,hand out,blue tint 10,body falling back,remote thumb press,shoulder,hair spike single,bf bent + arm,crt,foot raised right,dad hand,chill face 1,chill face 2,clenched fist,head SMOOSHED,shoulder left dad,df1,body chunk upright,df2,df3,df4,hat front piece,df5,foot rested right 2,hand in,arm spun,shoe raised left,bf 1 finger hand,bf mouth 1,Boyfriend DJ confirm,forearm down ,hand raised left,remote thumb up] + */ + override public function listAnimations():Array + { + var anims:Array = []; + @:privateAccess + for (animKey in anim.symbolDictionary) + { + anims.push(animKey.name); + } + return anims; } public override function update(elapsed:Float):Void @@ -44,51 +83,68 @@ class DJBoyfriend extends FlxSprite { case Intro: // Play the intro animation then leave this state immediately. - if (getCurrentAnimation() != 'intro') playAnimation('intro', true); + if (getCurrentAnimation() != 'boyfriend dj intro') playFlashAnimation('boyfriend dj intro', true); timeSinceSpook = 0; case Idle: // We are in this state the majority of the time. - if (getCurrentAnimation() != 'idle' || animation.finished) + if (getCurrentAnimation() != 'Boyfriend DJ' || anim.finished) { - if (timeSinceSpook > SPOOK_PERIOD) + if (timeSinceSpook > SPOOK_PERIOD && !gotSpooked) { currentState = Spook; } + else if (timeSinceSpook > TV_PERIOD) + { + currentState = TV; + } else { - playAnimation('idle', false); + playFlashAnimation('Boyfriend DJ', false); } } timeSinceSpook += elapsed; case Confirm: - if (getCurrentAnimation() != 'confirm') playAnimation('confirm', false); + if (getCurrentAnimation() != 'Boyfriend DJ confirm') playFlashAnimation('Boyfriend DJ confirm', false); timeSinceSpook = 0; case Spook: - if (getCurrentAnimation() != 'spook') + if (getCurrentAnimation() != 'bf dj afk') { onSpook.dispatch(); - playAnimation('spook', false); + playFlashAnimation('bf dj afk', false); } timeSinceSpook = 0; + case TV: + if (getCurrentAnimation() != 'Boyfriend DJ watchin tv OG') playFlashAnimation('Boyfriend DJ watchin tv OG', true); + timeSinceSpook = 0; default: // I shit myself. } } - function onFinishAnim(name:String):Void + function onFinishAnim():Void { + var name = anim.curSymbol.name; switch (name) { - case "intro": + case "boyfriend dj intro": // trace('Finished intro'); currentState = Idle; onIntroDone.dispatch(); - case "idle": + case "Boyfriend DJ": // trace('Finished idle'); - case "spook": + case "bf dj afk": // trace('Finished spook'); currentState = Idle; - case "confirm": + case "Boyfriend DJ confirm": + + case "Boyfriend DJ watchin tv OG": + var frame:Int = FlxG.random.bool(33) ? 112 : 166; + if (FlxG.random.bool(10)) + { + frame = 60; + // boyfriend switches channel code? + } + anim.play("Boyfriend DJ watchin tv OG", true, false, frame); // trace('Finished confirm'); } } @@ -100,19 +156,66 @@ class DJBoyfriend extends FlxSprite function setupAnimations():Void { - frames = FlxAnimationUtil.combineFramesCollections(Paths.getSparrowAtlas('freeplay/bfFreeplay'), Paths.getSparrowAtlas('freeplay/bf-freeplay-afk')); + // frames = FlxAnimationUtil.combineFramesCollections(Paths.getSparrowAtlas('freeplay/bfFreeplay'), Paths.getSparrowAtlas('freeplay/bf-freeplay-afk')); - animation.addByPrefix('intro', "boyfriend dj intro", 24, false); - addOffset('intro', 0, 0); + // animation.addByPrefix('intro', "boyfriend dj intro", 24, false); + addOffset('boyfriend dj intro', 8, 3); - animation.addByPrefix('idle', "Boyfriend DJ0", 24, false); - addOffset('idle', -4, -426); + // animation.addByPrefix('idle', "Boyfriend DJ0", 24, false); + addOffset('Boyfriend DJ', 0, 0); - animation.addByPrefix('confirm', "Boyfriend DJ confirm", 24, false); - addOffset('confirm', 40, -451); + // animation.addByPrefix('confirm', "Boyfriend DJ confirm", 24, false); + addOffset('Boyfriend DJ confirm', 0, 0); - animation.addByPrefix('spook', "bf dj afk0", 24, false); - addOffset('spook', -3, -272); + // animation.addByPrefix('spook', "bf dj afk0", 24, false); + addOffset('bf dj afk', 0, 0); + } + + var cartoonSnd:FlxStreamSound; + + public var playingCartoon:Bool = false; + + public function runTvLogic() + { + if (cartoonSnd == null) + { + // tv is OFF, but getting turned on + FlxG.sound.play(Paths.sound('tv_on')); + + cartoonSnd = new FlxStreamSound(); + FlxG.sound.defaultSoundGroup.add(cartoonSnd); + } + else + { + // plays it smidge after the click + new FlxTimer().start(0.1, function(_) { + FlxG.sound.play(Paths.sound('channel_switch')); + }); + } + // cartoonSnd.loadEmbedded(Paths.sound("cartoons/peck")); + // cartoonSnd.play(); + + loadCartoon(); + } + + function loadCartoon() + { + cartoonSnd.loadEmbedded(Paths.sound(getRandomFlashToon()), false, false, function() { + anim.play("Boyfriend DJ watchin tv OG", true, false, 60); + }); + cartoonSnd.play(true, FlxG.random.float(0, cartoonSnd.length)); + } + + var cartoonList:Array = openfl.utils.Assets.list().filter(function(path) return path.startsWith("assets/sounds/cartoons/")); + + function getRandomFlashToon():String + { + var randomFile = FlxG.random.getObject(cartoonList); + + randomFile = randomFile.replace("assets/sounds/", ""); + randomFile = randomFile.substring(0, randomFile.length - 4); + + return randomFile; } public function confirm():Void @@ -125,15 +228,15 @@ class DJBoyfriend extends FlxSprite animOffsets[name] = [x, y]; } - public function getCurrentAnimation():String + override public function getCurrentAnimation():String { - if (this.animation == null || this.animation.curAnim == null) return ""; - return this.animation.curAnim.name; + if (this.anim == null || this.anim.curSymbol == null) return ""; + return this.anim.curSymbol.name; } - public function playAnimation(AnimName:String, Force:Bool = false, Reversed:Bool = false, Frame:Int = 0):Void + public function playFlashAnimation(id:String, ?Force:Bool = false, ?Reverse:Bool = false, ?Frame:Int = 0):Void { - animation.play(AnimName, Force, Reversed, Frame); + anim.play(id, Force, Reverse, Frame); applyAnimOffset(); } @@ -156,4 +259,5 @@ enum DJBoyfriendState Idle; Confirm; Spook; + TV; } diff --git a/source/funkin/freeplayStuff/DifficultyStars.hx b/source/funkin/freeplayStuff/DifficultyStars.hx new file mode 100644 index 000000000..8611727be --- /dev/null +++ b/source/funkin/freeplayStuff/DifficultyStars.hx @@ -0,0 +1,106 @@ +package funkin.freeplayStuff; + +import flixel.group.FlxSpriteGroup; +import funkin.graphics.adobeanimate.FlxAtlasSprite; +import funkin.shaderslmfao.HSVShader; + +class DifficultyStars extends FlxSpriteGroup +{ + /** + * Internal handler var for difficulty... ranges from 0... to 15 + * 0 is 1 star... 15 is 0 stars! + */ + var curDifficulty(default, set):Int = 0; + + /** + * Range between 0 and 15 + */ + public var difficulty(default, set):Int = 1; + + public var stars:FlxAtlasSprite; + + var flames:FreeplayFlames; + + var hsvShader:HSVShader; + + public function new(x:Float, y:Float) + { + super(x, y); + + hsvShader = new HSVShader(); + + flames = new FreeplayFlames(0, 0); + add(flames); + + stars = new FlxAtlasSprite(0, 0, Paths.animateAtlas("freeplay/freeplayStars")); + stars.anim.play("diff stars"); + add(stars); + + stars.shader = hsvShader; + + for (memb in flames.members) + memb.shader = hsvShader; + } + + override function update(elapsed:Float):Void + { + super.update(elapsed); + + // "loops" the current animation + // for clarity, the animation file looks like + // frame : stars + // 0-99: 1 star + // 100-199: 2 stars + // ...... + // 1300-1499: 15 stars + // 1500 : 0 stars + if (curDifficulty < 15 && stars.anim.curFrame >= (curDifficulty + 1) * 100) + { + stars.anim.play("diff stars", true, false, curDifficulty * 100); + } + } + + function set_difficulty(value:Int):Int + { + difficulty = value; + + if (difficulty <= 0) + { + difficulty = 0; + curDifficulty = 15; + } + else if (difficulty <= 15) + { + difficulty = value; + curDifficulty = difficulty - 1; + } + else + { + difficulty = 15; + curDifficulty = difficulty - 1; + } + + if (difficulty > 10) flames.flameCount = difficulty - 10; + else + flames.flameCount = 0; + + return difficulty; + } + + function set_curDifficulty(value:Int):Int + { + curDifficulty = value; + if (curDifficulty == 15) + { + stars.anim.play("diff stars", true, false, 1500); + stars.anim.pause(); + } + else + { + stars.anim.curFrame = Std.int(curDifficulty * 100); + stars.anim.play("diff stars", true, false, curDifficulty * 100); + } + + return curDifficulty; + } +} diff --git a/source/funkin/freeplayStuff/FreeplayFlames.hx b/source/funkin/freeplayStuff/FreeplayFlames.hx new file mode 100644 index 000000000..8f54d210b --- /dev/null +++ b/source/funkin/freeplayStuff/FreeplayFlames.hx @@ -0,0 +1,117 @@ +package funkin.freeplayStuff; + +import flixel.group.FlxSpriteGroup; +import flixel.FlxSprite; +import flixel.util.FlxTimer; + +class FreeplayFlames extends FlxSpriteGroup +{ + var flameX(default, set):Float = 917; + var flameY(default, set):Float = 103; + var flameSpreadX(default, set):Float = 29; + var flameSpreadY(default, set):Float = 6; + + public var flameCount(default, set):Int = 0; + + var flameTimer:Float = 0.25; + + public function new(x:Float, y:Float) + { + super(x, y); + + for (i in 0...5) + { + var flame:FlxSprite = new FlxSprite(flameX + (flameSpreadX * i), flameY + (flameSpreadY * i)); + flame.frames = Paths.getSparrowAtlas("freeplay/freeplayFlame"); + flame.animation.addByPrefix("flame", "fire loop", FlxG.random.int(23, 25), false); + flame.animation.play("flame"); + flame.visible = false; + flameCount = 0; + + // sets the loop... maybe better way to do this lol! + flame.animation.finishCallback = function(_) { + flame.animation.play("flame", true, false, 2); + }; + add(flame); + } + } + + var properPositions:Bool = false; + + override public function update(elapsed:Float):Void + { + super.update(elapsed); + // doesn't work in create()/new() for some reason + // so putting it here bwah! + if (!properPositions) + { + setFlamePositions(); + properPositions = true; + } + } + + function set_flameCount(value:Int):Int + { + this.flameCount = value; + var visibleCount:Int = 0; + for (i in 0...5) + { + if (members[i] == null) continue; + var flame:FlxSprite = members[i]; + if (i < flameCount) + { + if (!flame.visible) + { + new FlxTimer().start(flameTimer * visibleCount, function(_) { + flame.animation.play("flame", true); + flame.visible = true; + }); + visibleCount++; + } + } + else + { + flame.visible = false; + } + } + return this.flameCount; + } + + function setFlamePositions() + { + for (i in 0...5) + { + var flame:FlxSprite = members[i]; + flame.x = flameX + (flameSpreadX * i); + flame.y = flameY + (flameSpreadY * i); + } + } + + function set_flameX(value:Float):Float + { + this.flameX = value; + setFlamePositions(); + return this.flameX; + } + + function set_flameY(value:Float):Float + { + this.flameY = value; + setFlamePositions(); + return this.flameY; + } + + function set_flameSpreadX(value:Float):Float + { + this.flameSpreadX = value; + setFlamePositions(); + return this.flameSpreadX; + } + + function set_flameSpreadY(value:Float):Float + { + this.flameSpreadY = value; + setFlamePositions(); + return this.flameSpreadY; + } +} diff --git a/source/funkin/freeplayStuff/LetterSort.hx b/source/funkin/freeplayStuff/LetterSort.hx index c3b22f973..e6d923c90 100644 --- a/source/funkin/freeplayStuff/LetterSort.hx +++ b/source/funkin/freeplayStuff/LetterSort.hx @@ -4,38 +4,68 @@ import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +import flixel.tweens.FlxTween; +import flixel.tweens.FlxEase; +import flixel.util.FlxColor; +import flixel.util.FlxTimer; +import funkin.graphics.adobeanimate.FlxAtlasSprite; -class LetterSort extends FlxTypedSpriteGroup +class LetterSort extends FlxTypedSpriteGroup { public var letters:Array = []; - var curSelection:Int = 0; + // starts at 2, cuz that's the middle letter on start (accounting for fav and #, it should begin at ALL filter) + var curSelection:Int = 2; public var changeSelectionCallback:String->Void; + var leftArrow:FlxSprite; + var rightArrow:FlxSprite; + var grpSeperators:Array = []; + public function new(x, y) { super(x, y); - var leftArrow:FreeplayLetter = new FreeplayLetter(-20, 0); - leftArrow.animation.play("arrow"); + leftArrow = new FlxSprite(-20, 15).loadGraphic(Paths.image("freeplay/miniArrow")); + // leftArrow.animation.play("arrow"); + leftArrow.flipX = true; add(leftArrow); - for (i in 0...6) + for (i in 0...5) { var letter:FreeplayLetter = new FreeplayLetter(i * 80, 0, i); + letter.x += 50; + letter.y += 50; + letter.ogY = y; + // letter.visible = false; add(letter); letters.push(letter); - if (i == 3) letter.alpha = 0.6; + if (i != 2) letter.scale.x = letter.scale.y = 0.8; - var sep:FreeplayLetter = new FreeplayLetter((i * 80) + 50, 0); - sep.animation.play("seperator"); + var darkness:Float = Math.abs(i - 2) / 6; + + letter.color = letter.color.getDarkened(darkness); + + // don't put the last seperator + if (i == 4) continue; + + var sep:FlxSprite = new FlxSprite((i * 80) + 55, 20).loadGraphic(Paths.image("freeplay/seperator")); + // sep.animation.play("seperator"); + sep.color = letter.color.getDarkened(darkness); add(sep); + + grpSeperators.push(sep); } - // changeSelection(-3); + rightArrow = new FlxSprite(380, 15).loadGraphic(Paths.image("freeplay/miniArrow")); + + // rightArrow.animation.play("arrow"); + add(rightArrow); + + changeSelection(0); } override function update(elapsed:Float) @@ -48,53 +78,168 @@ class LetterSort extends FlxTypedSpriteGroup public function changeSelection(diff:Int = 0) { - for (letter in letters) - letter.changeLetter(diff); + var ezTimer:Int->FlxSprite->Float->Void = function(frameNum:Int, spr:FlxSprite, offsetNum:Float) { + new FlxTimer().start(frameNum / 24, function(_) { + spr.offset.x = offsetNum; + }); + }; - if (changeSelectionCallback != null) changeSelectionCallback(letters[3].arr[letters[3].curLetter]); // bullshit and long lol! + var positions:Array = [-10, -22, 2, 0]; + + if (diff < 0) + { + for (sep in grpSeperators) + { + ezTimer(0, sep, positions[0]); + ezTimer(1, sep, positions[1]); + ezTimer(2, sep, positions[2]); + ezTimer(3, sep, positions[3]); + } + + for (index => letter in letters) + { + letter.offset.x = positions[0]; + + new FlxTimer().start(1 / 24, function(_) { + letter.offset.x = positions[1]; + if (index == 0) letter.visible = false; + }); + + new FlxTimer().start(2 / 24, function(_) { + letter.offset.x = positions[2]; + if (index == 0.) letter.visible = true; + }); + + if (index == 2) + { + ezTimer(3, letter, 0); + // letter.offset.x = 0; + continue; + } + + ezTimer(3, letter, positions[3]); + } + + leftArrow.offset.x = 3; + new FlxTimer().start(2 / 24, function(_) { + leftArrow.offset.x = 0; + }); + } + else if (diff > 0) + { + for (sep in grpSeperators) + { + ezTimer(0, sep, -positions[0]); + ezTimer(1, sep, -positions[1]); + ezTimer(2, sep, -positions[2]); + ezTimer(3, sep, -positions[3]); + } + // same timing and functions and shit as the left one... except to the right!! + + for (index => letter in letters) + { + letter.offset.x = -positions[0]; + + new FlxTimer().start(1 / 24, function(_) { + letter.offset.x = -positions[1]; + if (index == 0) letter.visible = false; + }); + + new FlxTimer().start(2 / 24, function(_) { + letter.offset.x = -positions[2]; + if (index == 0) letter.visible = true; + }); + + if (index == 2) + { + ezTimer(3, letter, 0); + // letter.offset.x = 0; + continue; + } + + ezTimer(3, letter, -positions[3]); + } + + rightArrow.offset.x = -3; + new FlxTimer().start(2 / 24, function(_) { + rightArrow.offset.x = 0; + }); + } + + curSelection += diff; + if (curSelection < 0) curSelection = letters[0].arr.length - 1; + if (curSelection >= letters[0].arr.length) curSelection = 0; + + for (letter in letters) + letter.changeLetter(diff, curSelection); + + if (changeSelectionCallback != null) changeSelectionCallback(letters[2].arr[letters[2].curLetter]); // bullshit and long lol! } } -class FreeplayLetter extends FlxSprite +class FreeplayLetter extends FlxAtlasSprite { public var arr:Array = []; public var curLetter:Int = 0; + public var ogY:Float = 0; + public function new(x:Float, y:Float, ?letterInd:Int) { - super(x, y); + super(x, y, Paths.animateAtlas("freeplay/sortedLetters")); + // frames = Paths.getSparrowAtlas("freeplay/letterStuff"); + // this.anim.play("AB"); + // trace(this.anim.symbolDictionary); - frames = Paths.getSparrowAtlas("freeplay/letterStuff"); - - var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; - arr = alphabet.split(""); - arr.insert(0, "#"); + var alphabet:String = "AB-CD-EH-I L-MN-OR-s-t-UZ"; + arr = alphabet.split("-"); arr.insert(0, "ALL"); arr.insert(0, "fav"); + arr.insert(0, "#"); - for (str in arr) - { - animation.addByPrefix(str, str + " "); // string followed by a space! intentional! - } + // trace(arr); - animation.addByPrefix("arrow", "mini arrow"); - animation.addByPrefix("seperator", "seperator"); + // for (str in arr) + // { + // animation.addByPrefix(str, str + " "); // string followed by a space! intentional! + // } + + // animation.addByPrefix("arrow", "mini arrow"); + // animation.addByPrefix("seperator", "seperator"); if (letterInd != null) { - animation.play(arr[letterInd]); + this.anim.play(arr[letterInd] + " move"); + this.anim.pause(); curLetter = letterInd; } } - public function changeLetter(diff:Int = 0) + public function changeLetter(diff:Int = 0, ?curSelection:Int) { curLetter += diff; if (curLetter < 0) curLetter = arr.length - 1; if (curLetter >= arr.length) curLetter = 0; - animation.play(arr[curLetter]); + var animName:String = arr[curLetter] + " move"; + + switch (arr[curLetter]) + { + case "I L": + animName = "IL move"; + case "s": + animName = "S move"; + case "t": + animName = "T move"; + } + + this.anim.play(animName); + if (curSelection != curLetter) + { + this.anim.pause(); + } + // updateHitbox(); } } diff --git a/source/funkin/freeplayStuff/SongMenuItem.hx b/source/funkin/freeplayStuff/SongMenuItem.hx index 37198f6d7..5fd7eb576 100644 --- a/source/funkin/freeplayStuff/SongMenuItem.hx +++ b/source/funkin/freeplayStuff/SongMenuItem.hx @@ -1,5 +1,8 @@ package funkin.freeplayStuff; +import funkin.shaderslmfao.HSVShader; +import funkin.shaderslmfao.GaussianBlurShader; +import flixel.group.FlxGroup; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; @@ -7,17 +10,29 @@ import flixel.group.FlxSpriteGroup; import flixel.math.FlxMath; import flixel.math.FlxPoint; import flixel.text.FlxText; +import flixel.util.FlxTimer; +import funkin.shaderslmfao.Grayscale; class SongMenuItem extends FlxSpriteGroup { - var capsule:FlxSprite; + public var capsule:FlxSprite; - public var selected(default, set):Bool = false; + var pixelIcon:FlxSprite; + + public var selected(default, set):Bool; public var songTitle:String = "Test"; - public var songText:FlxText; + public var songText:CapsuleText; public var favIcon:FlxSprite; + public var ranking:FlxSprite; + + var ranks:Array = ["fail", "average", "great", "excellent", "perfect"]; + + // lol... + var diffRanks:Array = [ + "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "14", "15" + ]; public var targetPos:FlxPoint = new FlxPoint(); public var doLerp:Bool = false; @@ -25,7 +40,12 @@ class SongMenuItem extends FlxSpriteGroup public var doJumpOut:Bool = false; - public function new(x:Float, y:Float, song:String) + public var onConfirm:Void->Void; + public var diffGrayscale:Grayscale; + + public var hsvShader(default, set):HSVShader; + + public function new(x:Float, y:Float, song:String, ?character:String) { super(x, y); @@ -38,19 +58,144 @@ class SongMenuItem extends FlxSpriteGroup // capsule.animation add(capsule); - songText = new FlxText(120, 40, 0, songTitle, 40); - songText.font = "5by7"; - songText.color = 0xFF43C1EA; - add(songText); + // doesn't get added, simply is here to help with visibility of things for the pop in! + grpHide = new FlxGroup(); - favIcon = new FlxSprite(440, 40); + var rank:String = FlxG.random.getObject(ranks); + + ranking = new FlxSprite(capsule.width * 0.84, 30); + ranking.loadGraphic(Paths.image("freeplay/ranks/" + rank)); + ranking.scale.x = ranking.scale.y = realScaled; + ranking.alpha = 0.75; + ranking.origin.set(capsule.origin.x - ranking.x, capsule.origin.y - ranking.y); + add(ranking); + grpHide.add(ranking); + + diffGrayscale = new Grayscale(1); + + var diffRank = new FlxSprite(145, 90).loadGraphic(Paths.image("freeplay/diffRankings/diff" + FlxG.random.getObject(diffRanks))); + diffRank.shader = diffGrayscale; + diffRank.visible = false; + add(diffRank); + diffRank.origin.set(capsule.origin.x - diffRank.x, capsule.origin.y - diffRank.y); + grpHide.add(diffRank); + + switch (rank) + { + case "perfect": + ranking.x -= 10; + } + + songText = new CapsuleText(capsule.width * 0.26, 45, songTitle, Std.int(40 * realScaled)); + add(songText); + grpHide.add(songText); + + pixelIcon = new FlxSprite(155, 15); + pixelIcon.makeGraphic(32, 32, 0x00000000); + pixelIcon.antialiasing = false; + pixelIcon.active = false; + add(pixelIcon); + grpHide.add(pixelIcon); + + if (character != null) setCharacter(character); + + favIcon = new FlxSprite(400, 40); favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart'); favIcon.animation.addByPrefix('fav', "favorite heart", 24, false); favIcon.animation.play('fav'); - favIcon.setGraphicSize(60, 60); + favIcon.setGraphicSize(50, 50); + favIcon.visible = false; add(favIcon); + // grpHide.add(favIcon); - selected = selected; // just to kickstart the set_selected + setVisibleGrp(false); + } + + function set_hsvShader(value:HSVShader):HSVShader + { + this.hsvShader = value; + capsule.shader = hsvShader; + songText.shader = hsvShader; + + return value; + } + + function textAppear() + { + songText.scale.x = 1.7; + songText.scale.y = 0.2; + + new FlxTimer().start(1 / 24, function(_) { + songText.scale.x = 0.4; + songText.scale.y = 1.4; + }); + + new FlxTimer().start(2 / 24, function(_) { + songText.scale.x = songText.scale.y = 1; + }); + } + + function setVisibleGrp(value:Bool) + { + for (spr in grpHide.members) + { + spr.visible = value; + } + + if (value) textAppear(); + + selectedAlpha(); + } + + public function init(x:Float, y:Float, song:String, ?character:String) + { + this.x = x; + this.y = y; + this.songTitle = song; + songText.text = this.songTitle; + if (character != null) setCharacter(character); + + selected = selected; + } + + /** + * Set the character displayed next to this song in the freeplay menu. + * @param char The character ID used by this song. + * If the character has no freeplay icon, a warning will be thrown and nothing will display. + */ + public function setCharacter(char:String) + { + var charPath:String = "freeplay/icons/"; + + trace(char); + + switch (char) + { + case "monster-christmas": + charPath += "monsterpixel"; + case "mom-car": + charPath += "mommypixel"; + case "dad": + charPath += "daddypixel"; + case "darnell-blazin": + charPath += "darnellpixel"; + case "senpai-angry": + charPath += "senpaipixel"; + default: + charPath += char + "pixel"; + } + + if (!openfl.utils.Assets.exists(Paths.image(charPath))) + { + trace('[WARN] Character ${char} has no freeplay icon.'); + return; + } + + pixelIcon.loadGraphic(Paths.image(charPath)); + pixelIcon.scale.x = pixelIcon.scale.y = 2; + pixelIcon.origin.x = 100; + // pixelIcon.origin.x = capsule.origin.x; + // pixelIcon.offset.x -= pixelIcon.origin.x; } var frameInTicker:Float = 0; @@ -63,6 +208,63 @@ class SongMenuItem extends FlxSpriteGroup var xPosLerpLol:Array = [0.9, 0.4, 0.16, 0.16, 0.22, 0.22, 0.245]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER var xPosOutLerpLol:Array = [0.245, 0.75, 0.98, 0.98, 1.2]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER + public var realScaled:Float = 0.8; + + public function initJumpIn(maxTimer:Float, ?force:Bool):Void + { + frameInTypeBeat = 0; + + new FlxTimer().start((1 / 24) * maxTimer, function(doShit) { + doJumpIn = true; + }); + + new FlxTimer().start((0.09 * maxTimer) + 0.85, function(lerpTmr) { + doLerp = true; + }); + + if (force) + { + visible = true; + capsule.alpha = 1; + setVisibleGrp(true); + } + else + { + new FlxTimer().start((xFrames.length / 24) * 2.5, function(_) { + visible = true; + capsule.alpha = 1; + setVisibleGrp(true); + }); + } + } + + var grpHide:FlxGroup; + + public function forcePosition() + { + visible = true; + capsule.alpha = 1; + selectedAlpha(); + doLerp = true; + doJumpIn = false; + doJumpOut = false; + + frameInTypeBeat = xFrames.length; + frameOutTypeBeat = 0; + + capsule.scale.x = xFrames[frameInTypeBeat - 1]; + capsule.scale.y = 1 / xFrames[frameInTypeBeat - 1]; + // x = FlxG.width * xPosLerpLol[Std.int(Math.min(frameInTypeBeat - 1, xPosLerpLol.length - 1))]; + + x = targetPos.x; + y = targetPos.y; + + capsule.scale.x *= realScaled; + capsule.scale.y *= realScaled; + + setVisibleGrp(true); + } + override function update(elapsed:Float) { if (doJumpIn) @@ -73,10 +275,13 @@ class SongMenuItem extends FlxSpriteGroup { frameInTicker = 0; - scale.x = xFrames[frameInTypeBeat]; - scale.y = 1 / xFrames[frameInTypeBeat]; + capsule.scale.x = xFrames[frameInTypeBeat]; + capsule.scale.y = 1 / xFrames[frameInTypeBeat]; x = FlxG.width * xPosLerpLol[Std.int(Math.min(frameInTypeBeat, xPosLerpLol.length - 1))]; + capsule.scale.x *= realScaled; + capsule.scale.y *= realScaled; + frameInTypeBeat += 1; } } @@ -89,10 +294,13 @@ class SongMenuItem extends FlxSpriteGroup { frameOutTicker = 0; - scale.x = xFrames[frameOutTypeBeat]; - scale.y = 1 / xFrames[frameOutTypeBeat]; + capsule.scale.x = xFrames[frameOutTypeBeat]; + capsule.scale.y = 1 / xFrames[frameOutTypeBeat]; x = FlxG.width * xPosOutLerpLol[Std.int(Math.min(frameOutTypeBeat, xPosOutLerpLol.length - 1))]; + capsule.scale.x *= realScaled; + capsule.scale.y *= realScaled; + frameOutTypeBeat += 1; } } @@ -106,14 +314,29 @@ class SongMenuItem extends FlxSpriteGroup super.update(elapsed); } + public function intendedY(index:Int):Float + { + return (index * ((height * realScaled) + 10)) + 120; + } + + /** + * Merely a helper function to call set_selected, to make sure that the alpha is correct on the rankings/selections + */ + public function selectedAlpha():Void + { + selected = selected; + } + function set_selected(value:Bool):Bool { - // trace(value); - // cute one liners, lol! + diffGrayscale.setAmount(value ? 0 : 0.8); songText.alpha = value ? 1 : 0.6; + songText.blurredText.visible = value ? true : false; capsule.offset.x = value ? 0 : -5; capsule.animation.play(value ? "selected" : "unselected"); + ranking.alpha = value ? 1 : 0.7; + ranking.color = value ? 0xFFFFFFFF : 0xFFAAAAAA; return value; } } diff --git a/source/funkin/input/PreciseInputManager.hx b/source/funkin/input/PreciseInputManager.hx index 6217b2fe7..4cce0964d 100644 --- a/source/funkin/input/PreciseInputManager.hx +++ b/source/funkin/input/PreciseInputManager.hx @@ -181,7 +181,7 @@ class PreciseInputManager extends FlxKeyManager updateKeyStates(key, true); - if (getInputByKey(key) ?.justPressed ?? false) + if (getInputByKey(key)?.justPressed ?? false) { onInputPressed.dispatch( { @@ -203,7 +203,7 @@ class PreciseInputManager extends FlxKeyManager updateKeyStates(key, false); - if (getInputByKey(key) ?.justReleased ?? false) + if (getInputByKey(key)?.justReleased ?? false) { onInputReleased.dispatch( { @@ -264,7 +264,7 @@ class PreciseInputList extends FlxKeyList { for (key in getKeysForDir(noteDir)) { - if (check(_preciseInputManager.getInputByKey(key) ?.ID)) return true; + if (check(_preciseInputManager.getInputByKey(key)?.ID)) return true; } return false; } diff --git a/source/funkin/shaderslmfao/BlendModesShader.hx b/source/funkin/shaderslmfao/BlendModesShader.hx new file mode 100644 index 000000000..6807a65c0 --- /dev/null +++ b/source/funkin/shaderslmfao/BlendModesShader.hx @@ -0,0 +1,23 @@ +package funkin.shaderslmfao; + +import flixel.addons.display.FlxRuntimeShader; +import funkin.Paths; +import openfl.utils.Assets; +import openfl.display.BitmapData; + +class BlendModesShader extends FlxRuntimeShader +{ + public var camera:BitmapData; + + public function new() + { + super(Assets.getText(Paths.frag('blendModes'))); + } + + public function setCamera(camera:BitmapData):Void + { + this.camera = camera; + + this.setBitmapData('camera', camera); + } +} diff --git a/source/funkin/shaderslmfao/GaussianBlurShader.hx b/source/funkin/shaderslmfao/GaussianBlurShader.hx new file mode 100644 index 000000000..ad472ac31 --- /dev/null +++ b/source/funkin/shaderslmfao/GaussianBlurShader.hx @@ -0,0 +1,25 @@ +package funkin.shaderslmfao; + +import flixel.addons.display.FlxRuntimeShader; +import funkin.Paths; +import openfl.utils.Assets; + +/** + * Note... not actually gaussian! + */ +class GaussianBlurShader extends FlxRuntimeShader +{ + public var amount:Float; + + public function new(amount:Float = 1.0) + { + super(Assets.getText(Paths.frag("gaussianBlur"))); + setAmount(amount); + } + + public function setAmount(value:Float):Void + { + this.amount = value; + this.setFloat("amount", amount); + } +} diff --git a/source/funkin/shaderslmfao/Grayscale.hx b/source/funkin/shaderslmfao/Grayscale.hx new file mode 100644 index 000000000..016d64b46 --- /dev/null +++ b/source/funkin/shaderslmfao/Grayscale.hx @@ -0,0 +1,22 @@ +package funkin.shaderslmfao; + +import flixel.addons.display.FlxRuntimeShader; +import funkin.Paths; +import openfl.utils.Assets; + +class Grayscale extends FlxRuntimeShader +{ + public var amount:Float = 1; + + public function new(amount:Float = 1) + { + super(Assets.getText(Paths.frag("grayscale"))); + setAmount(amount); + } + + public function setAmount(value:Float):Void + { + amount = value; + this.setFloat("amount", amount); + } +} diff --git a/source/funkin/shaderslmfao/HSVShader.hx b/source/funkin/shaderslmfao/HSVShader.hx new file mode 100644 index 000000000..066a49c96 --- /dev/null +++ b/source/funkin/shaderslmfao/HSVShader.hx @@ -0,0 +1,44 @@ +package funkin.shaderslmfao; + +import flixel.addons.display.FlxRuntimeShader; +import funkin.Paths; +import openfl.utils.Assets; + +class HSVShader extends FlxRuntimeShader +{ + public var hue(default, set):Float; + public var saturation(default, set):Float; + public var value(default, set):Float; + + public function new() + { + super(Assets.getText(Paths.frag('hsv'))); + hue = 1; + saturation = 1; + value = 1; + } + + function set_hue(value:Float):Float + { + this.setFloat('hue', value); + this.hue = value; + + return this.hue; + } + + function set_saturation(value:Float):Float + { + this.setFloat('sat', value); + this.saturation = value; + + return this.saturation; + } + + function set_value(value:Float):Float + { + this.setFloat('val', value); + this.value = value; + + return this.value; + } +} diff --git a/source/funkin/ui/title/FlxSpriteOverlay.hx b/source/funkin/ui/title/FlxSpriteOverlay.hx new file mode 100644 index 000000000..ddf58bbfd --- /dev/null +++ b/source/funkin/ui/title/FlxSpriteOverlay.hx @@ -0,0 +1,74 @@ +package funkin.ui.title; + +import flixel.FlxSprite; +import funkin.shaderslmfao.BlendModesShader; +import openfl.display.BitmapData; +import flixel.FlxCamera; +import flixel.FlxG; +import flixel.graphics.frames.FlxFrame.FlxFrameAngle; + +class FlxSpriteOverlay extends FlxSprite +{ + var blendShader:BlendModesShader; + var dipshitBitmap:BitmapData; + var temp:FlxSprite; + + public function new(x:Float, y:Float) + { + super(x, y); + temp = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, 0xFF000000); + blendShader = new BlendModesShader(); + dipshitBitmap = new BitmapData(2180, 1720, true, 0xFFCC00CC); + } + + override function drawComplex(camera:FlxCamera):Void + { + _frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, checkFlipX(), checkFlipY()); + _matrix.translate(-origin.x, -origin.y); + _matrix.scale(scale.x, scale.y); + if (bakedRotationAngle <= 0) + { + updateTrig(); + if (angle != 0) _matrix.rotateWithTrig(_cosAngle, _sinAngle); + } + getScreenPosition(_point, camera).subtractPoint(offset); + _point.add(origin.x, origin.y); + _matrix.translate(_point.x, _point.y); + if (isPixelPerfectRender(camera)) + { + _matrix.tx = Math.floor(_matrix.tx); + _matrix.ty = Math.floor(_matrix.ty); + } + + var sprRect = getScreenBounds(); + + // dipshitBitmap.draw(camera.canvas, camera.canvas.transform.matrix); + // blendShader.setCamera(dipshitBitmap); + + // FlxG.bitmapLog.add(dipshitBitmap); + + camera.drawPixels(_frame, framePixels, _matrix, colorTransform, blend, antialiasing, shader); + } + + function copyToFlash(rect):openfl.geom.Rectangle + { + var flashRect = new openfl.geom.Rectangle(); + flashRect.x = rect.x; + flashRect.y = rect.y; + flashRect.width = rect.width; + flashRect.height = rect.height; + return flashRect; + } + + override public function isSimpleRender(?camera:FlxCamera):Bool + { + if (FlxG.renderBlit) + { + return super.isSimpleRender(camera); + } + else + { + return false; + } + } +} diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index 313c578a3..9820e4ecc 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -23,6 +23,7 @@ import openfl.events.MouseEvent; import openfl.events.NetStatusEvent; import openfl.media.Video; import openfl.net.NetStream; +import openfl.display.BlendMode; #if desktop #end @@ -101,7 +102,7 @@ class TitleState extends MusicBeatState var logoBl:FlxSprite; var outlineShaderShit:TitleOutline; - var gfDance:FlxSprite; + var gfDance:FlxSpriteOverlay; var danceLeft:Bool = false; var titleText:FlxSprite; var maskShader = new LeftMaskShader(); @@ -124,13 +125,11 @@ class TitleState extends MusicBeatState outlineShaderShit = new TitleOutline(); - gfDance = new FlxSprite(FlxG.width * 0.4, FlxG.height * 0.07); + gfDance = new FlxSpriteOverlay(FlxG.width * 0.4, FlxG.height * 0.07); gfDance.frames = Paths.getSparrowAtlas('gfDanceTitle'); gfDance.animation.addByIndices('danceLeft', 'gfDance', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false); gfDance.animation.addByIndices('danceRight', 'gfDance', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false); - add(gfDance); - // maskShader.swagSprX = gfDance.x; // maskShader.swagMaskX = gfDance.x + 200; // maskShader.frameUV = gfDance.frame.uv; @@ -142,6 +141,8 @@ class TitleState extends MusicBeatState add(logoBl); + add(gfDance); + titleText = new FlxSprite(100, FlxG.height * 0.8); titleText.frames = Paths.getSparrowAtlas('titleEnter'); titleText.animation.addByPrefix('idle', "Press Enter to Begin", 24); @@ -245,6 +246,8 @@ class TitleState extends MusicBeatState override function update(elapsed:Float) { + FlxG.bitmapLog.add(FlxG.camera.buffer); + #if HAS_PITCH if (FlxG.keys.pressed.UP) FlxG.sound.music.pitch += 0.5 * elapsed;