1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-09-29 13:48:50 +00:00

Work in progress, basic stage done

This commit is contained in:
Eric Myllyoja 2022-02-23 16:49:54 -05:00
parent a11e182b79
commit 7b8883d3dd
10 changed files with 413 additions and 178 deletions

28
.vscode/launch.json vendored
View file

@ -1,19 +1,27 @@
{ {
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "HTML5 Debug",
"type": "chrome",
"request": "launch",
"url": "http://127.0.0.1:3001",
"sourceMaps": true,
"webRoot": "${workspaceFolder}",
"preLaunchTask": "debug: html"
},
{ {
// Launch in browser
"name": "HTML5 Debug",
"type": "chrome",
"request": "launch",
"url": "http://127.0.0.1:3001",
"sourceMaps": true,
"webRoot": "${workspaceFolder}",
"preLaunchTask": "debug: html"
},
{
// Launch in native/CPP
"name": "Lime", "name": "Lime",
"type": "lime", "type": "lime",
"request": "launch" "request": "launch"
},
{
// Evaluate macros with debugging enabled
"name": "Haxe Eval",
"type": "haxe-eval",
"request": "launch"
} }
] ]
} }

View file

@ -29,6 +29,10 @@
<!--Mobile-specific--> <!--Mobile-specific-->
<window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" resizable="false"/> <window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" resizable="false"/>
<!-- This macro permanently silences an annoying warning. -->
<option flashStrict="False" />
<haxeflag name="--macro" value="allowPackage('flash')" />
<!-- _____________________________ Path Settings ____________________________ --> <!-- _____________________________ Path Settings ____________________________ -->
<set name="BUILD_DIR" value="export/debug" if="debug" /> <set name="BUILD_DIR" value="export/debug" if="debug" />
@ -109,6 +113,7 @@
<assets path="assets/fonts" embed='true'/> <assets path="assets/fonts" embed='true'/>
<!-- _______________________________ Libraries ______________________________ --> <!-- _______________________________ Libraries ______________________________ -->
<haxelib name="openfl" />
<haxelib name="flixel" /> <haxelib name="flixel" />
<haxedev set='webgl' /> <haxedev set='webgl' />

View file

