mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-03-22 09:59:25 +00:00
Merge branch 'char-select-cherrypick' into rewrite/master
This commit is contained in:
commit
51a156eec9
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -13,5 +13,10 @@ shitAudio/
|
||||||
node_modules/
|
node_modules/
|
||||||
package.json
|
package.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
<<<<<<< HEAD
|
||||||
|
.aider*
|
||||||
|
||||||| bcaeae27
|
||||||
|
=======
|
||||||
.aider.*
|
.aider.*
|
||||||
.aider*
|
.aider*
|
||||||
|
>>>>>>> rewrite/master
|
||||||
|
|
2
art
2
art
|
@ -1 +1 @@
|
||||||
Subproject commit faeba700c5526bd4fd57ccc927d875c82b9d3553
|
Subproject commit 55c1b56823d4d7a74397bab9aeab30f15126499c
|
2
assets
2
assets
|
@ -1 +1 @@
|
||||||
Subproject commit 8d5bc0dce1e0cb4f545037ce4040e7a5f2d85871
|
Subproject commit fe7960dac67af26572376ded5df8eb4527e22095
|
|
@ -327,7 +327,8 @@
|
||||||
"INLINE",
|
"INLINE",
|
||||||
"DYNAMIC",
|
"DYNAMIC",
|
||||||
"FINAL"
|
"FINAL"
|
||||||
]
|
],
|
||||||
|
"severity": "IGNORE"
|
||||||
},
|
},
|
||||||
"type": "ModifierOrder"
|
"type": "ModifierOrder"
|
||||||
},
|
},
|
||||||
|
|
23
source/funkin/graphics/shaders/MosaicEffect.hx
Normal file
23
source/funkin/graphics/shaders/MosaicEffect.hx
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package funkin.graphics.shaders;
|
||||||
|
|
||||||
|
import flixel.addons.display.FlxRuntimeShader;
|
||||||
|
import openfl.utils.Assets;
|
||||||
|
import funkin.Paths;
|
||||||
|
import flixel.math.FlxPoint;
|
||||||
|
|
||||||
|
class MosaicEffect extends FlxRuntimeShader
|
||||||
|
{
|
||||||
|
public var blockSize:FlxPoint = FlxPoint.get(1.0, 1.0);
|
||||||
|
|
||||||
|
public function new()
|
||||||
|
{
|
||||||
|
super(Assets.getText(Paths.frag('mosaic')));
|
||||||
|
setBlockSize(1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBlockSize(w:Float, h:Float)
|
||||||
|
{
|
||||||
|
blockSize.set(w, h);
|
||||||
|
setFloatArray("uBlocksize", [w, h]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ class Controls extends FlxActionSet
|
||||||
var _freeplay_favorite = new FunkinAction(Action.FREEPLAY_FAVORITE);
|
var _freeplay_favorite = new FunkinAction(Action.FREEPLAY_FAVORITE);
|
||||||
var _freeplay_left = new FunkinAction(Action.FREEPLAY_LEFT);
|
var _freeplay_left = new FunkinAction(Action.FREEPLAY_LEFT);
|
||||||
var _freeplay_right = new FunkinAction(Action.FREEPLAY_RIGHT);
|
var _freeplay_right = new FunkinAction(Action.FREEPLAY_RIGHT);
|
||||||
|
var _freeplay_char_select = new FunkinAction(Action.FREEPLAY_CHAR_SELECT);
|
||||||
var _cutscene_advance = new FunkinAction(Action.CUTSCENE_ADVANCE);
|
var _cutscene_advance = new FunkinAction(Action.CUTSCENE_ADVANCE);
|
||||||
var _debug_menu = new FunkinAction(Action.DEBUG_MENU);
|
var _debug_menu = new FunkinAction(Action.DEBUG_MENU);
|
||||||
var _debug_chart = new FunkinAction(Action.DEBUG_CHART);
|
var _debug_chart = new FunkinAction(Action.DEBUG_CHART);
|
||||||
|
@ -262,6 +263,11 @@ class Controls extends FlxActionSet
|
||||||
inline function get_FREEPLAY_RIGHT()
|
inline function get_FREEPLAY_RIGHT()
|
||||||
return _freeplay_right.check();
|
return _freeplay_right.check();
|
||||||
|
|
||||||
|
public var FREEPLAY_CHAR_SELECT(get, never):Bool;
|
||||||
|
|
||||||
|
inline function get_FREEPLAY_CHAR_SELECT()
|
||||||
|
return _freeplay_char_select.check();
|
||||||
|
|
||||||
public var CUTSCENE_ADVANCE(get, never):Bool;
|
public var CUTSCENE_ADVANCE(get, never):Bool;
|
||||||
|
|
||||||
inline function get_CUTSCENE_ADVANCE()
|
inline function get_CUTSCENE_ADVANCE()
|
||||||
|
@ -318,6 +324,7 @@ class Controls extends FlxActionSet
|
||||||
add(_freeplay_favorite);
|
add(_freeplay_favorite);
|
||||||
add(_freeplay_left);
|
add(_freeplay_left);
|
||||||
add(_freeplay_right);
|
add(_freeplay_right);
|
||||||
|
add(_freeplay_char_select);
|
||||||
add(_cutscene_advance);
|
add(_cutscene_advance);
|
||||||
add(_debug_menu);
|
add(_debug_menu);
|
||||||
add(_debug_chart);
|
add(_debug_chart);
|
||||||
|
@ -424,6 +431,7 @@ class Controls extends FlxActionSet
|
||||||
case FREEPLAY_FAVORITE: _freeplay_favorite;
|
case FREEPLAY_FAVORITE: _freeplay_favorite;
|
||||||
case FREEPLAY_LEFT: _freeplay_left;
|
case FREEPLAY_LEFT: _freeplay_left;
|
||||||
case FREEPLAY_RIGHT: _freeplay_right;
|
case FREEPLAY_RIGHT: _freeplay_right;
|
||||||
|
case FREEPLAY_CHAR_SELECT: _freeplay_char_select;
|
||||||
case CUTSCENE_ADVANCE: _cutscene_advance;
|
case CUTSCENE_ADVANCE: _cutscene_advance;
|
||||||
case DEBUG_MENU: _debug_menu;
|
case DEBUG_MENU: _debug_menu;
|
||||||
case DEBUG_CHART: _debug_chart;
|
case DEBUG_CHART: _debug_chart;
|
||||||
|
@ -500,6 +508,8 @@ class Controls extends FlxActionSet
|
||||||
func(_freeplay_left, JUST_PRESSED);
|
func(_freeplay_left, JUST_PRESSED);
|
||||||
case FREEPLAY_RIGHT:
|
case FREEPLAY_RIGHT:
|
||||||
func(_freeplay_right, JUST_PRESSED);
|
func(_freeplay_right, JUST_PRESSED);
|
||||||
|
case FREEPLAY_CHAR_SELECT:
|
||||||
|
func(_freeplay_char_select, JUST_PRESSED);
|
||||||
case CUTSCENE_ADVANCE:
|
case CUTSCENE_ADVANCE:
|
||||||
func(_cutscene_advance, JUST_PRESSED);
|
func(_cutscene_advance, JUST_PRESSED);
|
||||||
case DEBUG_MENU:
|
case DEBUG_MENU:
|
||||||
|
@ -721,6 +731,7 @@ class Controls extends FlxActionSet
|
||||||
bindKeys(Control.FREEPLAY_FAVORITE, getDefaultKeybinds(scheme, Control.FREEPLAY_FAVORITE));
|
bindKeys(Control.FREEPLAY_FAVORITE, getDefaultKeybinds(scheme, Control.FREEPLAY_FAVORITE));
|
||||||
bindKeys(Control.FREEPLAY_LEFT, getDefaultKeybinds(scheme, Control.FREEPLAY_LEFT));
|
bindKeys(Control.FREEPLAY_LEFT, getDefaultKeybinds(scheme, Control.FREEPLAY_LEFT));
|
||||||
bindKeys(Control.FREEPLAY_RIGHT, getDefaultKeybinds(scheme, Control.FREEPLAY_RIGHT));
|
bindKeys(Control.FREEPLAY_RIGHT, getDefaultKeybinds(scheme, Control.FREEPLAY_RIGHT));
|
||||||
|
bindKeys(Control.FREEPLAY_CHAR_SELECT, getDefaultKeybinds(scheme, Control.FREEPLAY_CHAR_SELECT));
|
||||||
bindKeys(Control.CUTSCENE_ADVANCE, getDefaultKeybinds(scheme, Control.CUTSCENE_ADVANCE));
|
bindKeys(Control.CUTSCENE_ADVANCE, getDefaultKeybinds(scheme, Control.CUTSCENE_ADVANCE));
|
||||||
bindKeys(Control.DEBUG_MENU, getDefaultKeybinds(scheme, Control.DEBUG_MENU));
|
bindKeys(Control.DEBUG_MENU, getDefaultKeybinds(scheme, Control.DEBUG_MENU));
|
||||||
bindKeys(Control.DEBUG_CHART, getDefaultKeybinds(scheme, Control.DEBUG_CHART));
|
bindKeys(Control.DEBUG_CHART, getDefaultKeybinds(scheme, Control.DEBUG_CHART));
|
||||||
|
@ -756,6 +767,7 @@ class Controls extends FlxActionSet
|
||||||
case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu
|
case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu
|
||||||
case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu
|
case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu
|
||||||
case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu
|
case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu
|
||||||
|
case Control.FREEPLAY_CHAR_SELECT: return [TAB];
|
||||||
case Control.CUTSCENE_ADVANCE: return [Z, ENTER];
|
case Control.CUTSCENE_ADVANCE: return [Z, ENTER];
|
||||||
case Control.DEBUG_MENU: return [GRAVEACCENT];
|
case Control.DEBUG_MENU: return [GRAVEACCENT];
|
||||||
case Control.DEBUG_CHART: return [];
|
case Control.DEBUG_CHART: return [];
|
||||||
|
@ -784,6 +796,7 @@ class Controls extends FlxActionSet
|
||||||
case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu
|
case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu
|
||||||
case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu
|
case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu
|
||||||
case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu
|
case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu
|
||||||
|
case Control.FREEPLAY_CHAR_SELECT: return [TAB];
|
||||||
case Control.CUTSCENE_ADVANCE: return [G, Z];
|
case Control.CUTSCENE_ADVANCE: return [G, Z];
|
||||||
case Control.DEBUG_MENU: return [GRAVEACCENT];
|
case Control.DEBUG_MENU: return [GRAVEACCENT];
|
||||||
case Control.DEBUG_CHART: return [];
|
case Control.DEBUG_CHART: return [];
|
||||||
|
@ -812,6 +825,7 @@ class Controls extends FlxActionSet
|
||||||
case Control.FREEPLAY_FAVORITE: return [];
|
case Control.FREEPLAY_FAVORITE: return [];
|
||||||
case Control.FREEPLAY_LEFT: return [];
|
case Control.FREEPLAY_LEFT: return [];
|
||||||
case Control.FREEPLAY_RIGHT: return [];
|
case Control.FREEPLAY_RIGHT: return [];
|
||||||
|
case Control.FREEPLAY_CHAR_SELECT: return [];
|
||||||
case Control.CUTSCENE_ADVANCE: return [ENTER];
|
case Control.CUTSCENE_ADVANCE: return [ENTER];
|
||||||
case Control.DEBUG_MENU: return [];
|
case Control.DEBUG_MENU: return [];
|
||||||
case Control.DEBUG_CHART: return [];
|
case Control.DEBUG_CHART: return [];
|
||||||
|
@ -1548,6 +1562,7 @@ enum Control
|
||||||
FREEPLAY_FAVORITE;
|
FREEPLAY_FAVORITE;
|
||||||
FREEPLAY_LEFT;
|
FREEPLAY_LEFT;
|
||||||
FREEPLAY_RIGHT;
|
FREEPLAY_RIGHT;
|
||||||
|
FREEPLAY_CHAR_SELECT;
|
||||||
// WINDOW
|
// WINDOW
|
||||||
WINDOW_SCREENSHOT;
|
WINDOW_SCREENSHOT;
|
||||||
WINDOW_FULLSCREEN;
|
WINDOW_FULLSCREEN;
|
||||||
|
@ -1602,6 +1617,7 @@ enum abstract Action(String) to String from String
|
||||||
var FREEPLAY_FAVORITE = "freeplay_favorite";
|
var FREEPLAY_FAVORITE = "freeplay_favorite";
|
||||||
var FREEPLAY_LEFT = "freeplay_left";
|
var FREEPLAY_LEFT = "freeplay_left";
|
||||||
var FREEPLAY_RIGHT = "freeplay_right";
|
var FREEPLAY_RIGHT = "freeplay_right";
|
||||||
|
var FREEPLAY_CHAR_SELECT = "freeplay_char_select";
|
||||||
// VOLUME
|
// VOLUME
|
||||||
var VOLUME_UP = "volume_up";
|
var VOLUME_UP = "volume_up";
|
||||||
var VOLUME_DOWN = "volume_down";
|
var VOLUME_DOWN = "volume_down";
|
||||||
|
|
79
source/funkin/ui/PixelatedIcon.hx
Normal file
79
source/funkin/ui/PixelatedIcon.hx
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package funkin.ui;
|
||||||
|
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The icon that gets used for Freeplay capsules and char select
|
||||||
|
* NOT to be confused with the CharIcon class, which is for the in-game icons
|
||||||
|
*/
|
||||||
|
class PixelatedIcon extends FlxSprite
|
||||||
|
{
|
||||||
|
public function new(x:Float, y:Float)
|
||||||
|
{
|
||||||
|
super(x, y);
|
||||||
|
this.makeGraphic(32, 32, 0x00000000);
|
||||||
|
this.antialiasing = false;
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCharacter(char:String):Void
|
||||||
|
{
|
||||||
|
var charPath:String = "freeplay/icons/";
|
||||||
|
|
||||||
|
switch (char)
|
||||||
|
{
|
||||||
|
case 'monster-christmas':
|
||||||
|
charPath += 'monsterpixel';
|
||||||
|
case 'mom-car':
|
||||||
|
charPath += 'mommypixel';
|
||||||
|
case 'darnell-blazin':
|
||||||
|
charPath += 'darnellpixel';
|
||||||
|
case 'senpai-angry':
|
||||||
|
charPath += 'senpaipixel';
|
||||||
|
default:
|
||||||
|
charPath += '${char}pixel';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!openfl.utils.Assets.exists(Paths.image(charPath)))
|
||||||
|
{
|
||||||
|
trace('[WARN] Character ${char} has no freeplay icon.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isAnimated = openfl.utils.Assets.exists(Paths.file('images/$charPath.xml'));
|
||||||
|
|
||||||
|
if (isAnimated)
|
||||||
|
{
|
||||||
|
this.frames = Paths.getSparrowAtlas(charPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.loadGraphic(Paths.image(charPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scale.x = this.scale.y = 2;
|
||||||
|
|
||||||
|
switch (char)
|
||||||
|
{
|
||||||
|
case 'parents-christmas':
|
||||||
|
this.origin.x = 140;
|
||||||
|
default:
|
||||||
|
this.origin.x = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAnimated)
|
||||||
|
{
|
||||||
|
this.active = true;
|
||||||
|
this.animation.addByPrefix('idle', 'idle0', 10, true);
|
||||||
|
this.animation.addByPrefix('confirm', 'confirm0', 10, false);
|
||||||
|
this.animation.addByPrefix('confirm-hold', 'confirm-hold0', 10, true);
|
||||||
|
|
||||||
|
this.animation.finishCallback = function(name:String):Void {
|
||||||
|
trace('Finish pixel animation: ${name}');
|
||||||
|
if (name == 'confirm') this.animation.play('confirm-hold');
|
||||||
|
};
|
||||||
|
|
||||||
|
this.animation.play('idle');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
source/funkin/ui/charSelect/CharIcon.hx
Normal file
17
source/funkin/ui/charSelect/CharIcon.hx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
|
||||||
|
class CharIcon extends FlxSprite
|
||||||
|
{
|
||||||
|
public var locked:Bool = false;
|
||||||
|
|
||||||
|
public function new(x:Float, y:Float, locked:Bool = false)
|
||||||
|
{
|
||||||
|
super(x, y);
|
||||||
|
|
||||||
|
this.locked = locked;
|
||||||
|
|
||||||
|
makeGraphic(128, 128);
|
||||||
|
}
|
||||||
|
}
|
49
source/funkin/ui/charSelect/CharIconCharacter.hx
Normal file
49
source/funkin/ui/charSelect/CharIconCharacter.hx
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
import openfl.display.BitmapData;
|
||||||
|
import openfl.filters.DropShadowFilter;
|
||||||
|
import openfl.filters.ConvolutionFilter;
|
||||||
|
import funkin.graphics.shaders.StrokeShader;
|
||||||
|
|
||||||
|
class CharIconCharacter extends CharIcon
|
||||||
|
{
|
||||||
|
public var dropShadowFilter:DropShadowFilter;
|
||||||
|
|
||||||
|
var matrixFilter:Array<Float> = [
|
||||||
|
1, 1, 1,
|
||||||
|
1, 1, 1,
|
||||||
|
1, 1, 1
|
||||||
|
];
|
||||||
|
|
||||||
|
var divisor:Int = 1;
|
||||||
|
var bias:Int = 0;
|
||||||
|
var convolutionFilter:ConvolutionFilter;
|
||||||
|
|
||||||
|
public var noDropShadow:BitmapData;
|
||||||
|
public var withDropShadow:BitmapData;
|
||||||
|
|
||||||
|
var strokeShader:StrokeShader;
|
||||||
|
|
||||||
|
public function new(path:String)
|
||||||
|
{
|
||||||
|
super(0, 0, false);
|
||||||
|
|
||||||
|
loadGraphic(Paths.image('freeplay/icons/' + path + 'pixel'));
|
||||||
|
setGraphicSize(128, 128);
|
||||||
|
updateHitbox();
|
||||||
|
antialiasing = false;
|
||||||
|
|
||||||
|
strokeShader = new StrokeShader();
|
||||||
|
// shader = strokeShader;
|
||||||
|
|
||||||
|
// noDropShadow = pixels.clone();
|
||||||
|
|
||||||
|
// dropShadowFilter = new DropShadowFilter(5, 45, 0, 1, 0, 0);
|
||||||
|
// convolutionFilter = new ConvolutionFilter(3, 3, matrixFilter, divisor, bias);
|
||||||
|
// pixels.applyFilter(pixels, pixels.rect, new openfl.geom.Point(0, 0), dropShadowFilter);
|
||||||
|
// pixels.applyFilter(pixels, pixels.rect, new openfl.geom.Point(0, 0), convolutionFilter);
|
||||||
|
// withDropShadow = pixels.clone();
|
||||||
|
|
||||||
|
// pixels = noDropShadow.clone();
|
||||||
|
}
|
||||||
|
}
|
3
source/funkin/ui/charSelect/CharIconLocked.hx
Normal file
3
source/funkin/ui/charSelect/CharIconLocked.hx
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
class CharIconLocked extends CharIcon {}
|
137
source/funkin/ui/charSelect/CharSelectGF.hx
Normal file
137
source/funkin/ui/charSelect/CharSelectGF.hx
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
import funkin.graphics.adobeanimate.FlxAtlasSprite;
|
||||||
|
import flixel.tweens.FlxTween;
|
||||||
|
import flixel.tweens.FlxEase;
|
||||||
|
import flixel.math.FlxMath;
|
||||||
|
import funkin.util.FramesJSFLParser;
|
||||||
|
import funkin.util.FramesJSFLParser.FramesJSFLInfo;
|
||||||
|
import funkin.util.FramesJSFLParser.FramesJSFLFrame;
|
||||||
|
import flixel.math.FlxMath;
|
||||||
|
|
||||||
|
class CharSelectGF extends FlxAtlasSprite
|
||||||
|
{
|
||||||
|
var fadeTimer:Float = 0;
|
||||||
|
var fadingStatus:FadeStatus = OFF;
|
||||||
|
var fadeAnimIndex:Int = 0;
|
||||||
|
|
||||||
|
var animInInfo:FramesJSFLInfo;
|
||||||
|
var animOutInfo:FramesJSFLInfo;
|
||||||
|
|
||||||
|
var intendedYPos:Float = 0;
|
||||||
|
var intendedAlpha:Float = 0;
|
||||||
|
|
||||||
|
public function new()
|
||||||
|
{
|
||||||
|
super(0, 0, Paths.animateAtlas("charSelect/gfChill"));
|
||||||
|
anim.play("");
|
||||||
|
switchGF("bf");
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function update(elapsed:Float)
|
||||||
|
{
|
||||||
|
super.update(elapsed);
|
||||||
|
|
||||||
|
switch (fadingStatus)
|
||||||
|
{
|
||||||
|
case OFF:
|
||||||
|
// do nothing if it's off!
|
||||||
|
// or maybe force position to be 0,0?
|
||||||
|
// maybe reset timers?
|
||||||
|
resetFadeAnimParams();
|
||||||
|
case FADE_OUT:
|
||||||
|
doFade(animOutInfo);
|
||||||
|
case FADE_IN:
|
||||||
|
doFade(animInInfo);
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FlxG.keys.justPressed.J)
|
||||||
|
{
|
||||||
|
alpha = 1;
|
||||||
|
x = y = 0;
|
||||||
|
fadingStatus = FADE_OUT;
|
||||||
|
}
|
||||||
|
if (FlxG.keys.justPressed.K)
|
||||||
|
{
|
||||||
|
alpha = 0;
|
||||||
|
fadingStatus = FADE_IN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param animInfo Should not be confused with animInInfo!
|
||||||
|
* This is merely a local var for the function!
|
||||||
|
*/
|
||||||
|
function doFade(animInfo:FramesJSFLInfo)
|
||||||
|
{
|
||||||
|
fadeTimer += FlxG.elapsed;
|
||||||
|
if (fadeTimer >= 1 / 24)
|
||||||
|
{
|
||||||
|
fadeTimer = 0;
|
||||||
|
// only inc the index for the first frame, used for reference of where to "start"
|
||||||
|
if (fadeAnimIndex == 0)
|
||||||
|
{
|
||||||
|
fadeAnimIndex++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var curFrame:FramesJSFLFrame = animInfo.frames[fadeAnimIndex];
|
||||||
|
var prevFrame:FramesJSFLFrame = animInfo.frames[fadeAnimIndex - 1];
|
||||||
|
|
||||||
|
var xDiff:Float = curFrame.x - prevFrame.x;
|
||||||
|
var yDiff:Float = curFrame.y - prevFrame.y;
|
||||||
|
var alphaDiff:Float = curFrame.alpha - prevFrame.alpha;
|
||||||
|
alphaDiff /= 100; // flash exports alpha as a whole number
|
||||||
|
|
||||||
|
alpha += alphaDiff;
|
||||||
|
alpha = FlxMath.bound(alpha, 0, 1);
|
||||||
|
x += xDiff;
|
||||||
|
y += yDiff;
|
||||||
|
|
||||||
|
fadeAnimIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fadeAnimIndex >= animInfo.frames.length) fadingStatus = OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetFadeAnimParams()
|
||||||
|
{
|
||||||
|
fadeTimer = 0;
|
||||||
|
fadeAnimIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function switchGF(str:String)
|
||||||
|
{
|
||||||
|
str = switch (str)
|
||||||
|
{
|
||||||
|
case "pico":
|
||||||
|
"nene";
|
||||||
|
case "bf":
|
||||||
|
"gf";
|
||||||
|
default:
|
||||||
|
"gf";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch str
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
loadAtlas(Paths.animateAtlas("charSelect/" + str + "Chill"));
|
||||||
|
}
|
||||||
|
|
||||||
|
animInInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/" + str + "AnimInfo/" + str + "In.txt"));
|
||||||
|
animOutInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/" + str + "AnimInfo/" + str + "Out.txt"));
|
||||||
|
|
||||||
|
anim.play("");
|
||||||
|
playAnimation("idle", true, false, true);
|
||||||
|
|
||||||
|
updateHitbox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum FadeStatus
|
||||||
|
{
|
||||||
|
OFF;
|
||||||
|
FADE_OUT;
|
||||||
|
FADE_IN;
|
||||||
|
}
|
58
source/funkin/ui/charSelect/CharSelectPlayer.hx
Normal file
58
source/funkin/ui/charSelect/CharSelectPlayer.hx
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
import funkin.graphics.adobeanimate.FlxAtlasSprite;
|
||||||
|
|
||||||
|
class CharSelectPlayer extends FlxAtlasSprite
|
||||||
|
{
|
||||||
|
public function new(x:Float, y:Float)
|
||||||
|
{
|
||||||
|
super(x, y, Paths.animateAtlas("charSelect/bfChill"));
|
||||||
|
|
||||||
|
onAnimationFinish.add(function(animLabel:String) {
|
||||||
|
switch (animLabel)
|
||||||
|
{
|
||||||
|
case "slidein":
|
||||||
|
if (hasAnimation("slidein idle point")) playAnimation("slidein idle point", true, false, false);
|
||||||
|
else
|
||||||
|
playAnimation("idle", true, false, true);
|
||||||
|
case "slidein idle point":
|
||||||
|
playAnimation("idle", true, false, true);
|
||||||
|
case "select":
|
||||||
|
anim.pause();
|
||||||
|
case "deselect":
|
||||||
|
playAnimation("deselect loop start", true, false, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePosition(str:String)
|
||||||
|
{
|
||||||
|
switch (str)
|
||||||
|
{
|
||||||
|
case "bf":
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
case "pico":
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
case "random":
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function switchChar(str:String)
|
||||||
|
{
|
||||||
|
switch str
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
loadAtlas(Paths.animateAtlas("charSelect/" + str + "Chill"));
|
||||||
|
}
|
||||||
|
|
||||||
|
anim.play("");
|
||||||
|
playAnimation("slidein", true, false, false);
|
||||||
|
|
||||||
|
updateHitbox();
|
||||||
|
|
||||||
|
updatePosition(str);
|
||||||
|
}
|
||||||
|
}
|
632
source/funkin/ui/charSelect/CharSelectSubState.hx
Normal file
632
source/funkin/ui/charSelect/CharSelectSubState.hx
Normal file
|
@ -0,0 +1,632 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
import funkin.ui.freeplay.FreeplayState;
|
||||||
|
import flixel.text.FlxText;
|
||||||
|
import funkin.ui.PixelatedIcon;
|
||||||
|
import flixel.system.debug.watch.Tracker.TrackerProfile;
|
||||||
|
import flixel.math.FlxPoint;
|
||||||
|
import flixel.tweens.FlxTween;
|
||||||
|
import openfl.display.BlendMode;
|
||||||
|
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
import flixel.group.FlxSpriteGroup;
|
||||||
|
import funkin.play.stage.Stage;
|
||||||
|
import funkin.modding.events.ScriptEvent;
|
||||||
|
import funkin.modding.events.ScriptEventDispatcher;
|
||||||
|
import funkin.graphics.adobeanimate.FlxAtlasSprite;
|
||||||
|
import flixel.FlxObject;
|
||||||
|
import openfl.display.BlendMode;
|
||||||
|
import flixel.group.FlxGroup;
|
||||||
|
import funkin.util.MathUtil;
|
||||||
|
import flixel.util.FlxTimer;
|
||||||
|
import flixel.tweens.FlxEase;
|
||||||
|
import flixel.sound.FlxSound;
|
||||||
|
import funkin.audio.FunkinSound;
|
||||||
|
|
||||||
|
class CharSelectSubState extends MusicBeatSubState
|
||||||
|
{
|
||||||
|
var cursor:FlxSprite;
|
||||||
|
var cursorBlue:FlxSprite;
|
||||||
|
var cursorDarkBlue:FlxSprite;
|
||||||
|
|
||||||
|
var grpCursors:FlxTypedGroup<FlxSprite>;
|
||||||
|
|
||||||
|
var cursorConfirmed:FlxSprite;
|
||||||
|
var cursorDenied:FlxSprite;
|
||||||
|
|
||||||
|
var cursorX:Int = 0;
|
||||||
|
var cursorY:Int = 0;
|
||||||
|
|
||||||
|
var cursorFactor:Float = 110;
|
||||||
|
var cursorOffsetX:Float = -16;
|
||||||
|
var cursorOffsetY:Float = -48;
|
||||||
|
|
||||||
|
var cursorLocIntended:FlxPoint = new FlxPoint(0, 0);
|
||||||
|
var lerpAmnt:Float = 0.95;
|
||||||
|
|
||||||
|
var tmrFrames:Int = 60;
|
||||||
|
|
||||||
|
var currentStage:Stage;
|
||||||
|
|
||||||
|
var playerChill:CharSelectPlayer;
|
||||||
|
var playerChillOut:CharSelectPlayer;
|
||||||
|
var gfChill:CharSelectGF;
|
||||||
|
var gfChillOut:CharSelectGF;
|
||||||
|
|
||||||
|
var curChar(default, set):String = "pico";
|
||||||
|
var nametag:Nametag;
|
||||||
|
var camFollow:FlxObject;
|
||||||
|
|
||||||
|
var availableChars:Map<Int, String> = new Map<Int, String>();
|
||||||
|
var pressedSelect:Bool = false;
|
||||||
|
|
||||||
|
var selectTimer:FlxTimer = new FlxTimer();
|
||||||
|
var selectSound:FunkinSound;
|
||||||
|
|
||||||
|
public function new()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
availableChars.set(4, "bf");
|
||||||
|
availableChars.set(3, "pico");
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function create():Void
|
||||||
|
{
|
||||||
|
super.create();
|
||||||
|
|
||||||
|
selectSound = new FunkinSound();
|
||||||
|
selectSound.loadEmbedded(Paths.sound('CS_select'));
|
||||||
|
selectSound.pitch = 1;
|
||||||
|
selectSound.volume = 0.7;
|
||||||
|
FlxG.sound.defaultSoundGroup.add(selectSound);
|
||||||
|
|
||||||
|
// playing it here to preload it. not doing this makes a super awkward pause at the end of the intro
|
||||||
|
// TODO: probably make an intro thing for funkinSound itself that preloads the next audio?
|
||||||
|
FunkinSound.playMusic('stayFunky',
|
||||||
|
{
|
||||||
|
startingVolume: 0,
|
||||||
|
overrideExisting: true,
|
||||||
|
restartTrack: true
|
||||||
|
});
|
||||||
|
var introMusic:String = Paths.music('stayFunky/stayFunky-intro');
|
||||||
|
FunkinSound.load(introMusic, 1.0, false, true, true, () -> {
|
||||||
|
FunkinSound.playMusic('stayFunky',
|
||||||
|
{
|
||||||
|
startingVolume: 1,
|
||||||
|
overrideExisting: true,
|
||||||
|
restartTrack: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var bg:FlxSprite = new FlxSprite(-153, -140);
|
||||||
|
bg.loadGraphic(Paths.image('charSelect/charSelectBG'));
|
||||||
|
bg.scrollFactor.set(0.1, 0.1);
|
||||||
|
add(bg);
|
||||||
|
|
||||||
|
var crowd:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/crowd"));
|
||||||
|
crowd.anim.play("");
|
||||||
|
crowd.scrollFactor.set(0.3, 0.3);
|
||||||
|
add(crowd);
|
||||||
|
|
||||||
|
var stageSpr:FlxSprite = new FlxSprite(-40, 391);
|
||||||
|
stageSpr.frames = Paths.getSparrowAtlas("charSelect/charSelectStage");
|
||||||
|
stageSpr.animation.addByPrefix("idle", "stage", 24, true);
|
||||||
|
stageSpr.animation.play("idle");
|
||||||
|
add(stageSpr);
|
||||||
|
|
||||||
|
var curtains:FlxSprite = new FlxSprite(-47, -49);
|
||||||
|
curtains.loadGraphic(Paths.image('charSelect/curtains'));
|
||||||
|
curtains.scrollFactor.set(1.4, 1.4);
|
||||||
|
add(curtains);
|
||||||
|
|
||||||
|
var barthing:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/barThing"));
|
||||||
|
barthing.anim.play("");
|
||||||
|
barthing.blend = BlendMode.MULTIPLY;
|
||||||
|
barthing.scrollFactor.set(0, 0);
|
||||||
|
add(barthing);
|
||||||
|
|
||||||
|
var charLight:FlxSprite = new FlxSprite(800, 250);
|
||||||
|
charLight.loadGraphic(Paths.image('charSelect/charLight'));
|
||||||
|
add(charLight);
|
||||||
|
|
||||||
|
var charLightGF:FlxSprite = new FlxSprite(180, 240);
|
||||||
|
charLightGF.loadGraphic(Paths.image('charSelect/charLight'));
|
||||||
|
add(charLightGF);
|
||||||
|
|
||||||
|
gfChill = new CharSelectGF();
|
||||||
|
gfChill.switchGF("bf");
|
||||||
|
add(gfChill);
|
||||||
|
|
||||||
|
playerChill = new CharSelectPlayer(0, 0);
|
||||||
|
playerChill.switchChar("bf");
|
||||||
|
add(playerChill);
|
||||||
|
|
||||||
|
playerChillOut = new CharSelectPlayer(0, 0);
|
||||||
|
playerChillOut.switchChar("bf");
|
||||||
|
add(playerChillOut);
|
||||||
|
|
||||||
|
var speakers:FlxAtlasSprite = new FlxAtlasSprite(0, 0, Paths.animateAtlas("charSelect/charSelectSpeakers"));
|
||||||
|
speakers.anim.play("");
|
||||||
|
speakers.scrollFactor.set(1.8, 1.8);
|
||||||
|
add(speakers);
|
||||||
|
|
||||||
|
var fgBlur:FlxSprite = new FlxSprite(-125, 170);
|
||||||
|
fgBlur.loadGraphic(Paths.image('charSelect/foregroundBlur'));
|
||||||
|
fgBlur.blend = openfl.display.BlendMode.MULTIPLY;
|
||||||
|
add(fgBlur);
|
||||||
|
|
||||||
|
var dipshitBlur:FlxSprite = new FlxSprite(419, -65);
|
||||||
|
dipshitBlur.frames = Paths.getSparrowAtlas("charSelect/dipshitBlur");
|
||||||
|
dipshitBlur.animation.addByPrefix('idle', "CHOOSE vertical", 24, true);
|
||||||
|
dipshitBlur.blend = BlendMode.ADD;
|
||||||
|
dipshitBlur.animation.play("idle");
|
||||||
|
add(dipshitBlur);
|
||||||
|
|
||||||
|
var dipshitBacking:FlxSprite = new FlxSprite(423, -17);
|
||||||
|
dipshitBacking.frames = Paths.getSparrowAtlas("charSelect/dipshitBacking");
|
||||||
|
dipshitBacking.animation.addByPrefix('idle', "CHOOSE horizontal", 24, true);
|
||||||
|
dipshitBacking.blend = BlendMode.ADD;
|
||||||
|
dipshitBacking.animation.play("idle");
|
||||||
|
add(dipshitBacking);
|
||||||
|
|
||||||
|
var chooseDipshit:FlxSprite = new FlxSprite(426, -13);
|
||||||
|
chooseDipshit.loadGraphic(Paths.image('charSelect/chooseDipshit'));
|
||||||
|
add(chooseDipshit);
|
||||||
|
|
||||||
|
chooseDipshit.scrollFactor.set();
|
||||||
|
dipshitBacking.scrollFactor.set();
|
||||||
|
dipshitBlur.scrollFactor.set();
|
||||||
|
|
||||||
|
nametag = new Nametag();
|
||||||
|
add(nametag);
|
||||||
|
|
||||||
|
nametag.scrollFactor.set();
|
||||||
|
|
||||||
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSprite, ["x", "y", "alpha", "scale", "blend"]));
|
||||||
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxAtlasSprite, ["x", "y"]));
|
||||||
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSound, ["pitch", "volume"]));
|
||||||
|
|
||||||
|
// FlxG.debugger.track(crowd);
|
||||||
|
// FlxG.debugger.track(stageSpr, "stageSpr");
|
||||||
|
// FlxG.debugger.track(bfChill, "bf chill");
|
||||||
|
// FlxG.debugger.track(playerChill, "player");
|
||||||
|
// FlxG.debugger.track(nametag, "nametag");
|
||||||
|
FlxG.debugger.track(selectSound, "selectSound");
|
||||||
|
// FlxG.debugger.track(chooseDipshit, "choose dipshit");
|
||||||
|
// FlxG.debugger.track(barthing, "barthing");
|
||||||
|
// FlxG.debugger.track(fgBlur, "fgBlur");
|
||||||
|
// FlxG.debugger.track(dipshitBlur, "dipshitBlur");
|
||||||
|
// FlxG.debugger.track(dipshitBacking, "dipshitBacking");
|
||||||
|
// FlxG.debugger.track(charLightGF, "charLight");
|
||||||
|
// FlxG.debugger.track(gfChill, "gfChill");
|
||||||
|
|
||||||
|
grpCursors = new FlxTypedGroup<FlxSprite>();
|
||||||
|
add(grpCursors);
|
||||||
|
|
||||||
|
cursor = new FlxSprite(0, 0);
|
||||||
|
cursor.loadGraphic(Paths.image('charSelect/charSelector'));
|
||||||
|
cursor.color = 0xFFFFFF00;
|
||||||
|
|
||||||
|
// FFCC00
|
||||||
|
|
||||||
|
cursorBlue = new FlxSprite(0, 0);
|
||||||
|
cursorBlue.loadGraphic(Paths.image('charSelect/charSelector'));
|
||||||
|
cursorBlue.color = 0xFF3EBBFF;
|
||||||
|
|
||||||
|
cursorDarkBlue = new FlxSprite(0, 0);
|
||||||
|
cursorDarkBlue.loadGraphic(Paths.image('charSelect/charSelector'));
|
||||||
|
cursorDarkBlue.color = 0xFF3C74F7;
|
||||||
|
|
||||||
|
cursorBlue.blend = BlendMode.SCREEN;
|
||||||
|
cursorDarkBlue.blend = BlendMode.SCREEN;
|
||||||
|
|
||||||
|
cursorConfirmed = new FlxSprite(0, 0);
|
||||||
|
cursorConfirmed.scrollFactor.set();
|
||||||
|
cursorConfirmed.frames = Paths.getSparrowAtlas("charSelect/charSelectorConfirm");
|
||||||
|
cursorConfirmed.animation.addByPrefix("idle", "cursor ACCEPTED", 24, true);
|
||||||
|
cursorConfirmed.visible = false;
|
||||||
|
add(cursorConfirmed);
|
||||||
|
|
||||||
|
cursorDenied = new FlxSprite(0, 0);
|
||||||
|
cursorDenied.scrollFactor.set();
|
||||||
|
cursorDenied.frames = Paths.getSparrowAtlas("charSelect/charSelectorDenied");
|
||||||
|
cursorDenied.animation.addByPrefix("idle", "cursor DENIED", 24, false);
|
||||||
|
cursorDenied.visible = false;
|
||||||
|
add(cursorDenied);
|
||||||
|
|
||||||
|
grpCursors.add(cursorDarkBlue);
|
||||||
|
grpCursors.add(cursorBlue);
|
||||||
|
grpCursors.add(cursor);
|
||||||
|
|
||||||
|
initLocks();
|
||||||
|
|
||||||
|
cursor.scrollFactor.set();
|
||||||
|
cursorBlue.scrollFactor.set();
|
||||||
|
cursorDarkBlue.scrollFactor.set();
|
||||||
|
|
||||||
|
FlxTween.color(cursor, 0.2, 0xFFFFFF00, 0xFFFFCC00, {type: FlxTween.PINGPONG});
|
||||||
|
|
||||||
|
// FlxG.debugger.track(cursor);
|
||||||
|
|
||||||
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(CharSelectSubState, ["curChar", "grpXSpread", "grpYSpread"]));
|
||||||
|
FlxG.debugger.track(this);
|
||||||
|
|
||||||
|
FlxG.sound.playMusic(Paths.music('charSelect/charSelectMusic'));
|
||||||
|
|
||||||
|
camFollow = new FlxObject(0, 0, 1, 1);
|
||||||
|
add(camFollow);
|
||||||
|
camFollow.screenCenter();
|
||||||
|
|
||||||
|
FlxG.camera.follow(camFollow, LOCKON, 0.01);
|
||||||
|
|
||||||
|
var temp:FlxSprite = new FlxSprite();
|
||||||
|
temp.loadGraphic(Paths.image('charSelect/placement'));
|
||||||
|
add(temp);
|
||||||
|
temp.alpha = 0.0;
|
||||||
|
Conductor.stepHit.add(spamOnStep);
|
||||||
|
// FlxG.debugger.track(temp, "tempBG");
|
||||||
|
}
|
||||||
|
|
||||||
|
var grpIcons:FlxSpriteGroup;
|
||||||
|
|
||||||
|
var grpXSpread(default, set):Float = 107;
|
||||||
|
var grpYSpread(default, set):Float = 127;
|
||||||
|
|
||||||
|
function initLocks()
|
||||||
|
{
|
||||||
|
grpIcons = new FlxSpriteGroup();
|
||||||
|
add(grpIcons);
|
||||||
|
|
||||||
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(FlxSpriteGroup, ["x", "y"]));
|
||||||
|
// FlxG.debugger.track(grpIcons, "iconGrp");
|
||||||
|
|
||||||
|
for (i in 0...9)
|
||||||
|
{
|
||||||
|
if (availableChars.exists(i))
|
||||||
|
{
|
||||||
|
var path:String = availableChars.get(i);
|
||||||
|
var temp:PixelatedIcon = new PixelatedIcon(0, 0);
|
||||||
|
temp.setCharacter(path);
|
||||||
|
temp.setGraphicSize(128, 128);
|
||||||
|
temp.updateHitbox();
|
||||||
|
temp.ID = 0;
|
||||||
|
grpIcons.add(temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var temp:FlxSprite = new FlxSprite();
|
||||||
|
temp.ID = 1;
|
||||||
|
temp.frames = Paths.getSparrowAtlas("charSelect/locks");
|
||||||
|
|
||||||
|
var lockIndex:Int = i + 1;
|
||||||
|
|
||||||
|
if (i == 3) lockIndex = 3;
|
||||||
|
|
||||||
|
if (i >= 4) lockIndex = i - 2;
|
||||||
|
|
||||||
|
temp.animation.addByIndices("idle", "LOCK FULL " + lockIndex + " instance 1", [0], "", 24);
|
||||||
|
temp.animation.addByIndices("selected", "LOCK FULL " + lockIndex + " instance 1", [3, 4, 5], "", 24, false);
|
||||||
|
temp.animation.addByIndices("clicked", "LOCK FULL " + lockIndex + " instance 1", [9, 10, 11, 12, 13, 14, 15], "", 24, false);
|
||||||
|
|
||||||
|
temp.animation.play("idle");
|
||||||
|
|
||||||
|
grpIcons.add(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateIconPositions();
|
||||||
|
|
||||||
|
grpIcons.scrollFactor.set();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateIconPositions()
|
||||||
|
{
|
||||||
|
grpIcons.x = 450;
|
||||||
|
grpIcons.y = 120;
|
||||||
|
for (index => member in grpIcons.members)
|
||||||
|
{
|
||||||
|
var posX:Float = (index % 3);
|
||||||
|
var posY:Float = Math.floor(index / 3);
|
||||||
|
|
||||||
|
member.x = posX * grpXSpread;
|
||||||
|
member.y = posY * grpYSpread;
|
||||||
|
|
||||||
|
member.x += grpIcons.x;
|
||||||
|
member.y += grpIcons.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var holdTmrUp:Float = 0;
|
||||||
|
var holdTmrDown:Float = 0;
|
||||||
|
var holdTmrLeft:Float = 0;
|
||||||
|
var holdTmrRight:Float = 0;
|
||||||
|
var spamUp:Bool = false;
|
||||||
|
var spamDown:Bool = false;
|
||||||
|
var spamLeft:Bool = false;
|
||||||
|
var spamRight:Bool = false;
|
||||||
|
|
||||||
|
override public function update(elapsed:Float):Void
|
||||||
|
{
|
||||||
|
super.update(elapsed);
|
||||||
|
|
||||||
|
Conductor.instance.update();
|
||||||
|
|
||||||
|
if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R) selectSound.pitch = 1;
|
||||||
|
|
||||||
|
if (controls.UI_UP) holdTmrUp += elapsed;
|
||||||
|
if (controls.UI_UP_R)
|
||||||
|
{
|
||||||
|
holdTmrUp = 0;
|
||||||
|
spamUp = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controls.UI_DOWN) holdTmrDown += elapsed;
|
||||||
|
if (controls.UI_DOWN_R)
|
||||||
|
{
|
||||||
|
holdTmrDown = 0;
|
||||||
|
spamDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controls.UI_LEFT) holdTmrLeft += elapsed;
|
||||||
|
if (controls.UI_LEFT_R)
|
||||||
|
{
|
||||||
|
holdTmrLeft = 0;
|
||||||
|
spamLeft = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controls.UI_RIGHT) holdTmrRight += elapsed;
|
||||||
|
if (controls.UI_RIGHT_R)
|
||||||
|
{
|
||||||
|
holdTmrRight = 0;
|
||||||
|
spamRight = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var initSpam = 0.5;
|
||||||
|
|
||||||
|
if (holdTmrUp >= initSpam) spamUp = true;
|
||||||
|
if (holdTmrDown >= initSpam) spamDown = true;
|
||||||
|
if (holdTmrLeft >= initSpam) spamLeft = true;
|
||||||
|
if (holdTmrRight >= initSpam) spamRight = true;
|
||||||
|
|
||||||
|
if (controls.UI_UP_P)
|
||||||
|
{
|
||||||
|
cursorY -= 1;
|
||||||
|
holdTmrUp = 0;
|
||||||
|
|
||||||
|
selectSound.play(true);
|
||||||
|
}
|
||||||
|
if (controls.UI_DOWN_P)
|
||||||
|
{
|
||||||
|
cursorY += 1;
|
||||||
|
holdTmrDown = 0;
|
||||||
|
selectSound.play(true);
|
||||||
|
}
|
||||||
|
if (controls.UI_LEFT_P)
|
||||||
|
{
|
||||||
|
cursorX -= 1;
|
||||||
|
holdTmrLeft = 0;
|
||||||
|
selectSound.play(true);
|
||||||
|
}
|
||||||
|
if (controls.UI_RIGHT_P)
|
||||||
|
{
|
||||||
|
cursorX += 1;
|
||||||
|
holdTmrRight = 0;
|
||||||
|
selectSound.play(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursorX < -1)
|
||||||
|
{
|
||||||
|
cursorX = 1;
|
||||||
|
}
|
||||||
|
if (cursorX > 1)
|
||||||
|
{
|
||||||
|
cursorX = -1;
|
||||||
|
}
|
||||||
|
if (cursorY < -1)
|
||||||
|
{
|
||||||
|
cursorY = 1;
|
||||||
|
}
|
||||||
|
if (cursorY > 1)
|
||||||
|
{
|
||||||
|
cursorY = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableChars.exists(getCurrentSelected()))
|
||||||
|
{
|
||||||
|
curChar = availableChars.get(getCurrentSelected());
|
||||||
|
|
||||||
|
if (controls.ACCEPT)
|
||||||
|
{
|
||||||
|
cursorConfirmed.visible = true;
|
||||||
|
cursorConfirmed.x = cursor.x - 2;
|
||||||
|
cursorConfirmed.y = cursor.y - 4;
|
||||||
|
cursorConfirmed.animation.play("idle", true);
|
||||||
|
|
||||||
|
grpCursors.visible = false;
|
||||||
|
|
||||||
|
FlxG.sound.play(Paths.sound('CS_confirm'));
|
||||||
|
|
||||||
|
FlxTween.tween(FlxG.sound.music, {pitch: 0.1}, 1.5, {ease: FlxEase.quadInOut});
|
||||||
|
playerChill.playAnimation("select");
|
||||||
|
pressedSelect = true;
|
||||||
|
selectTimer.start(1.5, (_) -> {
|
||||||
|
pressedSelect = false;
|
||||||
|
FlxG.switchState(FreeplayState.build(
|
||||||
|
{
|
||||||
|
{
|
||||||
|
character: curChar
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressedSelect && controls.BACK)
|
||||||
|
{
|
||||||
|
cursorConfirmed.visible = false;
|
||||||
|
grpCursors.visible = true;
|
||||||
|
|
||||||
|
FlxTween.globalManager.cancelTweensOf(FlxG.sound.music);
|
||||||
|
FlxTween.tween(FlxG.sound.music, {pitch: 1.0}, 1, {ease: FlxEase.quartInOut});
|
||||||
|
playerChill.playAnimation("deselect");
|
||||||
|
pressedSelect = false;
|
||||||
|
selectTimer.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curChar = "locked";
|
||||||
|
|
||||||
|
if (controls.ACCEPT)
|
||||||
|
{
|
||||||
|
cursorDenied.visible = true;
|
||||||
|
cursorDenied.x = cursor.x - 2;
|
||||||
|
cursorDenied.y = cursor.y - 4;
|
||||||
|
cursorDenied.animation.play("idle", true);
|
||||||
|
cursorDenied.animation.finishCallback = (_) -> {
|
||||||
|
cursorDenied.visible = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLockAnims();
|
||||||
|
|
||||||
|
camFollow.screenCenter();
|
||||||
|
camFollow.x += cursorX * 10;
|
||||||
|
camFollow.y += cursorY * 10;
|
||||||
|
|
||||||
|
cursorLocIntended.x = (cursorFactor * cursorX) + (FlxG.width / 2) - cursor.width / 2;
|
||||||
|
cursorLocIntended.y = (cursorFactor * cursorY) + (FlxG.height / 2) - cursor.height / 2;
|
||||||
|
|
||||||
|
cursorLocIntended.x += cursorOffsetX;
|
||||||
|
cursorLocIntended.y += cursorOffsetY;
|
||||||
|
|
||||||
|
cursor.x = MathUtil.coolLerp(cursor.x, cursorLocIntended.x, lerpAmnt);
|
||||||
|
cursor.y = MathUtil.coolLerp(cursor.y, cursorLocIntended.y, lerpAmnt);
|
||||||
|
|
||||||
|
cursorBlue.x = MathUtil.coolLerp(cursorBlue.x, cursor.x, lerpAmnt * 0.4);
|
||||||
|
cursorBlue.y = MathUtil.coolLerp(cursorBlue.y, cursor.y, lerpAmnt * 0.4);
|
||||||
|
|
||||||
|
cursorDarkBlue.x = MathUtil.coolLerp(cursorDarkBlue.x, cursorLocIntended.x, lerpAmnt * 0.2);
|
||||||
|
cursorDarkBlue.y = MathUtil.coolLerp(cursorDarkBlue.y, cursorLocIntended.y, lerpAmnt * 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function spamOnStep():Void
|
||||||
|
{
|
||||||
|
if (spamUp || spamDown || spamLeft || spamRight)
|
||||||
|
{
|
||||||
|
// selectSound.changePitchBySemitone(1);
|
||||||
|
if (selectSound.pitch > 5) selectSound.pitch = 5;
|
||||||
|
selectSound.play(true);
|
||||||
|
|
||||||
|
if (spamUp)
|
||||||
|
{
|
||||||
|
cursorY -= 1;
|
||||||
|
holdTmrUp = 0;
|
||||||
|
}
|
||||||
|
if (spamDown)
|
||||||
|
{
|
||||||
|
cursorY += 1;
|
||||||
|
holdTmrDown = 0;
|
||||||
|
}
|
||||||
|
if (spamLeft)
|
||||||
|
{
|
||||||
|
cursorX -= 1;
|
||||||
|
holdTmrLeft = 0;
|
||||||
|
}
|
||||||
|
if (spamRight)
|
||||||
|
{
|
||||||
|
cursorX += 1;
|
||||||
|
holdTmrRight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateLockAnims():Void
|
||||||
|
{
|
||||||
|
for (index => member in grpIcons.group.members)
|
||||||
|
{
|
||||||
|
switch (member.ID)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if (index == getCurrentSelected())
|
||||||
|
{
|
||||||
|
switch (member.animation.curAnim.name)
|
||||||
|
{
|
||||||
|
case "idle":
|
||||||
|
member.animation.play("selected");
|
||||||
|
case "selected" | "clicked":
|
||||||
|
if (controls.ACCEPT) member.animation.play("clicked", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
member.animation.play("idle");
|
||||||
|
}
|
||||||
|
case 0:
|
||||||
|
var memb:PixelatedIcon = cast member;
|
||||||
|
|
||||||
|
if (index == getCurrentSelected())
|
||||||
|
{
|
||||||
|
// memb.pixels = memb.withDropShadow.clone();
|
||||||
|
memb.scale.set(2.6, 2.6);
|
||||||
|
|
||||||
|
if (controls.ACCEPT) memb.animation.play("confirm");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// memb.pixels = memb.noDropShadow.clone();
|
||||||
|
memb.scale.set(2, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentSelected():Int
|
||||||
|
{
|
||||||
|
var tempX:Int = cursorX + 1;
|
||||||
|
var tempY:Int = cursorY + 1;
|
||||||
|
var gridPosition:Int = tempX + tempY * 3;
|
||||||
|
return gridPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_curChar(value:String):String
|
||||||
|
{
|
||||||
|
if (curChar == value) return value;
|
||||||
|
|
||||||
|
curChar = value;
|
||||||
|
|
||||||
|
nametag.switchChar(value);
|
||||||
|
playerChill.visible = false;
|
||||||
|
playerChillOut.visible = true;
|
||||||
|
playerChillOut.anim.goToFrameLabel("slideout");
|
||||||
|
playerChillOut.anim.callback = (_, frame:Int) -> {
|
||||||
|
if (frame == playerChillOut.anim.getFrameLabel("slideout").index + 1)
|
||||||
|
{
|
||||||
|
playerChill.visible = true;
|
||||||
|
playerChill.switchChar(value);
|
||||||
|
gfChill.switchGF(value);
|
||||||
|
}
|
||||||
|
if (frame == playerChillOut.anim.getFrameLabel("slideout").index + 2)
|
||||||
|
{
|
||||||
|
playerChillOut.switchChar(value);
|
||||||
|
playerChillOut.visible = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_grpXSpread(value:Float):Float
|
||||||
|
{
|
||||||
|
grpXSpread = value;
|
||||||
|
updateIconPositions();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_grpYSpread(value:Float):Float
|
||||||
|
{
|
||||||
|
grpYSpread = value;
|
||||||
|
updateIconPositions();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
101
source/funkin/ui/charSelect/Nametag.hx
Normal file
101
source/funkin/ui/charSelect/Nametag.hx
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package funkin.ui.charSelect;
|
||||||
|
|
||||||
|
import flixel.FlxSprite;
|
||||||
|
import funkin.graphics.shaders.MosaicEffect;
|
||||||
|
import flixel.util.FlxTimer;
|
||||||
|
|
||||||
|
class Nametag extends FlxSprite
|
||||||
|
{
|
||||||
|
var midpointX(default, set):Float = 1008;
|
||||||
|
var midpointY(default, set):Float = 100;
|
||||||
|
var mosaicShader:MosaicEffect;
|
||||||
|
|
||||||
|
public function new(?x:Float = 0, ?y:Float = 0)
|
||||||
|
{
|
||||||
|
super(x, y);
|
||||||
|
|
||||||
|
mosaicShader = new MosaicEffect();
|
||||||
|
shader = mosaicShader;
|
||||||
|
|
||||||
|
switchChar("bf");
|
||||||
|
|
||||||
|
FlxG.debugger.addTrackerProfile(new TrackerProfile(Nametag, ["midpointX", "midpointY"]));
|
||||||
|
FlxG.debugger.track(this, "Nametag");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePosition():Void
|
||||||
|
{
|
||||||
|
var offsetX:Float = getMidpoint().x - midpointX;
|
||||||
|
var offsetY:Float = getMidpoint().y - midpointY;
|
||||||
|
|
||||||
|
x -= offsetX;
|
||||||
|
y -= offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function switchChar(str:String):Void
|
||||||
|
{
|
||||||
|
shaderEffect();
|
||||||
|
|
||||||
|
new FlxTimer().start(4 / 30, _ -> {
|
||||||
|
var path:String = str;
|
||||||
|
switch str
|
||||||
|
{
|
||||||
|
case "bf":
|
||||||
|
path = "boyfriend";
|
||||||
|
}
|
||||||
|
|
||||||
|
loadGraphic(Paths.image('charSelect/' + path + "Nametag"));
|
||||||
|
updateHitbox();
|
||||||
|
scale.x = scale.y = 0.77;
|
||||||
|
|
||||||
|
updatePosition();
|
||||||
|
shaderEffect(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function shaderEffect(fadeOut:Bool = false):Void
|
||||||
|
{
|
||||||
|
if (fadeOut)
|
||||||
|
{
|
||||||
|
setBlockTimer(0, 1, 1);
|
||||||
|
setBlockTimer(1, width / 27, height / 26);
|
||||||
|
setBlockTimer(2, width / 10, height / 10);
|
||||||
|
|
||||||
|
setBlockTimer(3, 1, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setBlockTimer(0, (width / 10), (height / 10));
|
||||||
|
setBlockTimer(1, width / 73, height / 6);
|
||||||
|
setBlockTimer(2, width / 10, height / 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBlockTimer(frame:Int, ?forceX:Float, ?forceY:Float)
|
||||||
|
{
|
||||||
|
var daX:Float = 10 * FlxG.random.int(1, 4);
|
||||||
|
var daY:Float = 10 * FlxG.random.int(1, 4);
|
||||||
|
|
||||||
|
if (forceX != null) daX = forceX;
|
||||||
|
|
||||||
|
if (forceY != null) daY = forceY;
|
||||||
|
|
||||||
|
new FlxTimer().start(frame / 30, _ -> {
|
||||||
|
mosaicShader.setBlockSize(daX, daY);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_midpointX(val:Float):Float
|
||||||
|
{
|
||||||
|
this.midpointX = val;
|
||||||
|
updatePosition();
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_midpointY(val:Float):Float
|
||||||
|
{
|
||||||
|
this.midpointY = val;
|
||||||
|
updatePosition();
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,8 +54,11 @@ class DebugMenuSubState extends MusicBeatSubState
|
||||||
|
|
||||||
// Create each menu item.
|
// Create each menu item.
|
||||||
// Call onMenuChange when the first item is created to move the camera .
|
// Call onMenuChange when the first item is created to move the camera .
|
||||||
|
#if CHART_EDITOR_SUPPORTED
|
||||||
onMenuChange(createItem("CHART EDITOR", openChartEditor));
|
onMenuChange(createItem("CHART EDITOR", openChartEditor));
|
||||||
|
#end
|
||||||
// createItem("Input Offset Testing", openInputOffsetTesting);
|
// createItem("Input Offset Testing", openInputOffsetTesting);
|
||||||
|
createItem("CHARACTER SELECT", openCharSelect, true);
|
||||||
createItem("ANIMATION EDITOR", openAnimationEditor);
|
createItem("ANIMATION EDITOR", openAnimationEditor);
|
||||||
// createItem("STAGE EDITOR", openStageEditor);
|
// createItem("STAGE EDITOR", openStageEditor);
|
||||||
// createItem("TEST STICKERS", testStickers);
|
// createItem("TEST STICKERS", testStickers);
|
||||||
|
@ -102,6 +105,11 @@ class DebugMenuSubState extends MusicBeatSubState
|
||||||
trace('Input Offset Testing');
|
trace('Input Offset Testing');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openCharSelect()
|
||||||
|
{
|
||||||
|
FlxG.switchState(new funkin.ui.charSelect.CharSelectSubState());
|
||||||
|
}
|
||||||
|
|
||||||
function openAnimationEditor()
|
function openAnimationEditor()
|
||||||
{
|
{
|
||||||
FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState());
|
FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState());
|
||||||
|
|
|
@ -1232,6 +1232,11 @@ class FreeplayState extends MusicBeatSubState
|
||||||
// }
|
// }
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
if (controls.FREEPLAY_CHAR_SELECT && !busy)
|
||||||
|
{
|
||||||
|
FlxG.switchState(new funkin.ui.charSelect.CharSelectSubState());
|
||||||
|
}
|
||||||
|
|
||||||
if (controls.FREEPLAY_FAVORITE && !busy)
|
if (controls.FREEPLAY_FAVORITE && !busy)
|
||||||
{
|
{
|
||||||
var targetSong = grpCapsules.members[curSelected]?.songData;
|
var targetSong = grpCapsules.members[curSelected]?.songData;
|
||||||
|
|
|
@ -24,12 +24,13 @@ import funkin.play.scoring.Scoring.ScoringRank;
|
||||||
import funkin.save.Save;
|
import funkin.save.Save;
|
||||||
import funkin.save.Save.SaveScoreData;
|
import funkin.save.Save.SaveScoreData;
|
||||||
import flixel.util.FlxColor;
|
import flixel.util.FlxColor;
|
||||||
|
import funkin.ui.PixelatedIcon;
|
||||||
|
|
||||||
class SongMenuItem extends FlxSpriteGroup
|
class SongMenuItem extends FlxSpriteGroup
|
||||||
{
|
{
|
||||||
public var capsule:FlxSprite;
|
public var capsule:FlxSprite;
|
||||||
|
|
||||||
var pixelIcon:FlxSprite;
|
var pixelIcon:PixelatedIcon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify this by calling `init()`
|
* Modify this by calling `init()`
|
||||||
|
@ -201,11 +202,7 @@ class SongMenuItem extends FlxSpriteGroup
|
||||||
// TODO: Use value from metadata instead of random.
|
// TODO: Use value from metadata instead of random.
|
||||||
updateDifficultyRating(FlxG.random.int(0, 20));
|
updateDifficultyRating(FlxG.random.int(0, 20));
|
||||||
|
|
||||||
pixelIcon = new FlxSprite(160, 35);
|
pixelIcon = new PixelatedIcon(160, 35);
|
||||||
|
|
||||||
pixelIcon.makeGraphic(32, 32, 0x00000000);
|
|
||||||
pixelIcon.antialiasing = false;
|
|
||||||
pixelIcon.active = false;
|
|
||||||
add(pixelIcon);
|
add(pixelIcon);
|
||||||
grpHide.add(pixelIcon);
|
grpHide.add(pixelIcon);
|
||||||
|
|
||||||
|
@ -512,7 +509,7 @@ class SongMenuItem extends FlxSpriteGroup
|
||||||
// Update capsule text.
|
// Update capsule text.
|
||||||
songText.text = songData?.songName ?? 'Random';
|
songText.text = songData?.songName ?? 'Random';
|
||||||
// Update capsule character.
|
// Update capsule character.
|
||||||
if (songData?.songCharacter != null) setCharacter(songData.songCharacter);
|
if (songData?.songCharacter != null) pixelIcon.setCharacter(songData.songCharacter);
|
||||||
updateBPM(Std.int(songData?.songStartingBpm) ?? 0);
|
updateBPM(Std.int(songData?.songStartingBpm) ?? 0);
|
||||||
updateDifficultyRating(songData?.difficultyRating ?? 0);
|
updateDifficultyRating(songData?.difficultyRating ?? 0);
|
||||||
updateScoringRank(songData?.scoringRank);
|
updateScoringRank(songData?.scoringRank);
|
||||||
|
@ -526,76 +523,6 @@ class SongMenuItem extends FlxSpriteGroup
|
||||||
checkWeek(songData?.songId);
|
checkWeek(songData?.songId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the character displayed next to this song in the freeplay menu.
|
|
||||||
* @param char The character ID used by this song.
|
|
||||||
* If the character has no freeplay icon, a warning will be thrown and nothing will display.
|
|
||||||
*/
|
|
||||||
public function setCharacter(char:String):Void
|
|
||||||
{
|
|
||||||
var charPath:String = "freeplay/icons/";
|
|
||||||
|
|
||||||
// TODO: Put this in the character metadata where it belongs.
|
|
||||||
// TODO: Also, can use CharacterDataParser.getCharPixelIconAsset()
|
|
||||||
switch (char)
|
|
||||||
{
|
|
||||||
case 'monster-christmas':
|
|
||||||
charPath += 'monsterpixel';
|
|
||||||
case 'mom-car':
|
|
||||||
charPath += 'mommypixel';
|
|
||||||
case 'darnell-blazin':
|
|
||||||
charPath += 'darnellpixel';
|
|
||||||
case 'senpai-angry':
|
|
||||||
charPath += 'senpaipixel';
|
|
||||||
default:
|
|
||||||
charPath += '${char}pixel';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!openfl.utils.Assets.exists(Paths.image(charPath)))
|
|
||||||
{
|
|
||||||
trace('[WARN] Character ${char} has no freeplay icon.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var isAnimated = openfl.utils.Assets.exists(Paths.file('images/$charPath.xml'));
|
|
||||||
|
|
||||||
if (isAnimated)
|
|
||||||
{
|
|
||||||
pixelIcon.frames = Paths.getSparrowAtlas(charPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pixelIcon.loadGraphic(Paths.image(charPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
pixelIcon.scale.x = pixelIcon.scale.y = 2;
|
|
||||||
|
|
||||||
switch (char)
|
|
||||||
{
|
|
||||||
case 'parents-christmas':
|
|
||||||
pixelIcon.origin.x = 140;
|
|
||||||
default:
|
|
||||||
pixelIcon.origin.x = 100;
|
|
||||||
}
|
|
||||||
// pixelIcon.origin.x = capsule.origin.x;
|
|
||||||
// pixelIcon.offset.x -= pixelIcon.origin.x;
|
|
||||||
|
|
||||||
if (isAnimated)
|
|
||||||
{
|
|
||||||
pixelIcon.active = true;
|
|
||||||
|
|
||||||
pixelIcon.animation.addByPrefix('idle', 'idle0', 10, true);
|
|
||||||
pixelIcon.animation.addByPrefix('confirm', 'confirm0', 10, false);
|
|
||||||
pixelIcon.animation.addByPrefix('confirm-hold', 'confirm-hold0', 10, true);
|
|
||||||
|
|
||||||
pixelIcon.animation.finishCallback = function(name:String):Void {
|
|
||||||
trace('Finish pixel animation: ${name}');
|
|
||||||
if (name == 'confirm') pixelIcon.animation.play('confirm-hold');
|
|
||||||
};
|
|
||||||
|
|
||||||
pixelIcon.animation.play('idle');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var frameInTicker:Float = 0;
|
var frameInTicker:Float = 0;
|
||||||
var frameInTypeBeat:Int = 0;
|
var frameInTypeBeat:Int = 0;
|
||||||
|
|
|
@ -344,17 +344,15 @@ class MainMenuState extends MusicBeatState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (debug || FORCE_DEBUG_VERSION)
|
||||||
// Open the debug menu, defaults to ` / ~
|
// Open the debug menu, defaults to ` / ~
|
||||||
#if CHART_EDITOR_SUPPORTED
|
|
||||||
if (controls.DEBUG_MENU)
|
if (controls.DEBUG_MENU)
|
||||||
{
|
{
|
||||||
persistentUpdate = false;
|
persistentUpdate = false;
|
||||||
|
|
||||||
FlxG.state.openSubState(new DebugMenuSubState());
|
FlxG.state.openSubState(new DebugMenuSubState());
|
||||||
}
|
}
|
||||||
#end
|
|
||||||
|
|
||||||
#if (debug || FORCE_DEBUG_VERSION)
|
|
||||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.W)
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.W)
|
||||||
{
|
{
|
||||||
// Give the user a score of 1 point on Weekend 1 story mode.
|
// Give the user a score of 1 point on Weekend 1 story mode.
|
||||||
|
|
48
source/funkin/util/FramesJSFLParser.hx
Normal file
48
source/funkin/util/FramesJSFLParser.hx
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package funkin.util;
|
||||||
|
|
||||||
|
import openfl.Assets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See `funScripts/jsfl/frames.jsfl` for more information in the art repo/folder!
|
||||||
|
* Homemade dipshit proprietary format to get simple animation info out of flash!
|
||||||
|
* Pure convienience!
|
||||||
|
*/
|
||||||
|
class FramesJSFLParser
|
||||||
|
{
|
||||||
|
public static function parse(path:String):FramesJSFLInfo
|
||||||
|
{
|
||||||
|
var text:String = Assets.getText(path);
|
||||||
|
|
||||||
|
// TODO: error handle if text is null
|
||||||
|
|
||||||
|
var output:FramesJSFLInfo = {frames: []};
|
||||||
|
|
||||||
|
var frames:Array<String> = text.split("\n");
|
||||||
|
|
||||||
|
for (frame in frames)
|
||||||
|
{
|
||||||
|
var frameInfo:Array<String> = frame.split(" ");
|
||||||
|
|
||||||
|
var x:Float = Std.parseFloat(frameInfo[0]);
|
||||||
|
var y:Float = Std.parseFloat(frameInfo[1]);
|
||||||
|
var alpha:Float = Std.parseFloat(frameInfo[2]);
|
||||||
|
|
||||||
|
var shit:FramesJSFLFrame = {x: x, y: y, alpha: alpha};
|
||||||
|
output.frames.push(shit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef FramesJSFLInfo =
|
||||||
|
{
|
||||||
|
var frames:Array<FramesJSFLFrame>;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef FramesJSFLFrame =
|
||||||
|
{
|
||||||
|
var x:Float;
|
||||||
|
var y:Float;
|
||||||
|
var alpha:Float;
|
||||||
|
}
|
Loading…
Reference in a new issue