From 1d5542ba4c2a830b04fd6f8dd562cafd6f312d2f Mon Sep 17 00:00:00 2001 From: CharlesCatYT <62410083+CharlesCatYT@users.noreply.github.com> Date: Wed, 26 Jun 2024 00:53:09 +0000 Subject: [PATCH] expanded score text WHATTT YOOOO --- .gitattributes | 11 +- source/funkin/Preferences.hx | 51 ++-- .../data/song/importer/FNFLegacyData.hx | 20 ++ source/funkin/play/PlayState.hx | 257 +++++++++++++++--- source/funkin/play/notes/NoteSprite.hx | 4 +- source/funkin/save/Save.hx | 7 + source/funkin/ui/MusicBeatState.hx | 3 +- .../ui/debug/charting/ChartEditorState.hx | 2 +- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- source/funkin/ui/mainmenu/MainMenuState.hx | 2 +- source/funkin/ui/options/PreferencesMenu.hx | 5 +- .../ui/transition/preload/FunkinPreloader.hx | 5 +- 12 files changed, 307 insertions(+), 62 deletions(-) diff --git a/.gitattributes b/.gitattributes index 94f480de94..d6ab7b082a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,10 @@ -* text=auto eol=lf \ No newline at end of file +* text=auto eol=lf + +*.hxc linguist-language=Haxe +*.hscript linguist-language=Haxe +*.hx linguist-language=Haxe +*.hxs linguist-language=Haxe +*.xml linguist-language=XML +*.js linguist-language=JavaScript +*.md linguist-language=Markdown +*.json linguist-language=JSON diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index eac394cca7..735a8485c7 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -7,21 +7,6 @@ import funkin.save.Save; */ class Preferences { - /** - * The framerate. - * @default `60` - */ - public static var framerate(get, set):Int; - - static function get_framerate():Int - { - #if web - return 60; - #else - return Save?.instance?.options?.framerate ?? 60; - #end - } - /** * Whenever to display a splash animation when perfectly hitting a note. * @default `true` @@ -41,6 +26,21 @@ class Preferences return value; } + /** + * The framerate. + * @default `60` + */ + public static var framerate(get, set):Int; + + static function get_framerate():Int + { + #if web + return 60; + #else + return Save?.instance?.options?.framerate ?? 60; + #end + } + static function set_framerate(value:Int):Int { #if web @@ -170,6 +170,25 @@ class Preferences return value; } + /** + * If disabled, the score text gets simplified to just the score display part. + * @default `false` + */ + public static var expandedScore(get, set):Bool; + + static function get_expandedScore():Bool + { + return Save?.instance?.options?.expandedScore; + } + + static function set_expandedScore(value:Bool):Bool + { + var save:Save = Save.instance; + save.options.expandedScore = value; + save.flush(); + return value; + } + /** * If enabled, an FPS and memory counter will be displayed even if this is not a debug build. * @default `false` @@ -233,7 +252,7 @@ class Preferences save.flush(); return value; } - + /** * Loads the user's preferences from the save data and apply them. */ diff --git a/source/funkin/data/song/importer/FNFLegacyData.hx b/source/funkin/data/song/importer/FNFLegacyData.hx index 52380d3445..56d3dff74c 100644 --- a/source/funkin/data/song/importer/FNFLegacyData.hx +++ b/source/funkin/data/song/importer/FNFLegacyData.hx @@ -16,12 +16,30 @@ class LegacySongData { public var player1:String; // Boyfriend public var player2:String; // Opponent + @:optional + public var gfVersion:String; // For Girlfriend (Psych Engine, i think) + @:optional + public var player3:String; // Deprecated in Psych, idk @:jcustomparse(funkin.data.DataParse.eitherLegacyScrollSpeeds) public var speed:Either; @:optional public var stageDefault:Null; public var bpm:Float; + // FOR CHARTS MADE IN SOME ENGINES LIKE PSYCH: + // (Won't be actually parsed since these are here solely to get Psych charts working.) + @:optional + public var stage:String; + @:optional + public var arrowSkin:String; + @:optional + public var splashSkin:String; + @:optional + public var validScore:Bool; + // @:optional + // public var events:Array; For some reason, the compiler doesn't like this shit. Thanks Haxe, very cool. + @:optional + public var needsVoices:Bool; @:jcustomparse(funkin.data.DataParse.eitherLegacyNoteData) public var notes:Either, LegacyNoteData>; @@ -95,6 +113,8 @@ typedef LegacyNoteSection = // BPM changes public var ?changeBPM:Bool; public var ?bpm:Float; + public var ?gfSection:Bool; + public var ?altAnim:Bool; } /** diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index ec07b4944f..91b591865f 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -198,7 +198,7 @@ class PlayState extends MusicBeatSubState /** * Resets the Characters and their sprites. * Gets disabled once resetting happens. - **/ + **/ public var needsCharacterReset:Bool = false; /** @@ -223,6 +223,57 @@ class PlayState extends MusicBeatSubState */ public var songScore:Int = 0; + /** + * The player's current amount of misses. + */ + public var songMisses:Int = 0; + + /** + * The player's current accuracy. + */ + public var ratingPercent:Float; + + /** + * The player's current rating. + */ + public var ratingName:String = "?"; + + /** + * The player's current FC rating. + */ + public var ratingFC:String = "N/A"; + + /** + * The current percentage for a song. + */ + public var songPercent:Float = 0; + + /** + * The amount of notes the player has hit. + */ + public var totalNotesHit:Float = 0.0; + + /** + * The amount of notes in total. + */ + public var totalNotesPlayed:Int = 0; + + /** + * The values for the rating system. + */ + public static var ratingStuff:Array = [ + ['You Suck!', 0.2], // From 0% to 19%. + ['F', 0.4], // From 20% to 39%. + ['D', 0.5], // From 40% to 49%. + ['C', 0.6], // From 50% to 59%. + ['B', 0.69], // From 60% to 68%. + ['Nice', 0.7], // 69%. Nice (: + ['A', 0.8], // From 70% to 79%. + ['S', 0.9], // From 80% to 89%. + ['X', 1], // From 90% to 99%. + ['PERFECT!!', 1] // The value on this one isn't used actually, since "PERFECT!!" is always 1. + ]; + /** * Start at this point in the song once the countdown is done. * For example, if `startTimestamp` is `30000`, the song will start at the 30 second mark. @@ -443,6 +494,11 @@ class PlayState extends MusicBeatSubState */ var startingSong:Bool = false; + /** + * True if the song has finished playing. + */ + var endingSong:Bool = false; + /** * Track if we currently have the music paused for a Pause substate, so we can unpause it when we return. */ @@ -474,7 +530,6 @@ class PlayState extends MusicBeatSubState /** * RENDER OBJECTS */ - /** * What? */ @@ -497,6 +552,11 @@ class PlayState extends MusicBeatSubState */ public var healthBarBG:FunkinSprite; + /** + * The FlxText which displays the judgements, NPS, etc. + */ + var judgementCounter:FlxText; + /** * The health icon representing the player. */ @@ -685,14 +745,20 @@ class PlayState extends MusicBeatSubState // This state receives draw calls even when a substate is active. this.persistentDraw = true; - // Stop any pre-existing music. - if (!overrideMusic && FlxG.sound.music != null) FlxG.sound.music.stop(); - - // Prepare the current song's instrumental and vocals to be played. - if (!overrideMusic && currentChart != null) + if (!overrideMusic) { - currentChart.cacheInst(); - currentChart.cacheVocals(); + // Stop any pre-existing music. + if (FlxG.sound.music != null) FlxG.sound.music.stop(); + + // Prepare the current song's instrumental and vocals to be played. + if (currentChart != null) + { + currentChart.cacheInst(); + currentChart.cacheVocals(); + + currentChart.playInst(0.0, false); + FlxG.sound.music.stop(); + } } // Prepare the Conductor. @@ -721,6 +787,18 @@ class PlayState extends MusicBeatSubState } initStrumlines(); + // Initialize the judgements, judgement counter, and combo meter. + judgementCounter = new FlxText(20, 0, 0, "", 20); + judgementCounter.setFormat(Paths.font("vcr.ttf"), 20, FlxColor.WHITE, FlxTextAlign.LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); + judgementCounter.scrollFactor.set(); + judgementCounter.screenCenter(Y); + judgementCounter.borderSize = 1.25; + add(judgementCounter); + + judgementCounter.text = 'NPS: 0 (Max: 0)\n\nSick!! - 0\nGood! - 0\nBad - 0\nShit - 0'; + + judgementCounter.cameras = [camHUD]; + // Initialize the judgements and combo meter. comboPopUps = new PopUpStuff(); comboPopUps.zIndex = 900; @@ -766,11 +844,11 @@ class PlayState extends MusicBeatSubState leftWatermarkText.cameras = [camHUD]; rightWatermarkText.cameras = [camHUD]; + this.rightWatermarkText.text = Constants.VERSION; + // Initialize some debug stuff. #if (debug || FORCE_DEBUG_VERSION) // Display the version number (and git commit hash) in the bottom right corner. - this.rightWatermarkText.text = Constants.VERSION; - FlxG.console.registerObject('playState', this); #end @@ -891,9 +969,13 @@ class PlayState extends MusicBeatSubState if (vocals != null) vocals.stop(); vocals = currentChart.buildVocals(); - if (vocals.members.length == 0) + if (vocals.members.length == 0) trace('WARNING: No vocals found for this song.'); + else { - trace('WARNING: No vocals found for this song.'); + vocals.volume = 0.0; + vocals.play(); + vocals.stop(); + vocals.volume = 1.0; } } vocals.pause(); @@ -925,8 +1007,10 @@ class PlayState extends MusicBeatSubState // Delete all notes and reset the arrays. regenNoteData(); - if (resetBoppers.size() > 0) { - for (bopper => speed in resetBoppers) { + if (resetBoppers.size() > 0) + { + for (bopper => speed in resetBoppers) + { bopper.danceEvery = speed; } } @@ -938,6 +1022,12 @@ class PlayState extends MusicBeatSubState health = Constants.HEALTH_STARTING; songScore = 0; + songMisses = 0; + totalNotesHit = 0; + totalNotesPlayed = 0; + ratingPercent = 0; + ratingName = "?"; + judgementCounter.text = 'NPS: 0 (Max: 0)\n\nSick!! - 0\nGood! - 0\nBad - 0\nShit - 0'; Highscore.tallies.combo = 0; Countdown.performCountdown(currentStageId.startsWith('school')); @@ -959,6 +1049,12 @@ class PlayState extends MusicBeatSubState Conductor.instance.update(Conductor.instance.songPosition - (Conductor.instance.instrumentalOffset + Conductor.instance.formatOffset + Conductor.instance.audioVisualOffset) + elapsed * 1000 * playbackRate); // Normal conductor update. + + // FlxG.sound.music.onComplete may sometimes not get fired up lol + if (Conductor.instance.songPosition >= FlxG.sound.music.length) + { + endSong(false); + } } var androidPause:Bool = false; @@ -1022,6 +1118,19 @@ class PlayState extends MusicBeatSubState if (health > Constants.HEALTH_MAX) health = Constants.HEALTH_MAX; if (health < Constants.HEALTH_MIN) health = Constants.HEALTH_MIN; + // Manage how NPS works. + var balls = npsArray.length - 1; + while (balls >= 0) + { + var cock:Date = npsArray[balls]; + if (cock != null && cock.getTime() + 1000 < Date.now().getTime()) npsArray.remove(cock); + else + balls = 0; + balls--; + } + notesPerSecond = npsArray.length; + if (notesPerSecond > maxNps) maxNps = notesPerSecond; + // Apply camera zoom + multipliers. if (subState == null && cameraZoomRate > 0.0) // && !isInCutscene) { @@ -1596,6 +1705,7 @@ class PlayState extends MusicBeatSubState */ function initHealthBar():Void { + // The health bar for the opponent and player. var healthBarYPos:Float = Preferences.downscroll ? FlxG.height * 0.1 : FlxG.height * 0.9; healthBarBG = FunkinSprite.create(0, healthBarYPos, 'healthBar'); healthBarBG.screenCenter(X); @@ -1619,7 +1729,6 @@ class PlayState extends MusicBeatSubState scoreText.setFormat(Paths.font('vcr.ttf'), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); scoreText.scrollFactor.set(); scoreText.zIndex = 851; - if (Preferences.scoreText) add(scoreText); add(scoreText); funnySexBox.scale.x = scoreText.fieldWidth; @@ -1767,7 +1876,7 @@ class PlayState extends MusicBeatSubState // CREATE HEALTH BAR WITH CHARACTERS COLORS if (Preferences.coloredHealthBar) healthBar.createFilledBar(iconP2.getDominantColor(), iconP1.getDominantColor()); - + // // ADD CHARACTERS TO SCENE // @@ -1811,8 +1920,7 @@ class PlayState extends MusicBeatSubState function initCharacterReset():Void { - if (currentSong == null || currentChart == null) - trace('Song difficulty could not be loaded.'); + if (currentSong == null || currentChart == null) trace('Song difficulty could not be loaded.'); if (currentStage.getDad() != null && iconP2 != null) { @@ -1826,8 +1934,7 @@ class PlayState extends MusicBeatSubState remove(iconP1); } - if (currentStage.getGirlfriend() != null) - currentStage.getGirlfriend(true); + if (currentStage.getGirlfriend() != null) currentStage.getGirlfriend(true); } /** @@ -1920,9 +2027,13 @@ class PlayState extends MusicBeatSubState if (vocals != null) vocals.stop(); vocals = currentChart.buildVocals(); - if (vocals.members.length == 0) + if (vocals.members.length == 0) trace('WARNING: No vocals found for this song.'); + else { - trace('WARNING: No vocals found for this song.'); + vocals.volume = 0.0; + vocals.play(); + vocals.stop(); + vocals.volume = 1.0; } } @@ -2121,30 +2232,30 @@ class PlayState extends MusicBeatSubState */ function updateScoreText():Void { - // TODO: Add functionality for modules to update the score text. - if (isBotPlayMode) + var accuracy:String = "?"; + if (totalNotesPlayed != 0) { - scoreText.text = 'Bot Play Enabled'; + var percent:Float = Math.floor(ratingPercent * 100 * 2); + accuracy = percent + '%'; } + + // TODO: Add functionality for modules to update the score text. + if (isBotPlayMode) scoreText.text = 'BOTPLAY (Scores will NOT be saved!)'; + else if (Preferences.expandedScore) scoreText.text = 'Score: $songScore • Misses: $songMisses • Accuracy: $accuracy'; else - { scoreText.text = 'Score:' + songScore; - } } + public var goMaxHealth:Bool = false; + /** * Updates the values of the health bar. */ function updateHealthBar():Void { - if (isBotPlayMode) - { - healthLerp = Constants.HEALTH_MAX; - } + if (goMaxHealth) healthLerp = Constants.HEALTH_MAX; else - { healthLerp = FlxMath.lerp(healthLerp, health, 0.15); - } } /** @@ -2538,6 +2649,10 @@ class PlayState extends MusicBeatSubState // Display the combo meter and add the calculation to the score. applyScore(event.score, event.judgement, event.healthChange, event.isComboBreak); popUpScore(event.judgement); + + if (!note.isHoldNote) npsArray.unshift(Date.now()); + + totalNotesPlayed++; } /** @@ -2588,11 +2703,13 @@ class PlayState extends MusicBeatSubState vocals.playerVolume = 0; applyScore(-10, 'miss', healthChange, true); - +songMisses += 1; if (playSound) { vocals.playerVolume = 0; - FunkinSound.playOnce(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.5, 0.6)); + FunkinSound.playOnce(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2), function() { + vocals.playerVolume = 1; + }); } } @@ -2647,7 +2764,9 @@ class PlayState extends MusicBeatSubState if (event.playSound) { vocals.playerVolume = 0; - FunkinSound.playOnce(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2)); + FunkinSound.playOnce(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2), function() { + vocals.playerVolume = 1; + }); } } @@ -2736,7 +2855,45 @@ class PlayState extends MusicBeatSubState case 'miss': Highscore.tallies.missed += 1; } + var ratingMod = switch (daRating) + { + case 'good': + 0.67; + case 'bad': + 0.34; + case 'shit': + 0; + case 'sick': + 0.82; + default: + 1; // This should only trigger on "Sick!" judgements. + } + + totalNotesPlayed++; + totalNotesHit += ratingMod; + + var sickJudge = Highscore.tallies.sick; + var goodJudge = Highscore.tallies.good; + var badJudge = Highscore.tallies.bad; + var shitJudge = Highscore.tallies.shit; + + if (songMisses == 0) + { + if (badJudge > 0 || shitJudge > 0) ratingFC = 'FC'; + else if (goodJudge > 0) ratingFC = 'GFC'; + else if (sickJudge > 0) ratingFC = 'SFC'; + } + else + { + if (songMisses < 10) ratingFC = 'SDCB'; + else + ratingFC = 'Clear'; + } + + judgementCounter.text = 'NPS: ${notesPerSecond} (Max: ${maxNps})\n\nSick!! - ${sickJudge}\nGood! - ${goodJudge}\nBad - ${badJudge}\nShit - ${shitJudge}'; + health += healthChange; + if (isComboBreak) { // Break the combo, but don't increment tallies.misses. @@ -2756,6 +2913,29 @@ class PlayState extends MusicBeatSubState */ function popUpScore(daRating:String, ?combo:Int):Void { + ratingName = '?'; + if (totalNotesPlayed != 0) // To prevent dividing by 0. + { + // Rating percent. + ratingPercent = Math.min(1, Math.max(0, totalNotesHit / totalNotesPlayed)); + + // Rating name. + ratingName = ratingStuff[ratingStuff.length - 1][0]; // Uses last string. + if (ratingPercent < 1) + { + for (i in 0...ratingStuff.length - 1) + { + if (ratingPercent < ratingStuff[i][1]) + { + ratingName = ratingStuff[i][0]; + break; + } + } + } + } + + ratingFC = ''; + if (daRating == 'miss') { // If daRating is 'miss', that means we made a mistake and should not continue. @@ -2873,6 +3053,9 @@ class PlayState extends MusicBeatSubState */ public function endSong(rightGoddamnNow:Bool = false):Void { + if (endingSong) return; + endingSong = true; + if (FlxG.sound.music != null) FlxG.sound.music.volume = 0; vocals.volume = 0; mayPauseGame = false; diff --git a/source/funkin/play/notes/NoteSprite.hx b/source/funkin/play/notes/NoteSprite.hx index a92cf16c19..c310f8a9ae 100644 --- a/source/funkin/play/notes/NoteSprite.hx +++ b/source/funkin/play/notes/NoteSprite.hx @@ -110,7 +110,7 @@ class NoteSprite extends FunkinSprite * Set this flag to disable playing animation on hit/miss. */ public var noAnimation:Bool = false; - + /** * Set this flag to true when hitting the note to avoid scoring it multiple times. */ @@ -237,6 +237,8 @@ class NoteSprite extends FunkinSprite this.mayHit = false; this.hasMissed = false; + this.noAnimation = false; + this.hsvShader.hue = 1.0; this.hsvShader.saturation = 1.0; this.hsvShader.value = 1.0; diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 87d10ba516..834f8c6410 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -98,6 +98,7 @@ class Save flashingLights: true, zoomCamera: true, coloredHealthBar: false, + expandedScore: false, debugDisplay: false, autoPause: true, inputOffset: 0, @@ -1110,6 +1111,12 @@ typedef SaveDataOptions = */ var zoomCamera:Bool; + /** + * If disabled, the score text gets simplified to just the score display part. + * @default `false` + */ + var expandedScore:Bool; + /** * If enabled, an FPS and memory counter will be displayed even if this is not a debug build. * @default `false` diff --git a/source/funkin/ui/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx index 92169df751..f29b26f64f 100644 --- a/source/funkin/ui/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -169,7 +169,8 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler { FunkinSound.stopAllAudio(); - onComplete(); + // onComplete(); + super.startOutro(onComplete); } } diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 6e2fb7ba29..3c21a37cc9 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -6487,7 +6487,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function applyWindowTitle():Void { - var inner:String = 'New Chart'; + var inner:String = 'Untitled Chart'; var cwfp:Null = currentWorkingFilePath; if (cwfp != null) { diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 0748e4c851..9e32684e54 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -455,7 +455,7 @@ class FreeplayState extends MusicBeatSubState }); // TODO: Replace this. - if (currentCharacter == 'pico') dj.visible = false; + if (currentCharacter == 'pico' || currentCharacter == 'tankman' || currentCharacter == 'hank') dj.visible = false; add(dj); diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index d09536eea2..e1b3765db9 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -168,7 +168,7 @@ class MainMenuState extends MusicBeatState // This has to come AFTER! this.leftWatermarkText.text = Constants.VERSION; - // this.rightWatermarkText.text = "blablabla test"; + this.rightWatermarkText.text = "Lowend Engine v1.0"; // NG.core.calls.event.logEvent('swag').send(); } diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index 81df9191dd..d9d1637d32 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -76,6 +76,9 @@ class PreferencesMenu extends Page createPrefItemCheckbox('Colored Health Bar', 'Enable to use the health bar with character-based colors', function(value:Bool):Void { Preferences.coloredHealthBar = value; }, Preferences.coloredHealthBar); + createPrefItemCheckbox('Expanded Score Text', 'Enable to display misses and accuracy', function(value:Bool):Void { + Preferences.expandedScore = value; + }, Preferences.expandedScore); createPrefItemCheckbox('Camera Zooming on Beat', 'Disable to stop the camera bouncing to the song', function(value:Bool):Void { Preferences.zoomCamera = value; }, Preferences.zoomCamera); @@ -126,7 +129,7 @@ class PreferencesMenu extends Page var value = !checkbox.currentValue; onChange(value); checkbox.currentValue = value; - }); + }, true); preferenceItems.add(checkbox); } diff --git a/source/funkin/ui/transition/preload/FunkinPreloader.hx b/source/funkin/ui/transition/preload/FunkinPreloader.hx index 9d25695884..14e93ce387 100644 --- a/source/funkin/ui/transition/preload/FunkinPreloader.hx +++ b/source/funkin/ui/transition/preload/FunkinPreloader.hx @@ -243,8 +243,9 @@ class FunkinPreloader extends FlxBasePreloader box.graphics.beginFill(Constants.COLOR_PRELOADER_BAR, 0.1); box.graphics.drawRoundRect(0, 0, 128, 20, 5, 5); box.graphics.endFill(); - box.x = 880; - box.y = 440; + // Just don't be that clear. + box.x = this._width - BAR_PADDING - BAR_HEIGHT - 432; + box.y = this._height - BAR_PADDING - BAR_HEIGHT - 244; addChild(box); dspText.selectable = false;