diff --git a/source/Alphabet.hx b/source/Alphabet.hx index 20556e359..4e04631ef 100644 --- a/source/Alphabet.hx +++ b/source/Alphabet.hx @@ -34,20 +34,26 @@ class Alphabet extends FlxSpriteGroup var splitWords:Array = []; + var isBold:Bool = false; + public function new(x:Float, y:Float, text:String = "", ?bold:Bool = false, typed:Bool = false) { super(x, y); _finalText = text; this.text = text; + isBold = bold; - if (typed) + if (text != "") { - startTypedText(); - } - else - { - addText(); + if (typed) + { + startTypedText(); + } + else + { + addText(); + } } } @@ -55,6 +61,7 @@ class Alphabet extends FlxSpriteGroup { doSplitWords(); + var xPos:Float = 0; for (character in splitWords) { // if (character.fastCodeAt() == " ") @@ -68,10 +75,9 @@ class Alphabet extends FlxSpriteGroup if (AlphaCharacter.alphabet.contains(character.toLowerCase())) { - var xPos:Float = 0; if (lastSprite != null) { - xPos = lastSprite.x + lastSprite.frameWidth; + xPos = lastSprite.x + lastSprite.width; } if (lastWasSpace) @@ -82,7 +88,14 @@ class Alphabet extends FlxSpriteGroup // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); var letter:AlphaCharacter = new AlphaCharacter(xPos, 0); - letter.createBold(character); + + if (isBold) + letter.createBold(character); + else + { + letter.createLetter(character); + } + add(letter); lastSprite = letter; @@ -97,6 +110,8 @@ class Alphabet extends FlxSpriteGroup splitWords = _finalText.split(""); } + public var personTalking:String = 'gf'; + public function startTypedText():Void { _finalText = text; @@ -106,34 +121,79 @@ class Alphabet extends FlxSpriteGroup var loopNum:Int = 0; + var xPos:Float = 0; + var curRow:Int = 0; + new FlxTimer().start(0.05, function(tmr:FlxTimer) { - var xPos:Float = 0; - // trace(_finalText.fastCodeAt(loopNum) + " " + _finalText.charAt(loopNum)); if (_finalText.fastCodeAt(loopNum) == "\n".code) { yMulti += 1; xPosResetted = true; - // xPos = 0; + xPos = 0; + curRow += 1; } - if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase())) + if (splitWords[loopNum] == " ") + { + lastWasSpace = true; + } + + var isNumber:Bool = AlphaCharacter.numbers.contains(splitWords[loopNum]); + var isSymbol:Bool = AlphaCharacter.symbols.contains(splitWords[loopNum]); + if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol) { if (lastSprite != null && !xPosResetted) { - xPos = lastSprite.x + lastSprite.frameWidth - 40; + lastSprite.updateHitbox(); + xPos += lastSprite.width + 3; + // if (isBold) + // xPos -= 80; } else { xPosResetted = false; } + if (lastWasSpace) + { + xPos += 20; + lastWasSpace = false; + } // trace(_finalText.fastCodeAt(loopNum) + " " + _finalText.charAt(loopNum)); // var letter:AlphaCharacter = new AlphaCharacter(30 * loopNum, 0); var letter:AlphaCharacter = new AlphaCharacter(xPos, 55 * yMulti); - letter.createBold(splitWords[loopNum]); + letter.row = curRow; + if (isBold) + { + letter.createBold(splitWords[loopNum]); + } + else + { + if (isNumber) + { + letter.createNumber(splitWords[loopNum]); + } + else if (isSymbol) + { + letter.createSymbol(splitWords[loopNum]); + } + else + { + letter.createLetter(splitWords[loopNum]); + } + + letter.x += 90; + } + + if (FlxG.random.bool(40)) + { + var daSound:String = "GF_"; + FlxG.sound.play('assets/sounds/' + daSound + FlxG.random.int(1, 4) + TitleState.soundExt, 0.4); + } + add(letter); lastSprite = letter; @@ -141,7 +201,7 @@ class Alphabet extends FlxSpriteGroup loopNum += 1; - tmr.time = FlxG.random.float(0.03, 0.09); + tmr.time = FlxG.random.float(0.04, 0.09); }, splitWords.length); } @@ -155,8 +215,11 @@ class AlphaCharacter extends FlxSprite { public static var alphabet:String = "abcdefghijklmnopqrstuvwxyz"; - var numbers:String = "1234567890"; - var symbols:String = "|~#$%()*+-:;<=>@[]^_"; + public static var numbers:String = "1234567890"; + + public static var symbols:String = "|~#$%()*+-:;<=>@[]^_.,'!?"; + + public var row:Int = 0; public function new(x:Float, y:Float) { @@ -184,5 +247,42 @@ class AlphaCharacter extends FlxSprite animation.addByPrefix(letter, letter + " " + letterCase, 24); animation.play(letter); + updateHitbox(); + + FlxG.log.add('the row' + row); + + y = (110 - height); + y += row * 60; + } + + public function createNumber(letter:String):Void + { + animation.addByPrefix(letter, letter, 24); + animation.play(letter); + + updateHitbox(); + } + + public function createSymbol(letter:String) + { + switch (letter) + { + case '.': + animation.addByPrefix(letter, 'period', 24); + animation.play(letter); + y += 50; + case "'": + animation.addByPrefix(letter, 'apostraphie', 24); + animation.play(letter); + y -= 0; + case "?": + animation.addByPrefix(letter, 'question mark', 24); + animation.play(letter); + case "!": + animation.addByPrefix(letter, 'exclamation point', 24); + animation.play(letter); + } + + updateHitbox(); } } diff --git a/source/ChartingState.hx b/source/ChartingState.hx index a4cf96c92..3ebeb10f9 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -18,6 +18,7 @@ import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup; import flixel.math.FlxMath; import flixel.math.FlxPoint; +import flixel.system.FlxSound; import flixel.text.FlxText; import flixel.ui.FlxButton; import flixel.ui.FlxSpriteButton; @@ -71,6 +72,8 @@ class ChartingState extends MusicBeatState var tempBpm:Int = 0; + var vocals:FlxSound; + override function create() { gridBG = FlxGridOverlay.create(GRID_SIZE, GRID_SIZE, GRID_SIZE * 8, GRID_SIZE * 16); @@ -276,12 +279,24 @@ class ChartingState extends MusicBeatState function loadSong(daSong:String):Void { if (FlxG.sound.music != null) + { FlxG.sound.music.stop(); + // vocals.stop(); + } + + FlxG.sound.playMusic('assets/music/' + daSong + "_Inst" + TitleState.soundExt, 0.6); + + // WONT WORK FOR TUTORIAL! REDO LATER + vocals = new FlxSound().loadEmbedded("assets/music/" + daSong + "_Voices" + TitleState.soundExt); + FlxG.sound.list.add(vocals); - FlxG.sound.playMusic('assets/music/' + daSong + TitleState.soundExt, 0.6); FlxG.sound.music.pause(); + vocals.pause(); + FlxG.sound.music.onComplete = function() { + vocals.pause(); + vocals.time = 0; FlxG.sound.music.pause(); FlxG.sound.music.time = 0; }; @@ -430,6 +445,7 @@ class ChartingState extends MusicBeatState { PlayState.SONG = _song; FlxG.sound.music.stop(); + vocals.stop(); FlxG.switchState(new PlayState()); } @@ -440,9 +456,13 @@ class ChartingState extends MusicBeatState if (FlxG.sound.music.playing) { FlxG.sound.music.pause(); + vocals.pause(); } else + { + vocals.play(); FlxG.sound.music.play(); + } } if (FlxG.keys.justPressed.R) @@ -456,6 +476,7 @@ class ChartingState extends MusicBeatState if (FlxG.keys.pressed.W || FlxG.keys.pressed.S) { FlxG.sound.music.pause(); + vocals.pause(); var daTime:Float = 700 * FlxG.elapsed; @@ -465,6 +486,8 @@ class ChartingState extends MusicBeatState } else FlxG.sound.music.time += daTime; + + vocals.time = FlxG.sound.music.time; } } @@ -497,6 +520,7 @@ class ChartingState extends MusicBeatState if (updateMusic) { FlxG.sound.music.pause(); + vocals.pause(); var daNum:Int = 0; var daLength:Int = 0; @@ -507,6 +531,7 @@ class ChartingState extends MusicBeatState } FlxG.sound.music.time = (daLength - (_song.notes[sec].lengthInSteps)) * Conductor.stepCrochet; + vocals.time = FlxG.sound.music.time; updateCurStep(); } diff --git a/source/Controls.hx b/source/Controls.hx index c90b85054..b5715a614 100644 --- a/source/Controls.hx +++ b/source/Controls.hx @@ -11,7 +11,8 @@ import flixel.input.gamepad.FlxGamepadButton; import flixel.input.gamepad.FlxGamepadInputID; import flixel.input.keyboard.FlxKey; -@:enum abstract Action(String) to String from String +#if (haxe >= "4.0.0") +enum abstract Action(String) to String from String { var UP = "up"; var LEFT = "left"; @@ -30,6 +31,28 @@ import flixel.input.keyboard.FlxKey; var PAUSE = "pause"; var RESET = "reset"; } +#else +@:enum +abstract Action(String) to String from String +{ + var UP = "up"; + var LEFT = "left"; + var RIGHT = "right"; + var DOWN = "down"; + var UP_P = "up-press"; + var LEFT_P = "left-press"; + var RIGHT_P = "right-press"; + var DOWN_P = "down-press"; + var UP_R = "up-release"; + var LEFT_R = "left-release"; + var RIGHT_R = "right-release"; + var DOWN_R = "down-release"; + var ACCEPT = "accept"; + var BACK = "back"; + var PAUSE = "pause"; + var RESET = "reset"; +} +#end enum Device { @@ -402,9 +425,9 @@ class Controls extends FlxActionSet inline bindKeys(Control.DOWN, [S, FlxKey.DOWN]); inline bindKeys(Control.LEFT, [A, FlxKey.LEFT]); inline bindKeys(Control.RIGHT, [D, FlxKey.RIGHT]); - inline bindKeys(Control.ACCEPT, [Z, SPACE]); - inline bindKeys(Control.BACK, [X]); - inline bindKeys(Control.PAUSE, [P, ENTER]); + inline bindKeys(Control.ACCEPT, [Z, SPACE, ENTER]); + inline bindKeys(Control.BACK, [BACKSPACE, ESCAPE]); + inline bindKeys(Control.PAUSE, [P, ENTER, ESCAPE]); inline bindKeys(Control.RESET, [R]); case Duo(true): inline bindKeys(Control.UP, [W]); diff --git a/source/DialogueBox.hx b/source/DialogueBox.hx new file mode 100644 index 000000000..488fe35fd --- /dev/null +++ b/source/DialogueBox.hx @@ -0,0 +1,86 @@ +package; + +import flixel.FlxG; +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxSpriteGroup; +import flixel.input.FlxKeyManager; + +class DialogueBox extends FlxSpriteGroup +{ + var box:FlxSprite; + + var dialogue:Alphabet; + var dialogueList:Array = []; + + public var finishThing:Void->Void; + + public function new(talkingRight:Bool = true, ?dialogueList:Array) + { + super(); + + box = new FlxSprite(40); + box.frames = FlxAtlasFrames.fromSparrow(AssetPaths.speech_bubble_talking__png, AssetPaths.speech_bubble_talking__xml); + box.animation.addByPrefix('normalOpen', 'Speech Bubble Normal Open', 24, false); + box.animation.addByPrefix('normal', 'speech bubble normal', 24); + box.animation.play('normalOpen'); + add(box); + + if (!talkingRight) + { + box.flipX = true; + } + + dialogue = new Alphabet(0, 80, "", false, true); + // dialogue.x = 90; + add(dialogue); + + this.dialogueList = dialogueList; + } + + var dialogueOpened:Bool = false; + var dialogueStarted:Bool = false; + + override function update(elapsed:Float) + { + if (box.animation.curAnim != null) + { + if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) + { + box.animation.play('normal'); + dialogueOpened = true; + } + } + + if (dialogueOpened && !dialogueStarted) + { + startDialogue(); + dialogueStarted = true; + } + + if (FlxG.keys.justPressed.SPACE) + { + remove(dialogue); + + if (dialogueList[1] == null) + { + finishThing(); + kill(); + } + else + { + dialogueList.remove(dialogueList[0]); + startDialogue(); + } + } + + super.update(elapsed); + } + + function startDialogue():Void + { + var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); + dialogue = theDialog; + add(theDialog); + } +} diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index f2a717fec..0927dd7e6 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -87,6 +87,7 @@ class FreeplayState extends MusicBeatState if (accepted) { PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase()); + PlayState.isStoryMode = false; FlxG.switchState(new PlayState()); FlxG.sound.music.stop(); } @@ -95,6 +96,7 @@ class FreeplayState extends MusicBeatState if (gamepad.anyJustPressed(["B"])) //"B" is swapped with "A" on Switch { PlayState.SONG = Song.loadFromJson(songs[curSelected].toLowerCase()); + PlayState.isStoryMode = false; FlxG.switchState(new PlayState()); FlxG.sound.music.stop(); } diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx new file mode 100644 index 000000000..687f6191b --- /dev/null +++ b/source/MainMenuState.hx @@ -0,0 +1,168 @@ +package; + +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.effects.FlxFlicker; +import flixel.graphics.frames.FlxAtlasFrames; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; + +class MainMenuState extends MusicBeatState +{ + var curSelected:Int = 0; + + var menuItems:FlxTypedGroup; + + var optionShit:Array = ['story mode', 'freeplay', 'donate']; + + var magenta:FlxSprite; + var camFollow:FlxObject; + + override function create() + { + persistentUpdate = persistentDraw = true; + + var bg:FlxSprite = new FlxSprite(-80).loadGraphic(AssetPaths.menuBG__png); + bg.scrollFactor.x = 0; + bg.scrollFactor.y = 0.18; + bg.setGraphicSize(Std.int(bg.width * 1.1)); + bg.updateHitbox(); + bg.screenCenter(); + bg.antialiasing = true; + add(bg); + + camFollow = new FlxObject(0, 0, 1, 1); + add(camFollow); + + magenta = new FlxSprite(-80).loadGraphic(AssetPaths.menuBGMagenta__png); + magenta.scrollFactor.x = 0; + magenta.scrollFactor.y = 0.18; + magenta.setGraphicSize(Std.int(magenta.width * 1.1)); + magenta.updateHitbox(); + magenta.screenCenter(); + magenta.visible = false; + magenta.antialiasing = true; + add(magenta); + // magenta.scrollFactor.set(); + + menuItems = new FlxTypedGroup(); + add(menuItems); + + var tex = FlxAtlasFrames.fromSparrow(AssetPaths.FNF_main_menu_assets__png, AssetPaths.FNF_main_menu_assets__xml); + + for (i in 0...optionShit.length) + { + var menuItem:FlxSprite = new FlxSprite(0, 60 + (i * 160)); + menuItem.frames = tex; + menuItem.animation.addByPrefix('idle', optionShit[i] + " basic", 24); + menuItem.animation.addByPrefix('selected', optionShit[i] + " white", 24); + menuItem.animation.play('idle'); + menuItem.ID = i; + menuItem.screenCenter(X); + menuItems.add(menuItem); + menuItem.scrollFactor.set(); + menuItem.antialiasing = true; + } + + FlxG.camera.follow(camFollow, null, 0.06); + + changeItem(); + + super.create(); + } + + override function update(elapsed:Float) + { + if (controls.UP_P) + { + FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt); + changeItem(-1); + } + + if (controls.DOWN_P) + { + FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt); + changeItem(1); + } + + if (controls.BACK) + { + FlxG.switchState(new TitleState()); + } + + super.update(elapsed); + + if (controls.ACCEPT) + { + if (optionShit[curSelected] == 'donate') + { + FlxG.openURL('https://ninja-muffin24.itch.io/funkin'); + } + else + { + FlxG.sound.play('assets/sounds/confirmMenu' + TitleState.soundExt); + + FlxFlicker.flicker(magenta, 1.1, 0.15, false); + + menuItems.forEach(function(spr:FlxSprite) + { + if (curSelected != spr.ID) + { + FlxTween.tween(spr, {alpha: 0}, 0.4, { + ease: FlxEase.quadOut, + onComplete: function(twn:FlxTween) + { + spr.kill(); + } + }); + } + else + { + FlxFlicker.flicker(spr, 1, 0.06, false, false, function(flick:FlxFlicker) + { + var daChoice:String = optionShit[curSelected]; + + switch (daChoice) + { + case 'story mode': + FlxG.switchState(new StoryMenuState()); + case 'freeplay': + FlxG.switchState(new FreeplayState()); + } + }); + } + }); + } + } + + menuItems.forEach(function(spr:FlxSprite) + { + spr.screenCenter(X); + }); + } + + function changeItem(huh:Int = 0) + { + curSelected += huh; + + if (curSelected >= menuItems.length) + curSelected = 0; + if (curSelected < 0) + curSelected = menuItems.length - 1; + + menuItems.forEach(function(spr:FlxSprite) + { + spr.animation.play('idle'); + + if (spr.ID == curSelected) + { + spr.animation.play('selected'); + camFollow.setPosition(spr.getGraphicMidpoint().x, spr.getGraphicMidpoint().y); + } + + spr.updateHitbox(); + }); + } +} diff --git a/source/MenuCharacter.hx b/source/MenuCharacter.hx new file mode 100644 index 000000000..6835daa9a --- /dev/null +++ b/source/MenuCharacter.hx @@ -0,0 +1,28 @@ +package; + +import flixel.FlxSprite; +import flixel.graphics.frames.FlxAtlasFrames; + +class MenuCharacter extends FlxSprite +{ + public var character:String; + + public function new(x:Float, character:String = 'bf') + { + super(x); + + this.character = character; + + var tex = FlxAtlasFrames.fromSparrow(AssetPaths.campaign_menu_UI_characters__png, AssetPaths.campaign_menu_UI_characters__xml); + frames = tex; + + animation.addByPrefix('bf', "BF idle dance white", 24); + animation.addByPrefix('bfConfirm', 'BF HEY!!', 24, false); + animation.addByPrefix('gf', "GF Dancing Beat WHITE", 24); + animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24); + animation.addByPrefix('spooky', "spooky dance idle BLACK LINES", 24); + + animation.play(character); + updateHitbox(); + } +} diff --git a/source/MenuItem.hx b/source/MenuItem.hx index 5e7ddc763..5aae4ee28 100644 --- a/source/MenuItem.hx +++ b/source/MenuItem.hx @@ -8,6 +8,7 @@ import flixel.math.FlxMath; class MenuItem extends FlxSpriteGroup { public var targetY:Float = 0; + public var week:FlxSprite; public function new(x:Float, y:Float, weekNum:Int = 0, unlocked:Bool = false) { @@ -15,13 +16,14 @@ class MenuItem extends FlxSpriteGroup var tex = FlxAtlasFrames.fromSparrow(AssetPaths.campaign_menu_UI_assets__png, AssetPaths.campaign_menu_UI_assets__xml); - var week:FlxSprite = new FlxSprite(); + week = new FlxSprite(); week.frames = tex; week.animation.addByPrefix('week0', "WEEK1 select", 24); week.animation.addByPrefix('week1', "week2 select", 24); add(week); week.animation.play('week' + weekNum); + week.animation.pause(); week.updateHitbox(); if (!unlocked) diff --git a/source/PlayState.hx b/source/PlayState.hx index 9f4784dfb..29aeb7335 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -16,6 +16,7 @@ import flixel.graphics.atlas.FlxAtlas; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxMath; +import flixel.math.FlxPoint; import flixel.system.FlxSound; import flixel.text.FlxText; import flixel.tweens.FlxEase; @@ -33,8 +34,13 @@ using StringTools; class PlayState extends MusicBeatState { - public static var curLevel:String = 'Bopeebo'; + public static var curLevel:String = 'Tutorial'; public static var SONG:SwagSong; + public static var isStoryMode:Bool = false; + public static var storyPlaylist:Array = []; + public static var storyDifficulty:Int = 1; + + var halloweenLevel:Bool = false; private var vocals:FlxSound; @@ -69,6 +75,12 @@ class PlayState extends MusicBeatState private var camHUD:FlxCamera; private var camGame:FlxCamera; + var dialogue:Array = ['blah blah blah', 'coolswag']; + + var halloweenBG:FlxSprite; + + var talking:Bool = true; + override public function create() { // var gameCam:FlxCamera = FlxG.camera; @@ -89,28 +101,68 @@ class PlayState extends MusicBeatState Conductor.changeBPM(SONG.bpm); - var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(AssetPaths.stageback__png); - // bg.setGraphicSize(Std.int(bg.width * 2.5)); - // bg.updateHitbox(); - bg.antialiasing = true; - bg.scrollFactor.set(0.9, 0.9); - bg.active = false; - add(bg); + switch (SONG.song.toLowerCase()) + { + case 'tutorial': + dialogue = ["Hey you're pretty cute.", 'Use the arrow keys to keep up \nwith me singing.']; + case 'bopeebo': + dialogue = [ + 'HEY!', + "You think you can just sing\nwith my daughter like that?", + "If you want to date her...", + "You're going to have to go \nthrough ME first!" + ]; + case 'fresh': + dialogue = ["Not too shabby boy.", ""]; + case 'dadbattle': + dialogue = [ + "gah you think you're hot stuff?", + "If you can beat me here...", + "Only then I will even CONSIDER letting you\ndate my daughter!" + ]; + } - var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(AssetPaths.stagefront__png); - stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); - stageFront.updateHitbox(); - stageFront.antialiasing = true; - stageFront.scrollFactor.set(0.9, 0.9); - stageFront.active = false; - add(stageFront); + if (SONG.song.toLowerCase() == 'spookeez' || SONG.song.toLowerCase() == 'monster' || SONG.song.toLowerCase() == 'south') + { + halloweenLevel = true; - var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(AssetPaths.stagecurtains__png); - stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); - stageCurtains.updateHitbox(); - stageCurtains.antialiasing = true; - stageCurtains.scrollFactor.set(1.3, 1.3); - stageCurtains.active = false; + var hallowTex = FlxAtlasFrames.fromSparrow(AssetPaths.halloween_bg__png, AssetPaths.halloween_bg__xml); + + halloweenBG = new FlxSprite(-200, -100); + halloweenBG.frames = hallowTex; + halloweenBG.animation.addByPrefix('idle', 'halloweem bg0'); + halloweenBG.animation.addByPrefix('lightning', 'halloweem bg lightning strike', 24, false); + halloweenBG.animation.play('idle'); + halloweenBG.antialiasing = true; + add(halloweenBG); + } + else + { + var bg:FlxSprite = new FlxSprite(-600, -200).loadGraphic(AssetPaths.stageback__png); + // bg.setGraphicSize(Std.int(bg.width * 2.5)); + // bg.updateHitbox(); + bg.antialiasing = true; + bg.scrollFactor.set(0.9, 0.9); + bg.active = false; + add(bg); + + var stageFront:FlxSprite = new FlxSprite(-650, 600).loadGraphic(AssetPaths.stagefront__png); + stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); + stageFront.updateHitbox(); + stageFront.antialiasing = true; + stageFront.scrollFactor.set(0.9, 0.9); + stageFront.active = false; + add(stageFront); + + var stageCurtains:FlxSprite = new FlxSprite(-500, -300).loadGraphic(AssetPaths.stagecurtains__png); + stageCurtains.setGraphicSize(Std.int(stageCurtains.width * 0.9)); + stageCurtains.updateHitbox(); + stageCurtains.antialiasing = true; + stageCurtains.scrollFactor.set(1.3, 1.3); + stageCurtains.active = false; + + add(stageCurtains); + } gf = new Character(400, 130, 'gf'); gf.scrollFactor.set(0.95, 0.95); @@ -120,21 +172,37 @@ class PlayState extends MusicBeatState dad = new Character(100, 100, SONG.player2); add(dad); + var camPos:FlxPoint = new FlxPoint(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y); + switch (SONG.player2) { case 'gf': dad.setPosition(gf.x, gf.y); gf.visible = false; + if (isStoryMode) + { + camPos.x += 600; + tweenCamIn(); + } + case "spooky": dad.y += 200; case "monster": dad.y += 100; + case 'dad': + camPos.x += 400; } boyfriend = new Boyfriend(770, 450); add(boyfriend); - add(stageCurtains); + var doof:DialogueBox = new DialogueBox(false, dialogue); + // doof.x += 70; + doof.y = FlxG.height * 0.5; + doof.scrollFactor.set(); + doof.finishThing = startCountdown; + + Conductor.songPosition = -5000; strumLine = new FlxSprite(0, 50).makeGraphic(FlxG.width, 10); strumLine.scrollFactor.set(); @@ -146,14 +214,15 @@ class PlayState extends MusicBeatState startingSong = true; - startCountdown(); + // startCountdown(); generateSong(SONG.song); // add(strumLine); camFollow = new FlxObject(0, 0, 1, 1); - camFollow.setPosition(dad.getGraphicMidpoint().x, dad.getGraphicMidpoint().y); + + camFollow.setPosition(camPos.x, camPos.y); add(camFollow); FlxG.camera.follow(camFollow, LOCKON, 0.04); @@ -186,11 +255,22 @@ class PlayState extends MusicBeatState healthHeads.antialiasing = true; add(healthHeads); + // healthBar.visible = healthHeads.visible = healthBarBG.visible = false; + if (isStoryMode) + { + // TEMP for now, later get rid of startCountdown() + // add(doof); + startCountdown(); + } + else + startCountdown(); + strumLineNotes.cameras = [camHUD]; notes.cameras = [camHUD]; healthBar.cameras = [camHUD]; healthBarBG.cameras = [camHUD]; healthHeads.cameras = [camHUD]; + doof.cameras = [camHUD]; // if (SONG.song == 'South') // FlxG.camera.alpha = 0.7; @@ -205,6 +285,10 @@ class PlayState extends MusicBeatState function startCountdown():Void { + generateStaticArrows(0); + generateStaticArrows(1); + + talking = false; startedCountdown = true; Conductor.songPosition = 0; Conductor.songPosition -= Conductor.crochet * 5; @@ -278,7 +362,8 @@ class PlayState extends MusicBeatState lastReportedPlayheadPosition = 0; startingSong = false; - FlxG.sound.playMusic("assets/music/" + SONG.song + "_Inst" + TitleState.soundExt); + FlxG.sound.playMusic("assets/music/" + SONG.song + "_Inst" + TitleState.soundExt, 1, false); + FlxG.sound.music.onComplete = endSong; vocals.play(); } @@ -288,9 +373,6 @@ class PlayState extends MusicBeatState { // FlxG.log.add(ChartParser.parse()); - generateStaticArrows(0); - generateStaticArrows(1); - var songData = SONG; Conductor.changeBPM(songData.bpm); @@ -448,6 +530,11 @@ class PlayState extends MusicBeatState } } + function tweenCamIn():Void + { + FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); + } + override function openSubState(SubState:FlxSubState) { if (paused) @@ -495,7 +582,7 @@ class PlayState extends MusicBeatState // trace("SONG POS: " + Conductor.songPosition); // FlxG.sound.music.pitch = 2; - if (FlxG.keys.justPressed.ENTER) + if (FlxG.keys.justPressed.ENTER && startedCountdown) { persistentUpdate = false; persistentDraw = true; @@ -570,7 +657,7 @@ class PlayState extends MusicBeatState if (SONG.song.toLowerCase() == 'tutorial') { - FlxTween.tween(FlxG.camera, {zoom: 1.3}, (Conductor.stepCrochet * 4 / 1000), {ease: FlxEase.elasticInOut}); + tweenCamIn(); } } @@ -606,9 +693,9 @@ class PlayState extends MusicBeatState case 112: gfSpeed = 1; case 163: - FlxG.sound.music.stop(); - curLevel = 'Bopeebo'; - FlxG.switchState(new TitleState()); + // FlxG.sound.music.stop(); + // curLevel = 'Bopeebo'; + // FlxG.switchState(new TitleState()); } } @@ -617,9 +704,9 @@ class PlayState extends MusicBeatState switch (totalBeats) { case 127: - FlxG.sound.music.stop(); - curLevel = 'Fresh'; - FlxG.switchState(new PlayState()); + // FlxG.sound.music.stop(); + // curLevel = 'Fresh'; + // FlxG.switchState(new PlayState()); } } // better streaming of shit @@ -697,7 +784,7 @@ class PlayState extends MusicBeatState { if (daNote.tooLate) { - health -= 0.03; + health -= 0.04; vocals.volume = 0; } @@ -714,6 +801,42 @@ class PlayState extends MusicBeatState keyShit(); } + function endSong():Void + { + trace('SONG DONE' + isStoryMode); + + if (isStoryMode) + { + storyPlaylist.remove(storyPlaylist[0]); + + if (storyPlaylist.length <= 0) + { + FlxG.switchState(new TitleState()); + + StoryMenuState.weekUnlocked[1] = true; + } + else + { + var difficulty:String = ""; + + if (storyDifficulty == 0) + difficulty = '-easy'; + + if (storyDifficulty == 2) + difficulty == '-hard'; + + PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + difficulty, PlayState.storyPlaylist[0]); + FlxG.switchState(new PlayState()); + } + } + else + { + FlxG.switchState(new FreeplayState()); + } + } + + var endingSong:Bool = false; + private function popUpScore(strumtime:Float):Void { var noteDiff:Float = Math.abs(strumtime - Conductor.songPosition); @@ -972,7 +1095,7 @@ class PlayState extends MusicBeatState { if (!boyfriend.stunned) { - health -= 0.055; + health -= 0.06; if (combo > 5) { gf.playAnim('sad'); @@ -1068,9 +1191,9 @@ class PlayState extends MusicBeatState } if (note.noteData >= 0) - health += 0.03; + health += 0.023; else - health += 0.007; + health += 0.004; switch (note.noteData) { @@ -1131,22 +1254,25 @@ class PlayState extends MusicBeatState notes.sort(FlxSort.byY, FlxSort.DESCENDING); } - FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); - if (SONG.notes[Std.int(curStep / 16)].changeBPM) + if (SONG.notes[Math.floor(curStep / 16)] != null) { - Conductor.changeBPM(SONG.notes[Std.int(curStep / 16)].bpm); - FlxG.log.add('CHANGED BPM!'); + if (SONG.notes[Math.floor(curStep / 16)].changeBPM) + { + Conductor.changeBPM(SONG.notes[Math.floor(curStep / 16)].bpm); + FlxG.log.add('CHANGED BPM!'); + } + else + Conductor.changeBPM(SONG.bpm); + + // Dad doesnt interupt his own notes + if (SONG.notes[Math.floor(curStep / 16)].mustHitSection) + dad.dance(); } - else - Conductor.changeBPM(SONG.bpm); + // FlxG.log.add('change bpm' + SONG.notes[Std.int(curStep / 16)].changeBPM); if (camZooming && FlxG.camera.zoom < 1.35 && totalBeats % 4 == 0) FlxG.camera.zoom += 0.025; - // Dad doesnt interupt his own notes - if (SONG.notes[Std.int(curStep / 16)].mustHitSection) - dad.dance(); - healthHeads.setGraphicSize(Std.int(healthHeads.width + 20)); if (totalBeats % gfSpeed == 0) diff --git a/source/Song.hx b/source/Song.hx index 3c2ac41be..aa75d3951 100644 --- a/source/Song.hx +++ b/source/Song.hx @@ -47,9 +47,9 @@ class Song } } - public static function loadFromJson(jsonInput:String):SwagSong + public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong { - var rawJson = Assets.getText('assets/data/' + jsonInput.toLowerCase() + '/' + jsonInput.toLowerCase() + '.json').trim(); + var rawJson = Assets.getText('assets/data/' + folder.toLowerCase() + '/' + jsonInput.toLowerCase() + '.json').trim(); while (!rawJson.endsWith("}")) { diff --git a/source/StoryMenuState.hx b/source/StoryMenuState.hx index bae5703c0..093746479 100644 --- a/source/StoryMenuState.hx +++ b/source/StoryMenuState.hx @@ -6,6 +6,9 @@ import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup; import flixel.text.FlxText; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; +import lime.net.curl.CURLCode; using StringTools; @@ -13,31 +16,38 @@ class StoryMenuState extends MusicBeatState { var scoreText:FlxText; - var weekData:Array = [['Tutorial', 'Bopeebo', 'Fresh', 'Dad Battle'], ['Spookeez', 'South', 'Monster']]; - var weekUnlocked:Array = [true, false]; + var weekData:Array = [['Tutorial', 'Bopeebo', 'Fresh', 'Dadbattle'], ['Spookeez', 'South', 'Monster']]; + var curDifficulty:Int = 1; + public static var weekUnlocked:Array = [true, false]; + + var weekCharacters:Array = [['dad', 'bf', 'gf'], ['spooky', 'bf', 'gf']]; var curWeek:Int = 0; var txtTracklist:FlxText; var grpWeekText:FlxTypedGroup; + var grpWeekCharacters:FlxTypedGroup; var grpLocks:FlxTypedGroup; var difficultySelectors:FlxGroup; + var sprDifficulty:FlxSprite; + var leftArrow:FlxSprite; + var rightArrow:FlxSprite; override function create() { + persistentUpdate = persistentDraw = true; + scoreText = new FlxText(10, 10, 0, "SCORE: 49324858", 36); scoreText.setFormat("VCR OSD Mono", 32); - add(scoreText); var rankText:FlxText = new FlxText(0, 10); rankText.text = 'RANK: GREAT'; rankText.setFormat("assets/fonts/vcr.ttf", 32); rankText.size = scoreText.size; rankText.screenCenter(X); - add(rankText); var ui_tex = FlxAtlasFrames.fromSparrow(AssetPaths.campaign_menu_UI_assets__png, AssetPaths.campaign_menu_UI_assets__xml); var yellowBG:FlxSprite = new FlxSprite(0, 56).makeGraphic(FlxG.width, 400, 0xFFF9CF51); @@ -45,6 +55,8 @@ class StoryMenuState extends MusicBeatState grpWeekText = new FlxTypedGroup(); add(grpWeekText); + grpWeekCharacters = new FlxTypedGroup(); + grpLocks = new FlxTypedGroup(); add(grpLocks); @@ -76,36 +88,65 @@ class StoryMenuState extends MusicBeatState } } + for (char in 0...3) + { + var weekCharacterThing:MenuCharacter = new MenuCharacter((FlxG.width * 0.25) * (1 + char) - 150, weekCharacters[curWeek][char]); + weekCharacterThing.y += 70; + weekCharacterThing.antialiasing = true; + switch (weekCharacterThing.character) + { + case 'dad': + weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * 0.5)); + weekCharacterThing.updateHitbox(); + + case 'bf': + weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * 0.9)); + weekCharacterThing.updateHitbox(); + case 'gf': + weekCharacterThing.setGraphicSize(Std.int(weekCharacterThing.width * 0.5)); + weekCharacterThing.updateHitbox(); + } + + grpWeekCharacters.add(weekCharacterThing); + } + difficultySelectors = new FlxGroup(); add(difficultySelectors); - var leftArrow:FlxSprite = new FlxSprite(grpWeekText.members[0].x + 400, grpWeekText.members[0].y + 10); + leftArrow = new FlxSprite(grpWeekText.members[0].x + 370, grpWeekText.members[0].y + 10); leftArrow.frames = ui_tex; leftArrow.animation.addByPrefix('idle', "arrow left"); + leftArrow.animation.addByPrefix('press', "arrow push left"); leftArrow.animation.play('idle'); difficultySelectors.add(leftArrow); - var sprDifficulty:FlxSprite = new FlxSprite(leftArrow.x + 70, leftArrow.y); + sprDifficulty = new FlxSprite(leftArrow.x + 130, leftArrow.y); sprDifficulty.frames = ui_tex; sprDifficulty.animation.addByPrefix('easy', 'EASY'); sprDifficulty.animation.addByPrefix('normal', 'NORMAL'); sprDifficulty.animation.addByPrefix('hard', 'HARD'); sprDifficulty.animation.play('easy'); + changeDifficulty(); + difficultySelectors.add(sprDifficulty); - var rightArrow:FlxSprite = new FlxSprite(sprDifficulty.x + sprDifficulty.width + 20, sprDifficulty.y); + rightArrow = new FlxSprite(sprDifficulty.x + sprDifficulty.width + 50, leftArrow.y); rightArrow.frames = ui_tex; rightArrow.animation.addByPrefix('idle', 'arrow right'); + rightArrow.animation.addByPrefix('press', "arrow push right", 24, false); rightArrow.animation.play('idle'); difficultySelectors.add(rightArrow); add(yellowBG); + add(grpWeekCharacters); txtTracklist = new FlxText(FlxG.width * 0.05, yellowBG.x + yellowBG.height + 100, 0, "Tracks", 32); txtTracklist.alignment = CENTER; txtTracklist.font = rankText.font; txtTracklist.color = 0xFFe55777; add(txtTracklist); + add(rankText); + add(scoreText); updateText(); @@ -125,14 +166,119 @@ class StoryMenuState extends MusicBeatState lock.y = grpWeekText.members[lock.ID].y; }); - if (controls.UP_P) - changeWeek(-1); - if (controls.DOWN_P) - changeWeek(1); + if (!movedBack) + { + if (!selectedWeek) + { + if (controls.UP_P) + { + changeWeek(-1); + } + + if (controls.DOWN_P) + { + changeWeek(1); + } + + if (controls.RIGHT) + rightArrow.animation.play('press') + else + rightArrow.animation.play('idle'); + + if (controls.LEFT) + leftArrow.animation.play('press'); + else + leftArrow.animation.play('idle'); + + if (controls.RIGHT_P) + changeDifficulty(1); + if (controls.LEFT_P) + changeDifficulty(-1); + } + + if (controls.ACCEPT) + { + selectWeek(); + } + } + + if (controls.BACK && !movedBack && !selectedWeek) + { + FlxG.sound.play('assets/sounds/cancelMenu' + TitleState.soundExt); + movedBack = true; + FlxG.switchState(new MainMenuState()); + } super.update(elapsed); } + var movedBack:Bool = false; + var selectedWeek:Bool = false; + + function selectWeek() + { + if (weekUnlocked[curWeek]) + { + FlxG.sound.play('assets/sounds/confirmMenu' + TitleState.soundExt); + + grpWeekText.members[curWeek].week.animation.resume(); + grpWeekCharacters.members[1].animation.play('bfConfirm'); + + PlayState.storyPlaylist = weekData[curWeek]; + PlayState.isStoryMode = true; + selectedWeek = true; + + var diffic = ""; + + switch (curDifficulty) + { + case 0: + diffic = '-easy'; + case 2: + diffic = '-hard'; + } + + PlayState.storyDifficulty = curDifficulty; + + PlayState.SONG = Song.loadFromJson(PlayState.storyPlaylist[0].toLowerCase() + diffic, PlayState.storyPlaylist[0].toLowerCase()); + new FlxTimer().start(1, function(tmr:FlxTimer) + { + FlxG.sound.music.stop(); + FlxG.switchState(new PlayState()); + }); + } + } + + function changeDifficulty(change:Int = 0):Void + { + curDifficulty += change; + + if (curDifficulty < 0) + curDifficulty = 2; + if (curDifficulty > 2) + curDifficulty = 0; + + sprDifficulty.offset.x = 0; + + switch (curDifficulty) + { + case 0: + sprDifficulty.animation.play('easy'); + sprDifficulty.offset.x = 20; + case 1: + sprDifficulty.animation.play('normal'); + sprDifficulty.offset.x = 70; + case 2: + sprDifficulty.animation.play('hard'); + sprDifficulty.offset.x = 20; + } + + sprDifficulty.alpha = 0; + sprDifficulty.y -= 15; + + FlxTween.tween(sprDifficulty, {y: sprDifficulty.y + 15, alpha: 1}, 0.07); + } + function changeWeek(change:Int = 0):Void { curWeek += change; @@ -150,11 +296,16 @@ class StoryMenuState extends MusicBeatState bullShit++; } + FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt); + updateText(); } function updateText() { + grpWeekCharacters.members[0].animation.play(weekCharacters[curWeek][0]); + grpWeekCharacters.members[1].animation.play(weekCharacters[curWeek][1]); + grpWeekCharacters.members[2].animation.play(weekCharacters[curWeek][2]); txtTracklist.text = "Tracks\n"; var stringThing:Array = weekData[curWeek]; diff --git a/source/TitleState.hx b/source/TitleState.hx index beb3c9d64..72cae1944 100644 --- a/source/TitleState.hx +++ b/source/TitleState.hx @@ -27,6 +27,17 @@ class TitleState extends MusicBeatState var credGroup:FlxGroup; var credTextShit:Alphabet; var textGroup:FlxGroup; + var ngSpr:FlxSprite; + + var wackyIntros:Array> = [ + ['Shoutouts to tom fulp', 'lmao'], ["Ludum dare", "extraordinaire"], ['Cyberzone', 'coming soon'], ['love to thriftman', 'swag'], + ['ULTIMATE RHYTHM GAMING', 'probably'], ['DOPE ASS GAME', 'playstation magazine'], ['in loving memory of', 'henryeyes'], ['dancin', 'forever'], + ['Ritz dx', 'rest in peace'], ['rate five', 'pls no blam'], ['rhythm gaming', 'ultimate'], ['game of the year', 'forever'], + ['you already know', 'we really out here'], ['rise and grind', 'love to luis'], ['like parappa', 'but cooler'], + ['album of the year', 'chuckie finster'], ["free gitaroo man", "with love to wandaboy"], ['better than geometry dash', 'fight me robtop'], + ['kiddbrute for president', 'vote now']]; + + var curWacky:Array = []; override public function create():Void { @@ -36,6 +47,8 @@ class TitleState extends MusicBeatState PlayerSettings.init(); + curWacky = FlxG.random.getObject(wackyIntros); + // DEBUG BULLSHIT super.create(); @@ -55,18 +68,20 @@ class TitleState extends MusicBeatState diamond.persist = true; diamond.destroyOnNoUse = false; - FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 2, new FlxPoint(0, -1), {asset: diamond, width: 32, height: 32}, + FlxTransitionableState.defaultTransIn = new TransitionData(FADE, FlxColor.BLACK, 1, new FlxPoint(0, -1), {asset: diamond, width: 32, height: 32}, new FlxRect(0, 0, FlxG.width, FlxG.height)); - FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 1.3, new FlxPoint(0, 1), + FlxTransitionableState.defaultTransOut = new TransitionData(FADE, FlxColor.BLACK, 0.7, new FlxPoint(0, 1), {asset: diamond, width: 32, height: 32}, new FlxRect(0, 0, FlxG.width, FlxG.height)); - initialized = true; - FlxTransitionableState.defaultTransIn.tileData = {asset: diamond, width: 32, height: 32}; FlxTransitionableState.defaultTransOut.tileData = {asset: diamond, width: 32, height: 32}; transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; + + FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt, 0); + + FlxG.sound.music.fadeIn(4, 0, 0.7); } persistentUpdate = true; @@ -104,13 +119,22 @@ class TitleState extends MusicBeatState credTextShit.visible = false; + ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadGraphic(AssetPaths.newgrounds_logo__png); + add(ngSpr); + ngSpr.visible = false; + ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); + ngSpr.updateHitbox(); + ngSpr.screenCenter(X); + ngSpr.antialiasing = true; + FlxTween.tween(credTextShit, {y: credTextShit.y + 20}, 2.9, {ease: FlxEase.quadInOut, type: PINGPONG}); + if (initialized) + skipIntro(); + else + initialized = true; + // credGroup.add(credTextShit); - - FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt, 0, false); - - FlxG.sound.music.fadeIn(4, 0, 0.7); } var transitioning:Bool = false; @@ -129,23 +153,24 @@ class TitleState extends MusicBeatState pressedEnter = true; } - if (pressedEnter && !skippedIntro) - { - skipIntro(); - } - if (pressedEnter && !transitioning && skippedIntro) { FlxG.camera.flash(FlxColor.WHITE, 1); + FlxG.sound.play('assets/sounds/confirmMenu' + TitleState.soundExt, 0.7); transitioning = true; - FlxG.sound.music.stop(); + // FlxG.sound.music.stop(); new FlxTimer().start(2, function(tmr:FlxTimer) { - FlxG.switchState(new FreeplayState()); + FlxG.switchState(new MainMenuState()); }); - FlxG.sound.play('assets/music/titleShoot' + TitleState.soundExt, 0.7); + // FlxG.sound.play('assets/music/titleShoot' + TitleState.soundExt, 0.7); + } + + if (pressedEnter && !skippedIntro) + { + skipIntro(); } super.update(elapsed); @@ -205,18 +230,20 @@ class TitleState extends MusicBeatState createCoolText(['In association', 'with']); case 7: addMoreText('newgrounds'); + ngSpr.visible = true; // credTextShit.text += '\nNewgrounds'; case 8: deleteCoolText(); + ngSpr.visible = false; // credTextShit.visible = false; // credTextShit.text = 'Shoutouts Tom Fulp'; // credTextShit.screenCenter(); case 9: - createCoolText(['Shoutouts Tom Fulp']); + createCoolText([curWacky[0]]); // credTextShit.visible = true; case 11: - addMoreText('lmao'); + addMoreText(curWacky[1]); // credTextShit.text += '\nlmao'; case 12: deleteCoolText(); @@ -243,6 +270,8 @@ class TitleState extends MusicBeatState { if (!skippedIntro) { + remove(ngSpr); + FlxG.camera.flash(FlxColor.WHITE, 4); remove(credGroup); skippedIntro = true;