diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d899d9f3..ee6e75211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,23 @@ All notable changes will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.2.2] - 2020-11-20 +### Added +- Music playing on the freeplay menu. +- UI sounds on freeplay menu +- Score now shows mid-song. +- Menu on pause screen! Can resume, and restart song, or go back to main menu. +- New music made for pause menu! + ### Changed - Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! ### Fixed +- Fixed soft lock when pausing on song finish ([shoutouts gedehari](https://github.com/ninjamuffin99/Funkin/issues/15)) +- Think I fixed issue that led to in-game scores being off by 2 ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/4)) +- Should have fixed the 1 frame note appearance thing. ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/6)) - Cleaned up some charting on South on hard mode -- Fixed some animation timings, should feel both better to play, and watch. -- Maaaybe fixed notes popping up randomly at the top of the screen for a frame or two? If this isn't fixed, uhh yall shout at me lolol +- Fixed some animation timings, should feel both better to play, and watch. (shoutouts Dave/Ivan lol) +- Animation issue where GF would freak out on the title screen if you returned to it([shoutouts MultiXIII](https://github.com/ninjamuffin99/Funkin/issues/12)). ## [0.2.1.2] - 2020-11-06 ### Fixed diff --git a/Project.xml b/Project.xml index 9dd031d07..cd6bf48e1 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + diff --git a/assets/data/introText.txt b/assets/data/introText.txt index 4c9f22b9e..8b7da62ca 100644 --- a/assets/data/introText.txt +++ b/assets/data/introText.txt @@ -21,4 +21,5 @@ kiddbrute for president--vote now play dead estate--on newgrounds this is a god damn prototype--we workin on it okay women are real--this is official +too over exposed--newgrounds cant handle us Nintendo Switch--pre-orders now available \ No newline at end of file diff --git a/assets/music/breakfast.mp3 b/assets/music/breakfast.mp3 new file mode 100644 index 000000000..abefad59d Binary files /dev/null and b/assets/music/breakfast.mp3 differ diff --git a/assets/music/breakfast.ogg b/assets/music/breakfast.ogg new file mode 100644 index 000000000..fe6823965 Binary files /dev/null and b/assets/music/breakfast.ogg differ diff --git a/docs/img/skin-funkin-cardbordtoast.jpg b/docs/img/skin-funkin-cardbordtoast.jpg new file mode 100644 index 000000000..dd0e96e60 Binary files /dev/null and b/docs/img/skin-funkin-cardbordtoast.jpg differ diff --git a/docs/index.html b/docs/index.html index b6ec87fd2..11137c674 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,8 +13,9 @@ Friday Night Funkin' - + + @@ -22,13 +23,38 @@
- Friday Night Funkin + Friday Night Funkin
- -

Friday Night Funkin the video game

- +

Friday Night Funkin' - Rhythm game extraordinaire

+ + +
+
+ +
+
+ + +
+

Friday Night Funkin' is a dope ass rhythm game.

+

It is made by ninjamuffin99 (programmer), PhantomArcade (animator), evilsk8r (artist), + and Kawaisprite (musician) originally for Ludum Dare 47.

+
+ + + + +
\ No newline at end of file diff --git a/docs/styles.css b/docs/styles.css new file mode 100644 index 000000000..5ee1062fb --- /dev/null +++ b/docs/styles.css @@ -0,0 +1,97 @@ +.coolBox { + background: #1a1a1aCC; + margin: 40px 4vw; + padding: 25px; + font-size: 120%; + border-radius: 10px; +} + +#wrapper +{ + padding: 20px; + margin: auto; +} + +marquee { + margin: auto; + text-align: center; + display: inline-block; +} + +h1 { + text-align: center; +} + +body { + background-image: url('img/skin-funkin-cardbordtoast.jpg'); + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; + color:white; + background-color: #000; + font-family: Arial, Helvetica, sans-serif; + +} + +a { color:inherit; + text-decoration: none;} + + +.hovertext a{ + color:white; + text-shadow: 0px 0px #00000077; + transition: color 1s, text-shadow 1s; +} + +.hovertext a:hover +{ + text-shadow: 2px 2px #00000077; + color: #ffb50e; +} + +.linktext { + text-align: center; + display:block; + font-size: 130%; + padding-bottom: 10px; +} + +.linktext a { + font-weight: bold; +} + +.linktext a:hover { + border-radius: 5px; +} + +#itch a:hover +{ + color: #fa5c5c; +} +#twitter a:hover +{ + color: #00acee; +} + + +#coolervidwrapper { + padding-left: min(12em, 75%); + padding-right: min(12em, 75%); + min-width: 30%; +} + +.videoWrapper { + position: relative; + padding-bottom: 56.25%; /* 16:9 */ + height: 0; + + max-block-size: 1400px; +} +.videoWrapper iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + +} diff --git a/source/ChartingState.hx b/source/ChartingState.hx index 1dd6eb0b6..f83eae315 100644 --- a/source/ChartingState.hx +++ b/source/ChartingState.hx @@ -384,6 +384,8 @@ class ChartingState extends MusicBeatState override function update(elapsed:Float) { + curStep = recalculateSteps(); + Conductor.songPosition = FlxG.sound.music.time; _song.song = typingShit.text; @@ -391,7 +393,7 @@ class ChartingState extends MusicBeatState if (curBeat % 4 == 0) { - if (curStep > lengthBpmBullshit() * (curSection + 1)) + if (curStep > 16 * (curSection + 1)) { trace(curStep); trace((_song.notes[curSection].lengthInSteps) * (curSection + 1)); @@ -406,6 +408,9 @@ class ChartingState extends MusicBeatState } } + FlxG.watch.addQuick('daBeat', curBeat); + FlxG.watch.addQuick('daStep', curStep); + if (FlxG.mouse.justPressed) { if (FlxG.mouse.overlaps(curRenderedNotes)) @@ -517,6 +522,28 @@ class ChartingState extends MusicBeatState super.update(elapsed); } + function recalculateSteps():Int + { + var steps:Int = 0; + var timeShit:Float = 0; + + for (i in 0...curSection) + { + steps += 16; + + if (_song.notes[i].changeBPM) + timeShit += (((60 / _song.notes[i].bpm) * 1000) / 4) * 16; + else + timeShit += (((60 / _song.bpm) * 1000) / 4) * 16; + } + + steps += Math.floor((FlxG.sound.music.time - timeShit) / Conductor.stepCrochet); + curStep = steps; + updateBeat(); + + return curStep; + } + function changeSection(sec:Int = 0, ?updateMusic:Bool = true):Void { trace('changing section' + sec); @@ -699,7 +726,7 @@ class ChartingState extends MusicBeatState private function addNote():Void { - var noteStrum = getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * lengthBpmBullshit())); + var noteStrum = getStrumTime(dummyArrow.y) + (curSection * (Conductor.stepCrochet * 16)); var noteData = Math.floor(FlxG.mouse.x / GRID_SIZE); var noteSus = 0; diff --git a/source/FreeplayState.hx b/source/FreeplayState.hx index 7b0dbbe8b..d92e1b4c0 100644 --- a/source/FreeplayState.hx +++ b/source/FreeplayState.hx @@ -24,14 +24,17 @@ class FreeplayState extends MusicBeatState var intendedScore:Int = 0; private var grpSongs:FlxTypedGroup; + private var curPlaying:Bool = false; override function create() { - if (FlxG.sound.music != null) - { - if (!FlxG.sound.music.playing) - FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); - } + /* + if (FlxG.sound.music != null) + { + if (!FlxG.sound.music.playing) + FlxG.sound.playMusic('assets/music/freakyMenu' + TitleState.soundExt); + } + */ var isDebug:Bool = false; @@ -118,6 +121,11 @@ class FreeplayState extends MusicBeatState { super.update(elapsed); + if (FlxG.sound.music.volume < 0.7) + { + FlxG.sound.music.volume += 0.5 * FlxG.elapsed; + } + lerpScore = Math.floor(FlxMath.lerp(lerpScore, intendedScore, 0.4)); if (Math.abs(lerpScore - intendedScore) <= 10) @@ -151,6 +159,7 @@ class FreeplayState extends MusicBeatState if (accepted) { var poop:String = Highscore.formatSong(songs[curSelected].toLowerCase(), curDifficulty); + trace(poop); PlayState.SONG = Song.loadFromJson(poop, songs[curSelected].toLowerCase()); @@ -192,6 +201,9 @@ class FreeplayState extends MusicBeatState NGio.logEvent('Fresh'); #end + // NGio.logEvent('Fresh'); + FlxG.sound.play('assets/sounds/scrollMenu' + TitleState.soundExt, 0.4); + curSelected += change; if (curSelected < 0) @@ -206,6 +218,8 @@ class FreeplayState extends MusicBeatState // lerpScore = 0; #end + FlxG.sound.playMusic('assets/music/' + songs[curSelected] + "_Inst" + TitleState.soundExt, 0); + var bullShit:Int = 0; for (item in grpSongs.members) diff --git a/source/MainMenuState.hx b/source/MainMenuState.hx index d92735e51..ecaa59d4b 100644 --- a/source/MainMenuState.hx +++ b/source/MainMenuState.hx @@ -113,7 +113,11 @@ class MainMenuState extends MusicBeatState { if (optionShit[curSelected] == 'donate') { + #if linux + Sys.command('/usr/bin/xdg-open', ["https://ninja-muffin24.itch.io/funkin", "&"]); + #else FlxG.openURL('https://ninja-muffin24.itch.io/funkin'); + #end } else { diff --git a/source/MusicBeatState.hx b/source/MusicBeatState.hx index 0d9da14a5..0d3862002 100644 --- a/source/MusicBeatState.hx +++ b/source/MusicBeatState.hx @@ -34,11 +34,17 @@ class MusicBeatState extends FlxUIState everyStep(); updateCurStep(); - curBeat = Math.floor(curStep / 4); + // Needs to be ROUNED, rather than ceil or floor + updateBeat(); super.update(elapsed); } + private function updateBeat():Void + { + curBeat = Math.round(curStep / 4); + } + /** * CHECKS EVERY FRAME */ @@ -64,6 +70,13 @@ class MusicBeatState extends FlxUIState totalSteps += 1; lastStep += Conductor.stepCrochet; + // If the song is at least 3 steps behind + if (Conductor.songPosition > lastStep + (Conductor.stepCrochet * 3)) + { + lastStep = Conductor.songPosition; + totalSteps = Math.ceil(lastStep / Conductor.stepCrochet); + } + if (totalSteps % 4 == 0) beatHit(); } diff --git a/source/PauseSubState.hx b/source/PauseSubState.hx index dbf232b6d..1c7297043 100644 --- a/source/PauseSubState.hx +++ b/source/PauseSubState.hx @@ -4,38 +4,124 @@ import Controls.Control; import flixel.FlxG; import flixel.FlxSprite; import flixel.FlxSubState; +import flixel.group.FlxGroup.FlxTypedGroup; import flixel.input.keyboard.FlxKey; +import flixel.system.FlxSound; import flixel.util.FlxColor; -class PauseSubState extends FlxSubState +class PauseSubState extends MusicBeatSubstate { + var grpMenuShit:FlxTypedGroup; + + var menuItems:Array = ['Resume', 'Restart Song', 'Exit to menu']; + var curSelected:Int = 0; + + var pauseMusic:FlxSound; + public function new(x:Float, y:Float) { super(); + + pauseMusic = new FlxSound().loadEmbedded('assets/music/breakfast' + TitleState.soundExt, true, true); + pauseMusic.volume = 0; + pauseMusic.play(false, FlxG.random.int(0, Std.int(pauseMusic.length / 2))); + + FlxG.sound.list.add(pauseMusic); + var bg:FlxSprite = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); bg.alpha = 0.6; bg.scrollFactor.set(); add(bg); - var bf:Boyfriend = new Boyfriend(x, y); - bf.scrollFactor.set(); - // add(bf); + grpMenuShit = new FlxTypedGroup(); + add(grpMenuShit); - bf.playAnim('firstDeath'); + for (i in 0...menuItems.length) + { + var songText:Alphabet = new Alphabet(0, (70 * i) + 30, menuItems[i], true, false); + songText.isMenuItem = true; + songText.targetY = i; + grpMenuShit.add(songText); + } - bg.cameras = [FlxG.cameras.list[1]]; + changeSelection(); + + cameras = [FlxG.cameras.list[1]]; } override function update(elapsed:Float) { + if (pauseMusic.volume < 0.5) + pauseMusic.volume += 0.01 * elapsed; + super.update(elapsed); + var upP = controls.UP_P; + var downP = controls.DOWN_P; + var accepted = controls.ACCEPT; + + if (upP) + { + changeSelection(-1); + } + if (downP) + { + changeSelection(1); + } + + if (accepted) + { + var daSelected:String = menuItems[curSelected]; + + switch (daSelected) + { + case "Resume": + close(); + case "Restart Song": + FlxG.resetState(); + case "Exit to menu": + FlxG.switchState(new MainMenuState()); + } + } + if (FlxG.keys.justPressed.J) { - PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); + // for reference later! + // PlayerSettings.player1.controls.replaceBinding(Control.LEFT, Keys, FlxKey.J, null); } + } - if (FlxG.keys.justPressed.ENTER) - close(); + override function destroy() + { + pauseMusic.destroy(); + + super.destroy(); + } + + function changeSelection(change:Int = 0):Void + { + curSelected += change; + + if (curSelected < 0) + curSelected = menuItems.length - 1; + if (curSelected >= menuItems.length) + curSelected = 0; + + var bullShit:Int = 0; + + for (item in grpMenuShit.members) + { + item.targetY = bullShit - curSelected; + bullShit++; + + item.alpha = 0.6; + // item.setGraphicSize(Std.int(item.width * 0.8)); + + if (item.targetY == 0) + { + item.alpha = 1; + // item.setGraphicSize(Std.int(item.width)); + } + } } } diff --git a/source/PlayState.hx b/source/PlayState.hx index 17ec105dc..6437c0f5a 100644 --- a/source/PlayState.hx +++ b/source/PlayState.hx @@ -83,6 +83,7 @@ class PlayState extends MusicBeatState var talking:Bool = true; var songScore:Int = 0; + var scoreTxt:FlxText; public static var campaignScore:Int = 0; @@ -252,6 +253,11 @@ class PlayState extends MusicBeatState // healthBar add(healthBar); + scoreTxt = new FlxText(healthBarBG.x + healthBarBG.width - 190, healthBarBG.y + 30, 0, "", 20); + scoreTxt.setFormat("assets/fonts/vcr.ttf", 16, FlxColor.WHITE, RIGHT); + scoreTxt.scrollFactor.set(); + add(scoreTxt); + healthHeads = new FlxSprite(); var headTex = FlxAtlasFrames.fromSparrow(AssetPaths.healthHeads__png, AssetPaths.healthHeads__xml); healthHeads.frames = headTex; @@ -277,6 +283,7 @@ class PlayState extends MusicBeatState healthBar.cameras = [camHUD]; healthBarBG.cameras = [camHUD]; healthHeads.cameras = [camHUD]; + scoreTxt.cameras = [camHUD]; doof.cameras = [camHUD]; // if (SONG.song == 'South') @@ -585,19 +592,18 @@ class PlayState extends MusicBeatState private var paused:Bool = false; var startedCountdown:Bool = false; + var canPause:Bool = true; override public function update(elapsed:Float) { super.update(elapsed); - //trace("FlxG.elapsed: " + FlxG.elapsed); trace("FlxG.sound.music.time: " + FlxG.sound.music.time); trace("Conductor.songPosition: " + Conductor.songPosition); - //trace("FlxG.sound.music.playing: " + FlxG.sound.music.playing); - //trace("SONG POS: " + Conductor.songPosition); - // FlxG.sound.music.pitch = 2; - if (FlxG.keys.justPressed.ENTER && startedCountdown) + scoreTxt.text = "Score:" + songScore; + + if (FlxG.keys.justPressed.ENTER && startedCountdown && canPause) { persistentUpdate = false; persistentDraw = true; @@ -846,6 +852,8 @@ class PlayState extends MusicBeatState function endSong():Void { + canPause = false; + #if !switch Highscore.saveScore(SONG.song, songScore, storyDifficulty); #end