@ -24,7 +24,7 @@ class GameOverSubstate extends MusicBeatSubstate
gameOverMusic = new FlxSound(); gameOverMusic = new FlxSound();
FlxG.sound.list.add(gameOverMusic); FlxG.sound.list.add(gameOverMusic);
var daStage = PlayState.curStage; var daStage = PlayState.curStageId;
var daBf:String = ''; var daBf:String = '';
switch (daStage) switch (daStage)
{ {

View file

@ -1,6 +1,6 @@
package; package;
#if !(macro) import play.stage.StageData;
import charting.ChartingState; import charting.ChartingState;
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionableState;
@ -13,6 +13,7 @@ import openfl.display.BitmapData;
import play.PicoFight; import play.PicoFight;
import ui.PreferencesMenu; import ui.PreferencesMenu;
import ui.stageBuildShit.StageBuilderState; import ui.stageBuildShit.StageBuilderState;
import util.macro.MacroUtil;
using StringTools; using StringTools;
@ -29,10 +30,15 @@ import sys.io.File;
import sys.thread.Thread; import sys.thread.Thread;
#end #end
/**
* Initializes the game state using custom defines.
* Only used in Debug builds.
*/
class InitState extends FlxTransitionableState class InitState extends FlxTransitionableState
{ {
override public function create():Void override public function create():Void
{ {
trace('This is a debug build, loading InitState...');
#if android #if android
FlxG.android.preventDefaultKeys = [FlxAndroidKey.BACK]; FlxG.android.preventDefaultKeys = [FlxAndroidKey.BACK];
#end #end
@ -113,6 +119,8 @@ class InitState extends FlxTransitionableState
// FlxTransitionableState.skipNextTransOut = true; // FlxTransitionableState.skipNextTransOut = true;
FlxTransitionableState.skipNextTransIn = true; FlxTransitionableState.skipNextTransIn = true;
StageDataParser.loadStageCache();
#if song #if song
var song = getSong(); var song = getSong();
@ -191,21 +199,12 @@ class InitState extends FlxTransitionableState
LoadingState.loadAndSwitchState(new PlayState()); LoadingState.loadAndSwitchState(new PlayState());
} }
} }
#end
function getWeek() function getWeek()
return Std.parseInt(getDefine("week")); return Std.parseInt(MacroUtil.getDefine("week"));
function getSong() function getSong()
return getDefine("song"); return MacroUtil.getDefine("song");
function getDif() function getDif()
return Std.parseInt(getDefine("dif", "1")); return Std.parseInt(MacroUtil.getDefine("dif", "1"));
macro function getDefine(key:String, defaultValue:String = null):haxe.macro.Expr
{
var value = haxe.macro.Context.definedValue(key);
if (value == null)
value = defaultValue;
return macro $v{value};
}

View file

@ -43,29 +43,41 @@ class Note extends FlxSprite
public var isSustainNote:Bool = false; public var isSustainNote:Bool = false;
public var colorSwap:ColorSwap; public var colorSwap:ColorSwap;
/** the lowercase name of the note, for anim control, i.e. left right up down */ /** the lowercase name of the note, for anim control, i.e. left right up down */
public var dirName(get, never):String; public var dirName(get, never):String;
inline function get_dirName() return data.dirName;
inline function get_dirName()
return data.dirName;
/** the uppercase name of the note, for anim control, i.e. left right up down */ /** the uppercase name of the note, for anim control, i.e. left right up down */
public var dirNameUpper(get, never):String; public var dirNameUpper(get, never):String;
inline function get_dirNameUpper() return data.dirNameUpper;
inline function get_dirNameUpper()
return data.dirNameUpper;
/** the lowercase name of the note's color, for anim control, i.e. purple blue green red */ /** the lowercase name of the note's color, for anim control, i.e. purple blue green red */
public var colorName(get, never):String; public var colorName(get, never):String;
inline function get_colorName() return data.colorName;
inline function get_colorName()
return data.colorName;
/** the lowercase name of the note's color, for anim control, i.e. purple blue green red */ /** the lowercase name of the note's color, for anim control, i.e. purple blue green red */
public var colorNameUpper(get, never):String; public var colorNameUpper(get, never):String;
inline function get_colorNameUpper() return data.colorNameUpper;
inline function get_colorNameUpper()
return data.colorNameUpper;
public var highStakes(get, never):Bool; public var highStakes(get, never):Bool;
inline function get_highStakes() return data.highStakes;
inline function get_highStakes()
return data.highStakes;
public var lowStakes(get, never):Bool; public var lowStakes(get, never):Bool;
inline function get_lowStakes() return data.lowStakes;
inline function get_lowStakes()
return data.lowStakes;
public static var swagWidth:Float = 160 * 0.7; public static var swagWidth:Float = 160 * 0.7;
public static var PURP_NOTE:Int = 0; public static var PURP_NOTE:Int = 0;
public static var GREEN_NOTE:Int = 2; public static var GREEN_NOTE:Int = 2;
@ -103,7 +115,7 @@ class Note extends FlxSprite
data.noteData = noteData; data.noteData = noteData;
var daStage:String = PlayState.curStage; var daStage:String = PlayState.curStageId;
switch (daStage) switch (daStage)
{ {
@ -187,7 +199,7 @@ class Note extends FlxSprite
x -= width / 2; x -= width / 2;
if (PlayState.curStage.startsWith('school')) if (PlayState.curStageId.startsWith('school'))
x += 30; x += 30;
if (prevNote.isSustainNote) if (prevNote.isSustainNote)
@ -263,7 +275,7 @@ class Note extends FlxSprite
alpha = 0.3; alpha = 0.3;
} }
} }
static public function fromData(data:NoteData, prevNote:Note, isSustainNote = false) static public function fromData(data:NoteData, prevNote:Note, isSustainNote = false)
{ {
return new Note(data.strumTime, data.noteData, prevNote, isSustainNote); return new Note(data.strumTime, data.noteData, prevNote, isSustainNote);
@ -281,96 +293,126 @@ typedef RawNoteData =
@:forward @:forward
abstract NoteData(RawNoteData) abstract NoteData(RawNoteData)
{ {
public function new (strumTime = 0.0, noteData:NoteType = 0, sustainLength = 0.0, altNote = false) public function new(strumTime = 0.0, noteData:NoteType = 0, sustainLength = 0.0, altNote = false)
{ {
this = this = {
{ strumTime : strumTime strumTime: strumTime,
, noteData : noteData noteData: noteData,
, sustainLength : sustainLength sustainLength: sustainLength,
, altNote : altNote altNote: altNote
} }
} }
public var note(get, never):NoteType; public var note(get, never):NoteType;
inline function get_note() return this.noteData.value;
inline function get_note()
return this.noteData.value;
public var int(get, never):Int; public var int(get, never):Int;
inline function get_int() return this.noteData.int;
inline function get_int()
return this.noteData.int;
public var dir(get, never):NoteDir; public var dir(get, never):NoteDir;
inline function get_dir() return this.noteData.value;
inline function get_dir()
return this.noteData.value;
public var dirName(get, never):String; public var dirName(get, never):String;
inline function get_dirName() return dir.name;
inline function get_dirName()
return dir.name;
public var dirNameUpper(get, never):String; public var dirNameUpper(get, never):String;
inline function get_dirNameUpper() return dir.nameUpper;
inline function get_dirNameUpper()
return dir.nameUpper;
public var color(get, never):NoteColor; public var color(get, never):NoteColor;
inline function get_color() return this.noteData.value;
inline function get_color()
return this.noteData.value;
public var colorName(get, never):String; public var colorName(get, never):String;
inline function get_colorName() return color.name;
inline function get_colorName()
return color.name;
public var colorNameUpper(get, never):String; public var colorNameUpper(get, never):String;
inline function get_colorNameUpper() return color.nameUpper;
inline function get_colorNameUpper()
return color.nameUpper;
public var highStakes(get, never):Bool; public var highStakes(get, never):Bool;
inline function get_highStakes() return this.noteData.highStakes;
inline function get_highStakes()
return this.noteData.highStakes;
public var lowStakes(get, never):Bool; public var lowStakes(get, never):Bool;
inline function get_lowStakes() return this.noteData.lowStakes;
inline function get_lowStakes()
return this.noteData.lowStakes;
} }
enum abstract NoteType(Int) from Int to Int enum abstract NoteType(Int) from Int to Int
{ {
// public var raw(get, never):Int; // public var raw(get, never):Int;
// inline function get_raw() return this; // inline function get_raw() return this;
public var int(get, never):Int; public var int(get, never):Int;
inline function get_int() return this < 0 ? -this : this % 4;
inline function get_int()
return this < 0 ? -this : this % 4;
public var value(get, never):NoteType; public var value(get, never):NoteType;
inline function get_value() return int;
inline function get_value()
return int;
public var highStakes(get, never):Bool; public var highStakes(get, never):Bool;
inline function get_highStakes() return this > 3;
inline function get_highStakes()
return this > 3;
public var lowStakes(get, never):Bool; public var lowStakes(get, never):Bool;
inline function get_lowStakes() return this < 0;
inline function get_lowStakes()
return this < 0;
} }
@:forward @:forward
enum abstract NoteDir(NoteType) from Int to Int from NoteType enum abstract NoteDir(NoteType) from Int to Int from NoteType
{ {
var LEFT = 0; var LEFT = 0;
var DOWN = 1; var DOWN = 1;
var UP = 2; var UP = 2;
var RIGHT = 3; var RIGHT = 3;
var value(get, never):NoteDir; var value(get, never):NoteDir;
inline function get_value() return this.value;
inline function get_value()
return this.value;
public var name(get, never):String; public var name(get, never):String;
function get_name() function get_name()
{ {
return switch(value) return switch (value)
{ {
case LEFT : "left" ; case LEFT: "left";
case DOWN : "down" ; case DOWN: "down";
case UP : "up" ; case UP: "up";
case RIGHT: "right"; case RIGHT: "right";
} }
} }
public var nameUpper(get, never):String; public var nameUpper(get, never):String;
function get_nameUpper() function get_nameUpper()
{ {
return switch(value) return switch (value)
{ {
case LEFT : "LEFT" ; case LEFT: "LEFT";
case DOWN : "DOWN" ; case DOWN: "DOWN";
case UP : "UP" ; case UP: "UP";
case RIGHT: "RIGHT"; case RIGHT: "RIGHT";
} }
} }
@ -380,34 +422,37 @@ enum abstract NoteDir(NoteType) from Int to Int from NoteType
enum abstract NoteColor(NoteType) from Int to Int from NoteType enum abstract NoteColor(NoteType) from Int to Int from NoteType
{ {
var PURPLE = 0; var PURPLE = 0;
var BLUE = 1; var BLUE = 1;
var GREEN = 2; var GREEN = 2;
var RED = 3; var RED = 3;
var value(get, never):NoteColor; var value(get, never):NoteColor;
inline function get_value() return this.value;
inline function get_value()
return this.value;
public var name(get, never):String; public var name(get, never):String;
function get_name() function get_name()
{ {
return switch(value) return switch (value)
{ {
case PURPLE: "purple"; case PURPLE: "purple";
case BLUE : "blue" ; case BLUE: "blue";
case GREEN : "green" ; case GREEN: "green";
case RED : "red" ; case RED: "red";
} }
} }
public var nameUpper(get, never):String; public var nameUpper(get, never):String;
function get_nameUpper() function get_nameUpper()
{ {
return switch(value) return switch (value)
{ {
case PURPLE: "PURPLE"; case PURPLE: "PURPLE";
case BLUE : "BLUE" ; case BLUE: "BLUE";
case GREEN : "GREEN" ; case GREEN: "GREEN";
case RED : "RED" ; case RED: "RED";
} }
} }
} }

View file

@ -1,5 +1,7 @@
package; package;
import play.stage.StageData;
import play.stage.Stage;
import Note; import Note;
import Section.SwagSection; import Section.SwagSection;
import SongLoad.SwagSong; import SongLoad.SwagSong;
@ -41,7 +43,7 @@ import Discord.DiscordClient;
class PlayState extends MusicBeatState class PlayState extends MusicBeatState
{ {
public static var curStage:String = ''; public static var curStageId:String = '';
public static var SONG:SwagSong; public static var SONG:SwagSong;
public static var isStoryMode:Bool = false; public static var isStoryMode:Bool = false;
public static var storyWeek:Int = 0; public static var storyWeek:Int = 0;
@ -51,8 +53,6 @@ class PlayState extends MusicBeatState
public static var practiceMode:Bool = false; public static var practiceMode:Bool = false;
public static var needsReset:Bool = false; public static var needsReset:Bool = false;
var halloweenLevel:Bool = false;
private var vocals:VoicesGroup; private var vocals:VoicesGroup;
private var vocalsFinished:Bool = false; private var vocalsFinished:Bool = false;
@ -390,22 +390,13 @@ class PlayState extends MusicBeatState
switch (SONG.song.toLowerCase()) switch (SONG.song.toLowerCase())
{ {
case 'spookeez' | 'monster' | 'south': case 'spookeez' | 'monster' | 'south':
curStage = "spooky"; curStageId = "spookyMansion";
halloweenLevel = true;
var hallowTex = Paths.getSparrowAtlas('halloween_bg'); // TODO: Move lightning strike behavior to a scripted class extending Stage.
loadStage(curStageId);
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);
isHalloween = true;
case 'pico' | 'blammed' | 'philly': case 'pico' | 'blammed' | 'philly':
curStage = 'philly'; curStageId = 'philly';
var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky')); var bg:FlxSprite = new FlxSprite(-100).loadGraphic(Paths.image('philly/sky'));
bg.scrollFactor.set(0.1, 0.1); bg.scrollFactor.set(0.1, 0.1);
@ -448,7 +439,7 @@ class PlayState extends MusicBeatState
var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street')); var street:FlxSprite = new FlxSprite(-40, streetBehind.y).loadGraphic(Paths.image('philly/street'));
add(street); add(street);
case "milf" | 'satin-panties' | 'high': case "milf" | 'satin-panties' | 'high':
curStage = 'limo'; curStageId = 'limo';
defaultCamZoom *= 0.90; defaultCamZoom *= 0.90;
var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset')); var skyBG:FlxSprite = new FlxSprite(-120, -50).loadGraphic(Paths.image('limo/limoSunset'));
@ -496,7 +487,7 @@ class PlayState extends MusicBeatState
fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol')); fastCar = new FlxSprite(-300, 160).loadGraphic(Paths.image('limo/fastCarLol'));
// add(limo); // add(limo);
case "cocoa" | 'eggnog': case "cocoa" | 'eggnog':
curStage = 'mall'; curStageId = 'mall';
defaultCamZoom *= 0.80; defaultCamZoom *= 0.80;
@ -550,9 +541,9 @@ class PlayState extends MusicBeatState
santa.antialiasing = true; santa.antialiasing = true;
add(santa); add(santa);
case 'winter-horrorland': case 'winter-horrorland':
loadStage('mallEvil'); loadStageOld('mallEvil');
case 'senpai' | 'roses': case 'senpai' | 'roses':
curStage = 'school'; curStageId = 'school';
// defaultCamZoom *= 0.9; // defaultCamZoom *= 0.9;
@ -618,7 +609,7 @@ class PlayState extends MusicBeatState
add(bgGirls); add(bgGirls);
case 'thorns': case 'thorns':
// loadStage('schoolEvil'); // loadStage('schoolEvil');
curStage = 'schoolEvil'; curStageId = 'schoolEvil';
var schoolBG:FlxSprite = new FlxSprite(-200, 0).loadGraphic(Paths.image('weeb/evilSchoolBG')); var schoolBG:FlxSprite = new FlxSprite(-200, 0).loadGraphic(Paths.image('weeb/evilSchoolBG'));
wiggleShit.waveAmplitude = 0.017; wiggleShit.waveAmplitude = 0.017;
@ -639,9 +630,8 @@ class PlayState extends MusicBeatState
schoolFront.setGraphicSize(Std.int(schoolFront.width * 6)); schoolFront.setGraphicSize(Std.int(schoolFront.width * 6));
schoolFront.updateHitbox(); schoolFront.updateHitbox();
add(schoolFront); add(schoolFront);
case 'guns' | 'stress' | 'ugh': case 'guns' | 'stress' | 'ugh':
loadStage('tank'); loadStageOld('tank');
// this goes after tankSky and before tankMountains in stage file // this goes after tankSky and before tankMountains in stage file
// need to accomodate for the velocity thing! // need to accomodate for the velocity thing!
@ -687,12 +677,10 @@ class PlayState extends MusicBeatState
var fgTank3:BGSprite = new BGSprite('tank3', 1300, 1200, 3.5, 2.5, ['fg']); var fgTank3:BGSprite = new BGSprite('tank3', 1300, 1200, 3.5, 2.5, ['fg']);
foregroundSprites.add(fgTank3); foregroundSprites.add(fgTank3);
case "darnell": case "darnell":
loadStage('phillyStreets'); loadStageOld('phillyStreets');
default: default:
loadStage('stage'); loadStageOld('stage');
} }
} }
@ -701,7 +689,7 @@ class PlayState extends MusicBeatState
// all dis is shitty, redo later for stage shit // all dis is shitty, redo later for stage shit
var gfVersion:String = 'gf'; var gfVersion:String = 'gf';
switch (curStage) switch (curStageId)
{ {
case 'limo': case 'limo':
gfVersion = 'gf-car'; gfVersion = 'gf-car';
@ -790,7 +778,7 @@ class PlayState extends MusicBeatState
boyfriend = new Boyfriend(770, 450, SONG.player1); boyfriend = new Boyfriend(770, 450, SONG.player1);
// REPOSITIONING PER STAGE // REPOSITIONING PER STAGE
switch (curStage) switch (curStageId)
{ {
case 'limo': case 'limo':
boyfriend.y -= 220; boyfriend.y -= 220;
@ -838,20 +826,31 @@ class PlayState extends MusicBeatState
dad.y = 870 - dad.height; dad.y = 870 - dad.height;
} }
add(gf); if (curStage != null)
{
// We're using Eric's stage handler.
// Characters get added to the stage, not the main scene.
curStage.addCharacter(boyfriend, BF);
curStage.addCharacter(gf, GF);
curStage.addCharacter(dad, DAD);
}
else
{
add(gf);
gfCutsceneLayer = new FlxGroup(); gfCutsceneLayer = new FlxGroup();
add(gfCutsceneLayer); add(gfCutsceneLayer);
bfTankCutsceneLayer = new FlxGroup(); bfTankCutsceneLayer = new FlxGroup();
add(bfTankCutsceneLayer); add(bfTankCutsceneLayer);
// Shitty layering but whatev it works LOL // Shitty layering but whatev it works LOL
if (curStage == 'limo') if (curStageId == 'limo')
add(limo); add(limo);
add(dad); add(dad);
add(boyfriend); add(boyfriend);
}
} }
function ughIntro() function ughIntro()
@ -940,11 +939,35 @@ class PlayState extends MusicBeatState
});*/ });*/
} }
function loadStage(path:String) public var curStage:Stage;
{
curStage = path;
var json = Assets.getText(Paths.file('data/stagedata/' + curStage + 'Stage.json')); /**
* Loads stage data from cache, assembles the props,
* and adds it to the state.
* @param id
*/
function loadStage(id:String)
{
curStage = StageDataParser.fetchStage(id);
if (curStage != null)
{
// Actually create and position the sprites.
curStage.buildStage();
// Apply camera zoom.
defaultCamZoom *= curStage.camZoom;
// Add the stage to the scene.
this.add(curStage);
}
}
function loadStageOld(path:String)
{
curStageId = path;
var json = Assets.getText(Paths.file('data/stagedata/${curStageId}Stage.json'));
var parsed:StageData = cast Json.parse(json); var parsed:StageData = cast Json.parse(json);
@ -1464,7 +1487,7 @@ class PlayState extends MusicBeatState
var introSprPaths:Array<String> = ["ready", "set", "go"]; var introSprPaths:Array<String> = ["ready", "set", "go"];
var altSuffix:String = ""; var altSuffix:String = "";
if (curStage.startsWith("school")) if (curStageId.startsWith("school"))
{ {
altSuffix = '-pixel'; altSuffix = '-pixel';
introSprPaths = ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel']; introSprPaths = ['weeb/pixelUI/ready-pixel', 'weeb/pixelUI/set-pixel', 'weeb/pixelUI/date-pixel'];
@ -1500,7 +1523,7 @@ class PlayState extends MusicBeatState
var spr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(path)); var spr:FlxSprite = new FlxSprite().loadGraphic(Paths.image(path));
spr.scrollFactor.set(); spr.scrollFactor.set();
if (curStage.startsWith('school')) if (curStageId.startsWith('school'))
spr.setGraphicSize(Std.int(spr.width * daPixelZoom)); spr.setGraphicSize(Std.int(spr.width * daPixelZoom));
spr.updateHitbox(); spr.updateHitbox();
@ -1673,7 +1696,7 @@ class PlayState extends MusicBeatState
babyArrow.shader = colorswap.shader; babyArrow.shader = colorswap.shader;
colorswap.update(Note.arrowColors[i]); colorswap.update(Note.arrowColors[i]);
switch (curStage) switch (curStageId)
{ {
case 'school' | 'schoolEvil': case 'school' | 'schoolEvil':
babyArrow.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17); babyArrow.loadGraphic(Paths.image('weeb/pixelUI/arrows-pixels'), true, 17, 17);
@ -1943,7 +1966,7 @@ class PlayState extends MusicBeatState
// Conductor.lastSongPos = FlxG.sound.music.time; // Conductor.lastSongPos = FlxG.sound.music.time;
} }
switch (curStage) switch (curStageId)
{ {
case 'philly': case 'philly':
if (trainMoving) if (trainMoving)
@ -2498,7 +2521,7 @@ class PlayState extends MusicBeatState
{ {
camFollow.setPosition(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100); camFollow.setPosition(boyfriend.getMidpoint().x - 100, boyfriend.getMidpoint().y - 100);
switch (curStage) switch (curStageId)
{ {
case 'limo': case 'limo':
camFollow.x = boyfriend.getMidpoint().x - 300; camFollow.x = boyfriend.getMidpoint().x - 300;
@ -2684,7 +2707,7 @@ class PlayState extends MusicBeatState
if (!holdArray[spr.ID]) if (!holdArray[spr.ID])
spr.animation.play('static'); spr.animation.play('static');
if (spr.animation.curAnim.name == 'confirm' && !curStage.startsWith('school')) if (spr.animation.curAnim.name == 'confirm' && !curStageId.startsWith('school'))
{ {
spr.centerOffsets(); spr.centerOffsets();
spr.offset.x -= 13; spr.offset.x -= 13;
@ -2695,10 +2718,17 @@ class PlayState extends MusicBeatState
}); });
} }
override function switchTo(nextState:FlxState):Bool function performCleanup()
{ {
openfl.utils.Assets.cache.clear(Paths.inst(SONG.song)); openfl.utils.Assets.cache.clear(Paths.inst(SONG.song));
openfl.utils.Assets.cache.clear(Paths.voices(SONG.song)); openfl.utils.Assets.cache.clear(Paths.voices(SONG.song));
curStage.cleanup();
curStage = null;
}
override function switchTo(nextState:FlxState):Bool
{
performCleanup();
return super.switchTo(nextState); return super.switchTo(nextState);
} }
@ -3002,7 +3032,7 @@ class PlayState extends MusicBeatState
}); });
// boppin friends // boppin friends
switch (curStage) switch (curStageId)
{ {
case 'school': case 'school':
bgGirls.dance(); bgGirls.dance();
@ -3048,10 +3078,10 @@ class PlayState extends MusicBeatState
tankWatchtower.dance(); tankWatchtower.dance();
} }
if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset) // if (isHalloween && FlxG.random.bool(10) && curBeat > lightningStrikeBeat + lightningOffset)
{ // {
lightningStrikeShit(); // lightningStrikeShit();
} // }
} }
var curLight:Int = 0; var curLight:Int = 0;

