mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-04-10 14:24:56 +00:00
Merge pull request #122 from FunkinCrew/bugfix/attract-screen
Fix trailer playback on the title screen.
This commit is contained in:
commit
34d7267769
|
@ -24,6 +24,7 @@ import funkin.play.song.SongData.SongDataParser;
|
||||||
import funkin.play.stage.StageData.StageDataParser;
|
import funkin.play.stage.StageData.StageDataParser;
|
||||||
import funkin.play.character.CharacterData.CharacterDataParser;
|
import funkin.play.character.CharacterData.CharacterDataParser;
|
||||||
import funkin.modding.module.ModuleHandler;
|
import funkin.modding.module.ModuleHandler;
|
||||||
|
import funkin.ui.title.TitleState;
|
||||||
#if discord_rpc
|
#if discord_rpc
|
||||||
import Discord.DiscordClient;
|
import Discord.DiscordClient;
|
||||||
#end
|
#end
|
||||||
|
|
|
@ -22,6 +22,7 @@ import funkin.shaderslmfao.ScreenWipeShader;
|
||||||
import funkin.ui.AtlasMenuList;
|
import funkin.ui.AtlasMenuList;
|
||||||
import funkin.ui.MenuList.MenuItem;
|
import funkin.ui.MenuList.MenuItem;
|
||||||
import funkin.ui.MenuList;
|
import funkin.ui.MenuList;
|
||||||
|
import funkin.ui.title.TitleState;
|
||||||
import funkin.ui.story.StoryMenuState;
|
import funkin.ui.story.StoryMenuState;
|
||||||
import funkin.ui.OptionsState;
|
import funkin.ui.OptionsState;
|
||||||
import funkin.ui.PreferencesMenu;
|
import funkin.ui.PreferencesMenu;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,6 +9,7 @@ import openfl.net.NetStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays a video via a NetStream. Only works on HTML5.
|
* 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
|
class FlxVideo extends FlxBasic
|
||||||
{
|
{
|
||||||
|
|
109
source/funkin/ui/title/AttractState.hx
Normal file
109
source/funkin/ui/title/AttractState.hx
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* 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');
|
||||||
|
|
||||||
|
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),
|
||||||
|
* switch immediately to the title screen.
|
||||||
|
*/
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package funkin;
|
package funkin.ui.title;
|
||||||
|
|
||||||
import flixel.FlxSprite;
|
import flixel.FlxSprite;
|
||||||
import flixel.FlxState;
|
import flixel.FlxState;
|
||||||
|
@ -28,6 +28,9 @@ import openfl.net.NetStream;
|
||||||
#end
|
#end
|
||||||
class TitleState extends MusicBeatState
|
class TitleState extends MusicBeatState
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Only play the credits once per session.
|
||||||
|
*/
|
||||||
public static var initialized:Bool = false;
|
public static var initialized:Bool = false;
|
||||||
|
|
||||||
var blackScreen:FlxSprite;
|
var blackScreen:FlxSprite;
|
||||||
|
@ -148,14 +151,20 @@ class TitleState extends MusicBeatState
|
||||||
// titleText.screenCenter(X);
|
// titleText.screenCenter(X);
|
||||||
add(titleText);
|
add(titleText);
|
||||||
|
|
||||||
credGroup = new FlxGroup();
|
if (!initialized) // Fix an issue where returning to the credits would play a black screen.
|
||||||
add(credGroup);
|
{
|
||||||
|
credGroup = new FlxGroup();
|
||||||
|
add(credGroup);
|
||||||
|
}
|
||||||
|
|
||||||
textGroup = new FlxGroup();
|
textGroup = new FlxGroup();
|
||||||
|
|
||||||
blackScreen = bg.clone();
|
blackScreen = bg.clone();
|
||||||
credGroup.add(blackScreen);
|
if (credGroup != null)
|
||||||
credGroup.add(textGroup);
|
{
|
||||||
|
credGroup.add(blackScreen);
|
||||||
|
credGroup.add(textGroup);
|
||||||
|
}
|
||||||
|
|
||||||
// var atlasBullShit:FlxSprite = new FlxSprite();
|
// var atlasBullShit:FlxSprite = new FlxSprite();
|
||||||
// atlasBullShit.frames = CoolUtil.fromAnimate(Paths.image('money'), Paths.file('images/money.json'));
|
// atlasBullShit.frames = CoolUtil.fromAnimate(Paths.image('money'), Paths.file('images/money.json'));
|
||||||
|
@ -192,7 +201,15 @@ class TitleState extends MusicBeatState
|
||||||
else
|
else
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
if (FlxG.sound.music != null) FlxG.sound.music.onComplete = function() FlxG.switchState(new VideoState());
|
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 moveToAttract():Void
|
||||||
|
{
|
||||||
|
FlxG.switchState(new AttractState());
|
||||||
}
|
}
|
||||||
|
|
||||||
function playMenuMusic():Void
|
function playMenuMusic():Void
|
||||||
|
@ -284,7 +301,7 @@ class TitleState extends MusicBeatState
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
// a faster intro thing lol!
|
// If you spam Enter, we should skip the transition.
|
||||||
if (pressedEnter && transitioning && skippedIntro)
|
if (pressedEnter && transitioning && skippedIntro)
|
||||||
{
|
{
|
||||||
FlxG.switchState(new MainMenuState());
|
FlxG.switchState(new MainMenuState());
|
||||||
|
@ -304,50 +321,19 @@ class TitleState extends MusicBeatState
|
||||||
|
|
||||||
var targetState:FlxState = new MainMenuState();
|
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) {
|
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
|
// 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???
|
// Saves about 50mb of RAM or so???
|
||||||
Assets.cache.clear(Paths.image('gfDanceTitle'));
|
// TODO: This BREAKS the title screen if you return back to it! Figure out how to fix that.
|
||||||
Assets.cache.clear(Paths.image('logoBumpin'));
|
// Assets.cache.clear(Paths.image('gfDanceTitle'));
|
||||||
Assets.cache.clear(Paths.image('titleEnter'));
|
// Assets.cache.clear(Paths.image('logoBumpin'));
|
||||||
|
// Assets.cache.clear(Paths.image('titleEnter'));
|
||||||
// ngSpr??
|
// ngSpr??
|
||||||
FlxG.switchState(targetState);
|
FlxG.switchState(targetState);
|
||||||
});
|
});
|
||||||
// FlxG.sound.play(Paths.music('titleShoot'), 0.7);
|
// FlxG.sound.play(Paths.music('titleShoot'), 0.7);
|
||||||
}
|
}
|
||||||
if (pressedEnter && !skippedIntro && initialized) skipIntro();
|
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_LEFT) swagShader.update(-elapsed * 0.1);
|
||||||
if (controls.UI_RIGHT) swagShader.update(elapsed * 0.1);
|
if (controls.UI_RIGHT) swagShader.update(elapsed * 0.1);
|
||||||
|
@ -358,12 +344,6 @@ class TitleState extends MusicBeatState
|
||||||
override function draw()
|
override function draw()
|
||||||
{
|
{
|
||||||
super.draw();
|
super.draw();
|
||||||
|
|
||||||
// if (gfDance != null)
|
|
||||||
// {
|
|
||||||
// trace(gfDance.frame.uv);
|
|
||||||
// maskShader.frameUV = gfDance.frame.uv;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var cheatArray:Array<Int> = [0x0001, 0x0010, 0x0001, 0x0010, 0x0100, 0x1000, 0x0100, 0x1000];
|
var cheatArray:Array<Int> = [0x0001, 0x0010, 0x0001, 0x0010, 0x0100, 0x1000, 0x0100, 0x1000];
|
||||||
|
@ -523,7 +503,7 @@ class TitleState extends MusicBeatState
|
||||||
{
|
{
|
||||||
remove(ngSpr);
|
remove(ngSpr);
|
||||||
|
|
||||||
FlxG.camera.flash(FlxColor.WHITE, 4);
|
FlxG.camera.flash(FlxColor.WHITE, initialized ? 1 : 4);
|
||||||
remove(credGroup);
|
remove(credGroup);
|
||||||
skippedIntro = true;
|
skippedIntro = true;
|
||||||
}
|
}
|
Loading…
Reference in a new issue