week 7 stuff + video cutscenes
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
package funkin.cutscenes;
|
||||
|
||||
class Cutscene extends MusicBeatSubstate {
|
||||
public override function update(elapsed:Float) {
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
public override function close() {
|
||||
PlayState.instance.startCountdown();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package funkin.cutscenes;
|
||||
|
||||
import vlc.bitmap.VlcBitmap;
|
||||
import flixel.util.FlxTimer;
|
||||
import funkin.options.PlayerSettings;
|
||||
import openfl.events.Event;
|
||||
import flixel.FlxState;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxSprite;
|
||||
|
||||
class MP4Handler
|
||||
{
|
||||
public var finishCallback:Void->Void;
|
||||
public var stateCallback:FlxState;
|
||||
|
||||
public var bitmap:VlcBitmap;
|
||||
|
||||
public var sprite:FlxSprite;
|
||||
public var canvasWidth:Null<Int> = null;
|
||||
public var canvasHeight:Null<Int> = null;
|
||||
public var fillScreen:Bool;
|
||||
public var skippable:Bool = true;
|
||||
|
||||
public function new()
|
||||
{
|
||||
//FlxG.autoPause = false;
|
||||
}
|
||||
|
||||
public function playMP4(path:String, ?repeat:Bool = false, ?outputTo:FlxSprite = null, ?isWindow:Bool = false, ?isFullscreen:Bool = false,
|
||||
?midSong:Bool = false):Void
|
||||
{
|
||||
if (!midSong)
|
||||
{
|
||||
if (FlxG.sound.music != null)
|
||||
{
|
||||
FlxG.sound.music.stop();
|
||||
}
|
||||
}
|
||||
|
||||
bitmap = new VlcBitmap();
|
||||
|
||||
if (FlxG.stage.stageHeight / 9 < FlxG.stage.stageWidth / 16)
|
||||
{
|
||||
bitmap.set_width(FlxG.stage.stageHeight * (16 / 9));
|
||||
bitmap.set_height(FlxG.stage.stageHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap.set_width(FlxG.stage.stageWidth);
|
||||
bitmap.set_height(FlxG.stage.stageWidth / (16 / 9));
|
||||
}
|
||||
|
||||
|
||||
|
||||
bitmap.onVideoReady = onVLCVideoReady;
|
||||
bitmap.onComplete = onVLCComplete;
|
||||
bitmap.onError = onVLCError;
|
||||
|
||||
FlxG.stage.addEventListener(Event.ENTER_FRAME, update);
|
||||
|
||||
if (repeat)
|
||||
bitmap.repeat = -1;
|
||||
else
|
||||
bitmap.repeat = 0;
|
||||
|
||||
// bitmap.inWindow = isWindow;
|
||||
// bitmap.fullscreen = isFullscreen;
|
||||
|
||||
FlxG.addChildBelowMouse(bitmap);
|
||||
bitmap.play(checkFile(path));
|
||||
|
||||
if (outputTo != null)
|
||||
{
|
||||
// lol this is bad kek
|
||||
bitmap.alpha = 0;
|
||||
|
||||
sprite = outputTo;
|
||||
}
|
||||
}
|
||||
|
||||
function checkFile(fileName:String):String
|
||||
{
|
||||
var pDir = "";
|
||||
var appDir = "file:///" + Sys.getCwd() + "/";
|
||||
|
||||
if (fileName.indexOf(":") == -1) // Not a path
|
||||
pDir = appDir;
|
||||
else if (fileName.indexOf("file://") == -1 || fileName.indexOf("http") == -1) // C:, D: etc? ..missing "file:///" ?
|
||||
pDir = "file:///";
|
||||
|
||||
return pDir + fileName;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function onVLCVideoReady()
|
||||
{
|
||||
trace("video loaded!");
|
||||
|
||||
if (sprite != null) {
|
||||
sprite.loadGraphic(bitmap.bitmapData);
|
||||
if (canvasWidth != null && canvasHeight != null) {
|
||||
sprite.setGraphicSize(canvasWidth, canvasHeight);
|
||||
sprite.updateHitbox();
|
||||
|
||||
var r = (fillScreen ? Math.max : Math.min)(sprite.scale.x, sprite.scale.y);
|
||||
sprite.scale.set(r, r); // lol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onVLCComplete()
|
||||
{
|
||||
bitmap.stop();
|
||||
|
||||
new FlxTimer().start(0.3, function(tmr:FlxTimer)
|
||||
{
|
||||
if (finishCallback != null)
|
||||
{
|
||||
finishCallback();
|
||||
}
|
||||
else if (stateCallback != null)
|
||||
{
|
||||
FlxG.switchState(stateCallback);
|
||||
}
|
||||
|
||||
bitmap.dispose();
|
||||
|
||||
if (FlxG.game.contains(bitmap))
|
||||
{
|
||||
FlxG.game.removeChild(bitmap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function kill()
|
||||
{
|
||||
bitmap.stop();
|
||||
|
||||
if (finishCallback != null)
|
||||
{
|
||||
finishCallback();
|
||||
}
|
||||
|
||||
bitmap.visible = false;
|
||||
}
|
||||
|
||||
function onVLCError()
|
||||
{
|
||||
if (finishCallback != null)
|
||||
{
|
||||
finishCallback();
|
||||
}
|
||||
else if (stateCallback != null)
|
||||
{
|
||||
FlxG.switchState(stateCallback);
|
||||
}
|
||||
}
|
||||
|
||||
function update(e:Event)
|
||||
{
|
||||
if (PlayerSettings.player1.controls.ACCEPT && skippable)
|
||||
{
|
||||
if (bitmap.isPlaying)
|
||||
{
|
||||
onVLCComplete();
|
||||
}
|
||||
}
|
||||
|
||||
bitmap.volume = FlxG.sound.volume + 0.3; // shitty volume fix. then make it louder.
|
||||
|
||||
if (FlxG.sound.volume <= 0.1 || FlxG.sound.muted)
|
||||
bitmap.volume = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package funkin.cutscenes;
|
||||
|
||||
import flixel.FlxSprite;
|
||||
import flixel.FlxG;
|
||||
import flixel.FlxCamera;
|
||||
import openfl.utils.Assets;
|
||||
|
||||
class VideoCutscene extends Cutscene {
|
||||
var path:String;
|
||||
var localPath:String;
|
||||
|
||||
var video:MP4Handler;
|
||||
var videoSprite:FlxSprite;
|
||||
var cutsceneCamera:FlxCamera;
|
||||
public function new(path:String) {
|
||||
super();
|
||||
localPath = Assets.getPath(this.path = path);
|
||||
}
|
||||
|
||||
public override function create() {
|
||||
super.create();
|
||||
|
||||
cutsceneCamera = new FlxCamera();
|
||||
cutsceneCamera.bgColor = 0;
|
||||
FlxG.cameras.add(cutsceneCamera, false);
|
||||
|
||||
video = new MP4Handler();
|
||||
video.finishCallback = close;
|
||||
video.canvasWidth = cutsceneCamera.width;
|
||||
video.canvasHeight = cutsceneCamera.height;
|
||||
|
||||
videoSprite = new FlxSprite();
|
||||
videoSprite.cameras = [cutsceneCamera];
|
||||
videoSprite.antialiasing = true;
|
||||
add(videoSprite);
|
||||
|
||||
video.playMP4(localPath, false, videoSprite);
|
||||
|
||||
cameras = [cutsceneCamera];
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
super.update(elapsed);
|
||||
// video.se
|
||||
// video.setUnstretchedGraphicSize(FlxG.width, FlxG.height, false);
|
||||
// trace(video);
|
||||
// trace(video.getScreenBounds(null, cutsceneCamera));
|
||||
}
|
||||
public override function destroy() {
|
||||
FlxG.cameras.remove(camera, true);
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ import funkin.system.Conductor;
|
||||
import funkin.system.Song;
|
||||
import funkin.editors.ChartingState;
|
||||
import funkin.debug.AnimationDebug;
|
||||
import funkin.cutscenes.*;
|
||||
|
||||
import funkin.menus.*;
|
||||
import funkin.scripting.events.*;
|
||||
@@ -323,9 +324,25 @@ class PlayState extends MusicBeatState
|
||||
super.create();
|
||||
}
|
||||
|
||||
// PATH TO STRING CUTSCENE
|
||||
public var cutscene:String = null;
|
||||
public override function createPost() {
|
||||
|
||||
var videoCutscene = Paths.video('${PlayState.SONG.song.toLowerCase()}-cutscene');
|
||||
trace(videoCutscene);
|
||||
|
||||
FlxTransitionableState.skipNextTransIn = true;
|
||||
if (cutscene != null) {
|
||||
// TODO: Script cutscenes
|
||||
} else if (Assets.exists(videoCutscene)) {
|
||||
openSubState(new VideoCutscene(videoCutscene));
|
||||
persistentUpdate = false;
|
||||
persistentDraw = false;
|
||||
} else {
|
||||
FlxTransitionableState.skipNextTransIn = false;
|
||||
startCountdown();
|
||||
}
|
||||
super.createPost();
|
||||
startCountdown();
|
||||
scripts.call("createPost");
|
||||
}
|
||||
|
||||
@@ -333,7 +350,7 @@ class PlayState extends MusicBeatState
|
||||
public var perfectMode:Bool = false;
|
||||
public var introLength:Int = 5;
|
||||
|
||||
function startCountdown():Void
|
||||
public function startCountdown():Void
|
||||
{
|
||||
|
||||
inCutscene = false;
|
||||
|
||||
@@ -84,7 +84,7 @@ class Conductor
|
||||
@:dox(hide) public function new() {}
|
||||
|
||||
public static function reset() {
|
||||
songPosition = lastSongPos = 0;
|
||||
songPosition = lastSongPos = curBeatFloat = curStepFloat = curBeat = curStep = 0;
|
||||
bpmChangeMap = [];
|
||||
changeBPM(0);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ class Conductor
|
||||
if (FlxG.state != null && FlxG.state is MusicBeatState && cast(FlxG.state, MusicBeatState).cancelConductorUpdate) return;
|
||||
if (lastSongPos != (lastSongPos = FlxG.sound.music.time)) {
|
||||
// update conductor
|
||||
songPosition = FlxG.sound.music.time;
|
||||
songPosition = lastSongPos;
|
||||
} else {
|
||||
songPosition += elapsed * 1000;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ class Paths
|
||||
return getPreloadPath(file);
|
||||
}
|
||||
|
||||
static public function video(key:String) {
|
||||
return getPath('videos/$key.mp4', BINARY, null);
|
||||
}
|
||||
|
||||
static public function getLibraryPath(file:String, library = "preload")
|
||||
{
|
||||
return if (library == "preload" || library == "default") getPreloadPath(file); else getLibraryPathForce(file, library);
|
||||
|
||||
Reference in New Issue
Block a user