View file

@ -48,7 +48,7 @@ class SongLoad
public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong public static function loadFromJson(jsonInput:String, ?folder:String):SwagSong
{ {
var rawJson = Assets.getText(Paths.json(folder.toLowerCase() + '/' + jsonInput.toLowerCase())).trim(); var rawJson = Assets.getText(Paths.json('songs/${folder.toLowerCase()}/${jsonInput.toLowerCase()}')).trim();
while (!rawJson.endsWith("}")) while (!rawJson.endsWith("}"))
{ {

View file

@ -1,9 +1,164 @@
package play.stage; package play.stage;
import flixel.FlxObject; import flixel.FlxObject;
import flixel.group.FlxGroup.FlxTypedGroup; import flixel.FlxSprite;
import flixel.group.FlxSpriteGroup;
import flixel.util.FlxSort;
import modding.IHook;
import play.character.Character.CharacterType;
import play.stage.StageData.StageDataParser;
import util.SortUtil;
/** /**
* A Stage is a group of objects. * A Stage is a group of objects rendered in the PlayState.
*
* A Stage is comprised of one or more props, each of which is a FlxSprite.
*/ */
class Stage extends FlxTypedGroup<FlxObject> {} class Stage extends FlxSpriteGroup implements IHook
{
public final stageId:String;
public final stageName:String;
final _data:StageData;
public var camZoom:Float = 1.0;
var namedProps:Map<String, FlxObject> = new Map<String, FlxObject>();
var characters:Map<String, Character> = new Map<String, Character>();
/**
* The Stage elements get initialized at the beginning of the game.
* They're used to cache the data needed to build the stage,
* then accessed and fleshed out when the stage needs to be built.
*
* @param stageId
*/
public function new(stageId:String)
{
super();
this.stageId = stageId;
_data = StageDataParser.parseStageData(this.stageId);
this.stageName = _data.name;
}
/**
* The default stage construction routine. Called when the stage is going to be played in.
* Instantiates each prop and adds it to the stage, while setting its parameters.
*/
public function buildStage()
{
trace('Building stage for display: ${this.stageId}');
this.camZoom = _data.cameraZoom;
for (dataProp in _data.props)
{
trace(' Placing prop: ${dataProp.name} (${dataProp.assetPath})');
var imagePath = Paths.image(dataProp.assetPath);
var propSprite = new FlxSprite().loadGraphic(imagePath);
if (Std.isOfType(dataProp.scale, Array))
{
propSprite.scale.set(dataProp.scale[0], dataProp.scale[1]);
}
else
{
propSprite.scale.set(dataProp.scale);
}
propSprite.updateHitbox();
propSprite.x = dataProp.position[0];
propSprite.y = dataProp.position[1];
propSprite.scrollFactor.x = dataProp.scroll[0];
propSprite.scrollFactor.y = dataProp.scroll[1];
propSprite.zIndex = dataProp.zIndex;
for (propAnim in dataProp.animations)
{
propSprite.animation.addByPrefix(propAnim.name, propAnim.prefix, propAnim.frameRate, propAnim.loop);
}
if (dataProp.startingAnimation != null)
{
propSprite.animation.play(dataProp.startingAnimation);
}
if (dataProp.name != null)
{
namedProps.set(dataProp.name, propSprite);
}
trace(' Prop placed.');
this.add(propSprite);
}
this.refresh();
}
/**
* Refreshes the stage, by redoing the render order of all props.
* It does this based on the `zIndex` of each prop.
*/
public function refresh()
{
sort(SortUtil.byZIndex, FlxSort.ASCENDING);
}
public function addCharacter(character:Character, charType:CharacterType)
{
// Apply position and z-index.
switch (charType)
{
case BF:
this.characters.set("bf", character);
character.zIndex = _data.characters.bf.zIndex;
character.x = _data.characters.bf.position[0];
character.y = _data.characters.bf.position[1];
case GF:
this.characters.set("gf", character);
character.zIndex = _data.characters.gf.zIndex;
character.x = _data.characters.gf.position[0];
character.y = _data.characters.gf.position[1];
case DAD:
this.characters.set("dad", character);
character.zIndex = _data.characters.dad.zIndex;
character.x = _data.characters.dad.position[0];
character.y = _data.characters.dad.position[1];
default:
this.characters.set(character.curCharacter, character);
}
// Add the character to the scene.
this.add(character);
}
public function getCharacter(id:String):Character
{
return this.characters.get(id);
}
public function getBoyfriend():Character
{
return this.characters.get("bf");
}
public function getGirlfriend():Character
{
return this.characters.get("gf");
}
public function getDad():Character
{
return this.characters.get("dad");
}
public function cleanup()
{
this.clear();
namedProps.clear();
characters.clear();
}
}

View file

@ -21,7 +21,7 @@ class PopUpStuff extends FlxTypedGroup<FlxSprite>
var rating:FlxSprite = new FlxSprite(); var rating:FlxSprite = new FlxSprite();
var ratingPath:String = daRating; var ratingPath:String = daRating;
if (PlayState.curStage.startsWith('school')) if (PlayState.curStageId.startsWith('school'))
ratingPath = "weeb/pixelUI/" + ratingPath + "-pixel"; ratingPath = "weeb/pixelUI/" + ratingPath + "-pixel";
rating.loadGraphic(Paths.image(ratingPath)); rating.loadGraphic(Paths.image(ratingPath));
@ -39,7 +39,7 @@ class PopUpStuff extends FlxTypedGroup<FlxSprite>
add(rating); add(rating);
if (PlayState.curStage.startsWith('school')) if (PlayState.curStageId.startsWith('school'))
{ {
rating.setGraphicSize(Std.int(rating.width * PlayState.daPixelZoom * 0.7)); rating.setGraphicSize(Std.int(rating.width * PlayState.daPixelZoom * 0.7));
} }
@ -68,7 +68,7 @@ class PopUpStuff extends FlxTypedGroup<FlxSprite>
var pixelShitPart1:String = ""; var pixelShitPart1:String = "";
var pixelShitPart2:String = ''; var pixelShitPart2:String = '';
if (PlayState.curStage.startsWith('school')) if (PlayState.curStageId.startsWith('school'))
{ {
pixelShitPart1 = 'weeb/pixelUI/'; pixelShitPart1 = 'weeb/pixelUI/';
pixelShitPart2 = '-pixel'; pixelShitPart2 = '-pixel';
@ -89,7 +89,7 @@ class PopUpStuff extends FlxTypedGroup<FlxSprite>
add(comboSpr); add(comboSpr);
if (PlayState.curStage.startsWith('school')) if (PlayState.curStageId.startsWith('school'))
{ {
comboSpr.setGraphicSize(Std.int(comboSpr.width * PlayState.daPixelZoom * 0.7)); comboSpr.setGraphicSize(Std.int(comboSpr.width * PlayState.daPixelZoom * 0.7));
} }
@ -128,7 +128,7 @@ class PopUpStuff extends FlxTypedGroup<FlxSprite>
var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2)); var numScore:FlxSprite = new FlxSprite().loadGraphic(Paths.image(pixelShitPart1 + 'num' + Std.int(i) + pixelShitPart2));
numScore.y = comboSpr.y; numScore.y = comboSpr.y;
if (PlayState.curStage.startsWith('school')) if (PlayState.curStageId.startsWith('school'))
{ {
numScore.setGraphicSize(Std.int(numScore.width * PlayState.daPixelZoom)); numScore.setGraphicSize(Std.int(numScore.width * PlayState.daPixelZoom));
} }

View file

@ -1,8 +1,10 @@
package util; package util;
#if !macro
import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.util.FlxSort; import flixel.util.FlxSort;
import flixel.FlxObject; import flixel.FlxObject;
#end
class SortUtil class SortUtil
{ {
@ -14,13 +16,4 @@ class SortUtil
{ {
return FlxSort.byValues(Order, Obj1.zIndex, Obj2.zIndex); return FlxSort.byValues(Order, Obj1.zIndex, Obj2.zIndex);
} }
/**
* Sorts the element in an FlxTypedGroup by their z-index values.
* @param group The group to sort.
*/
public static inline function sortByZIndex(group:FlxTypedGroup<FlxObject>)
{
group.sort(byZIndex, FlxSort.ASCENDING);
}
} }