mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-12-08 04:58:48 +00:00
Compare commits
16 commits
6213bd3949
...
da69c55f71
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da69c55f71 | ||
|
|
0ca2d912be | ||
|
|
758f712eb5 | ||
|
|
01029817c0 | ||
|
|
8a31e12d10 | ||
|
|
90ab04caa1 | ||
|
|
ba7f89b9a2 | ||
|
|
ee36cbbbcf | ||
|
|
d74b8fb4ca | ||
|
|
8fa622e147 | ||
|
|
a12950d5a7 | ||
|
|
71bc847698 | ||
|
|
a560bf51a9 | ||
|
|
866e5aa008 | ||
|
|
3c213ad45c | ||
|
|
a0b933ce8f |
112
.vscode/settings.json
vendored
112
.vscode/settings.json
vendored
|
|
@ -1,31 +1,22 @@
|
|||
{
|
||||
"[haxe]": {
|
||||
// Automatically keep Haxe files formatted.
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "never"
|
||||
},
|
||||
"editor.codeActionsOnSave": { "source.organizeImports": "never" },
|
||||
"editor.defaultFormatter": "nadako.vshaxe",
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
|
||||
"[json]": {
|
||||
// Automatically keep JSON files formatted.
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
|
||||
"[jsonc]": {
|
||||
// Automatically keep JSONC files formatted.
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"prettier.tabWidth": 2,
|
||||
|
||||
// XML formatting style configuration
|
||||
// XML Formatting
|
||||
"xml.format.enabled": true,
|
||||
"xml.format.legacy": false,
|
||||
"xml.format.emptyElements": "collapse",
|
||||
|
|
@ -33,7 +24,7 @@
|
|||
"xml.format.enforceQuoteStyle": "preferred",
|
||||
"xml.format.preserveAttributeLineBreaks": false,
|
||||
"xml.format.preservedNewlines": 0,
|
||||
"xml.format.splitAttributes": false,
|
||||
"xml.format.splitAttributes": "preserve",
|
||||
"xml.format.joinCDATALines": true,
|
||||
"xml.format.preserveEmptyContent": false,
|
||||
"xml.format.joinCommentLines": false,
|
||||
|
|
@ -56,26 +47,19 @@
|
|||
"xml.format.maxLineWidth": 0,
|
||||
"xml.format.grammarAwareFormatting": true,
|
||||
|
||||
// Generic file formatting style configuration
|
||||
// General formatting
|
||||
"files.insertFinalNewline": true,
|
||||
"files.trimFinalNewlines": false,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
|
||||
// Automatically detect indentation.
|
||||
"editor.detectIndentation": true,
|
||||
"editor.insertSpaces": true,
|
||||
"editor.tabSize": 2,
|
||||
|
||||
// Automatically enforce Linux style line endings.
|
||||
"prettier.tabWidth": 2,
|
||||
"files.eol": "\n",
|
||||
|
||||
"haxe.displayPort": "auto",
|
||||
"haxe.enableCompilationServer": true,
|
||||
"haxe.enableServerView": true,
|
||||
"haxe.displayServer": {
|
||||
"arguments": ["-v"]
|
||||
},
|
||||
// Fix file associations for HScript.
|
||||
"haxe.displayServer": { "arguments": ["-v"] },
|
||||
"files.associations": {
|
||||
"*.hxp": "haxe",
|
||||
"*.hscript": "haxe",
|
||||
|
|
@ -84,14 +68,27 @@
|
|||
"*.hxc": "haxe"
|
||||
},
|
||||
"projectManager.git.baseFolders": ["./"],
|
||||
|
||||
"haxecheckstyle.sourceFolders": ["src", "source"],
|
||||
"haxecheckstyle.externalSourceRoots": [],
|
||||
"haxecheckstyle.configurationFile": "checkstyle.json",
|
||||
"haxecheckstyle.codeSimilarityBufferSize": 100,
|
||||
|
||||
"lime.projectFile": "project.hxp",
|
||||
|
||||
"lime.targets": [
|
||||
{ "name": "windows", "enabled": true, "label": "Windows" },
|
||||
{ "name": "mac", "enabled": true, "label": "macOS" },
|
||||
{ "name": "linux", "enabled": true, "label": "Linux" },
|
||||
{ "name": "html5", "enabled": true, "label": "HTML5" },
|
||||
{ "name": "android", "enabled": true, "label": "Android" },
|
||||
{ "name": "ios", "enabled": true, "label": "iOS" },
|
||||
// Disabled targets
|
||||
{ "name": "hl", "enabled": false, "label": "HashLink" },
|
||||
{ "name": "air", "enabled": false },
|
||||
{ "name": "electron", "enabled": false },
|
||||
{ "name": "flash", "enabled": false },
|
||||
{ "name": "neko", "enabled": false },
|
||||
{ "name": "tvos", "enabled": false }
|
||||
],
|
||||
"lime.defaultTargetConfiguration": "Windows / Debug",
|
||||
"lime.targetConfigurations": [
|
||||
{
|
||||
"label": "Windows / Debug (Discord)",
|
||||
|
|
@ -103,21 +100,11 @@
|
|||
"target": "windows",
|
||||
"args": ["-debug", "-DANIMATE", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (FlxAnimate Test)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DANIMATE"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Straight to Freeplay)",
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DFREEPLAY", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (Straight to Freeplay)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DFREEPLAY"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Straight to Play - Bopeebo Normal)",
|
||||
"target": "windows",
|
||||
|
|
@ -132,26 +119,6 @@
|
|||
"target": "windows",
|
||||
"args": ["-debug", "-DSONG=2hot", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (Straight to Play - Bopeebo Normal)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DSONG=bopeebo -DDIFFICULTY=normal"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Conversation Test)",
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DDIALOGUE", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (Conversation Test)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DDIALOGUE"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Results Screen Test)",
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DRESULTS"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Straight to Stage Editor)",
|
||||
"target": "windows",
|
||||
|
|
@ -172,36 +139,16 @@
|
|||
"target": "windows",
|
||||
"args": ["-debug", "-DHXVLC_LOGGING", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (Straight to Animation Editor)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DANIMDEBUG"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Latency Test)",
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DLATENCY", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (Latency Test)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DLATENCY"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Waveform Test)",
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DWAVEFORM", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Release (GitHub Actions)",
|
||||
"target": "windows",
|
||||
"args": ["-release", "-DGITHUB_BUILD"]
|
||||
},
|
||||
{
|
||||
"label": "HashLink / Debug (Waveform Test)",
|
||||
"target": "hl",
|
||||
"args": ["-debug", "-DWAVEFORM"]
|
||||
},
|
||||
{
|
||||
"label": "HTML5 / Debug (Watch)",
|
||||
"target": "html5",
|
||||
|
|
@ -209,10 +156,7 @@
|
|||
}
|
||||
],
|
||||
"lime.buildTypes": [
|
||||
{
|
||||
"label": "Debug",
|
||||
"args": ["-debug", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{ "label": "Debug", "args": ["-debug", "-DFEATURE_DEBUG_FUNCTIONS"] },
|
||||
{
|
||||
"label": "Debug (Unlock Everything)",
|
||||
"args": ["-debug", "-DUNLOCK_EVERYTHING"]
|
||||
|
|
@ -225,10 +169,7 @@
|
|||
"label": "Debug (Straight to Chart Editor)",
|
||||
"args": ["-debug", "-DCHARTING", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "Release",
|
||||
"args": ["-release"]
|
||||
},
|
||||
{ "label": "Release", "args": ["-release"] },
|
||||
{
|
||||
"label": "Release (GitHub Actions)",
|
||||
"args": ["-release", "-DGITHUB_BUILD"]
|
||||
|
|
@ -244,9 +185,6 @@
|
|||
],
|
||||
"vscord.app.privacyMode.enable": true,
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": ["/hmm.json"],
|
||||
"url": "./.vscode/schema/hmm.json"
|
||||
}
|
||||
{ "fileMatch": ["/hmm.json"], "url": "./.vscode/schema/hmm.json" }
|
||||
]
|
||||
}
|
||||
|
|
|
|||
2
assets
2
assets
|
|
@ -1 +1 @@
|
|||
Subproject commit 1374c558b577ce64e205cf838e2ee6f0311a7a7c
|
||||
Subproject commit 1a961f111381eb3bfc452166c4e4b5a18b409781
|
||||
|
|
@ -451,6 +451,46 @@ class FunkinSprite extends FlxAnimate
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets every frame on every symbol that starts with the given keyword.
|
||||
* @param keyword The keyword to search for.
|
||||
* @return An array of frames.
|
||||
*/
|
||||
public function getFramesWithKeyword(keyword:String):Array<animate.internal.Frame>
|
||||
{
|
||||
if (!this.isAnimate)
|
||||
{
|
||||
trace('WARNING: getFramesWithKeyword() only works texture atlases!');
|
||||
return [];
|
||||
}
|
||||
|
||||
var symbolItems:Array<animate.internal.SymbolItem> = [];
|
||||
var frames:Array<animate.internal.Frame> = [];
|
||||
|
||||
@:privateAccess
|
||||
for (symbol in this.library.dictionary.keys())
|
||||
{
|
||||
var symbolItem:Null<animate.internal.SymbolItem> = this.library.getSymbol(symbol);
|
||||
if (symbolItem == null) continue;
|
||||
|
||||
if (symbolItem.name.contains(keyword))
|
||||
{
|
||||
symbolItems.push(symbolItem);
|
||||
}
|
||||
}
|
||||
|
||||
for (symbolItem in symbolItems)
|
||||
{
|
||||
symbolItem.timeline.forEachLayer((layer) -> {
|
||||
layer.forEachFrame((frame) -> {
|
||||
frames.push(frame);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current animation ID.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1267,6 +1267,8 @@ class FunkinAction extends FlxActionDigital
|
|||
public var namePressed(default, null):Null<String>;
|
||||
public var nameReleased(default, null):Null<String>;
|
||||
|
||||
var cache:Map<String, {timestamp:Int, value:Bool}> = [];
|
||||
|
||||
public function new(?name:String = "", ?namePressed:String, ?nameReleased:String)
|
||||
{
|
||||
super(name);
|
||||
|
|
@ -1386,7 +1388,13 @@ class FunkinAction extends FlxActionDigital
|
|||
public function checkFiltered(?filterTrigger:FlxInputState, ?filterDevice:FlxInputDevice):Bool
|
||||
{
|
||||
// Make sure we only update the inputs once per frame.
|
||||
if (_timestamp == FlxG.game.ticks) return triggered; // run no more than once per frame
|
||||
var key = '${filterTrigger}:${filterDevice}';
|
||||
var cacheEntry = cache.get(key);
|
||||
|
||||
if (cacheEntry != null && cacheEntry.timestamp == FlxG.game.ticks)
|
||||
{
|
||||
return cacheEntry.value;
|
||||
}
|
||||
|
||||
_x = null;
|
||||
_y = null;
|
||||
|
|
@ -1428,6 +1436,8 @@ class FunkinAction extends FlxActionDigital
|
|||
}
|
||||
}
|
||||
|
||||
cache.set(key, {timestamp: FlxG.game.ticks, value: triggered});
|
||||
|
||||
return triggered;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1349,7 +1349,6 @@ class PlayState extends MusicBeatSubState
|
|||
|
||||
if (!event.eventCanceled)
|
||||
{
|
||||
shouldSubstatePause = true;
|
||||
persistentUpdate = false;
|
||||
persistentDraw = true;
|
||||
|
||||
|
|
@ -1402,6 +1401,7 @@ class PlayState extends MusicBeatSubState
|
|||
FlxTransitionableState.skipNextTransOut = true;
|
||||
pauseSubState.camera = cam;
|
||||
persistentUpdate = false;
|
||||
shouldSubstatePause = true;
|
||||
openSubState(pauseSubState);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import funkin.util.MathUtil;
|
|||
|
||||
class CharSelectCursors extends FlxTypedSpriteContainer<FunkinSprite>
|
||||
{
|
||||
/**
|
||||
* The main cursor sprite for this class.
|
||||
*/
|
||||
public var main:FunkinSprite;
|
||||
|
||||
var lightBlue:FunkinSprite;
|
||||
|
|
@ -56,6 +59,7 @@ class CharSelectCursors extends FlxTypedSpriteContainer<FunkinSprite>
|
|||
add(cursorDenied);
|
||||
|
||||
scrollFactor.set();
|
||||
directAlpha = true;
|
||||
}
|
||||
|
||||
public function confirm():Void
|
||||
|
|
@ -86,6 +90,32 @@ class CharSelectCursors extends FlxTypedSpriteContainer<FunkinSprite>
|
|||
main.visible = lightBlue.visible = darkBlue.visible = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Snaps the cursors to the given position.
|
||||
* @param intendedPosition The position to snap to as a `FlxPoint`.
|
||||
*/
|
||||
public function snapToLocation(intendedPosition:FlxPoint):Void
|
||||
{
|
||||
main.x = intendedPosition.x;
|
||||
main.y = intendedPosition.y;
|
||||
|
||||
lightBlue.x = main.x;
|
||||
lightBlue.y = main.y;
|
||||
|
||||
darkBlue.x = intendedPosition.x;
|
||||
darkBlue.y = intendedPosition.y;
|
||||
|
||||
cursorConfirmed.x = main.x - 2;
|
||||
cursorConfirmed.y = main.y - 4;
|
||||
|
||||
cursorDenied.x = main.x - 2;
|
||||
cursorDenied.y = main.y - 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lerps the cursors to the given position.
|
||||
* @param intendedPosition The position to lerp to as a `FlxPoint`.
|
||||
*/
|
||||
public function lerpToLocation(intendedPosition:FlxPoint):Void
|
||||
{
|
||||
main.x = MathUtil.snap(MathUtil.smoothLerpPrecision(main.x, intendedPosition.x, FlxG.elapsed, 0.1), intendedPosition.x, 1);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@ import funkin.util.TouchUtil;
|
|||
@:nullSafety
|
||||
class CharSelectSubState extends MusicBeatSubState
|
||||
{
|
||||
/**
|
||||
* The default index for the cursor.
|
||||
*/
|
||||
final DEFAULT_CURSOR_INDEX:Int = 4;
|
||||
|
||||
var cursors:CharSelectCursors;
|
||||
|
||||
var cursorX:Int = 0;
|
||||
|
|
@ -235,14 +240,17 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
{
|
||||
if (charId == rememberedChar)
|
||||
{
|
||||
setCursorPosition(pos);
|
||||
setCursorPosition(pos, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@:bypassAccessor curChar = rememberedChar;
|
||||
}
|
||||
else
|
||||
{
|
||||
setupPlayerChill(Constants.DEFAULT_CHARACTER);
|
||||
setCursorPosition(DEFAULT_CURSOR_INDEX, true);
|
||||
}
|
||||
|
||||
var speakers:FunkinSprite = FunkinSprite.createTextureAtlas(cutoutSize - 10, 0, "charSelect/charSelectSpeakers",
|
||||
{
|
||||
|
|
@ -307,15 +315,12 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
charHitbox.scrollFactor.set();
|
||||
|
||||
selectSound.loadEmbedded(Paths.sound('CS_select'));
|
||||
selectSound.pitch = 1;
|
||||
selectSound.volume = 0.7;
|
||||
|
||||
FlxG.sound.defaultSoundGroup.add(selectSound);
|
||||
FlxG.sound.list.add(selectSound);
|
||||
|
||||
unlockSound.loadEmbedded(Paths.sound('CS_unlock'));
|
||||
unlockSound.pitch = 1;
|
||||
|
||||
unlockSound.volume = 0;
|
||||
unlockSound.play(true);
|
||||
|
||||
|
|
@ -323,18 +328,13 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
FlxG.sound.list.add(unlockSound);
|
||||
|
||||
lockedSound.loadEmbedded(Paths.sound('CS_locked'));
|
||||
lockedSound.pitch = 1;
|
||||
|
||||
lockedSound.volume = 1.;
|
||||
|
||||
FlxG.sound.defaultSoundGroup.add(lockedSound);
|
||||
FlxG.sound.list.add(lockedSound);
|
||||
|
||||
staticSound.loadEmbedded(Paths.sound('static loop'));
|
||||
staticSound.pitch = 1;
|
||||
|
||||
staticSound.looped = true;
|
||||
|
||||
staticSound.volume = 0.6;
|
||||
|
||||
FlxG.sound.defaultSoundGroup.add(staticSound);
|
||||
|
|
@ -415,7 +415,6 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
|
||||
introSound = new FunkinSound();
|
||||
introSound.loadEmbedded(Paths.sound('CS_Lights'));
|
||||
introSound.pitch = 1;
|
||||
introSound.volume = 0;
|
||||
|
||||
FlxG.sound.defaultSoundGroup.add(introSound);
|
||||
|
|
@ -722,6 +721,7 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
var holdTmrLeft:Float = 0;
|
||||
var holdTmrRight:Float = 0;
|
||||
var spamDirections:FlxDirectionFlags = NONE;
|
||||
var initSpam = 0.5;
|
||||
|
||||
var mobileDeny:Bool = false;
|
||||
var mobileAccept:Bool = false;
|
||||
|
|
@ -736,9 +736,6 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
|
||||
mobileAccept = false;
|
||||
|
||||
if (controls.UI_UP_R || controls.UI_DOWN_R || controls.UI_LEFT_R || controls.UI_RIGHT_R #if FEATURE_TOUCH_CONTROLS || TouchUtil.justReleased #end)
|
||||
selectSound.pitch = 1;
|
||||
|
||||
if (allowInput && !pressedSelect)
|
||||
{
|
||||
#if FEATURE_TOUCH_CONTROLS
|
||||
|
|
@ -774,41 +771,6 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
}
|
||||
#end
|
||||
|
||||
if (controls.UI_UP) holdTmrUp += elapsed;
|
||||
if (controls.UI_UP_R)
|
||||
{
|
||||
holdTmrUp = 0;
|
||||
spamDirections = spamDirections.without(UP);
|
||||
}
|
||||
|
||||
if (controls.UI_DOWN) holdTmrDown += elapsed;
|
||||
if (controls.UI_DOWN_R)
|
||||
{
|
||||
holdTmrDown = 0;
|
||||
spamDirections = spamDirections.without(DOWN);
|
||||
}
|
||||
|
||||
if (controls.UI_LEFT) holdTmrLeft += elapsed;
|
||||
if (controls.UI_LEFT_R)
|
||||
{
|
||||
holdTmrLeft = 0;
|
||||
spamDirections = spamDirections.without(LEFT);
|
||||
}
|
||||
|
||||
if (controls.UI_RIGHT) holdTmrRight += elapsed;
|
||||
if (controls.UI_RIGHT_R)
|
||||
{
|
||||
holdTmrRight = 0;
|
||||
spamDirections = spamDirections.without(RIGHT);
|
||||
}
|
||||
|
||||
var initSpam = 0.5;
|
||||
|
||||
if (holdTmrUp >= initSpam) spamDirections = spamDirections.with(UP);
|
||||
if (holdTmrDown >= initSpam) spamDirections = spamDirections.with(DOWN);
|
||||
if (holdTmrLeft >= initSpam) spamDirections = spamDirections.with(LEFT);
|
||||
if (holdTmrRight >= initSpam) spamDirections = spamDirections.with(RIGHT);
|
||||
|
||||
if (controls.UI_UP_P)
|
||||
{
|
||||
cursorY -= 1;
|
||||
|
|
@ -841,6 +803,39 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
selectSound.play(true);
|
||||
}
|
||||
|
||||
if (controls.UI_UP) holdTmrUp += elapsed;
|
||||
if (controls.UI_UP_R || !controls.UI_UP)
|
||||
{
|
||||
holdTmrUp = 0;
|
||||
spamDirections = spamDirections.without(UP);
|
||||
}
|
||||
|
||||
if (controls.UI_DOWN) holdTmrDown += elapsed;
|
||||
if (controls.UI_DOWN_R || !controls.UI_DOWN)
|
||||
{
|
||||
holdTmrDown = 0;
|
||||
spamDirections = spamDirections.without(DOWN);
|
||||
}
|
||||
|
||||
if (controls.UI_LEFT) holdTmrLeft += elapsed;
|
||||
if (controls.UI_LEFT_R || !controls.UI_LEFT)
|
||||
{
|
||||
holdTmrLeft = 0;
|
||||
spamDirections = spamDirections.without(LEFT);
|
||||
}
|
||||
|
||||
if (controls.UI_RIGHT) holdTmrRight += elapsed;
|
||||
if (controls.UI_RIGHT_R || !controls.UI_RIGHT)
|
||||
{
|
||||
holdTmrRight = 0;
|
||||
spamDirections = spamDirections.without(RIGHT);
|
||||
}
|
||||
|
||||
if (holdTmrUp >= initSpam) spamDirections = spamDirections.with(UP);
|
||||
if (holdTmrDown >= initSpam) spamDirections = spamDirections.with(DOWN);
|
||||
if (holdTmrLeft >= initSpam) spamDirections = spamDirections.with(LEFT);
|
||||
if (holdTmrRight >= initSpam) spamDirections = spamDirections.with(RIGHT);
|
||||
|
||||
if (controls.BACK_P) goBack();
|
||||
}
|
||||
|
||||
|
|
@ -895,7 +890,7 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
|
||||
cursors.confirm();
|
||||
|
||||
FlxG.sound.play(Paths.sound('CS_confirm'));
|
||||
FunkinSound.playOnce(Paths.sound('CS_confirm'));
|
||||
|
||||
dispatchEvent(new CharacterSelectScriptEvent(CHARACTER_CONFIRMED, curChar));
|
||||
|
||||
|
|
@ -1124,8 +1119,7 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
return gridPosition;
|
||||
}
|
||||
|
||||
// Moved this code into a function because is now used twice
|
||||
function setCursorPosition(index:Int)
|
||||
function setCursorPosition(index:Int, instant:Bool = false):Void
|
||||
{
|
||||
var copy = 3;
|
||||
var yThing = -1;
|
||||
|
|
@ -1141,6 +1135,17 @@ class CharSelectSubState extends MusicBeatSubState
|
|||
// Look, I'd write better code but I had better aneurysms, my bad - Cheems
|
||||
cursorY = yThing;
|
||||
cursorX = xThing;
|
||||
|
||||
if (instant)
|
||||
{
|
||||
cursorLocIntended.x = (cursorFactor * cursorX) + (FlxG.width / 2) - cursors.main.width / 2;
|
||||
cursorLocIntended.y = (cursorFactor * cursorY) + (FlxG.height / 2) - cursors.main.height / 2;
|
||||
|
||||
cursorLocIntended.x += cursorOffsetX;
|
||||
cursorLocIntended.y += cursorOffsetY;
|
||||
|
||||
cursors.snapToLocation(cursorLocIntended);
|
||||
}
|
||||
}
|
||||
|
||||
function set_curChar(value:String):String
|
||||
|
|
|
|||
|
|
@ -386,12 +386,10 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
if (isViewDownscroll)
|
||||
{
|
||||
gridTiledSprite.y = -scrollPositionInPixels + (GRID_INITIAL_Y_POS);
|
||||
measureTicks.y = gridTiledSprite.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
gridTiledSprite.y = -scrollPositionInPixels + (GRID_INITIAL_Y_POS);
|
||||
measureTicks.y = gridTiledSprite.y;
|
||||
|
||||
for (member in audioWaveforms.members)
|
||||
{
|
||||
|
|
@ -2173,11 +2171,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
*/
|
||||
var notePreviewViewportBitmap:Null<BitmapData> = null;
|
||||
|
||||
/**
|
||||
* The IMAGE used for the measure ticks. Updated by ChartEditorThemeHandler.
|
||||
*/
|
||||
var measureTickBitmap:Null<BitmapData> = null;
|
||||
|
||||
/**
|
||||
* The IMAGE used for the offset ticks. Updated by ChartEditorThemeHandler.
|
||||
*/
|
||||
|
|
@ -2408,7 +2401,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
|
||||
// Setup the onClick listeners for the UI after it's been created.
|
||||
setupUIListeners();
|
||||
setupContextMenu();
|
||||
setupTurboKeyHandlers();
|
||||
|
||||
setupAutoSave();
|
||||
|
|
@ -2736,10 +2728,10 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
measureTicks = new ChartEditorMeasureTicks(this);
|
||||
var measureTicksWidth = (GRID_SIZE);
|
||||
measureTicks.x = gridTiledSprite.x - measureTicksWidth;
|
||||
measureTicks.y = MENU_BAR_HEIGHT + GRID_TOP_PAD;
|
||||
measureTicks.zIndex = 20;
|
||||
|
||||
add(measureTicks);
|
||||
|
||||
handleMeasureTickPosition();
|
||||
}
|
||||
|
||||
function buildNotePreview():Void
|
||||
|
|
@ -3376,21 +3368,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
// registerContextMenu(null, Paths.ui('chart-editor/context/test'));
|
||||
}
|
||||
|
||||
function setupContextMenu():Void
|
||||
{
|
||||
Screen.instance.registerEvent(MouseEvent.RIGHT_MOUSE_UP, function(e:MouseEvent) {
|
||||
var xPos = e.screenX;
|
||||
var yPos = e.screenY;
|
||||
onContextMenu(xPos, yPos);
|
||||
});
|
||||
}
|
||||
|
||||
function onContextMenu(xPos:Float, yPos:Float)
|
||||
{
|
||||
trace('User right clicked to open menu at (${xPos}, ${yPos})');
|
||||
// this.openDefaultContextMenu(xPos, yPos);
|
||||
}
|
||||
|
||||
function copySelection():Void
|
||||
{
|
||||
// Doesn't use a command because it's not undoable.
|
||||
|
|
@ -6447,6 +6424,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
if (gridTiledSprite != null)
|
||||
{
|
||||
gridTiledSprite.height = songLengthInPixels;
|
||||
measureTicks.setHeight(gridTiledSprite.height);
|
||||
}
|
||||
|
||||
// Remove any notes past the end of the song.
|
||||
|
|
@ -6802,32 +6780,16 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
|||
/**
|
||||
* Updates the measure tick bitmap forcibly to make sure it's correct.
|
||||
*/
|
||||
function updateTimeSignature():Void
|
||||
{
|
||||
this.updateMeasureTicks(true);
|
||||
gridTiledSprite.loadGraphic(gridBitmap);
|
||||
}
|
||||
function updateTimeSignature():Void {}
|
||||
|
||||
/**
|
||||
* Handle positioning the measure ticks sprite.
|
||||
*/
|
||||
function handleMeasureTickPosition():Void
|
||||
{
|
||||
this.updateMeasureTicks();
|
||||
var currentMeasureTime = Conductor.instance.getMeasureTimeInMs(Math.floor(Conductor.instance.getTimeInMeasures(scrollPositionInMs)));
|
||||
var currentMeasurePos = currentMeasureTime < 0 ? 0 : Conductor.instance.getTimeInSteps(currentMeasureTime) * GRID_SIZE;
|
||||
measureTicks.y = gridTiledSprite?.y + currentMeasurePos;
|
||||
// Make sure the measure tick bitmap does not past the grid itself.
|
||||
var totalMeasureTicksHeight:Float = currentMeasurePos + measureTickBitmap.height;
|
||||
if (totalMeasureTicksHeight >= songLengthInPixels)
|
||||
{
|
||||
var spillOver:Float = totalMeasureTicksHeight - songLengthInPixels;
|
||||
measureTicks.setClipRect(new FlxRect(0, 0, measureTickBitmap.width, measureTickBitmap.height - spillOver));
|
||||
}
|
||||
else
|
||||
{
|
||||
measureTicks.setClipRect(null);
|
||||
}
|
||||
// var currentMeasureTime = Conductor.instance.getMeasureTimeInMs(Math.floor(Conductor.instance.getTimeInMeasures(scrollPositionInMs)));
|
||||
// var currentMeasurePos = currentMeasureTime < 0 ? 0 : Conductor.instance.getTimeInSteps(currentMeasureTime) * GRID_SIZE;
|
||||
measureTicks.y = gridTiledSprite?.y;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,29 +1,63 @@
|
|||
package funkin.ui.debug.charting.components;
|
||||
|
||||
#if FEATURE_CHART_EDITOR
|
||||
import flixel.addons.display.FlxTiledSprite;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.graphics.FunkinSprite;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.geom.Rectangle;
|
||||
|
||||
/**
|
||||
* Handles the display of the measure ticks and numbers on the left side.
|
||||
*/
|
||||
@:nullSafety
|
||||
@:access(funkin.ui.debug.charting.ChartEditorState)
|
||||
class ChartEditorMeasureTicks extends FlxTypedSpriteGroup<FlxSprite>
|
||||
{
|
||||
/**
|
||||
* The owning ChartEditorState.
|
||||
*/
|
||||
var chartEditorState:ChartEditorState;
|
||||
|
||||
var measureTicksSprite:FlxSprite;
|
||||
var measureNumbers:Array<FlxText> = [];
|
||||
/**
|
||||
* The measure ticks underneath the numbers.
|
||||
*/
|
||||
var measureTicksSprite:FlxTiledSprite = new FlxTiledSprite(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE * 16);
|
||||
|
||||
public var measureLengthsInPixels:Array<Int> = [];
|
||||
/**
|
||||
* The numbers that display the current measure number.
|
||||
* This is a group so we can kill and recycle its members.
|
||||
*/
|
||||
var measureNumbers:FlxTypedSpriteGroup<FlxText> = new FlxTypedSpriteGroup<FlxText>();
|
||||
|
||||
/**
|
||||
* The horizontal bars over the grid at each measure tick.
|
||||
*/
|
||||
var measureDividers:FlxTypedSpriteGroup<FlxSprite> = new FlxTypedSpriteGroup<FlxSprite>();
|
||||
|
||||
/**
|
||||
* The positions of each measure tick, in pixels, relative to the start of the song.
|
||||
*/
|
||||
var measurePositions:Array<Float> = [];
|
||||
|
||||
/**
|
||||
* A map of the
|
||||
* @param value
|
||||
* @return Float
|
||||
*/
|
||||
override function set_y(value:Float):Float
|
||||
{
|
||||
var result = super.set_y(value);
|
||||
// Don't update if the value hasn't changed.
|
||||
if (this.y == value) return value;
|
||||
|
||||
updateMeasureNumber();
|
||||
super.set_y(value);
|
||||
|
||||
return result;
|
||||
updateMeasureNumbers();
|
||||
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public function new(chartEditorState:ChartEditorState)
|
||||
|
|
@ -32,59 +66,182 @@ class ChartEditorMeasureTicks extends FlxTypedSpriteGroup<FlxSprite>
|
|||
|
||||
this.chartEditorState = chartEditorState;
|
||||
|
||||
measureTicksSprite = new FlxSprite(0, 0);
|
||||
add(measureTicksSprite);
|
||||
add(measureNumbers);
|
||||
add(measureDividers);
|
||||
|
||||
for (i in 0...5)
|
||||
{
|
||||
var measureNumber = new FlxText(0, 0, ChartEditorState.GRID_SIZE, "1");
|
||||
measureNumber.setFormat(Paths.font('vcr.ttf'), 20, FlxColor.WHITE);
|
||||
measureNumber.borderStyle = FlxTextBorderStyle.OUTLINE;
|
||||
measureNumber.borderColor = FlxColor.BLACK;
|
||||
add(measureNumber);
|
||||
measureNumbers.push(measureNumber);
|
||||
}
|
||||
// Need these two lines or the ticks don't render before loading a chart!
|
||||
chartEditorState.updateMeasureTicks(true);
|
||||
reloadTickBitmap();
|
||||
}
|
||||
|
||||
public function reloadTickBitmap():Void
|
||||
{
|
||||
measureTicksSprite.loadGraphic(chartEditorState.measureTickBitmap);
|
||||
}
|
||||
|
||||
public function setClipRect(rect:Null<FlxRect>):Void
|
||||
{
|
||||
measureTicksSprite.clipRect = rect;
|
||||
buildMeasureTicksSprite();
|
||||
updateMeasureNumbers(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all 5 measure numbers, since that's the most we can really see at a time, even if barely.
|
||||
* Please excuse the horror you're about to witness.
|
||||
* Welp, you gotta go back in commits to see it now.
|
||||
* Set the overall height of the measure ticks.
|
||||
* @param height The desired height in pixels.
|
||||
*/
|
||||
function updateMeasureNumber()
|
||||
public function setHeight(height:Float):Void
|
||||
{
|
||||
if (measureLengthsInPixels.length == 0 || measureLengthsInPixels == null) return;
|
||||
measureTicksSprite.height = height;
|
||||
}
|
||||
|
||||
var currentMeasure:Int = Math.floor(Conductor.instance?.getTimeInMeasures(chartEditorState.scrollPositionInMs));
|
||||
for (i in 0...measureNumbers.length)
|
||||
public function updateTheme():Void
|
||||
{
|
||||
buildMeasureTicksSprite();
|
||||
updateMeasureNumbers(true);
|
||||
}
|
||||
|
||||
function buildMeasureTicksSprite():Void
|
||||
{
|
||||
var backingColor:FlxColor = switch (chartEditorState.currentTheme)
|
||||
{
|
||||
var measureNumber:FlxText = measureNumbers[i];
|
||||
if (measureNumber == null) continue;
|
||||
case Light: ChartEditorThemeHandler.MEASTURE_TICKS_BACKING_COLOR_LIGHT;
|
||||
case Dark: ChartEditorThemeHandler.MEASTURE_TICKS_BACKING_COLOR_DARK;
|
||||
default: ChartEditorThemeHandler.MEASTURE_TICKS_BACKING_COLOR_LIGHT;
|
||||
};
|
||||
var dividerColor:FlxColor = switch (chartEditorState.currentTheme)
|
||||
{
|
||||
case Light: ChartEditorThemeHandler.GRID_MEASURE_DIVIDER_COLOR_LIGHT;
|
||||
case Dark: ChartEditorThemeHandler.GRID_MEASURE_DIVIDER_COLOR_DARK;
|
||||
default: ChartEditorThemeHandler.GRID_MEASURE_DIVIDER_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
var measureNumberPosition = measureLengthsInPixels[i];
|
||||
measureNumber.y = this.y + measureNumberPosition;
|
||||
// TODO: This does NOT account for time signature, and always assumes 4/4!
|
||||
// Better to have the little lines not line up than be required to redraw the image every frame,
|
||||
// but we need to fix this eventually.
|
||||
var stepsPerMeasure:Int = Constants.STEPS_PER_BEAT * 4;
|
||||
|
||||
// Show the measure number only if it isn't beneath the end of the note grid.
|
||||
// Using measureNumber + 1 because the cut-off bar at the bottom is technically a bar, but it looks bad if a measure number shows up there.
|
||||
var fixedMeasureNumberValue = currentMeasure + i + 1;
|
||||
if (fixedMeasureNumberValue < Math.ceil(Conductor.instance?.getTimeInMeasures(chartEditorState.songLengthInMs)))
|
||||
measureNumber.text = '${fixedMeasureNumberValue}';
|
||||
// Start the bitmap with the basic gray color.
|
||||
var measureTickBitmap = new BitmapData(ChartEditorState.GRID_SIZE, ChartEditorState.GRID_SIZE * 16, true, backingColor);
|
||||
|
||||
// Draw the measure ticks at the top and bottom.
|
||||
measureTickBitmap.fillRect(new Rectangle(0, 0, ChartEditorState.GRID_SIZE, ChartEditorThemeHandler.MEASURE_TICKS_MEASURE_WIDTH / 2), dividerColor);
|
||||
var bottomTickY:Float = measureTickBitmap.height - (ChartEditorThemeHandler.MEASURE_TICKS_MEASURE_WIDTH / 2);
|
||||
measureTickBitmap.fillRect(new Rectangle(0, bottomTickY, ChartEditorState.GRID_SIZE, ChartEditorThemeHandler.MEASURE_TICKS_MEASURE_WIDTH / 2),
|
||||
dividerColor);
|
||||
|
||||
// Draw the beat ticks and dividers, and step ticks. No need for two seperate loops thankfully.
|
||||
for (i in 1...stepsPerMeasure)
|
||||
{
|
||||
if ((i % Constants.STEPS_PER_BEAT) == 0) // If we're on a beat, draw a beat tick and divider.
|
||||
{
|
||||
var beatTickY:Float = ChartEditorState.GRID_SIZE * i - (ChartEditorThemeHandler.MEASURE_TICKS_BEAT_WIDTH / 2);
|
||||
var beatTickLength:Float = ChartEditorState.GRID_SIZE * 2 / 3;
|
||||
measureTickBitmap.fillRect(new Rectangle(0, beatTickY, beatTickLength, ChartEditorThemeHandler.MEASURE_TICKS_BEAT_WIDTH), dividerColor);
|
||||
}
|
||||
else
|
||||
measureNumber.text = '';
|
||||
{
|
||||
// Draw a step tick.
|
||||
var stepTickY:Float = ChartEditorState.GRID_SIZE * i - (ChartEditorThemeHandler.MEASURE_TICKS_STEP_WIDTH / 2);
|
||||
var stepTickLength:Float = ChartEditorState.GRID_SIZE * 1 / 3;
|
||||
measureTickBitmap.fillRect(new Rectangle(0, stepTickY, stepTickLength, ChartEditorThemeHandler.MEASURE_TICKS_STEP_WIDTH), dividerColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, set the sprite to use the image.
|
||||
measureTicksSprite.loadGraphic(measureTickBitmap);
|
||||
|
||||
// Destroy these so they get rebuilt with the right theme later.
|
||||
measureNumbers.forEach(function(measureNumber:FlxText) {
|
||||
measureNumber.destroy();
|
||||
});
|
||||
measureNumbers.clear();
|
||||
// Destroy these so they get rebuilt with the right theme later.
|
||||
measureDividers.forEach(function(measureDivider:FlxSprite) {
|
||||
measureDivider.destroy();
|
||||
});
|
||||
measureDividers.clear();
|
||||
}
|
||||
|
||||
// The last measure number we updated the ticks on.
|
||||
var previousMeasure:Int = 0;
|
||||
|
||||
function updateMeasureNumbers(force:Bool = false):Void
|
||||
{
|
||||
if (chartEditorState == null || Conductor.instance == null) return;
|
||||
|
||||
// Get the time at the top of the screen, in measures, rounded down.
|
||||
// This is the earliest measure we'll need to display a tick for.
|
||||
var currentMeasure:Int = Math.floor(Conductor.instance.getTimeInMeasures(chartEditorState.scrollPositionInMs));
|
||||
if (previousMeasure == currentMeasure && !force) return;
|
||||
if (currentMeasure < 0) currentMeasure = previousMeasure = 0;
|
||||
|
||||
// Remove existing measure numbers.
|
||||
measureNumbers.forEachAlive(function(measureNumber:FlxText) {
|
||||
measureNumber.kill();
|
||||
});
|
||||
measureDividers.forEachAlive(function(measureDivider:FlxSprite) {
|
||||
measureDivider.kill();
|
||||
});
|
||||
|
||||
final ARBITRARY_LIMIT = 5;
|
||||
|
||||
for (i in 0...ARBITRARY_LIMIT)
|
||||
{
|
||||
var targetMeasure:Int = currentMeasure + i - 1;
|
||||
if (targetMeasure < 0) continue;
|
||||
|
||||
// TODO: This math is kinda awkward but DOES account for time signatures,
|
||||
// might want some cleanup though? Maybe add a `getMeasureTimeInSteps` method?
|
||||
var measureTimeInMs:Float = Conductor.instance.getMeasureTimeInMs(targetMeasure);
|
||||
var measureTimeInSteps:Float = Conductor.instance.getTimeInSteps(measureTimeInMs);
|
||||
var measureTimeInPixels:Float = measureTimeInSteps * ChartEditorState.GRID_SIZE;
|
||||
|
||||
var relativeMeasureTimeInPixels:Float = measureTimeInPixels + this.y;
|
||||
|
||||
final SCREEN_PADDING:Float = ChartEditorState.GRID_SIZE / 2;
|
||||
|
||||
// Above the visible area, keep going.
|
||||
if (relativeMeasureTimeInPixels < 0 - SCREEN_PADDING)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Below the visible area, quit it.
|
||||
if (relativeMeasureTimeInPixels > FlxG.height + SCREEN_PADDING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Else, display a number.
|
||||
|
||||
// Reuse an existing number. If we need a new number, create one with makeMeasureNumber().
|
||||
final REVIVE:Bool = true;
|
||||
var measureNumber = measureNumbers.recycle(makeMeasureNumber, false, REVIVE);
|
||||
|
||||
trace('Placing measure number. $relativeMeasureTimeInPixels -> $targetMeasure');
|
||||
|
||||
// Measures are base ZERO gah!
|
||||
final OFFSET = 2;
|
||||
measureNumber.text = '${targetMeasure + 1}';
|
||||
measureNumber.y = relativeMeasureTimeInPixels + OFFSET;
|
||||
measureNumber.x = this.x;
|
||||
|
||||
// Place a measure divider too.
|
||||
var measureDivider = measureDividers.recycle(makeMeasureDivider, false, REVIVE);
|
||||
measureDivider.y = relativeMeasureTimeInPixels - (ChartEditorThemeHandler.MEASURE_TICKS_MEASURE_WIDTH / 2);
|
||||
measureDivider.x = this.x + (measureTicksSprite.width);
|
||||
}
|
||||
}
|
||||
|
||||
function makeMeasureNumber():FlxText
|
||||
{
|
||||
var measureNumber = new FlxText(0, 0, ChartEditorState.GRID_SIZE, "1");
|
||||
measureNumber.setFormat(Paths.font('vcr.ttf'), 20, FlxColor.WHITE);
|
||||
measureNumber.borderStyle = FlxTextBorderStyle.OUTLINE;
|
||||
measureNumber.borderColor = FlxColor.BLACK;
|
||||
return measureNumber;
|
||||
}
|
||||
|
||||
function makeMeasureDivider():FlxSprite
|
||||
{
|
||||
var dividerColor:FlxColor = switch (chartEditorState.currentTheme)
|
||||
{
|
||||
case Light: ChartEditorThemeHandler.GRID_MEASURE_DIVIDER_COLOR_LIGHT;
|
||||
case Dark: ChartEditorThemeHandler.GRID_MEASURE_DIVIDER_COLOR_DARK;
|
||||
default: ChartEditorThemeHandler.GRID_MEASURE_DIVIDER_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
var measureDivider = new FunkinSprite().makeSolidColor(ChartEditorState.GRID_SIZE * ChartEditorThemeHandler.TOTAL_COLUMN_COUNT,
|
||||
ChartEditorThemeHandler.MEASURE_TICKS_MEASURE_WIDTH, dividerColor);
|
||||
return measureDivider;
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
|
|
|||
|
|
@ -25,35 +25,37 @@ class ChartEditorThemeHandler
|
|||
static final BACKGROUND_COLOR_DARK:FlxColor = 0xFF361E60;
|
||||
|
||||
// Color 1 of the grid pattern. Alternates with Color 2.
|
||||
static final GRID_COLOR_1_LIGHT:FlxColor = 0xFFE7E6E6;
|
||||
static final GRID_COLOR_1_DARK:FlxColor = 0xFF181919;
|
||||
public static final GRID_COLOR_1_LIGHT:FlxColor = 0xFFE7E6E6;
|
||||
public static final GRID_COLOR_1_DARK:FlxColor = 0xFF181919;
|
||||
|
||||
// Color 2 of the grid pattern. Alternates with Color 1.
|
||||
static final GRID_COLOR_2_LIGHT:FlxColor = 0xFFF8F8F8;
|
||||
static final GRID_COLOR_2_DARK:FlxColor = 0xFF202020;
|
||||
public static final GRID_COLOR_2_LIGHT:FlxColor = 0xFFF8F8F8;
|
||||
public static final GRID_COLOR_2_DARK:FlxColor = 0xFF202020;
|
||||
|
||||
// Color 3 of the grid pattern. Borders the other colors.
|
||||
static final GRID_COLOR_3_LIGHT:FlxColor = 0xFFD9D5D5;
|
||||
static final GRID_COLOR_3_DARK:FlxColor = 0xFF262A2A;
|
||||
public static final GRID_COLOR_3_LIGHT:FlxColor = 0xFFD9D5D5;
|
||||
public static final GRID_COLOR_3_DARK:FlxColor = 0xFF262A2A;
|
||||
|
||||
// Vertical divider between characters.
|
||||
static final GRID_STRUMLINE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111;
|
||||
static final GRID_STRUMLINE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4;
|
||||
public static final GRID_STRUMLINE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111;
|
||||
public static final GRID_STRUMLINE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4;
|
||||
static final GRID_STRUMLINE_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH;
|
||||
|
||||
// Horizontal divider between measures.
|
||||
static final GRID_MEASURE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111;
|
||||
static final GRID_MEASURE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4;
|
||||
public static final GRID_MEASURE_DIVIDER_COLOR_LIGHT:FlxColor = 0xFF111111;
|
||||
public static final GRID_MEASURE_DIVIDER_COLOR_DARK:FlxColor = 0xFFC4C4C4;
|
||||
static final GRID_MEASURE_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH;
|
||||
|
||||
// Horizontal divider between beats.
|
||||
static final GRID_BEAT_DIVIDER_COLOR_LIGHT:FlxColor = 0xFFC1C1C1;
|
||||
static final GRID_BEAT_DIVIDER_COLOR_DARK:FlxColor = 0xFF848484;
|
||||
static final GRID_BEAT_DIVIDER_WIDTH:Float = ChartEditorState.GRID_SELECTION_BORDER_WIDTH;
|
||||
public static final MEASTURE_TICKS_BACKING_COLOR_LIGHT:FlxColor = 0xFFC1C1C1;
|
||||
public static final MEASTURE_TICKS_BACKING_COLOR_DARK:FlxColor = 0xFF484848;
|
||||
|
||||
// Border on the square highlighting selected notes.
|
||||
static final SELECTION_SQUARE_BORDER_COLOR_LIGHT:FlxColor = 0xFF339933;
|
||||
static final SELECTION_SQUARE_BORDER_COLOR_DARK:FlxColor = 0xFF339933;
|
||||
|
||||
/**
|
||||
* The width of the opaque border around the square highlighting selected notes.
|
||||
*/
|
||||
public static final SELECTION_SQUARE_BORDER_WIDTH:Int = 1;
|
||||
|
||||
// Fill on the square highlighting selected notes.
|
||||
|
|
@ -65,6 +67,11 @@ class ChartEditorThemeHandler
|
|||
static final PLAYHEAD_BLOCK_BORDER_COLOR:FlxColor = 0xFF9D0011;
|
||||
static final PLAYHEAD_BLOCK_FILL_COLOR:FlxColor = 0xFFBD0231;
|
||||
|
||||
// Lines on the measure ticks.
|
||||
public static final MEASURE_TICKS_MEASURE_WIDTH:Int = 6;
|
||||
public static final MEASURE_TICKS_BEAT_WIDTH:Int = 4;
|
||||
public static final MEASURE_TICKS_STEP_WIDTH:Int = 2;
|
||||
|
||||
// Border on the square over the note preview.
|
||||
static final NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_LIGHT = 0xFFF8A657;
|
||||
static final NOTE_PREVIEW_VIEWPORT_BORDER_COLOR_DARK = 0xFFF8A657;
|
||||
|
|
@ -73,10 +80,7 @@ class ChartEditorThemeHandler
|
|||
static final NOTE_PREVIEW_VIEWPORT_FILL_COLOR_LIGHT = 0x80F8A657;
|
||||
static final NOTE_PREVIEW_VIEWPORT_FILL_COLOR_DARK = 0x80F8A657;
|
||||
|
||||
static final TOTAL_COLUMN_COUNT:Int = ChartEditorState.STRUMLINE_SIZE * 2 + 1;
|
||||
|
||||
// Used for checking in updateMeasureTicks() so we don't have to redraw it everytime if the current measure is the same as before.
|
||||
static var previousMeasure:Int = -69;
|
||||
public static final TOTAL_COLUMN_COUNT:Int = ChartEditorState.STRUMLINE_SIZE * 2 + 1;
|
||||
|
||||
/**
|
||||
* When the theme is changed, this function updates all of the UI elements to match the new theme.
|
||||
|
|
@ -86,10 +90,10 @@ class ChartEditorThemeHandler
|
|||
{
|
||||
updateBackground(state);
|
||||
updateGridBitmap(state);
|
||||
updateMeasureTicks(state);
|
||||
updateOffsetTicks(state);
|
||||
updateSelectionSquare(state);
|
||||
updateNotePreview(state);
|
||||
updateMeasureTicks(state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -127,6 +131,13 @@ class ChartEditorThemeHandler
|
|||
default: GRID_COLOR_2_LIGHT;
|
||||
};
|
||||
|
||||
var dividerColor:FlxColor = switch (state.currentTheme)
|
||||
{
|
||||
case Light: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT;
|
||||
case Dark: GRID_STRUMLINE_DIVIDER_COLOR_DARK;
|
||||
default: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT;
|
||||
}
|
||||
|
||||
// Draw the base grid.
|
||||
|
||||
// 2 * (Strumline Size) + 1 grid squares wide, by (4 * quarter notes per measure) grid squares tall.
|
||||
|
|
@ -161,7 +172,7 @@ class ChartEditorThemeHandler
|
|||
ChartEditorState.GRID_SELECTION_BORDER_WIDTH),
|
||||
selectionBorderColor);
|
||||
|
||||
// Selection border at left.
|
||||
// Selection border at far left.
|
||||
state.gridBitmap.fillRect(new Rectangle(-(ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0, ChartEditorState.GRID_SELECTION_BORDER_WIDTH,
|
||||
state.gridBitmap.height),
|
||||
selectionBorderColor);
|
||||
|
|
@ -169,12 +180,14 @@ class ChartEditorThemeHandler
|
|||
// Selection borders vertically along the middle.
|
||||
for (i in 1...TOTAL_COLUMN_COUNT)
|
||||
{
|
||||
var isStrumlineColumn:Bool = (i % ChartEditorState.STRUMLINE_SIZE == 0) && (i > 0);
|
||||
|
||||
state.gridBitmap.fillRect(new Rectangle((ChartEditorState.GRID_SIZE * i) - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0,
|
||||
ChartEditorState.GRID_SELECTION_BORDER_WIDTH, state.gridBitmap.height),
|
||||
selectionBorderColor);
|
||||
isStrumlineColumn ? dividerColor : selectionBorderColor);
|
||||
}
|
||||
|
||||
// Selection border at right.
|
||||
// Selection border at far right.
|
||||
state.gridBitmap.fillRect(new Rectangle(state.gridBitmap.width - (ChartEditorState.GRID_SELECTION_BORDER_WIDTH / 2), 0,
|
||||
ChartEditorState.GRID_SELECTION_BORDER_WIDTH, state.gridBitmap.height),
|
||||
selectionBorderColor);
|
||||
|
|
@ -186,115 +199,6 @@ class ChartEditorThemeHandler
|
|||
// Else, gridTiledSprite will be built later.
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the measure ticks left of the grid. This also includes the horizontal beat and measure dividers as well as the vertical strumline dividers.
|
||||
*/
|
||||
public static function updateMeasureTicks(state:ChartEditorState, force:Bool = false):Void
|
||||
{
|
||||
var measureTickWidth:Int = 6;
|
||||
var beatTickWidth:Int = 4;
|
||||
var stepTickWidth:Int = 2;
|
||||
var measuresToCheck:Int = 5;
|
||||
|
||||
var currentMeasure:Int = Math.floor(Conductor.instance.getTimeInMeasures(state.scrollPositionInMs));
|
||||
if (previousMeasure == currentMeasure && !force) return;
|
||||
if (currentMeasure < 0) currentMeasure = previousMeasure = 0;
|
||||
|
||||
// Make the bitmap.
|
||||
var ticksWidth:Int = Std.int(ChartEditorState.GRID_SIZE);
|
||||
var linesWidth:Int = Std.int(ChartEditorState.GRID_SIZE * TOTAL_COLUMN_COUNT);
|
||||
state.measureTickBitmap = new BitmapData(ticksWidth + linesWidth, 6144, true, 0x00FFFFFF);
|
||||
|
||||
// Draw the vertical grey sidebar.
|
||||
state.measureTickBitmap.fillRect(new Rectangle(0, 0, ticksWidth, 6144), GRID_BEAT_DIVIDER_COLOR_DARK);
|
||||
|
||||
// Then draw the ticks and dividers themselves.
|
||||
var totalTicksHeight:Int = 0;
|
||||
var measureLengthsInPixels:Array<Int> = [];
|
||||
for (measure in 0...measuresToCheck)
|
||||
{
|
||||
var currentTimeInMs:Float = Conductor.instance.getMeasureTimeInMs(currentMeasure + measure)
|
||||
+ 10; // Manual adjustment as it can get the wrong time change without this.
|
||||
var currentTimeChange:SongTimeChange = Conductor.instance.getTimeChange(currentTimeInMs);
|
||||
var stepsPerMeasure:Int = Constants.STEPS_PER_BEAT * currentTimeChange.timeSignatureNum;
|
||||
var ticksHeight:Int = Std.int(ChartEditorState.GRID_SIZE * stepsPerMeasure);
|
||||
|
||||
// Draw horizontal dividers between the measures.
|
||||
var gridMeasureDividerColor:FlxColor = switch (state.currentTheme)
|
||||
{
|
||||
case Light: GRID_MEASURE_DIVIDER_COLOR_LIGHT;
|
||||
case Dark: GRID_MEASURE_DIVIDER_COLOR_DARK;
|
||||
default: GRID_MEASURE_DIVIDER_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
// Divider at top
|
||||
state.measureTickBitmap.fillRect(new Rectangle(ticksWidth, totalTicksHeight, linesWidth, GRID_MEASURE_DIVIDER_WIDTH / 2), gridMeasureDividerColor);
|
||||
// Divider at bottom
|
||||
var dividerLineBY:Float = ticksHeight - (GRID_MEASURE_DIVIDER_WIDTH / 2);
|
||||
state.measureTickBitmap.fillRect(new Rectangle(ticksWidth, totalTicksHeight + dividerLineBY, linesWidth, GRID_MEASURE_DIVIDER_WIDTH / 2),
|
||||
gridMeasureDividerColor);
|
||||
|
||||
// Measure ticks.
|
||||
state.measureTickBitmap.fillRect(new Rectangle(0, totalTicksHeight, ticksWidth, measureTickWidth / 2), GRID_MEASURE_DIVIDER_COLOR_LIGHT);
|
||||
var bottomTickY:Float = ticksHeight - (measureTickWidth / 2);
|
||||
state.measureTickBitmap.fillRect(new Rectangle(0, totalTicksHeight + bottomTickY, ticksWidth, measureTickWidth / 2), GRID_MEASURE_DIVIDER_COLOR_LIGHT);
|
||||
|
||||
// Draw horizontal dividers between the beats, this is done inside the following loop.
|
||||
var gridBeatDividerColor:FlxColor = switch (state.currentTheme)
|
||||
{
|
||||
case Light: GRID_BEAT_DIVIDER_COLOR_LIGHT;
|
||||
case Dark: GRID_BEAT_DIVIDER_COLOR_DARK;
|
||||
default: GRID_BEAT_DIVIDER_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
// Draw the beat ticks and dividers, and step ticks. No need for two seperate loops thankfully.
|
||||
for (i in 1...stepsPerMeasure)
|
||||
{
|
||||
if ((i % Constants.STEPS_PER_BEAT) == 0) // If we're on a beat, draw a beat tick and divider.
|
||||
{
|
||||
var beatTickY:Float = totalTicksHeight + ChartEditorState.GRID_SIZE * i - (beatTickWidth / 2);
|
||||
var beatTickLength:Float = ticksWidth * 2 / 3;
|
||||
state.measureTickBitmap.fillRect(new Rectangle(0, beatTickY, beatTickLength, beatTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT);
|
||||
|
||||
// Horizontal divider.
|
||||
state.measureTickBitmap.fillRect(new Rectangle(ticksWidth, totalTicksHeight + (ChartEditorState.GRID_SIZE * i) - (GRID_BEAT_DIVIDER_WIDTH / 2),
|
||||
linesWidth, GRID_BEAT_DIVIDER_WIDTH),
|
||||
gridBeatDividerColor);
|
||||
}
|
||||
else // Else, draw a step tick.
|
||||
{
|
||||
var stepTickY:Float = totalTicksHeight + ChartEditorState.GRID_SIZE * i - (stepTickWidth / 2);
|
||||
var stepTickLength:Float = ticksWidth * 1 / 3;
|
||||
state.measureTickBitmap.fillRect(new Rectangle(0, stepTickY, stepTickLength, stepTickWidth), GRID_MEASURE_DIVIDER_COLOR_LIGHT);
|
||||
}
|
||||
}
|
||||
measureLengthsInPixels.push(totalTicksHeight);
|
||||
totalTicksHeight += ticksHeight;
|
||||
}
|
||||
previousMeasure = currentMeasure;
|
||||
|
||||
// Finally, draw vertical dividers between the strumlines.
|
||||
var gridStrumlineDividerColor:FlxColor = switch (state.currentTheme)
|
||||
{
|
||||
case Light: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT;
|
||||
case Dark: GRID_STRUMLINE_DIVIDER_COLOR_DARK;
|
||||
default: GRID_STRUMLINE_DIVIDER_COLOR_LIGHT;
|
||||
};
|
||||
|
||||
// Divider at 1 * (Strumline Size)
|
||||
var dividerLineAX:Float = ticksWidth + ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE) - (GRID_STRUMLINE_DIVIDER_WIDTH / 2);
|
||||
state.measureTickBitmap.fillRect(new Rectangle(dividerLineAX, 0, GRID_STRUMLINE_DIVIDER_WIDTH, state.measureTickBitmap.height), gridStrumlineDividerColor);
|
||||
// Divider at 2 * (Strumline Size)
|
||||
var dividerLineBX:Float = ticksWidth + ChartEditorState.GRID_SIZE * (ChartEditorState.STRUMLINE_SIZE * 2) - (GRID_STRUMLINE_DIVIDER_WIDTH / 2);
|
||||
state.measureTickBitmap.fillRect(new Rectangle(dividerLineBX, 0, GRID_STRUMLINE_DIVIDER_WIDTH, state.measureTickBitmap.height), gridStrumlineDividerColor);
|
||||
|
||||
if (state.measureTicks != null)
|
||||
{
|
||||
state.measureTicks.measureLengthsInPixels = measureLengthsInPixels;
|
||||
state.measureTicks.reloadTickBitmap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Horizontal offset ticks.
|
||||
*/
|
||||
|
|
@ -306,7 +210,7 @@ class ChartEditorThemeHandler
|
|||
var ticksWidth:Int = Std.int(ChartEditorState.GRID_SIZE * Conductor.instance.stepsPerMeasure); // 10 minor ticks wide.
|
||||
var ticksHeight:Int = Std.int(ChartEditorState.GRID_SIZE); // 1 grid squares tall.
|
||||
state.offsetTickBitmap = new BitmapData(ticksWidth, ticksHeight, true);
|
||||
state.offsetTickBitmap.fillRect(new Rectangle(0, 0, ticksWidth, ticksHeight), GRID_BEAT_DIVIDER_COLOR_DARK);
|
||||
state.offsetTickBitmap.fillRect(new Rectangle(0, 0, ticksWidth, ticksHeight), 0xFFC4C4C4);
|
||||
|
||||
// Draw the major ticks.
|
||||
var leftTickX:Float = 0;
|
||||
|
|
@ -420,6 +324,11 @@ class ChartEditorThemeHandler
|
|||
}
|
||||
}
|
||||
|
||||
static function updateMeasureTicks(state:ChartEditorState):Void
|
||||
{
|
||||
state.measureTicks?.updateTheme();
|
||||
}
|
||||
|
||||
public static function buildPlayheadBlock():FlxSprite
|
||||
{
|
||||
var playheadBlock:FlxSprite = new FlxSprite();
|
||||
|
|
|
|||
|
|
@ -1,125 +1,95 @@
|
|||
package funkin.ui.freeplay;
|
||||
|
||||
import flixel.FlxObject;
|
||||
import flixel.group.FlxSpriteGroup;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.util.FlxSort;
|
||||
import flixel.FlxSprite;
|
||||
import flixel.util.FlxDestroyUtil;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.FlxSort;
|
||||
|
||||
// its kinda like marqeee html lol!
|
||||
@:nullSafety
|
||||
class BGScrollingText extends FlxSpriteGroup
|
||||
class BGScrollingText extends FlxText
|
||||
{
|
||||
var grpTexts:FlxTypedSpriteGroup<FlxSprite>;
|
||||
var sourceText:FlxText;
|
||||
var _textPositions:Array<FlxPoint> = [];
|
||||
var _positionCache:FlxPoint = FlxPoint.get();
|
||||
|
||||
public var widthShit:Float = FlxG.width;
|
||||
public var placementOffset:Float = 20;
|
||||
public var speed:Float = 1;
|
||||
public var size(default, set):Int = 48;
|
||||
|
||||
public var funnyColor(default, set):FlxColor = 0xFFFFFFFF;
|
||||
@:deprecated("Use color instead")
|
||||
public var funnyColor(get, set):FlxColor;
|
||||
|
||||
function get_funnyColor():FlxColor
|
||||
return color;
|
||||
|
||||
function set_funnyColor(c:FlxColor):FlxColor
|
||||
{
|
||||
return color = c;
|
||||
}
|
||||
|
||||
public function new(x:Float, y:Float, text:String, widthShit:Float = 100, ?bold:Bool = false, ?size:Int = 48)
|
||||
{
|
||||
super(x, y);
|
||||
|
||||
grpTexts = new FlxTypedSpriteGroup<FlxSprite>();
|
||||
super(x, y, 0, text, size);
|
||||
_positionCache = FlxPoint.get(x, y);
|
||||
font = "5by7";
|
||||
this.bold = bold ?? false;
|
||||
|
||||
this.widthShit = widthShit;
|
||||
|
||||
// Only keep one FlxText graphic at a time for batching
|
||||
sourceText = new FlxText(0, 0, 0, text, size ?? this.size);
|
||||
sourceText.font = "5by7";
|
||||
sourceText.bold = bold ?? false;
|
||||
|
||||
@:privateAccess
|
||||
sourceText.regenGraphic();
|
||||
regenGraphic();
|
||||
|
||||
var needed:Int = Math.ceil(widthShit / sourceText.frameWidth) + 1;
|
||||
var needed:Int = Math.ceil(widthShit / frameWidth) + 1;
|
||||
|
||||
for (i in 0...needed)
|
||||
{
|
||||
var coolText = new FlxSprite((i * sourceText.frameWidth) + (i * 20), 0);
|
||||
grpTexts.add(coolText);
|
||||
}
|
||||
|
||||
if (size != null) this.size = size;
|
||||
|
||||
add(grpTexts);
|
||||
}
|
||||
|
||||
function reloadGraphics()
|
||||
{
|
||||
if (grpTexts != null)
|
||||
{
|
||||
@:privateAccess
|
||||
sourceText.regenGraphic();
|
||||
grpTexts.forEach(function(txt:FlxSprite) {
|
||||
txt.loadGraphic(sourceText.graphic);
|
||||
txt.updateHitbox();
|
||||
});
|
||||
_textPositions.push(FlxPoint.get((i * frameWidth) + (i * 20), 0));
|
||||
}
|
||||
}
|
||||
|
||||
function set_size(value:Int):Int
|
||||
override public function update(elapsed:Float):Void
|
||||
{
|
||||
sourceText.size = value;
|
||||
reloadGraphics();
|
||||
this.size = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
function set_funnyColor(value:FlxColor):FlxColor
|
||||
{
|
||||
sourceText.color = value;
|
||||
reloadGraphics();
|
||||
this.funnyColor = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
override public function update(elapsed:Float)
|
||||
{
|
||||
for (txt in grpTexts.group)
|
||||
{
|
||||
if (txt == null) continue;
|
||||
txt.x -= 1 * (speed * (elapsed / (1 / 60)));
|
||||
|
||||
if (speed > 0)
|
||||
{
|
||||
if (txt.x < -txt.frameWidth)
|
||||
{
|
||||
txt.x = grpTexts.group.members[grpTexts.length - 1].x + grpTexts.group.members[grpTexts.length - 1].frameWidth + placementOffset;
|
||||
|
||||
sortTextShit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (txt.x > txt.frameWidth * 2)
|
||||
{
|
||||
txt.x = grpTexts.group.members[0].x - grpTexts.group.members[0].frameWidth - placementOffset;
|
||||
|
||||
sortTextShit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.update(elapsed);
|
||||
|
||||
for (txtPosition in _textPositions)
|
||||
{
|
||||
if (txtPosition == null) continue;
|
||||
txtPosition.x -= 1 * (speed * (elapsed / (1 / 60)));
|
||||
|
||||
if (speed > 0) // Going left
|
||||
{
|
||||
if (txtPosition.x < -frameWidth)
|
||||
{
|
||||
txtPosition.x = _textPositions[_textPositions.length - 1].x + frameWidth + placementOffset;
|
||||
sortTextShit();
|
||||
}
|
||||
}
|
||||
else // Going right
|
||||
{
|
||||
if (txtPosition.x > frameWidth * 2)
|
||||
{
|
||||
txtPosition.x = _textPositions[0].x - frameWidth - placementOffset;
|
||||
sortTextShit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override public function draw():Void
|
||||
{
|
||||
_positionCache.set(x, y);
|
||||
for (position in _textPositions)
|
||||
{
|
||||
setPosition(_positionCache.x + position.x, _positionCache.y + position.y);
|
||||
super.draw();
|
||||
}
|
||||
setPosition(_positionCache.x, _positionCache.y);
|
||||
}
|
||||
|
||||
function sortTextShit():Void
|
||||
{
|
||||
grpTexts.sort(function(Order:Int, Obj1:FlxObject, Obj2:FlxObject) {
|
||||
return FlxSort.byValues(Order, Obj1.x, Obj2.x);
|
||||
_textPositions.sort(function(Obj1:FlxPoint, Obj2:FlxPoint) {
|
||||
return FlxSort.byValues(FlxSort.ASCENDING, Obj1.x, Obj2.x);
|
||||
});
|
||||
}
|
||||
|
||||
override function destroy():Void
|
||||
{
|
||||
super.destroy();
|
||||
sourceText = FlxDestroyUtil.destroy(sourceText);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,27 +131,27 @@ class NewCharacterCard extends BackingCard
|
|||
darkBg = new FlxSprite(0, 0).loadGraphic(bitmap);
|
||||
add(darkBg);
|
||||
|
||||
friendFoe.funnyColor = 0xFF139376;
|
||||
friendFoe.color = 0xFF139376;
|
||||
friendFoe.speed = -4;
|
||||
add(friendFoe);
|
||||
|
||||
newUnlock1.funnyColor = 0xFF99BDF2;
|
||||
newUnlock1.color = 0xFF99BDF2;
|
||||
newUnlock1.speed = 2;
|
||||
add(newUnlock1);
|
||||
|
||||
waiting.funnyColor = 0xFF40EA84;
|
||||
waiting.color = 0xFF40EA84;
|
||||
waiting.speed = -2;
|
||||
add(waiting);
|
||||
|
||||
newUnlock2.funnyColor = 0xFF99BDF2;
|
||||
newUnlock2.color = 0xFF99BDF2;
|
||||
newUnlock2.speed = 2;
|
||||
add(newUnlock2);
|
||||
|
||||
friendFoe2.funnyColor = 0xFF139376;
|
||||
friendFoe2.color = 0xFF139376;
|
||||
friendFoe2.speed = -4;
|
||||
add(friendFoe2);
|
||||
|
||||
newUnlock3.funnyColor = 0xFF99BDF2;
|
||||
newUnlock3.color = 0xFF99BDF2;
|
||||
newUnlock3.speed = 2;
|
||||
add(newUnlock3);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue