mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-11-15 11:22:55 +00:00
Merge pull request #580 from FunkinCrew/feature/freeplay-shit+santa-cutscene
freeplay shit + santa cutscene
This commit is contained in:
commit
d4cf18df00
2
assets
2
assets
|
@ -1 +1 @@
|
|||
Subproject commit 371cce1fdc44914ddc3a5327e996cece4e676715
|
||||
Subproject commit 8fea0bf1fe07b6dd0efb8ecf46dc8091b0177007
|
240
source/funkin/effects/IntervalShake.hx
Normal file
240
source/funkin/effects/IntervalShake.hx
Normal file
|
@ -0,0 +1,240 @@
|
|||
package funkin.effects;
|
||||
|
||||
import flixel.FlxObject;
|
||||
import flixel.util.FlxDestroyUtil.IFlxDestroyable;
|
||||
import flixel.util.FlxPool;
|
||||
import flixel.util.FlxTimer;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.util.FlxAxes;
|
||||
import flixel.tweens.FlxEase.EaseFunction;
|
||||
import flixel.math.FlxMath;
|
||||
|
||||
/**
|
||||
* pretty much a copy of FlxFlicker geared towards making sprites
|
||||
* shake around at a set interval and slow down over time.
|
||||
*/
|
||||
class IntervalShake implements IFlxDestroyable
|
||||
{
|
||||
static var _pool:FlxPool<IntervalShake> = new FlxPool<IntervalShake>(IntervalShake.new);
|
||||
|
||||
/**
|
||||
* Internal map for looking up which objects are currently shaking and getting their shake data.
|
||||
*/
|
||||
static var _boundObjects:Map<FlxObject, IntervalShake> = new Map<FlxObject, IntervalShake>();
|
||||
|
||||
/**
|
||||
* An effect that shakes the sprite on a set interval and a starting intensity that goes down over time.
|
||||
*
|
||||
* @param Object The object to shake.
|
||||
* @param Duration How long to shake for (in seconds). `0` means "forever".
|
||||
* @param Interval In what interval to update the shake position. Set to `FlxG.elapsed` if `<= 0`!
|
||||
* @param StartIntensity The starting intensity of the shake.
|
||||
* @param EndIntensity The ending intensity of the shake.
|
||||
* @param Ease Control the easing of the intensity over the shake.
|
||||
* @param CompletionCallback Callback on shake completion
|
||||
* @param ProgressCallback Callback on each shake interval
|
||||
* @return The `IntervalShake` object. `IntervalShake`s are pooled internally, so beware of storing references.
|
||||
*/
|
||||
public static function shake(Object:FlxObject, Duration:Float = 1, Interval:Float = 0.04, StartIntensity:Float = 0, EndIntensity:Float = 0,
|
||||
Ease:EaseFunction, ?CompletionCallback:IntervalShake->Void, ?ProgressCallback:IntervalShake->Void):IntervalShake
|
||||
{
|
||||
if (isShaking(Object))
|
||||
{
|
||||
// if (ForceRestart)
|
||||
// {
|
||||
// stopShaking(Object);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Ignore this call if object is already flickering.
|
||||
return _boundObjects[Object];
|
||||
// }
|
||||
}
|
||||
|
||||
if (Interval <= 0)
|
||||
{
|
||||
Interval = FlxG.elapsed;
|
||||
}
|
||||
|
||||
var shake:IntervalShake = _pool.get();
|
||||
shake.start(Object, Duration, Interval, StartIntensity, EndIntensity, Ease, CompletionCallback, ProgressCallback);
|
||||
return _boundObjects[Object] = shake;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is shaking or not.
|
||||
*
|
||||
* @param Object The object to test.
|
||||
*/
|
||||
public static function isShaking(Object:FlxObject):Bool
|
||||
{
|
||||
return _boundObjects.exists(Object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops shaking the object.
|
||||
*
|
||||
* @param Object The object to stop shaking.
|
||||
*/
|
||||
public static function stopShaking(Object:FlxObject):Void
|
||||
{
|
||||
var boundShake:IntervalShake = _boundObjects[Object];
|
||||
if (boundShake != null)
|
||||
{
|
||||
boundShake.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The shaking object.
|
||||
*/
|
||||
public var object(default, null):FlxObject;
|
||||
|
||||
/**
|
||||
* The shaking timer. You can check how many seconds has passed since shaking started etc.
|
||||
*/
|
||||
public var timer(default, null):FlxTimer;
|
||||
|
||||
/**
|
||||
* The starting intensity of the shake.
|
||||
*/
|
||||
public var startIntensity(default, null):Float;
|
||||
|
||||
/**
|
||||
* The ending intensity of the shake.
|
||||
*/
|
||||
public var endIntensity(default, null):Float;
|
||||
|
||||
/**
|
||||
* How long to shake for (in seconds). `0` means "forever".
|
||||
*/
|
||||
public var duration(default, null):Float;
|
||||
|
||||
/**
|
||||
* The interval of the shake.
|
||||
*/
|
||||
public var interval(default, null):Float;
|
||||
|
||||
/**
|
||||
* Defines on what axes to `shake()`. Default value is `XY` / both.
|
||||
*/
|
||||
public var axes(default, null):FlxAxes;
|
||||
|
||||
/**
|
||||
* Defines the initial position of the object at the beginning of the shake effect.
|
||||
*/
|
||||
public var initialOffset(default, null):FlxPoint;
|
||||
|
||||
/**
|
||||
* The callback that will be triggered after the shake has completed.
|
||||
*/
|
||||
public var completionCallback(default, null):IntervalShake->Void;
|
||||
|
||||
/**
|
||||
* The callback that will be triggered every time the object shakes.
|
||||
*/
|
||||
public var progressCallback(default, null):IntervalShake->Void;
|
||||
|
||||
/**
|
||||
* The easing of the intensity over the shake.
|
||||
*/
|
||||
public var ease(default, null):EaseFunction;
|
||||
|
||||
/**
|
||||
* Nullifies the references to prepare object for reuse and avoid memory leaks.
|
||||
*/
|
||||
public function destroy():Void
|
||||
{
|
||||
object = null;
|
||||
timer = null;
|
||||
ease = null;
|
||||
completionCallback = null;
|
||||
progressCallback = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts shaking behavior.
|
||||
*/
|
||||
function start(Object:FlxObject, Duration:Float = 1, Interval:Float = 0.04, StartIntensity:Float = 0, EndIntensity:Float = 0, Ease:EaseFunction,
|
||||
?CompletionCallback:IntervalShake->Void, ?ProgressCallback:IntervalShake->Void):Void
|
||||
{
|
||||
object = Object;
|
||||
duration = Duration;
|
||||
interval = Interval;
|
||||
completionCallback = CompletionCallback;
|
||||
startIntensity = StartIntensity;
|
||||
endIntensity = EndIntensity;
|
||||
initialOffset = new FlxPoint(Object.x, Object.y);
|
||||
ease = Ease;
|
||||
axes = FlxAxes.XY;
|
||||
_secondsSinceStart = 0;
|
||||
timer = new FlxTimer().start(interval, shakeProgress, Std.int(duration / interval));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prematurely ends shaking.
|
||||
*/
|
||||
public function stop():Void
|
||||
{
|
||||
timer.cancel();
|
||||
// object.visible = true;
|
||||
object.x = initialOffset.x;
|
||||
object.y = initialOffset.y;
|
||||
release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbinds the object from shaking and releases it into pool for reuse.
|
||||
*/
|
||||
function release():Void
|
||||
{
|
||||
_boundObjects.remove(object);
|
||||
_pool.put(this);
|
||||
}
|
||||
|
||||
public var _secondsSinceStart(default, null):Float = 0;
|
||||
|
||||
public var scale(default, null):Float = 0;
|
||||
|
||||
/**
|
||||
* Just a helper function for shake() to update object's position.
|
||||
*/
|
||||
function shakeProgress(timer:FlxTimer):Void
|
||||
{
|
||||
_secondsSinceStart += interval;
|
||||
scale = _secondsSinceStart / duration;
|
||||
if (ease != null)
|
||||
{
|
||||
scale = 1 - ease(scale);
|
||||
// trace(scale);
|
||||
}
|
||||
|
||||
var curIntensity:Float = 0;
|
||||
curIntensity = FlxMath.lerp(endIntensity, startIntensity, scale);
|
||||
|
||||
if (axes.x) object.x = initialOffset.x + FlxG.random.float((-curIntensity) * object.width, (curIntensity) * object.width);
|
||||
if (axes.y) object.y = initialOffset.y + FlxG.random.float((-curIntensity) * object.width, (curIntensity) * object.width);
|
||||
|
||||
// object.visible = !object.visible;
|
||||
|
||||
if (progressCallback != null) progressCallback(this);
|
||||
|
||||
if (timer.loops > 0 && timer.loopsLeft == 0)
|
||||
{
|
||||
object.x = initialOffset.x;
|
||||
object.y = initialOffset.y;
|
||||
if (completionCallback != null)
|
||||
{
|
||||
completionCallback(this);
|
||||
}
|
||||
|
||||
if (this.timer == timer) release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor. Use static methods.
|
||||
*/
|
||||
@:keep
|
||||
function new() {}
|
||||
}
|
|
@ -4,6 +4,12 @@ import openfl.filters.BitmapFilterQuality;
|
|||
import flixel.text.FlxText;
|
||||
import flixel.group.FlxSpriteGroup;
|
||||
import funkin.graphics.shaders.GaussianBlurShader;
|
||||
import funkin.graphics.shaders.LeftMaskShader;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.tweens.FlxEase;
|
||||
import flixel.util.FlxTimer;
|
||||
import flixel.tweens.FlxTween;
|
||||
import openfl.display.BlendMode;
|
||||
|
||||
class CapsuleText extends FlxSpriteGroup
|
||||
{
|
||||
|
@ -13,6 +19,15 @@ class CapsuleText extends FlxSpriteGroup
|
|||
|
||||
public var text(default, set):String;
|
||||
|
||||
var maskShaderSongName:LeftMaskShader = new LeftMaskShader();
|
||||
|
||||
public var clipWidth(default, set):Int = 255;
|
||||
|
||||
public var tooLong:Bool = false;
|
||||
|
||||
// 255, 27 normal
|
||||
// 220, 27 favourited
|
||||
|
||||
public function new(x:Float, y:Float, songTitle:String, size:Float)
|
||||
{
|
||||
super(x, y);
|
||||
|
@ -36,6 +51,30 @@ class CapsuleText extends FlxSpriteGroup
|
|||
return text;
|
||||
}
|
||||
|
||||
// ???? none
|
||||
// 255, 27 normal
|
||||
// 220, 27 favourited
|
||||
|
||||
function set_clipWidth(value:Int):Int
|
||||
{
|
||||
resetText();
|
||||
if (whiteText.width > value)
|
||||
{
|
||||
tooLong = true;
|
||||
|
||||
blurredText.clipRect = new FlxRect(0, 0, value, blurredText.height);
|
||||
whiteText.clipRect = new FlxRect(0, 0, value, whiteText.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
tooLong = false;
|
||||
|
||||
blurredText.clipRect = null;
|
||||
whiteText.clipRect = null;
|
||||
}
|
||||
return clipWidth = value;
|
||||
}
|
||||
|
||||
function set_text(value:String):String
|
||||
{
|
||||
if (value == null) return value;
|
||||
|
@ -51,6 +90,102 @@ class CapsuleText extends FlxSpriteGroup
|
|||
new openfl.filters.GlowFilter(0x00ccff, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM),
|
||||
// new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW)
|
||||
];
|
||||
|
||||
return text = value;
|
||||
}
|
||||
|
||||
var moveTimer:FlxTimer = new FlxTimer();
|
||||
var moveTween:FlxTween;
|
||||
|
||||
public function initMove():Void
|
||||
{
|
||||
moveTimer.start(0.6, (timer) -> {
|
||||
moveTextRight();
|
||||
});
|
||||
}
|
||||
|
||||
function moveTextRight():Void
|
||||
{
|
||||
var distToMove:Float = whiteText.width - clipWidth;
|
||||
moveTween = FlxTween.tween(whiteText.offset, {x: distToMove}, 2,
|
||||
{
|
||||
onUpdate: function(_) {
|
||||
whiteText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height);
|
||||
blurredText.offset = whiteText.offset;
|
||||
blurredText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, blurredText.height);
|
||||
},
|
||||
onComplete: function(_) {
|
||||
moveTimer.start(0.3, (timer) -> {
|
||||
moveTextLeft();
|
||||
});
|
||||
},
|
||||
ease: FlxEase.sineInOut
|
||||
});
|
||||
}
|
||||
|
||||
function moveTextLeft():Void
|
||||
{
|
||||
moveTween = FlxTween.tween(whiteText.offset, {x: 0}, 2,
|
||||
{
|
||||
onUpdate: function(_) {
|
||||
whiteText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height);
|
||||
blurredText.offset = whiteText.offset;
|
||||
blurredText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, blurredText.height);
|
||||
},
|
||||
onComplete: function(_) {
|
||||
moveTimer.start(0.3, (timer) -> {
|
||||
moveTextRight();
|
||||
});
|
||||
},
|
||||
ease: FlxEase.sineInOut
|
||||
});
|
||||
}
|
||||
|
||||
public function resetText():Void
|
||||
{
|
||||
if (moveTween != null) moveTween.cancel();
|
||||
if (moveTimer != null) moveTimer.cancel();
|
||||
whiteText.offset.x = 0;
|
||||
whiteText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height);
|
||||
blurredText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height);
|
||||
}
|
||||
|
||||
var flickerState:Bool = false;
|
||||
var flickerTimer:FlxTimer;
|
||||
|
||||
public function flickerText():Void
|
||||
{
|
||||
resetText();
|
||||
flickerTimer = new FlxTimer().start(1 / 24, flickerProgress, 19);
|
||||
}
|
||||
|
||||
function flickerProgress(timer:FlxTimer):Void
|
||||
{
|
||||
if (flickerState == true)
|
||||
{
|
||||
whiteText.blend = BlendMode.ADD;
|
||||
blurredText.blend = BlendMode.ADD;
|
||||
blurredText.color = 0xFFFFFFFF;
|
||||
whiteText.color = 0xFFFFFFFF;
|
||||
whiteText.textField.filters = [
|
||||
new openfl.filters.GlowFilter(0xFFFFFF, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM),
|
||||
// new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW)
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
blurredText.color = 0xFF00aadd;
|
||||
whiteText.color = 0xFFDDDDDD;
|
||||
whiteText.textField.filters = [
|
||||
new openfl.filters.GlowFilter(0xDDDDDD, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM),
|
||||
// new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW)
|
||||
];
|
||||
}
|
||||
flickerState = !flickerState;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ class DJBoyfriend extends FlxAtlasSprite
|
|||
return anims;
|
||||
}
|
||||
|
||||
var lowPumpLoopPoint:Int = 4;
|
||||
|
||||
public override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
@ -114,6 +116,14 @@ class DJBoyfriend extends FlxAtlasSprite
|
|||
case Confirm:
|
||||
if (getCurrentAnimation() != 'Boyfriend DJ confirm') playFlashAnimation('Boyfriend DJ confirm', false);
|
||||
timeSinceSpook = 0;
|
||||
case PumpIntro:
|
||||
if (getCurrentAnimation() != 'Boyfriend DJ fist pump') playFlashAnimation('Boyfriend DJ fist pump', false);
|
||||
if (getCurrentAnimation() == 'Boyfriend DJ fist pump' && anim.curFrame >= 4)
|
||||
{
|
||||
anim.play("Boyfriend DJ fist pump", true, false, 0);
|
||||
}
|
||||
case FistPump:
|
||||
|
||||
case Spook:
|
||||
if (getCurrentAnimation() != 'bf dj afk')
|
||||
{
|
||||
|
@ -174,6 +184,12 @@ class DJBoyfriend extends FlxAtlasSprite
|
|||
currentState = Idle;
|
||||
case "Boyfriend DJ confirm":
|
||||
|
||||
case "Boyfriend DJ fist pump":
|
||||
currentState = Idle;
|
||||
|
||||
case "Boyfriend DJ loss reaction 1":
|
||||
currentState = Idle;
|
||||
|
||||
case "Boyfriend DJ watchin tv OG":
|
||||
var frame:Int = FlxG.random.bool(33) ? 112 : 166;
|
||||
|
||||
|
@ -275,6 +291,23 @@ class DJBoyfriend extends FlxAtlasSprite
|
|||
currentState = Confirm;
|
||||
}
|
||||
|
||||
public function fistPump():Void
|
||||
{
|
||||
currentState = PumpIntro;
|
||||
}
|
||||
|
||||
public function pumpFist():Void
|
||||
{
|
||||
currentState = FistPump;
|
||||
anim.play("Boyfriend DJ fist pump", true, false, 4);
|
||||
}
|
||||
|
||||
public function pumpFistBad():Void
|
||||
{
|
||||
currentState = FistPump;
|
||||
anim.play("Boyfriend DJ loss reaction 1", true, false, 4);
|
||||
}
|
||||
|
||||
public inline function addOffset(name:String, x:Float = 0, y:Float = 0)
|
||||
{
|
||||
animOffsets[name] = [x, y];
|
||||
|
@ -331,6 +364,8 @@ enum DJBoyfriendState
|
|||
Intro;
|
||||
Idle;
|
||||
Confirm;
|
||||
PumpIntro;
|
||||
FistPump;
|
||||
Spook;
|
||||
TV;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package funkin.ui.freeplay;
|
||||
|
||||
import funkin.graphics.adobeanimate.FlxAtlasSprite;
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
import flixel.addons.ui.FlxInputText;
|
||||
import flixel.FlxCamera;
|
||||
|
@ -10,6 +11,7 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
|
|||
import flixel.input.touch.FlxTouch;
|
||||
import flixel.math.FlxAngle;
|
||||
import flixel.math.FlxPoint;
|
||||
import openfl.display.BlendMode;
|
||||
import flixel.system.debug.watch.Tracker.TrackerProfile;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.tweens.FlxEase;
|
||||
|
@ -38,6 +40,8 @@ import funkin.ui.transition.LoadingState;
|
|||
import funkin.ui.transition.StickerSubState;
|
||||
import funkin.util.MathUtil;
|
||||
import lime.utils.Assets;
|
||||
import flixel.tweens.misc.ShakeTween;
|
||||
import funkin.effects.IntervalShake;
|
||||
|
||||
/**
|
||||
* Parameters used to initialize the FreeplayState.
|
||||
|
@ -133,6 +137,29 @@ class FreeplayState extends MusicBeatSubState
|
|||
public static var rememberedDifficulty:Null<String> = Constants.DEFAULT_DIFFICULTY;
|
||||
public static var rememberedSongId:Null<String> = 'tutorial';
|
||||
|
||||
var funnyCam:FunkinCamera;
|
||||
var rankCamera:FunkinCamera;
|
||||
var rankBg:FunkinSprite;
|
||||
var rankVignette:FlxSprite;
|
||||
|
||||
var backingTextYeah:FlxAtlasSprite;
|
||||
var orangeBackShit:FunkinSprite;
|
||||
var alsoOrangeLOL:FunkinSprite;
|
||||
var pinkBack:FunkinSprite;
|
||||
var confirmGlow:FlxSprite;
|
||||
var confirmGlow2:FlxSprite;
|
||||
var confirmTextGlow:FlxSprite;
|
||||
|
||||
var moreWays:BGScrollingText;
|
||||
var funnyScroll:BGScrollingText;
|
||||
var txtNuts:BGScrollingText;
|
||||
var funnyScroll2:BGScrollingText;
|
||||
var moreWays2:BGScrollingText;
|
||||
var funnyScroll3:BGScrollingText;
|
||||
|
||||
var bgDad:FlxSprite;
|
||||
var cardGlow:FlxSprite;
|
||||
|
||||
public function new(?params:FreeplayStateParams, ?stickers:StickerSubState)
|
||||
{
|
||||
currentCharacter = params?.character ?? Constants.DEFAULT_CHARACTER;
|
||||
|
@ -211,17 +238,17 @@ class FreeplayState extends MusicBeatSubState
|
|||
trace(FlxG.camera.initialZoom);
|
||||
trace(FlxCamera.defaultZoom);
|
||||
|
||||
var pinkBack:FunkinSprite = FunkinSprite.create('freeplay/pinkBack');
|
||||
pinkBack = FunkinSprite.create('freeplay/pinkBack');
|
||||
pinkBack.color = 0xFFFFD4E9; // sets it to pink!
|
||||
pinkBack.x -= pinkBack.width;
|
||||
|
||||
FlxTween.tween(pinkBack, {x: 0}, 0.6, {ease: FlxEase.quartOut});
|
||||
add(pinkBack);
|
||||
|
||||
var orangeBackShit:FunkinSprite = new FunkinSprite(84, 440).makeSolidColor(Std.int(pinkBack.width), 75, 0xFFFEDA00);
|
||||
orangeBackShit = new FunkinSprite(84, 440).makeSolidColor(Std.int(pinkBack.width), 75, 0xFFFEDA00);
|
||||
add(orangeBackShit);
|
||||
|
||||
var alsoOrangeLOL:FunkinSprite = new FunkinSprite(0, orangeBackShit.y).makeSolidColor(100, Std.int(orangeBackShit.height), 0xFFFFD400);
|
||||
alsoOrangeLOL = new FunkinSprite(0, orangeBackShit.y).makeSolidColor(100, Std.int(orangeBackShit.height), 0xFFFFD400);
|
||||
add(alsoOrangeLOL);
|
||||
|
||||
exitMovers.set([pinkBack, orangeBackShit, alsoOrangeLOL],
|
||||
|
@ -236,13 +263,30 @@ class FreeplayState extends MusicBeatSubState
|
|||
orangeBackShit.visible = false;
|
||||
alsoOrangeLOL.visible = false;
|
||||
|
||||
confirmTextGlow = new FlxSprite(-8, 115).loadGraphic(Paths.image('freeplay/glowingText'));
|
||||
confirmTextGlow.blend = BlendMode.ADD;
|
||||
confirmTextGlow.visible = false;
|
||||
|
||||
confirmGlow = new FlxSprite(-30, 240).loadGraphic(Paths.image('freeplay/confirmGlow'));
|
||||
confirmGlow.blend = BlendMode.ADD;
|
||||
|
||||
confirmGlow2 = new FlxSprite(confirmGlow.x, confirmGlow.y).loadGraphic(Paths.image('freeplay/confirmGlow2'));
|
||||
|
||||
confirmGlow.visible = false;
|
||||
confirmGlow2.visible = false;
|
||||
|
||||
add(confirmGlow2);
|
||||
add(confirmGlow);
|
||||
|
||||
add(confirmTextGlow);
|
||||
|
||||
var grpTxtScrolls:FlxGroup = new FlxGroup();
|
||||
add(grpTxtScrolls);
|
||||
grpTxtScrolls.visible = false;
|
||||
|
||||
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 = new BGScrollingText(0, 160, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43);
|
||||
moreWays.funnyColor = 0xFFFFF383;
|
||||
moreWays.speed = 6.8;
|
||||
grpTxtScrolls.add(moreWays);
|
||||
|
@ -253,7 +297,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
speed: 0.4,
|
||||
});
|
||||
|
||||
var funnyScroll:BGScrollingText = new BGScrollingText(0, 220, 'BOYFRIEND', FlxG.width / 2, false, 60);
|
||||
funnyScroll = new BGScrollingText(0, 220, 'BOYFRIEND', FlxG.width / 2, false, 60);
|
||||
funnyScroll.funnyColor = 0xFFFF9963;
|
||||
funnyScroll.speed = -3.8;
|
||||
grpTxtScrolls.add(funnyScroll);
|
||||
|
@ -266,7 +310,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
wait: 0
|
||||
});
|
||||
|
||||
var txtNuts:BGScrollingText = new BGScrollingText(0, 285, 'PROTECT YO NUTS', FlxG.width / 2, true, 43);
|
||||
txtNuts = new BGScrollingText(0, 285, 'PROTECT YO NUTS', FlxG.width / 2, true, 43);
|
||||
txtNuts.speed = 3.5;
|
||||
grpTxtScrolls.add(txtNuts);
|
||||
exitMovers.set([txtNuts],
|
||||
|
@ -275,7 +319,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
speed: 0.4,
|
||||
});
|
||||
|
||||
var funnyScroll2:BGScrollingText = new BGScrollingText(0, 335, 'BOYFRIEND', FlxG.width / 2, false, 60);
|
||||
funnyScroll2 = new BGScrollingText(0, 335, 'BOYFRIEND', FlxG.width / 2, false, 60);
|
||||
funnyScroll2.funnyColor = 0xFFFF9963;
|
||||
funnyScroll2.speed = -3.8;
|
||||
grpTxtScrolls.add(funnyScroll2);
|
||||
|
@ -286,7 +330,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
speed: 0.5,
|
||||
});
|
||||
|
||||
var moreWays2:BGScrollingText = new BGScrollingText(0, 397, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43);
|
||||
moreWays2 = new BGScrollingText(0, 397, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43);
|
||||
moreWays2.funnyColor = 0xFFFFF383;
|
||||
moreWays2.speed = 6.8;
|
||||
grpTxtScrolls.add(moreWays2);
|
||||
|
@ -297,7 +341,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
speed: 0.4
|
||||
});
|
||||
|
||||
var funnyScroll3:BGScrollingText = new BGScrollingText(0, orangeBackShit.y + 10, 'BOYFRIEND', FlxG.width / 2, 60);
|
||||
funnyScroll3 = new BGScrollingText(0, orangeBackShit.y + 10, 'BOYFRIEND', FlxG.width / 2, 60);
|
||||
funnyScroll3.funnyColor = 0xFFFEA400;
|
||||
funnyScroll3.speed = -3.8;
|
||||
grpTxtScrolls.add(funnyScroll3);
|
||||
|
@ -308,6 +352,24 @@ class FreeplayState extends MusicBeatSubState
|
|||
speed: 0.3
|
||||
});
|
||||
|
||||
backingTextYeah = new FlxAtlasSprite(640, 370, Paths.animateAtlas("freeplay/backing-text-yeah"),
|
||||
{
|
||||
FrameRate: 24.0,
|
||||
Reversed: false,
|
||||
// ?OnComplete:Void -> Void,
|
||||
ShowPivot: false,
|
||||
Antialiasing: true,
|
||||
ScrollFactor: new FlxPoint(1, 1),
|
||||
});
|
||||
|
||||
add(backingTextYeah);
|
||||
|
||||
cardGlow = new FlxSprite(-30, -30).loadGraphic(Paths.image('freeplay/cardGlow'));
|
||||
cardGlow.blend = BlendMode.ADD;
|
||||
cardGlow.visible = false;
|
||||
|
||||
add(cardGlow);
|
||||
|
||||
dj = new DJBoyfriend(640, 366);
|
||||
exitMovers.set([dj],
|
||||
{
|
||||
|
@ -320,7 +382,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
add(dj);
|
||||
|
||||
var bgDad:FlxSprite = new FlxSprite(pinkBack.width * 0.75, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad'));
|
||||
bgDad = new FlxSprite(pinkBack.width * 0.75, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad'));
|
||||
bgDad.setGraphicSize(0, FlxG.height);
|
||||
bgDad.updateHitbox();
|
||||
bgDad.shader = new AngleMask();
|
||||
|
@ -337,10 +399,14 @@ class FreeplayState extends MusicBeatSubState
|
|||
});
|
||||
|
||||
add(bgDad);
|
||||
FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.75}, 0.7, {ease: FlxEase.quintOut});
|
||||
FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.76}, 0.7, {ease: FlxEase.quintOut});
|
||||
|
||||
blackOverlayBullshitLOLXD.shader = bgDad.shader;
|
||||
|
||||
rankBg = new FunkinSprite(0, 0);
|
||||
rankBg.makeSolidColor(FlxG.width, FlxG.height, 0xD3000000);
|
||||
add(rankBg);
|
||||
|
||||
grpSongs = new FlxTypedGroup<Alphabet>();
|
||||
add(grpSongs);
|
||||
|
||||
|
@ -518,18 +584,35 @@ class FreeplayState extends MusicBeatSubState
|
|||
orangeBackShit.visible = true;
|
||||
alsoOrangeLOL.visible = true;
|
||||
grpTxtScrolls.visible = true;
|
||||
|
||||
cardGlow.visible = true;
|
||||
FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.45, {ease: FlxEase.sineOut});
|
||||
});
|
||||
|
||||
generateSongList(null, false);
|
||||
|
||||
// dedicated camera for the state so we don't need to fuk around with camera scrolls from the mainmenu / elsewhere
|
||||
var funnyCam:FunkinCamera = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height);
|
||||
funnyCam = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height);
|
||||
funnyCam.bgColor = FlxColor.TRANSPARENT;
|
||||
FlxG.cameras.add(funnyCam, false);
|
||||
|
||||
rankVignette = new FlxSprite(0, 0).loadGraphic(Paths.image('freeplay/rankVignette'));
|
||||
rankVignette.scale.set(2, 2);
|
||||
rankVignette.updateHitbox();
|
||||
rankVignette.blend = BlendMode.ADD;
|
||||
// rankVignette.cameras = [rankCamera];
|
||||
add(rankVignette);
|
||||
rankVignette.alpha = 0;
|
||||
|
||||
forEach(function(bs) {
|
||||
bs.cameras = [funnyCam];
|
||||
});
|
||||
|
||||
rankCamera = new FunkinCamera('rankCamera', 0, 0, FlxG.width, FlxG.height);
|
||||
rankCamera.bgColor = FlxColor.TRANSPARENT;
|
||||
FlxG.cameras.add(rankCamera, false);
|
||||
rankBg.cameras = [rankCamera];
|
||||
rankBg.alpha = 0;
|
||||
}
|
||||
|
||||
var currentFilter:SongFilter = null;
|
||||
|
@ -576,6 +659,7 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
for (cap in grpCapsules.members)
|
||||
{
|
||||
cap.songText.resetText();
|
||||
cap.kill();
|
||||
}
|
||||
|
||||
|
@ -593,9 +677,11 @@ class FreeplayState extends MusicBeatSubState
|
|||
};
|
||||
randomCapsule.y = randomCapsule.intendedY(0) + 10;
|
||||
randomCapsule.targetPos.x = randomCapsule.x;
|
||||
randomCapsule.alpha = 0.5;
|
||||
randomCapsule.alpha = 0;
|
||||
randomCapsule.songText.visible = false;
|
||||
randomCapsule.favIcon.visible = false;
|
||||
randomCapsule.ranking.visible = false;
|
||||
randomCapsule.blurredRanking.visible = false;
|
||||
randomCapsule.initJumpIn(0, force);
|
||||
randomCapsule.hsvShader = hsvShader;
|
||||
grpCapsules.add(randomCapsule);
|
||||
|
@ -618,8 +704,12 @@ class FreeplayState extends MusicBeatSubState
|
|||
funnyMenu.favIcon.visible = tempSongs[i].isFav;
|
||||
funnyMenu.hsvShader = hsvShader;
|
||||
|
||||
funnyMenu.newText.animation.curAnim.curFrame = 45 - ((i * 4) % 45);
|
||||
|
||||
funnyMenu.forcePosition();
|
||||
|
||||
funnyMenu.checkClip();
|
||||
|
||||
grpCapsules.add(funnyMenu);
|
||||
}
|
||||
|
||||
|
@ -673,6 +763,210 @@ class FreeplayState extends MusicBeatSubState
|
|||
return songsToFilter;
|
||||
}
|
||||
|
||||
function rankAnimStart()
|
||||
{
|
||||
dj.fistPump();
|
||||
// rankCamera.fade(FlxColor.BLACK, 0.5, true);
|
||||
rankCamera.fade(0xFF000000, 0.5, true, null, true);
|
||||
FlxG.sound.music.volume = 0;
|
||||
rankBg.alpha = 1;
|
||||
|
||||
originalPos.x = grpCapsules.members[curSelected].x;
|
||||
originalPos.y = grpCapsules.members[curSelected].y;
|
||||
|
||||
grpCapsules.members[curSelected].ranking.alpha = 0;
|
||||
grpCapsules.members[curSelected].blurredRanking.alpha = 0;
|
||||
|
||||
rankCamera.zoom = 1.85;
|
||||
FlxTween.tween(rankCamera, {"zoom": 1.8}, 0.6, {ease: FlxEase.sineIn});
|
||||
|
||||
funnyCam.zoom = 1.15;
|
||||
FlxTween.tween(funnyCam, {"zoom": 1.1}, 0.6, {ease: FlxEase.sineIn});
|
||||
|
||||
grpCapsules.members[curSelected].cameras = [rankCamera];
|
||||
grpCapsules.members[curSelected].targetPos.set((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2),
|
||||
(FlxG.height / 2) - (grpCapsules.members[curSelected].height / 2));
|
||||
|
||||
new FlxTimer().start(0.5, _ -> {
|
||||
grpCapsules.members[curSelected].doLerp = false;
|
||||
rankDisplayNew();
|
||||
});
|
||||
}
|
||||
|
||||
function rankDisplayNew()
|
||||
{
|
||||
grpCapsules.members[curSelected].ranking.alpha = 1;
|
||||
grpCapsules.members[curSelected].blurredRanking.alpha = 1;
|
||||
|
||||
grpCapsules.members[curSelected].ranking.scale.set(20, 20);
|
||||
grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20);
|
||||
// var tempr:Int = FlxG.random.int(0, 4);
|
||||
|
||||
// grpCapsules.members[curSelected].ranking.rank = tempr;
|
||||
grpCapsules.members[curSelected].ranking.animation.play(grpCapsules.members[curSelected].ranking.animation.curAnim.name, true);
|
||||
FlxTween.tween(grpCapsules.members[curSelected].ranking, {"scale.x": 1, "scale.y": 1}, 0.1);
|
||||
|
||||
grpCapsules.members[curSelected].blurredRanking.animation.play(grpCapsules.members[curSelected].blurredRanking.animation.curAnim.name, true);
|
||||
FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1);
|
||||
|
||||
new FlxTimer().start(0.1, _ -> {
|
||||
trace(grpCapsules.members[curSelected].ranking.rank);
|
||||
switch (grpCapsules.members[curSelected].tempr)
|
||||
{
|
||||
case 0:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/rankinbad'));
|
||||
case 4:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/rankinperfect'));
|
||||
case 5:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/rankinperfect'));
|
||||
default:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/rankinnormal'));
|
||||
}
|
||||
rankCamera.zoom = 1.3;
|
||||
// FlxTween.tween(rankCamera, {"zoom": 1.4}, 0.3, {ease: FlxEase.elasticOut});
|
||||
|
||||
FlxTween.tween(rankCamera, {"zoom": 1.5}, 0.3, {ease: FlxEase.backInOut});
|
||||
|
||||
grpCapsules.members[curSelected].x -= 10;
|
||||
grpCapsules.members[curSelected].y -= 20;
|
||||
|
||||
FlxTween.tween(funnyCam, {"zoom": 1.05}, 0.3, {ease: FlxEase.elasticOut});
|
||||
|
||||
grpCapsules.members[curSelected].capsule.angle = -3;
|
||||
FlxTween.tween(grpCapsules.members[curSelected].capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut});
|
||||
|
||||
IntervalShake.shake(grpCapsules.members[curSelected].capsule, 0.3, 1 / 30, 0.1, 0, FlxEase.quadOut);
|
||||
});
|
||||
|
||||
new FlxTimer().start(0.4, _ -> {
|
||||
FlxTween.tween(funnyCam, {"zoom": 1}, 0.8, {ease: FlxEase.sineIn});
|
||||
FlxTween.tween(rankCamera, {"zoom": 1.2}, 0.8, {ease: FlxEase.backIn});
|
||||
// IntervalShake.shake(grpCapsules.members[curSelected], 0.8 + 0.5, 1 / 24, 0, 2, FlxEase.quadIn);
|
||||
FlxTween.tween(grpCapsules.members[curSelected], {x: originalPos.x - 7, y: originalPos.y - 80}, 0.8 + 0.5, {ease: FlxEase.quartIn});
|
||||
});
|
||||
|
||||
new FlxTimer().start(0.6, _ -> {
|
||||
rankAnimSlam();
|
||||
// IntervalShake.shake(grpCapsules.members[curSelected].capsule, 0.3, 1 / 30, 0, 0.3, FlxEase.quartIn);
|
||||
});
|
||||
}
|
||||
|
||||
function rankAnimSlam()
|
||||
{
|
||||
// FlxTween.tween(rankCamera, {"zoom": 1.9}, 0.5, {ease: FlxEase.backOut});
|
||||
FlxTween.tween(rankBg, {alpha: 0}, 0.5, {ease: FlxEase.expoIn});
|
||||
|
||||
// FlxTween.tween(grpCapsules.members[curSelected], {angle: 5}, 0.5, {ease: FlxEase.backIn});
|
||||
|
||||
switch (grpCapsules.members[curSelected].tempr)
|
||||
{
|
||||
case 0:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/loss'));
|
||||
case 1:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/good'));
|
||||
case 2:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/great'));
|
||||
case 3:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/excellent'));
|
||||
case 4:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/perfect'));
|
||||
case 5:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/perfect'));
|
||||
default:
|
||||
FunkinSound.playOnce(Paths.sound('ranks/loss'));
|
||||
}
|
||||
|
||||
FlxTween.tween(grpCapsules.members[curSelected], {"targetPos.x": originalPos.x, "targetPos.y": originalPos.y}, 0.5, {ease: FlxEase.expoOut});
|
||||
new FlxTimer().start(0.5, _ -> {
|
||||
funnyCam.shake(0.0045, 0.35);
|
||||
|
||||
if (grpCapsules.members[curSelected].tempr == 0)
|
||||
{
|
||||
dj.pumpFistBad();
|
||||
}
|
||||
else
|
||||
{
|
||||
dj.pumpFist();
|
||||
}
|
||||
|
||||
rankCamera.zoom = 0.8;
|
||||
funnyCam.zoom = 0.8;
|
||||
FlxTween.tween(rankCamera, {"zoom": 1}, 1, {ease: FlxEase.elasticOut});
|
||||
FlxTween.tween(funnyCam, {"zoom": 1}, 0.8, {ease: FlxEase.elasticOut});
|
||||
|
||||
for (index => capsule in grpCapsules.members)
|
||||
{
|
||||
var distFromSelected:Float = Math.abs(index - curSelected) - 1;
|
||||
|
||||
if (distFromSelected < 5)
|
||||
{
|
||||
if (index == curSelected)
|
||||
{
|
||||
FlxTween.cancelTweensOf(capsule);
|
||||
// capsule.targetPos.x += 50;
|
||||
capsule.fadeAnim();
|
||||
|
||||
rankVignette.color = capsule.getTrailColor();
|
||||
rankVignette.alpha = 1;
|
||||
FlxTween.tween(rankVignette, {alpha: 0}, 0.6, {ease: FlxEase.expoOut});
|
||||
|
||||
capsule.doLerp = false;
|
||||
capsule.setPosition(originalPos.x, originalPos.y);
|
||||
IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12, 0, FlxEase.quadOut, function(_) {
|
||||
capsule.doLerp = true;
|
||||
capsule.cameras = [funnyCam];
|
||||
}, null);
|
||||
|
||||
// FlxTween.tween(capsule, {"targetPos.x": capsule.targetPos.x - 50}, 0.6,
|
||||
// {
|
||||
// ease: FlxEase.backInOut,
|
||||
// onComplete: function(_) {
|
||||
// capsule.cameras = [funnyCam];
|
||||
// }
|
||||
// });
|
||||
FlxTween.tween(capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut});
|
||||
}
|
||||
if (index > curSelected)
|
||||
{
|
||||
// capsule.color = FlxColor.RED;
|
||||
new FlxTimer().start(distFromSelected / 20, _ -> {
|
||||
capsule.doLerp = false;
|
||||
|
||||
capsule.capsule.angle = FlxG.random.float(-10 + (distFromSelected * 2), 10 - (distFromSelected * 2));
|
||||
FlxTween.tween(capsule.capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut});
|
||||
|
||||
IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12 / (distFromSelected + 1), 0, FlxEase.quadOut, function(_) {
|
||||
capsule.doLerp = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (index < curSelected)
|
||||
{
|
||||
// capsule.color = FlxColor.BLUE;
|
||||
new FlxTimer().start(distFromSelected / 20, _ -> {
|
||||
capsule.doLerp = false;
|
||||
|
||||
capsule.capsule.angle = FlxG.random.float(-10 + (distFromSelected * 2), 10 - (distFromSelected * 2));
|
||||
FlxTween.tween(capsule.capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut});
|
||||
|
||||
IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12 / (distFromSelected + 1), 0, FlxEase.quadOut, function(_) {
|
||||
capsule.doLerp = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
index += 1;
|
||||
}
|
||||
});
|
||||
|
||||
new FlxTimer().start(2, _ -> {
|
||||
// dj.fistPump();
|
||||
FlxG.sound.music.fadeIn(4.0, 0.0, 1.0);
|
||||
});
|
||||
}
|
||||
|
||||
var touchY:Float = 0;
|
||||
var touchX:Float = 0;
|
||||
var dxTouch:Float = 0;
|
||||
|
@ -689,10 +983,48 @@ class FreeplayState extends MusicBeatSubState
|
|||
|
||||
var busy:Bool = false; // Set to true once the user has pressed enter to select a song.
|
||||
|
||||
var originalPos:FlxPoint = new FlxPoint();
|
||||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
if (FlxG.keys.justPressed.T)
|
||||
{
|
||||
rankAnimStart();
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.H)
|
||||
{
|
||||
rankDisplayNew();
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.G)
|
||||
{
|
||||
rankAnimSlam();
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.I)
|
||||
{
|
||||
confirmTextGlow.y -= 1;
|
||||
trace(confirmTextGlow.x, confirmTextGlow.y);
|
||||
}
|
||||
if (FlxG.keys.justPressed.J)
|
||||
{
|
||||
confirmTextGlow.x -= 1;
|
||||
trace(confirmTextGlow.x, confirmTextGlow.y);
|
||||
}
|
||||
if (FlxG.keys.justPressed.L)
|
||||
{
|
||||
confirmTextGlow.x += 1;
|
||||
trace(confirmTextGlow.x, confirmTextGlow.y);
|
||||
}
|
||||
if (FlxG.keys.justPressed.K)
|
||||
{
|
||||
confirmTextGlow.y += 1;
|
||||
trace(confirmTextGlow.x, confirmTextGlow.y);
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.F)
|
||||
{
|
||||
var targetSong = grpCapsules.members[curSelected]?.songData;
|
||||
|
@ -1153,6 +1485,42 @@ class FreeplayState extends MusicBeatSubState
|
|||
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
||||
dj.confirm();
|
||||
|
||||
grpCapsules.members[curSelected].songText.flickerText();
|
||||
|
||||
// FlxTween.color(bgDad, 0.33, 0xFFFFFFFF, 0xFF555555, {ease: FlxEase.quadOut});
|
||||
FlxTween.color(pinkBack, 0.33, 0xFFFFD0D5, 0xFF171831, {ease: FlxEase.quadOut});
|
||||
orangeBackShit.visible = false;
|
||||
alsoOrangeLOL.visible = false;
|
||||
|
||||
confirmGlow.visible = true;
|
||||
confirmGlow2.visible = true;
|
||||
|
||||
backingTextYeah.anim.play("BF back card confirm raw", false, false, 0);
|
||||
confirmGlow2.alpha = 0;
|
||||
confirmGlow.alpha = 0;
|
||||
|
||||
FlxTween.tween(confirmGlow2, {alpha: 0.5}, 0.33,
|
||||
{
|
||||
ease: FlxEase.quadOut,
|
||||
onComplete: function(_) {
|
||||
confirmGlow2.alpha = 0.6;
|
||||
confirmGlow.alpha = 1;
|
||||
confirmTextGlow.visible = true;
|
||||
confirmTextGlow.alpha = 1;
|
||||
FlxTween.tween(confirmTextGlow, {alpha: 0.4}, 0.5);
|
||||
FlxTween.tween(confirmGlow, {alpha: 0}, 0.5);
|
||||
}
|
||||
});
|
||||
|
||||
// confirmGlow
|
||||
|
||||
moreWays.visible = false;
|
||||
funnyScroll.visible = false;
|
||||
txtNuts.visible = false;
|
||||
funnyScroll2.visible = false;
|
||||
moreWays2.visible = false;
|
||||
funnyScroll3.visible = false;
|
||||
|
||||
new FlxTimer().start(1, function(tmr:FlxTimer) {
|
||||
Paths.setCurrentLevel(cap.songData.levelId);
|
||||
LoadingState.loadPlayState(
|
||||
|
@ -1391,6 +1759,7 @@ class FreeplaySongData
|
|||
|
||||
public var songName(default, null):String = '';
|
||||
public var songCharacter(default, null):String = '';
|
||||
public var songStartingBpm(default, null):Float = 0;
|
||||
public var difficultyRating(default, null):Int = 0;
|
||||
public var albumId(default, null):Null<String> = null;
|
||||
|
||||
|
@ -1445,6 +1814,7 @@ class FreeplaySongData
|
|||
|
||||
var songDifficulty:SongDifficulty = song.getDifficulty(currentDifficulty, variations);
|
||||
if (songDifficulty == null) return;
|
||||
this.songStartingBpm = songDifficulty.getStartingBPM();
|
||||
this.songName = songDifficulty.songName;
|
||||
this.songCharacter = songDifficulty.characters.opponent;
|
||||
this.difficultyRating = songDifficulty.difficultyRating;
|
||||
|
|
|
@ -14,6 +14,13 @@ import flixel.text.FlxText;
|
|||
import flixel.util.FlxTimer;
|
||||
import funkin.util.MathUtil;
|
||||
import funkin.graphics.shaders.Grayscale;
|
||||
import funkin.graphics.shaders.GaussianBlurShader;
|
||||
import openfl.display.BlendMode;
|
||||
import funkin.graphics.FunkinSprite;
|
||||
import flixel.tweens.FlxEase;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.addons.effects.FlxTrail;
|
||||
import flixel.util.FlxColor;
|
||||
|
||||
class SongMenuItem extends FlxSpriteGroup
|
||||
{
|
||||
|
@ -31,9 +38,10 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
|
||||
public var songText:CapsuleText;
|
||||
public var favIcon:FlxSprite;
|
||||
public var ranking:FlxSprite;
|
||||
public var ranking:FreeplayRank;
|
||||
public var blurredRanking:FreeplayRank;
|
||||
|
||||
var ranks:Array<String> = ["fail", "average", "great", "excellent", "perfect"];
|
||||
var ranks:Array<String> = ["fail", "average", "great", "excellent", "perfect", "perfectsick"];
|
||||
|
||||
public var targetPos:FlxPoint = new FlxPoint();
|
||||
public var doLerp:Bool = false;
|
||||
|
@ -47,6 +55,22 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
public var hsvShader(default, set):HSVShader;
|
||||
|
||||
// var diffRatingSprite:FlxSprite;
|
||||
public var bpmText:FlxSprite;
|
||||
public var difficultyText:FlxSprite;
|
||||
public var weekType:FlxSprite;
|
||||
|
||||
public var newText:FlxSprite;
|
||||
|
||||
// public var weekType:FlxSprite;
|
||||
public var bigNumbers:Array<CapsuleNumber> = [];
|
||||
|
||||
public var smallNumbers:Array<CapsuleNumber> = [];
|
||||
|
||||
public var weekNumbers:Array<CapsuleNumber> = [];
|
||||
|
||||
var impactThing:FunkinSprite;
|
||||
|
||||
public var tempr:Int;
|
||||
|
||||
public function new(x:Float, y:Float)
|
||||
{
|
||||
|
@ -59,12 +83,64 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
// capsule.animation
|
||||
add(capsule);
|
||||
|
||||
bpmText = new FlxSprite(144, 87).loadGraphic(Paths.image('freeplay/freeplayCapsule/bpmtext'));
|
||||
bpmText.setGraphicSize(Std.int(bpmText.width * 0.9));
|
||||
add(bpmText);
|
||||
|
||||
difficultyText = new FlxSprite(414, 87).loadGraphic(Paths.image('freeplay/freeplayCapsule/difficultytext'));
|
||||
difficultyText.setGraphicSize(Std.int(difficultyText.width * 0.9));
|
||||
add(difficultyText);
|
||||
|
||||
weekType = new FlxSprite(291, 87);
|
||||
weekType.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/weektypes');
|
||||
|
||||
weekType.animation.addByPrefix('WEEK', 'WEEK text instance 1', 24, false);
|
||||
weekType.animation.addByPrefix('WEEKEND', 'WEEKEND text instance 1', 24, false);
|
||||
|
||||
weekType.setGraphicSize(Std.int(weekType.width * 0.9));
|
||||
add(weekType);
|
||||
|
||||
newText = new FlxSprite(454, 9);
|
||||
newText.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/new');
|
||||
newText.animation.addByPrefix('newAnim', 'NEW notif', 24, true);
|
||||
newText.animation.play('newAnim', true);
|
||||
newText.setGraphicSize(Std.int(newText.width * 0.9));
|
||||
|
||||
newText.visible = false;
|
||||
|
||||
add(newText);
|
||||
|
||||
// var debugNumber2:CapsuleNumber = new CapsuleNumber(0, 0, true, 2);
|
||||
// add(debugNumber2);
|
||||
|
||||
for (i in 0...2)
|
||||
{
|
||||
var bigNumber:CapsuleNumber = new CapsuleNumber(466 + (i * 30), 32, true, 0);
|
||||
add(bigNumber);
|
||||
|
||||
bigNumbers.push(bigNumber);
|
||||
}
|
||||
|
||||
for (i in 0...3)
|
||||
{
|
||||
var smallNumber:CapsuleNumber = new CapsuleNumber(185 + (i * 11), 88.5, false, 0);
|
||||
add(smallNumber);
|
||||
|
||||
smallNumbers.push(smallNumber);
|
||||
}
|
||||
|
||||
// doesn't get added, simply is here to help with visibility of things for the pop in!
|
||||
grpHide = new FlxGroup();
|
||||
|
||||
var rank:String = FlxG.random.getObject(ranks);
|
||||
|
||||
ranking = new FlxSprite(capsule.width * 0.84, 30);
|
||||
tempr = FlxG.random.int(0, 5);
|
||||
ranking = new FreeplayRank(420, 41, tempr);
|
||||
add(ranking);
|
||||
|
||||
blurredRanking = new FreeplayRank(ranking.x, ranking.y, tempr);
|
||||
blurredRanking.shader = new GaussianBlurShader(1);
|
||||
add(blurredRanking);
|
||||
// ranking.loadGraphic(Paths.image('freeplay/ranks/' + rank));
|
||||
// ranking.scale.x = ranking.scale.y = realScaled;
|
||||
// ranking.alpha = 0.75;
|
||||
|
@ -73,11 +149,11 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
// add(ranking);
|
||||
// grpHide.add(ranking);
|
||||
|
||||
switch (rank)
|
||||
{
|
||||
case 'perfect':
|
||||
ranking.x -= 10;
|
||||
}
|
||||
// switch (rank)
|
||||
// {
|
||||
// case 'perfect':
|
||||
// ranking.x -= 10;
|
||||
// }
|
||||
|
||||
grayscaleShader = new Grayscale(1);
|
||||
|
||||
|
@ -93,7 +169,7 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
grpHide.add(songText);
|
||||
|
||||
// TODO: Use value from metadata instead of random.
|
||||
updateDifficultyRating(FlxG.random.int(0, 15));
|
||||
updateDifficultyRating(FlxG.random.int(0, 20));
|
||||
|
||||
pixelIcon = new FlxSprite(160, 35);
|
||||
|
||||
|
@ -103,21 +179,216 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
add(pixelIcon);
|
||||
grpHide.add(pixelIcon);
|
||||
|
||||
favIcon = new FlxSprite(400, 40);
|
||||
favIcon = new FlxSprite(380, 40);
|
||||
favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart');
|
||||
favIcon.animation.addByPrefix('fav', 'favorite heart', 24, false);
|
||||
favIcon.animation.play('fav');
|
||||
favIcon.setGraphicSize(50, 50);
|
||||
favIcon.visible = false;
|
||||
favIcon.blend = BlendMode.ADD;
|
||||
add(favIcon);
|
||||
// grpHide.add(favIcon);
|
||||
|
||||
var weekNumber:CapsuleNumber = new CapsuleNumber(355, 88.5, false, 0);
|
||||
add(weekNumber);
|
||||
|
||||
weekNumbers.push(weekNumber);
|
||||
|
||||
setVisibleGrp(false);
|
||||
}
|
||||
|
||||
// no way to grab weeks rn, so this needs to be done :/
|
||||
// negative values mean weekends
|
||||
function checkWeek(name:String):Void
|
||||
{
|
||||
// trace(name);
|
||||
var weekNum:Int = 0;
|
||||
switch (name)
|
||||
{
|
||||
case 'bopeebo' | 'fresh' | 'dadbattle':
|
||||
weekNum = 1;
|
||||
case 'spookeez' | 'south' | 'monster':
|
||||
weekNum = 2;
|
||||
case 'pico' | 'philly-nice' | 'blammed':
|
||||
weekNum = 3;
|
||||
case "satin-panties" | 'high' | 'milf':
|
||||
weekNum = 4;
|
||||
case "cocoa" | 'eggnog' | 'winter-horrorland':
|
||||
weekNum = 5;
|
||||
case 'senpai' | 'roses' | 'thorns':
|
||||
weekNum = 6;
|
||||
case 'ugh' | 'guns' | 'stress':
|
||||
weekNum = 7;
|
||||
case 'darnell' | 'lit-up' | '2hot' | 'blazin':
|
||||
weekNum = -1;
|
||||
default:
|
||||
weekNum = 0;
|
||||
}
|
||||
|
||||
weekNumbers[0].digit = Std.int(Math.abs(weekNum));
|
||||
|
||||
if (weekNum == 0)
|
||||
{
|
||||
weekType.visible = false;
|
||||
weekNumbers[0].visible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
weekType.visible = true;
|
||||
weekNumbers[0].visible = true;
|
||||
}
|
||||
if (weekNum > 0)
|
||||
{
|
||||
weekType.animation.play('WEEK', true);
|
||||
}
|
||||
else
|
||||
{
|
||||
weekType.animation.play('WEEKEND', true);
|
||||
weekNumbers[0].offset.x -= 35;
|
||||
}
|
||||
}
|
||||
|
||||
// 255, 27 normal
|
||||
// 220, 27 favourited
|
||||
public function checkClip():Void
|
||||
{
|
||||
var clipSize:Int = 290;
|
||||
var clipType:Int = 0;
|
||||
|
||||
if (ranking.visible == true) clipType += 1;
|
||||
if (favIcon.visible == true) clipType += 1;
|
||||
switch (clipType)
|
||||
{
|
||||
case 2:
|
||||
clipSize = 220;
|
||||
case 1:
|
||||
clipSize = 255;
|
||||
}
|
||||
songText.clipWidth = clipSize;
|
||||
}
|
||||
|
||||
function updateBPM(newBPM:Int):Void
|
||||
{
|
||||
trace(newBPM);
|
||||
|
||||
var shiftX:Float = 191;
|
||||
var tempShift:Float = 0;
|
||||
|
||||
if (Math.floor(newBPM / 100) == 1)
|
||||
{
|
||||
shiftX = 186;
|
||||
}
|
||||
|
||||
for (i in 0...smallNumbers.length)
|
||||
{
|
||||
smallNumbers[i].x = this.x + (shiftX + (i * 11));
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (newBPM < 100)
|
||||
{
|
||||
smallNumbers[i].digit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
smallNumbers[i].digit = Math.floor(newBPM / 100) % 10;
|
||||
}
|
||||
|
||||
case 1:
|
||||
if (newBPM < 10)
|
||||
{
|
||||
smallNumbers[i].digit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
smallNumbers[i].digit = Math.floor(newBPM / 10) % 10;
|
||||
|
||||
if (Math.floor(newBPM / 10) % 10 == 1) tempShift = -4;
|
||||
}
|
||||
case 2:
|
||||
smallNumbers[i].digit = newBPM % 10;
|
||||
default:
|
||||
trace('why the fuck is this being called');
|
||||
}
|
||||
smallNumbers[i].x += tempShift;
|
||||
}
|
||||
// diffRatingSprite.loadGraphic(Paths.image('freeplay/diffRatings/diff${ratingPadded}'));
|
||||
// diffRatingSprite.visible = false;
|
||||
}
|
||||
|
||||
var evilTrail:FlxTrail;
|
||||
|
||||
public function fadeAnim()
|
||||
{
|
||||
impactThing = new FunkinSprite(0, 0);
|
||||
impactThing.frames = capsule.frames;
|
||||
impactThing.frame = capsule.frame;
|
||||
impactThing.updateHitbox();
|
||||
// impactThing.x = capsule.x;
|
||||
// impactThing.y = capsule.y;
|
||||
// picoFade.stamp(this, 0, 0);
|
||||
impactThing.alpha = 0;
|
||||
impactThing.zIndex = capsule.zIndex - 3;
|
||||
add(impactThing);
|
||||
FlxTween.tween(impactThing.scale, {x: 2.5, y: 2.5}, 0.5);
|
||||
// FlxTween.tween(impactThing, {alpha: 0}, 0.5);
|
||||
|
||||
evilTrail = new FlxTrail(impactThing, null, 15, 2, 0.01, 0.069);
|
||||
evilTrail.blend = BlendMode.ADD;
|
||||
evilTrail.zIndex = capsule.zIndex - 5;
|
||||
FlxTween.tween(evilTrail, {alpha: 0}, 0.6,
|
||||
{
|
||||
ease: FlxEase.quadOut,
|
||||
onComplete: function(_) {
|
||||
remove(evilTrail);
|
||||
}
|
||||
});
|
||||
add(evilTrail);
|
||||
|
||||
switch (tempr)
|
||||
{
|
||||
case 0:
|
||||
evilTrail.color = 0xFF6044FF;
|
||||
case 1:
|
||||
evilTrail.color = 0xFFEF8764;
|
||||
case 2:
|
||||
evilTrail.color = 0xFFEAF6FF;
|
||||
case 3:
|
||||
evilTrail.color = 0xFFFDCB42;
|
||||
case 4:
|
||||
evilTrail.color = 0xFFFF58B4;
|
||||
case 5:
|
||||
evilTrail.color = 0xFFFFB619;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTrailColor():FlxColor
|
||||
{
|
||||
return evilTrail.color;
|
||||
}
|
||||
|
||||
function updateDifficultyRating(newRating:Int):Void
|
||||
{
|
||||
var ratingPadded:String = newRating < 10 ? '0$newRating' : '$newRating';
|
||||
|
||||
for (i in 0...bigNumbers.length)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (newRating > 10)
|
||||
{
|
||||
bigNumbers[i].digit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bigNumbers[i].digit = Math.floor(newRating / 10);
|
||||
}
|
||||
case 1:
|
||||
bigNumbers[i].digit = newRating % 10;
|
||||
default:
|
||||
trace('why the fuck is this being called');
|
||||
}
|
||||
}
|
||||
// diffRatingSprite.loadGraphic(Paths.image('freeplay/diffRatings/diff${ratingPadded}'));
|
||||
// diffRatingSprite.visible = false;
|
||||
}
|
||||
|
@ -168,9 +439,12 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
songText.text = songData?.songName ?? 'Random';
|
||||
// Update capsule character.
|
||||
if (songData?.songCharacter != null) setCharacter(songData.songCharacter);
|
||||
updateBPM(Std.int(songData?.songStartingBpm) ?? 0);
|
||||
updateDifficultyRating(songData?.difficultyRating ?? 0);
|
||||
// Update opacity, offsets, etc.
|
||||
updateSelected();
|
||||
|
||||
checkWeek(songData?.songId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -289,6 +563,28 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
if (impactThing != null) impactThing.angle = capsule.angle;
|
||||
|
||||
// if (FlxG.keys.justPressed.I)
|
||||
// {
|
||||
// newText.y -= 1;
|
||||
// trace(this.x - newText.x, this.y - newText.y);
|
||||
// }
|
||||
// if (FlxG.keys.justPressed.J)
|
||||
// {
|
||||
// newText.x -= 1;
|
||||
// trace(this.x - newText.x, this.y - newText.y);
|
||||
// }
|
||||
// if (FlxG.keys.justPressed.L)
|
||||
// {
|
||||
// newText.x += 1;
|
||||
// trace(this.x - newText.x, this.y - newText.y);
|
||||
// }
|
||||
// if (FlxG.keys.justPressed.K)
|
||||
// {
|
||||
// newText.y += 1;
|
||||
// trace(this.x - newText.x, this.y - newText.y);
|
||||
// }
|
||||
if (doJumpIn)
|
||||
{
|
||||
frameInTicker += elapsed;
|
||||
|
@ -358,5 +654,137 @@ class SongMenuItem extends FlxSpriteGroup
|
|||
capsule.animation.play(this.selected ? "selected" : "unselected");
|
||||
ranking.alpha = this.selected ? 1 : 0.7;
|
||||
ranking.color = this.selected ? 0xFFFFFFFF : 0xFFAAAAAA;
|
||||
|
||||
if (selected)
|
||||
{
|
||||
if (songText.tooLong == true) songText.initMove();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (songText.tooLong == true) songText.resetText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FreeplayRank extends FlxSprite
|
||||
{
|
||||
public var rank(default, set):Int = 0;
|
||||
|
||||
var numToRank:Array<String> = ["LOSS", "GOOD", "GREAT", "EXCELLENT", "PERFECT", "PERFECTSICK"];
|
||||
|
||||
function set_rank(val):Int
|
||||
{
|
||||
animation.play(numToRank[val], true, false);
|
||||
|
||||
centerOffsets(false);
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case 0:
|
||||
// offset.x -= 1;
|
||||
case 1:
|
||||
// offset.x -= 1;
|
||||
offset.y -= 8;
|
||||
case 2:
|
||||
// offset.x -= 1;
|
||||
offset.y -= 8;
|
||||
case 3:
|
||||
// offset.y += 5;
|
||||
case 4:
|
||||
// offset.y += 5;
|
||||
default:
|
||||
centerOffsets(false);
|
||||
}
|
||||
updateHitbox();
|
||||
return val;
|
||||
}
|
||||
|
||||
public var baseY:Float = 0;
|
||||
public var baseX:Float = 0;
|
||||
|
||||
public function new(x:Float, y:Float, ?initRank:Int = 0)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
frames = Paths.getSparrowAtlas('freeplay/rankbadges');
|
||||
|
||||
animation.addByPrefix('PERFECT', 'PERFECT rank0', 24, false);
|
||||
animation.addByPrefix('EXCELLENT', 'EXCELLENT rank0', 24, false);
|
||||
animation.addByPrefix('GOOD', 'GOOD rank0', 24, false);
|
||||
animation.addByPrefix('PERFECTSICK', 'PERFECT rank GOLD', 24, false);
|
||||
animation.addByPrefix('GREAT', 'GREAT rank0', 24, false);
|
||||
animation.addByPrefix('LOSS', 'LOSS rank0', 24, false);
|
||||
|
||||
blend = BlendMode.ADD;
|
||||
|
||||
this.rank = initRank;
|
||||
|
||||
animation.play(numToRank[initRank], true);
|
||||
|
||||
// setGraphicSize(Std.int(width * 0.9));
|
||||
scale.set(0.9, 0.9);
|
||||
updateHitbox();
|
||||
}
|
||||
}
|
||||
|
||||
class CapsuleNumber extends FlxSprite
|
||||
{
|
||||
public var digit(default, set):Int = 0;
|
||||
|
||||
function set_digit(val):Int
|
||||
{
|
||||
animation.play(numToString[val], true, false, 0);
|
||||
|
||||
centerOffsets(false);
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case 1:
|
||||
offset.x -= 4;
|
||||
case 3:
|
||||
offset.x -= 1;
|
||||
|
||||
case 6:
|
||||
|
||||
case 4:
|
||||
// offset.y += 5;
|
||||
case 9:
|
||||
// offset.y += 5;
|
||||
default:
|
||||
centerOffsets(false);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public var baseY:Float = 0;
|
||||
public var baseX:Float = 0;
|
||||
|
||||
var numToString:Array<String> = ["ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"];
|
||||
|
||||
public function new(x:Float, y:Float, big:Bool = false, ?initDigit:Int = 0)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
if (big)
|
||||
{
|
||||
frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/bignumbers');
|
||||
}
|
||||
else
|
||||
{
|
||||
frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/smallnumbers');
|
||||
}
|
||||
|
||||
for (i in 0...10)
|
||||
{
|
||||
var stringNum:String = numToString[i];
|
||||
animation.addByPrefix(stringNum, '$stringNum', 24, false);
|
||||
}
|
||||
|
||||
this.digit = initDigit;
|
||||
|
||||
animation.play(numToString[initDigit], true);
|
||||
|
||||
setGraphicSize(Std.int(width * 0.9));
|
||||
updateHitbox();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue