This commit is contained in:
Kade M 2021-07-11 15:33:57 -07:00
commit a575a4c9c4
18 changed files with 154 additions and 97 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 560 KiB

After

Width:  |  Height:  |  Size: 443 KiB

View File

@ -24,17 +24,23 @@ If you're looking for documentation, changelogs, or guides, you can find those o
# Previews ([skip](#features))
![Tutorial (Hard) on Downscroll](https://user-images.githubusercontent.com/15311104/113989685-fa5aea80-9850-11eb-9180-f5819a774c79.gif) ![Milf (Hard) on Downscroll](https://user-images.githubusercontent.com/15311104/113990845-2c208100-9852-11eb-8e6d-f1c9e8439871.gif)
![Title Screen](art/readme/KadeEngineTitleScreen.png)
![Roses (Hard) on Upscroll](https://user-images.githubusercontent.com/15311104/113993573-e31dfc00-9854-11eb-82ae-1f29dc8a0b04.png)
![Week Select](art/readme/KadeEngineWeekSelect.png)
![Milf (Hard) on Downscroll](https://user-images.githubusercontent.com/15311104/113991654-f4660900-9852-11eb-8c3d-f3927571f19b.png)
![Freeplay](art/readme/KadeEngineFreeplay.png)
![He malding](https://user-images.githubusercontent.com/15311104/113993693-02b52480-9855-11eb-9975-eb8a7a1be8d1.png)
![Options](art/readme/KadeEngineOptions.png)
![Free Play selection screen](https://i.imgur.com/LR0eWIC.png)
![Senpai Gameplay (Hard, Upscroll)](art/readme/KadeEnginePixelGameplay.png)
![Options Menu](https://i.imgur.com/LBXW9C1.png)
![Roses Dialogue](art/readme/KadeEngineDialogue.png)
![Pause Screen](art/readme/KadeEnginePauseScreen.png)
![Results Screen](art/readme/KadeEngineResultsScreen.png)
![Replay Loader](art/readme/KadeEngineReplayLoader.png)
# Features
@ -43,12 +49,15 @@ If you're looking for documentation, changelogs, or guides, you can find those o
- **More information during gameplay**
- While you're playing, we show you information about how you're doing, such as your accuracy, combo break count, notes per second, and your grade/rating.
- **Customizable keybinds**
- Instead of being forced to use WASD and the arrow keys, you can customize the keybinds to any keys you want!
- Instead of being forced to use WASD and the arrow keys, you can set any keybinds you want!
- **Replays** (in beta)
- Have you ever gotten a crazy score but didn't record? The replay system solves that: it automatically saves a "replay" of your gameplay every time you complete a song, which you can play back inside of the game.
- Replays just store information about what you're doing, they don't actually record the screen -- so they take up way less space on your disk than videos.
- **Audio offset**
- If your headphones are delayed, you can set an offset in the options menu to line the game up with the delay and play with synced audio like intended.
- If your speakers or headphones are delayed, you can set an offset in the options menu to line the game up with the delay and play with synced audio like intended!
- **And much, much more!**
- There's so much more in store than just what's listed here! If you can imagine a quality of life feature, it's probably
either already included in Kade Engine or is being worked on!
# Credits
### Friday Night Funkin'

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 942 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 KiB

View File

@ -66,6 +66,9 @@ class KadeEngineData
if (FlxG.save.data.distractions == null)
FlxG.save.data.distractions = true;
if (FlxG.save.data.stepMania == null)
FlxG.save.data.stepMania = false;
if (FlxG.save.data.flashing == null)
FlxG.save.data.flashing = true;

View File

@ -1,6 +1,7 @@
package;
import flixel.FlxSprite;
import flixel.FlxG;
import flixel.graphics.frames.FlxAtlasFrames;
class CharacterSetting
@ -33,6 +34,10 @@ class MenuCharacter extends FlxSprite
];
private var flipped:Bool = false;
//questionable variable name lmfao
private var goesLeftNRight:Bool = false;
private var danceLeft:Bool = false;
private var character:String = '';
public function new(x:Int, y:Int, scale:Float, flipped:Bool)
{
@ -43,15 +48,17 @@ class MenuCharacter extends FlxSprite
frames = Paths.getSparrowAtlas('campaign_menu_UI_characters');
animation.addByPrefix('bf', "BF idle dance white", 24);
animation.addByPrefix('bf', "BF idle dance white", 24, false);
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.addByPrefix('pico', "Pico Idle Dance", 24);
animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24);
animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24);
animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24);
animation.addByIndices('gf-left', 'GF Dancing Beat WHITE', [30, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "", 24, false);
animation.addByIndices('gf-right', 'GF Dancing Beat WHITE', [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29], "", 24, false);
animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24, false);
animation.addByIndices('spooky-left', 'spooky dance idle BLACK LINES', [0, 2, 6], "", 12, false);
animation.addByIndices('spooky-right', 'spooky dance idle BLACK LINES', [8, 10, 12, 14], "", 12, false);
animation.addByPrefix('pico', "Pico Idle Dance", 24, false);
animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24, false);
animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24, false);
animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24, false);
setGraphicSize(Std.int(width * scale));
updateHitbox();
@ -59,6 +66,8 @@ class MenuCharacter extends FlxSprite
public function setCharacter(character:String):Void
{
var sameCharacter:Bool = character == this.character;
this.character = character;
if (character == '')
{
visible = false;
@ -69,11 +78,33 @@ class MenuCharacter extends FlxSprite
visible = true;
}
animation.play(character);
if (!sameCharacter) {
bopHead(true);
}
var setting:CharacterSetting = settings[character];
offset.set(setting.x, setting.y);
setGraphicSize(Std.int(width * setting.scale));
flipX = setting.flipped != flipped;
}
public function bopHead(LastFrame:Bool = false):Void
{
if (character == 'gf' || character == 'spooky') {
danceLeft = !danceLeft;
if (danceLeft)
animation.play(character + "-left", true);
else
animation.play(character + "-right", true);
} else {
//no spooky nor girlfriend so we do da normal animation
if (animation.name == "bfConfirm")
return;
animation.play(character, true);
}
if (LastFrame) {
animation.finish();
}
}
}

View File

@ -17,6 +17,9 @@ class Note extends FlxSprite
{
public var strumTime:Float = 0;
public var baseStrum:Float = 0;
public var rStrumTime:Float = 0;
public var mustPress:Bool = false;
public var noteData:Int = 0;
public var rawNoteData:Int = 0;
@ -27,6 +30,8 @@ class Note extends FlxSprite
public var modifiedByLua:Bool = false;
public var sustainLength:Float = 0;
public var isSustainNote:Bool = false;
public var originColor:Int = 0; // The sustain note's original note's color
public var noteSection:Int = 0;
public var noteScore:Float = 1;
@ -38,7 +43,12 @@ class Note extends FlxSprite
public var rating:String = "shit";
public var modAngle:Float = 0; // The angle set by modcharts
public var localAngle:Float = 0; // The angle to be edited inside Note.hx
public var dataColor:Array<String> = ['purple', 'blue', 'green', 'red'];
public var quantityColor:Array<Int> = [RED_NOTE, 2, BLUE_NOTE, 2, PURP_NOTE, 2, BLUE_NOTE, 2];
public var arrowAngles:Array<Int> = [180, 90, 270, 0];
public var isParent:Bool = false;
public var parent:Note = null;
@ -60,10 +70,17 @@ class Note extends FlxSprite
x += 50;
// MAKE SURE ITS DEFINITELY OFF SCREEN?
y -= 2000;
if (inCharter)
{
this.strumTime = strumTime;
else
rStrumTime = strumTime;
}
else
{
this.strumTime = Math.round(strumTime);
rStrumTime = strumTime - (FlxG.save.data.offset + PlayState.songOffset);
}
if (this.strumTime < 0 )
@ -127,9 +144,27 @@ class Note extends FlxSprite
x += swagWidth * noteData;
animation.play(dataColor[noteData] + 'Scroll');
originColor = noteData; // The note's origin color will be checked by its sustain notes
// trace(prevNote);
if (FlxG.save.data.stepMania && !isSustainNote)
{
var strumCheck:Float = rStrumTime;
// I give up on fluctuating bpms. something has to be subtracted from strumCheck to make them look right but idk what.
// I'd use the note's section's start time but neither the note's section nor its start time are accessible by themselves
//strumCheck -= ???
var ind:Int = Std.int(Math.round(strumCheck / (Conductor.stepCrochet / 2)));
var col:Int = 0;
col = quantityColor[ind % 8]; // Set the color depending on the beats
animation.play(dataColor[col] + 'Scroll');
localAngle -= arrowAngles[col];
localAngle += arrowAngles[noteData];
originColor = col;
}
// we make sure its downscroll and its a SUSTAIN NOTE (aka a trail, not a note)
// and flip it so it doesn't look weird.
// THIS DOESN'T FUCKING FLIP THE NOTE, CONTRIBUTERS DON'T JUST COMMENT THIS OUT JESUS
@ -144,8 +179,9 @@ class Note extends FlxSprite
x += width / 2;
animation.play(dataColor[noteData] + 'holdend');
originColor = prevNote.originColor;
animation.play(dataColor[originColor] + 'holdend'); // This works both for normal colors and quantization colors
updateHitbox();
x -= width / 2;
@ -158,7 +194,7 @@ class Note extends FlxSprite
if (prevNote.isSustainNote)
{
prevNote.animation.play(dataColor[prevNote.noteData] + 'hold');
prevNote.animation.play(dataColor[prevNote.originColor] + 'hold');
if(FlxG.save.data.scrollSpeed != 1)
prevNote.scale.y *= Conductor.stepCrochet / 100 * 1.5 * FlxG.save.data.scrollSpeed;
@ -173,6 +209,7 @@ class Note extends FlxSprite
override function update(elapsed:Float)
{
super.update(elapsed);
angle = modAngle + localAngle;
if (!modifiedByLua)
if (!sustainActive)

View File

@ -244,6 +244,26 @@ class DistractionsAndEffectsOption extends Option
}
}
class StepManiaOption extends Option
{
public function new(desc:String)
{
super();
description = desc;
}
public override function press():Bool
{
FlxG.save.data.stepMania = !FlxG.save.data.stepMania;
display = updateDisplay();
return true;
}
private override function updateDisplay():String
{
return "Colors by quantization " + (!FlxG.save.data.stepMania ? "off" : "on");
}
}
class ResetButtonOption extends Option
{
public function new(desc:String)
@ -833,6 +853,7 @@ class ResetSettings extends Option
FlxG.save.data.strumline = null;
FlxG.save.data.customStrumLine = null;
FlxG.save.data.camzoom = null;
FlxG.save.data.stepMania = null;
KadeEngineData.initSave();
confirm = false;
trace('All settings have been reset');

View File

@ -42,10 +42,11 @@ class OptionsMenu extends MusicBeatState
new OptionCategory("Appearance", [
new DistractionsAndEffectsOption("Toggle stage distractions that can hinder your gameplay."),
new CamZoomOption("Toggle the camera zoom in-game."),
new RainbowFPSOption("Make the FPS Counter Rainbow"),
new StepManiaOption("Sets the colors of the arrows depending on quantization instead of direction."),
new AccuracyOption("Display accuracy information."),
new NPSDisplayOption("Shows your current Notes Per Second."),
new SongPositionOption("Show the songs current position (as a bar)"),
new NPSDisplayOption("Shows your current Notes Per Second."),
new RainbowFPSOption("Make the FPS Counter Rainbow"),
new CpuStrums("CPU's strumline lights up when a note hits it."),
]),

View File

@ -241,6 +241,7 @@ class PlayState extends MusicBeatState
// Animation common suffixes
private var dataSuffix:Array<String> = ['LEFT', 'DOWN', 'UP', 'RIGHT'];
private var dataColor:Array<String> = ['purple', 'blue', 'green', 'red'];
// API stuff
@ -1878,73 +1879,23 @@ class PlayState extends MusicBeatState
babyArrow.animation.add('confirm', [12, 16], 24, false);
}
case 'normal':
babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
babyArrow.animation.addByPrefix('green', 'arrowUP');
babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
babyArrow.antialiasing = true;
babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
switch (Math.abs(i))
{
case 2:
babyArrow.x += Note.swagWidth * 2;
babyArrow.animation.addByPrefix('static', 'arrowUP');
babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
case 3:
babyArrow.x += Note.swagWidth * 3;
babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
case 1:
babyArrow.x += Note.swagWidth * 1;
babyArrow.animation.addByPrefix('static', 'arrowDOWN');
babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
case 0:
babyArrow.x += Note.swagWidth * 0;
babyArrow.animation.addByPrefix('static', 'arrowLEFT');
babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
}
default:
babyArrow.frames = Paths.getSparrowAtlas('NOTE_assets');
babyArrow.animation.addByPrefix('green', 'arrowUP');
babyArrow.animation.addByPrefix('blue', 'arrowDOWN');
babyArrow.animation.addByPrefix('purple', 'arrowLEFT');
babyArrow.animation.addByPrefix('red', 'arrowRIGHT');
for (j in 0...4)
{
babyArrow.animation.addByPrefix(dataColor[j], 'arrow' + dataSuffix[j]);
}
var lowerDir:String = dataSuffix[i].toLowerCase();
babyArrow.animation.addByPrefix('static', 'arrow' + dataSuffix[i]);
babyArrow.animation.addByPrefix('pressed', lowerDir + ' press', 24, false);
babyArrow.animation.addByPrefix('confirm', lowerDir + ' confirm', 24, false);
babyArrow.x += Note.swagWidth * i;
babyArrow.antialiasing = true;
babyArrow.setGraphicSize(Std.int(babyArrow.width * 0.7));
switch (Math.abs(i))
{
case 2:
babyArrow.x += Note.swagWidth * 2;
babyArrow.animation.addByPrefix('static', 'arrowUP');
babyArrow.animation.addByPrefix('pressed', 'up press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'up confirm', 24, false);
case 3:
babyArrow.x += Note.swagWidth * 3;
babyArrow.animation.addByPrefix('static', 'arrowRIGHT');
babyArrow.animation.addByPrefix('pressed', 'right press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'right confirm', 24, false);
case 1:
babyArrow.x += Note.swagWidth * 1;
babyArrow.animation.addByPrefix('static', 'arrowDOWN');
babyArrow.animation.addByPrefix('pressed', 'down press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'down confirm', 24, false);
case 0:
babyArrow.x += Note.swagWidth * 0;
babyArrow.animation.addByPrefix('static', 'arrowLEFT');
babyArrow.animation.addByPrefix('pressed', 'left press', 24, false);
babyArrow.animation.addByPrefix('confirm', 'left confirm', 24, false);
}
}
babyArrow.updateHitbox();
@ -2790,18 +2741,6 @@ class PlayState extends MusicBeatState
// Accessing the animation name directly to play it
var singData:Int = Std.int(Math.abs(daNote.noteData));
dad.playAnim('sing' + dataSuffix[singData] + altAnim, true);
switch (Math.abs(daNote.noteData))
{
case 2:
dad.playAnim('singUP' + altAnim, true);
case 3:
dad.playAnim('singRIGHT' + altAnim, true);
case 1:
dad.playAnim('singDOWN' + altAnim, true);
case 0:
dad.playAnim('singLEFT' + altAnim, true);
}
if (FlxG.save.data.cpuStrums)
{
@ -2847,6 +2786,8 @@ class PlayState extends MusicBeatState
daNote.angle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
if (daNote.sustainActive)
daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
daNote.modAngle = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].angle;
daNote.alpha = playerStrums.members[Math.floor(Math.abs(daNote.noteData))].alpha;
}
else if (!daNote.wasGoodHit && !daNote.modifiedByLua)
{
@ -2856,6 +2797,8 @@ class PlayState extends MusicBeatState
daNote.angle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
if (daNote.sustainActive)
daNote.alpha = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].alpha;
daNote.modAngle = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].angle;
daNote.alpha = strumLineNotes.members[Math.floor(Math.abs(daNote.noteData))].alpha;
}
if (daNote.isSustainNote)

View File

@ -323,6 +323,9 @@ class StoryMenuState extends MusicBeatState
FlxG.switchState(new MainMenuState());
}
if (FlxG.sound.music != null)
Conductor.songPosition = FlxG.sound.music.time;
super.update(elapsed);
}
@ -474,4 +477,13 @@ class StoryMenuState extends MusicBeatState
FlxG.save.data.weekUnlocked = weekUnlocked.length - 1;
FlxG.save.flush();
}
override function beatHit()
{
super.beatHit();
grpWeekCharacters.members[0].bopHead();
grpWeekCharacters.members[1].bopHead();
grpWeekCharacters.members[2].bopHead();
}
}