From 3f99e0e3daa3a20205425b02e94734e14fdcf0d9 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 8 Aug 2023 15:41:25 -0400 Subject: [PATCH 1/5] Move TitleState into its own package. --- source/funkin/InitState.hx | 1 + source/funkin/MainMenuState.hx | 1 + source/funkin/{ => ui/title}/TitleState.hx | 46 ++-------------------- 3 files changed, 6 insertions(+), 42 deletions(-) rename source/funkin/{ => ui/title}/TitleState.hx (91%) diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index eeffebdb1..6c465be9c 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -24,6 +24,7 @@ import funkin.play.song.SongData.SongDataParser; import funkin.play.stage.StageData.StageDataParser; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.modding.module.ModuleHandler; +import funkin.ui.title.TitleState; #if discord_rpc import Discord.DiscordClient; #end diff --git a/source/funkin/MainMenuState.hx b/source/funkin/MainMenuState.hx index 2c251635c..ab2e0e560 100644 --- a/source/funkin/MainMenuState.hx +++ b/source/funkin/MainMenuState.hx @@ -22,6 +22,7 @@ import funkin.shaderslmfao.ScreenWipeShader; import funkin.ui.AtlasMenuList; import funkin.ui.MenuList.MenuItem; import funkin.ui.MenuList; +import funkin.ui.title.TitleState; import funkin.ui.story.StoryMenuState; import funkin.ui.OptionsState; import funkin.ui.PreferencesMenu; diff --git a/source/funkin/TitleState.hx b/source/funkin/ui/title/TitleState.hx similarity index 91% rename from source/funkin/TitleState.hx rename to source/funkin/ui/title/TitleState.hx index 8ba5121fa..3cd060a37 100644 --- a/source/funkin/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -192,7 +192,6 @@ class TitleState extends MusicBeatState else initialized = true; - if (FlxG.sound.music != null) FlxG.sound.music.onComplete = function() FlxG.switchState(new VideoState()); } function playMenuMusic():Void @@ -304,50 +303,19 @@ class TitleState extends MusicBeatState var targetState:FlxState = new MainMenuState(); - #if newgrounds - if (!OutdatedSubState.leftState) - { - NGio.checkVersion(function(version) { - // Check if version is outdated - var localVersion:String = "v" + Application.current.meta.get('version'); - var onlineVersion = version.split(" ")[0].trim(); - if (version.trim() != onlineVersion) - { - trace('OLD VERSION!'); - // targetState = new OutdatedSubState(); - } - else - { - // targetState = new MainMenuState(); - } - // REDO FOR ITCH/FINAL SHIT - }); - } - #end new FlxTimer().start(2, function(tmr:FlxTimer) { // These assets are very unlikely to be used for the rest of gameplay, so it unloads them from cache/memory // Saves about 50mb of RAM or so??? - Assets.cache.clear(Paths.image('gfDanceTitle')); - Assets.cache.clear(Paths.image('logoBumpin')); - Assets.cache.clear(Paths.image('titleEnter')); + // TODO: This BREAKS the title screen if you return back to it! Figure out how to fix that. + // Assets.cache.clear(Paths.image('gfDanceTitle')); + // Assets.cache.clear(Paths.image('logoBumpin')); + // Assets.cache.clear(Paths.image('titleEnter')); // ngSpr?? FlxG.switchState(targetState); }); // FlxG.sound.play(Paths.music('titleShoot'), 0.7); } if (pressedEnter && !skippedIntro && initialized) skipIntro(); - /* - #if web - if (!initialized && controls.ACCEPT) - { - // netStream.dispose(); - // FlxG.stage.removeChild(video); - - startIntro(); - skipIntro(); - } - #end - */ if (controls.UI_LEFT) swagShader.update(-elapsed * 0.1); if (controls.UI_RIGHT) swagShader.update(elapsed * 0.1); @@ -358,12 +326,6 @@ class TitleState extends MusicBeatState override function draw() { super.draw(); - - // if (gfDance != null) - // { - // trace(gfDance.frame.uv); - // maskShader.frameUV = gfDance.frame.uv; - // } } var cheatArray:Array = [0x0001, 0x0010, 0x0001, 0x0010, 0x0100, 0x1000, 0x0100, 0x1000]; From ec76c54ccd621a261f429a99742177feabcd219f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 8 Aug 2023 15:41:48 -0400 Subject: [PATCH 2/5] Implement basic AttractState. --- source/funkin/ui/title/AttractState.hx | 24 ++++++++++++++++++++++++ source/funkin/ui/title/TitleState.hx | 6 ++++++ 2 files changed, 30 insertions(+) create mode 100644 source/funkin/ui/title/AttractState.hx diff --git a/source/funkin/ui/title/AttractState.hx b/source/funkin/ui/title/AttractState.hx new file mode 100644 index 000000000..d630c07f2 --- /dev/null +++ b/source/funkin/ui/title/AttractState.hx @@ -0,0 +1,24 @@ +package funkin.ui.title; + +/** + * After about 2 minutes of inactivity on the title screen, + * the game will enter the Attract state, as a reference to physical arcade machines. + * + * In the current version, this just plays the Kickstarter trailer, but this can be changed to + * gameplay footage, a generic game trailer, or something more elaborate. + */ +class AttractState extends MusicBeatState +{ + static final ATTRACT_VIDEO_PATH:String = Paths.videos('kickstarterTrailer.mp4'); + + public override function create():Void {} + + /** + * When the attraction state ends (after the video ends or the user presses any button), + * switch immediately to the title screen. + */ + function onAttractEnd():Void + { + FlxG.switchState(new TitleState()); + } +} diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index 3cd060a37..d946f2a6e 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -192,8 +192,14 @@ class TitleState extends MusicBeatState else initialized = true; + if (FlxG.sound.music != null) FlxG.sound.music.onComplete = moveToAttract; } + /** + * After sitting on the title screen for a while, transition to the attract screen. + */ + function moveToAttact():Void {} + function playMenuMusic():Void { if (FlxG.sound.music == null || !FlxG.sound.music.playing) From b7f5f33f3efe7e4e78ea49a690ae9912e3e677ce Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 8 Aug 2023 15:42:15 -0400 Subject: [PATCH 3/5] Delete ancient VideoState. --- source/funkin/VideoState.hx | 100 ------------------------------------ 1 file changed, 100 deletions(-) delete mode 100644 source/funkin/VideoState.hx diff --git a/source/funkin/VideoState.hx b/source/funkin/VideoState.hx deleted file mode 100644 index a169ce5af..000000000 --- a/source/funkin/VideoState.hx +++ /dev/null @@ -1,100 +0,0 @@ -package funkin; - -import openfl.display.Sprite; -import openfl.events.AsyncErrorEvent; -import openfl.events.MouseEvent; -import openfl.events.NetStatusEvent; -import openfl.media.Video; -import openfl.net.NetConnection; -import openfl.net.NetStream; - -class VideoState extends MusicBeatState -{ - var video:Video; - var netStream:NetStream; - var overlay:Sprite; - - public static var seenVideo:Bool = false; - - override function create() - { - super.create(); - - seenVideo = true; - - FlxG.save.data.seenVideo = true; - FlxG.save.flush(); - - if (FlxG.sound.music != null) FlxG.sound.music.stop(); - - video = new Video(); - FlxG.addChildBelowMouse(video); - - var netConnection = new NetConnection(); - netConnection.connect(null); - - netStream = new NetStream(netConnection); - netStream.client = {onMetaData: client_onMetaData}; - netStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, netStream_onAsyncError); - netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnection_onNetStatus); - // netStream.addEventListener(NetStatusEvent.NET_STATUS); - netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - - overlay = new Sprite(); - overlay.graphics.beginFill(0, 0.5); - overlay.graphics.drawRect(0, 0, 1280, 720); - overlay.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); - - overlay.buttonMode = true; - // FlxG.stage.addChild(overlay); - } - - override function update(elapsed:Float) - { - if (controls.ACCEPT) finishVid(); - - super.update(elapsed); - } - - function finishVid():Void - { - netStream.dispose(); - FlxG.removeChild(video); - - TitleState.initialized = false; - FlxG.switchState(new TitleState()); - } - - function client_onMetaData(metaData:Dynamic) - { - video.attachNetStream(netStream); - - video.width = video.videoWidth; - video.height = video.videoHeight; - // video. - } - - function netStream_onAsyncError(event:AsyncErrorEvent):Void - { - trace("Error loading video"); - } - - function netConnection_onNetStatus(event:NetStatusEvent):Void - { - if (event.info.code == 'NetStream.Play.Complete') - { - finishVid(); - } - - trace(event.toString()); - } - - function overlay_onMouseDown(event:MouseEvent):Void - { - netStream.soundTransform.volume = 0.2; - netStream.soundTransform.pan = -1; - // netStream.play(Paths.file('music/kickstarterTrailer.mp4')); - - FlxG.stage.removeChild(overlay); - } -} From ea31d72cbe2347344c532d64b53e22187ee7f4c7 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 8 Aug 2023 16:37:17 -0400 Subject: [PATCH 4/5] AttractState now properly plays the trailer --- source/funkin/graphics/video/FlxVideo.hx | 1 + source/funkin/ui/title/AttractState.hx | 89 +++++++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/source/funkin/graphics/video/FlxVideo.hx b/source/funkin/graphics/video/FlxVideo.hx index 393e2d49c..e95d7caa6 100644 --- a/source/funkin/graphics/video/FlxVideo.hx +++ b/source/funkin/graphics/video/FlxVideo.hx @@ -9,6 +9,7 @@ import openfl.net.NetStream; /** * Plays a video via a NetStream. Only works on HTML5. + * This does NOT replace hxCodec, nor does hxCodec replace this. hxCodec only works on desktop and does not work on HTML5! */ class FlxVideo extends FlxBasic { diff --git a/source/funkin/ui/title/AttractState.hx b/source/funkin/ui/title/AttractState.hx index d630c07f2..67c762da4 100644 --- a/source/funkin/ui/title/AttractState.hx +++ b/source/funkin/ui/title/AttractState.hx @@ -1,5 +1,11 @@ package funkin.ui.title; +#if html5 +import funkin.graphics.video.FlxVideo; +#else +import hxcodec.flixel.FlxVideoSprite; +#end + /** * After about 2 minutes of inactivity on the title screen, * the game will enter the Attract state, as a reference to physical arcade machines. @@ -9,9 +15,73 @@ package funkin.ui.title; */ class AttractState extends MusicBeatState { - static final ATTRACT_VIDEO_PATH:String = Paths.videos('kickstarterTrailer.mp4'); + static final ATTRACT_VIDEO_PATH:String = Paths.videos('kickstarterTrailer'); - public override function create():Void {} + public override function create():Void + { + // Pause existing music. + FlxG.sound.music.stop(); + + #if html5 + playVideoHTML5(ATTRACT_VIDEO_PATH); + #else + playVideoNative(ATTRACT_VIDEO_PATH); + #end + } + + #if html5 + var vid:FlxVideo; + + function playVideoHTML5(filePath:String):Void + { + // Video displays OVER the FlxState. + vid = new FlxVideo(filePath); + if (vid != null) + { + vid.zIndex = 0; + + vid.finishCallback = onAttractEnd; + + add(vid); + } + else + { + trace('ALERT: Video is null! Could not play cutscene!'); + } + } + #else + var vid:FlxVideoSprite; + + function playVideoNative(filePath:String):Void + { + // Video displays OVER the FlxState. + vid = new FlxVideoSprite(0, 0); + + if (vid != null) + { + vid.zIndex = 0; + vid.bitmap.onEndReached.add(onAttractEnd); + + add(vid); + vid.play(filePath, false); + } + else + { + trace('ALERT: Video is null! Could not play cutscene!'); + } + } + #end + + public override function update(elapsed:Float):Void + { + super.update(elapsed); + + // If the user presses any button, skip the video. + if (FlxG.keys.justPressed.ANY) + { + onAttractEnd(); + } + } /** * When the attraction state ends (after the video ends or the user presses any button), @@ -19,6 +89,21 @@ class AttractState extends MusicBeatState */ function onAttractEnd():Void { + #if html5 + if (vid != null) + { + remove(vid); + } + #else + if (vid != null) + { + vid.stop(); + remove(vid); + } + #end + vid.destroy(); + vid = null; + FlxG.switchState(new TitleState()); } } From 92e94a84b6cb0caf0f3aed054d686e1f25a49373 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 8 Aug 2023 16:41:23 -0400 Subject: [PATCH 5/5] Fix a bug where returning to title displays a black screen. --- source/funkin/ui/title/TitleState.hx | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index d946f2a6e..387502e83 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.ui.title; import flixel.FlxSprite; import flixel.FlxState; @@ -28,6 +28,9 @@ import openfl.net.NetStream; #end class TitleState extends MusicBeatState { + /** + * Only play the credits once per session. + */ public static var initialized:Bool = false; var blackScreen:FlxSprite; @@ -148,14 +151,20 @@ class TitleState extends MusicBeatState // titleText.screenCenter(X); add(titleText); - credGroup = new FlxGroup(); - add(credGroup); + if (!initialized) // Fix an issue where returning to the credits would play a black screen. + { + credGroup = new FlxGroup(); + add(credGroup); + } textGroup = new FlxGroup(); blackScreen = bg.clone(); - credGroup.add(blackScreen); - credGroup.add(textGroup); + if (credGroup != null) + { + credGroup.add(blackScreen); + credGroup.add(textGroup); + } // var atlasBullShit:FlxSprite = new FlxSprite(); // atlasBullShit.frames = CoolUtil.fromAnimate(Paths.image('money'), Paths.file('images/money.json')); @@ -198,7 +207,10 @@ class TitleState extends MusicBeatState /** * After sitting on the title screen for a while, transition to the attract screen. */ - function moveToAttact():Void {} + function moveToAttract():Void + { + FlxG.switchState(new AttractState()); + } function playMenuMusic():Void { @@ -289,7 +301,7 @@ class TitleState extends MusicBeatState #end } - // a faster intro thing lol! + // If you spam Enter, we should skip the transition. if (pressedEnter && transitioning && skippedIntro) { FlxG.switchState(new MainMenuState()); @@ -491,7 +503,7 @@ class TitleState extends MusicBeatState { remove(ngSpr); - FlxG.camera.flash(FlxColor.WHITE, 4); + FlxG.camera.flash(FlxColor.WHITE, initialized ? 1 : 4); remove(credGroup); skippedIntro = true; }