ArrayList<Object> RenderLater;
float LavaIntensity2 = 1;
boolean DebugMode = false;
boolean BuildMode = false;
ArrayList<Object> Selected;
float BuildModeDragX = 0;
float BuildModeDragY = 0;
float BuildModeXDrag = 0;
float BuildModeYDrag = 0;
boolean BuildModeDrag = false;
boolean OpenedBuildEditor = false;
boolean PressedKeyBind = false;
float BuildModeMoveX = 0;
float BuildModeMoveY = 0;
boolean BuildModeMove = false;
float BuildModeSelectX = 0;
float BuildModeSelectY = 0;
boolean BuildModeSelect = false;
float BuildModeSnapToGrid = 50;
int RealSecondsPassed = 0;
int LastSecond = second();
float CalcMass(float x, float y) {
return (x * y) * MassMult;
float SnapToGrid(float Input, float Grid) {
return round(Input/Grid)*Grid;
float FloorSnapToGrid(float Input, float Grid) {
return floor(Input/Grid)*Grid;
void LoadLevel(String directory) {
BuildModeSnapToGrid = 50 / float(data[8]);
player = new Object(600, 400, float(data[7]), float(data[7]), color(int(data[0]), int(data[1]), int(data[2])), true, true, float(data[5]), float(data[6]), false);
player = new Object(600, 400, float(data[7]), float(data[7]), color(int(data[0]), int(data[1]), int(data[2])), false, false, 0, 0, false);
for (int i = obs.size()-1; i > -1; i--) {
levelData = loadStrings(directory);
for (int i = 0 ; i < levelData.length; i++) {
String LineText = levelData[i];
if (LineText.length() >= 2) {
if (LineText.substring(0, 2).equals("//")) {
if (LineText.substring(0, 1).equals("#")) {
String[] Split = split(LineText, ", ");
float PosX = float(Split[0]);
float PosY = float(Split[1]);
float SizeX = float(Split[2]);
float SizeY = float(Split[3]);
boolean Collide = boolean(Split[7]);
boolean Gravity = boolean(Split[8]);
float GravityX = float(Split[9]);
float GravityY = float(Split[10]);
boolean Deadly = boolean(Split[11]);
obs.add(new Object(PosX, PosY, SizeX, SizeY, color(R, G, B), Collide, Gravity, GravityX, GravityY, Deadly));
data = loadStrings("data.txt");
obs = new ArrayList<Object>();
RenderLater = new ArrayList<Object>();
Selected = new ArrayList<Object>();
player = new Object(600, 400, float(data[7]), float(data[7]), color(int(data[0]), int(data[1]), int(data[2])), true, true, float(data[5]), float(data[6]), false);
player = new Object(600, 400, float(data[7]), float(data[7]), color(int(data[0]), int(data[1]), int(data[2])), false, false, 0, 0, false);
screene = new Object(width/2, height/2, width, height, color(0, 0, 0, 0), true, false, 0, 0, false);
TrailDistance = int(data[9]);
LastFrames = new PVector[TrailDistance];
for (int i = LastFrames.length-1; i > -1; i--) {
LastFrames[i] = new PVector(0, 0);
void SaveLevel(String directory) {
String[] NewList = new String[obs.size()+7];
NewList[0] = "//This is level data, the format of an object for each line is: X, Y, SizeX, SizeY, ColorR, ColorG, ColorB, Collidable, HasGravity, GravityX, GravityY, Deadly";
NewList[1] = "//For example: 100, 500, 1000, 50, 100, 100, 100, true, false, 0, 0, false";
NewList[2] = "//Also if you use // or # at the start, it wont be read as data";
String PosX = str(b.pos.x);
String PosY = str(b.pos.y);
String SizeX = str(b.size.x);
String SizeY = str(b.size.y);
String R = str(red(b.c));
String G = str(green(b.c));
String B = str(blue(b.c));
String Collide = str(b.collide);
String Gravity = str(b.gravity);
String GravityX = str(b.grv.x);
String GravityY = str(b.grv.y);
String Deadly = str(b.Deadly);
String Thing = PosX + ", " + PosY + ", " + SizeX + ", " + SizeY + ", " + R + ", " + G + ", " + B + ", " + Collide + ", " + Gravity + ", " + GravityX + ", " + GravityY + ", " + Deadly;
NewList[NewList.length - 1] = "//https://discord.gg/gbCyzNtCWx join discord to share";
saveStrings(directory, NewList);
float GetMag(PVector Vector) {
return Vector.x + Vector.y + Vector.z;
boolean MouseInFrame(float x1, float y1, float x2, float y2) {
if (mouseX >= x1 && mouseX <= x2 && mouseY >= y1 && mouseY <= y2) {
boolean LeftPress = false;
boolean RightPress = false;
boolean DownPress = false;
PVector LastFrame1 = new PVector(0, 0);
PVector LastFrame2 = new PVector(0, 0);
PVector LastFrame3 = new PVector(0, 0);
PVector LastFrame4 = new PVector(0, 0);
int LastRandom = int(random(2, 10));
float DTMultiplier = 60 / frameRate;
BMS = BuildModeSnapToGrid;
DTMultiplier = 60 / frameRate;
if (second() > LastSecond || second() < LastSecond) {
translate(-player.pos.x - player.vel.x + (width/2), -player.pos.y - player.vel.y + (height/2));
screene.pos = new PVector(player.pos.x, player.pos.y);
BuildModeX = player.pos.x - player.vel.x + (width/2);
BuildModeY = player.pos.y - player.vel.y + (height/2);
for (int i = LastFrames.length-1 ; i > 0; i--) {
LastFrames[i] = new PVector(LastFrames[i-1].x, LastFrames[i-1].y);
player.fakeframe(LastFrames[i].x, LastFrames[i].y, color(int(data[0]), int(data[1]), int(data[2]), 100/i));
LastFrames[0] = player.pos;
player.fakeframe(LastFrames[0].x, LastFrames[0].y, color(int(data[0]), int(data[1]), int(data[2]), 100));
if (screene.colliding(o) || o.gravity) {
for (Object o : RenderLater) {
for (int i = RenderLater.size()-1; i > -1; i--) {
RenderLater.remove(RenderLater.get(i));
player.frame(true, false);
player.fakeframe(player.pos.x, player.pos.y, player.c);
player.vel.x = lerp(player.vel.x, -float(data[3]), 0.2);
player.vel.x = lerp(player.vel.x, float(data[3]), 0.2);
player.vel.x = lerp(player.vel.x, 0, 0.2);
if (!OpenedBuildEditor) {
text("Press B", width/2, height/2);
for (int x = 0; x < width; x+=50) {
stroke(255, 255, 255, 50);
while (FakeX + BuildModeX < 0) {
while (FakeX + BuildModeX > width) {
line(FakeX + BuildModeX, 0, FakeX + BuildModeX, height);
for (int y = 0; y < height; y+=50) {
stroke(255, 255, 255, 50);
while (FakeY + BuildModeY < 0) {
while (FakeY + BuildModeY > height) {
line(0, FakeY + BuildModeY, width, FakeY + BuildModeY);
translate(BuildModeX, BuildModeY);
screene.pos = new PVector(-BuildModeX + width/2, -BuildModeY + height/2);
if (screene.colliding(o)) {
for (Object o : RenderLater) {
for (int i = RenderLater.size()-1; i > -1; i--) {
RenderLater.remove(RenderLater.get(i));
player.frame(true, false);
rect(BuildModeDragX - BuildModeXDrag, BuildModeDragY - BuildModeYDrag, SnapToGrid((mouseX - (BuildModeDragX - BuildModeXDrag) - SnapToGrid(BuildModeX, BuildModeSnapToGrid)), BuildModeSnapToGrid), SnapToGrid((mouseY - (BuildModeDragY - BuildModeYDrag) - SnapToGrid(BuildModeY, BuildModeSnapToGrid)), BuildModeSnapToGrid));
rect(SnapToGrid(mouseX - SnapToGrid(BuildModeX, BMS), BMS), SnapToGrid(mouseY - SnapToGrid(BuildModeY, BMS), BMS), BMS, BMS);
stroke(102, 255, 255, 50);
rect(BuildModeSelectX - BuildModeX, BuildModeSelectY - BuildModeY, mouseX - BuildModeSelectX, mouseY - BuildModeSelectY);
for (int i = Selected.size()-1; i > -1; i--) {
Object o = Selected.get(i);
stroke(102, 255, 255, 50);
rect(o.pos.x - o.size.x/2, o.pos.y - o.size.y/2, o.size.x, o.size.y);
o.pos.x += mouseX - BuildModeMoveX;
o.pos.y += mouseY - BuildModeMoveY;
text("Controls", width/2, 50);
text("B - Toggle Build Mode", width/2, 125);
text("G - (Will remove when gamejam ends) Tell the AI to generate you a random template in Build Mode", width/2, 200);
text("Shift + F - Toggle Lava for an Object in Build Mode", width/2, 275);
text("Z (Hold) - Selection for Build Mode", width/2, 350);
text("M (Hold) - Move Selected Objects in Build Mode", width/2, 425);
text("Q/Del - Delete Objects in Build Mode", width/2, 500);
text("Shift + C - Duplciate Selected Objects in Build Mode", width/2, 575);
text("Shift + R - Reset your cube in PlayTest Mode", width/2, 650);
text("Shift + P - Print the level data in the console so you can share it with others (If the console doesn't automatically open, press a button that should pop up bottom right (This is a WEB VERSION exclusive feature))", width/2, 725);
text("Shift + A - Select All in Build Mode", width/2, 800);
text("Shift + B - Display this shit again", width/2, 875);
text("Press B again to disable this menu", width/2, 950);
int LoadableLevels = int(loadStrings("LoadableLevels.txt")[0]);
float Level = random(1, LoadableLevels);
String string = str(round(Level)-1);
LoadLevel("level" + string + ".txt");
ArrayList<Object> NewSelect = new ArrayList<Object>();
for (Object b : Selected) {
Object newb = new Object(b.pos.x, b.pos.y, b.size.x, b.size.y, b.c, b.collide, b.gravity, b.grv.x, b.grv.y, b.Deadly);
for (int i = Selected.size()-1; i > -1; i--) {
Selected.remove(Selected.get(i));
for (Object b : NewSelect) {
for (int i = NewSelect.size()-1; i > -1; i--) {
NewSelect.remove(NewSelect.get(i));
if (key == 'a' || key == 'A') {
for (int i = Selected.size()-1; i > -1; i--) {
Selected.remove(Selected.get(i));
if (o.pointColliding(mouseX - BuildModeX, mouseY - BuildModeY)) {
o.grv = new PVector(0, 0.1);
if (key == 'd' || key == 'D') {
if (key == 'w' || key == 'W') {
if (key == 's' || key == 'S') {
PVector fakegrv = new PVector(player.grv.x, player.grv.y);
player.vel.y -= fakegrv.y * float(data[4]);
if (key == 'q' || key == 'Q' || keyCode == DELETE) {
for (int i = Selected.size()-1; i > -1; i--) {
Object o = Selected.get(i);
for (int i = obs.size()-1; i > -1; i--) {
if (o.pointColliding(mouseX - BuildModeX, mouseY - BuildModeY)) {
data = loadStrings("data.txt");
OpenedBuildEditor = true;
player = new Object(600, 400, float(data[7]), float(data[7]), color(int(data[0]), int(data[1]), int(data[2])), true, true, float(data[5]), float(data[6]), false);
if (cheatcodes.length() >= 5) {
if (cheatcodes.substring(cheatcodes.length() - 5, cheatcodes.length()).equals("savel")) {
if (o.pointColliding(mouseX - BuildModeX, mouseY - BuildModeY)) {
if (!BuildModeSelect && BuildMode) {
BuildModeSelectX = mouseX;
BuildModeSelectY = mouseY;
for (int i = Selected.size()-1; i > -1; i--) {
Object o = Selected.get(i);
if (BuildMode & !BuildModeMove) {
String[] File = loadStrings("level.txt");
for (int i = 0; i < File.length; i++) {
FileString = FileString + File[i] + "\n";
if (keyCode == CONTROL) {
if (key == 'a' || key == 'A') {
if (key == 'd' || key == 'D') {
if (key == 'w' || key == 'W') {
if (key == 's' || key == 'S') {
Object Selection = new Object(lerp(BuildModeSelectX - BuildModeX, mouseX - BuildModeX, 0.5), lerp(BuildModeSelectY - BuildModeY, mouseY - BuildModeY, 0.5), abs(mouseX - BuildModeSelectX), abs(mouseY - BuildModeSelectY), color(0, 100, 255), true, false, 0, 0, false);
if (Selection.colliding(o) || Selection.pointColliding(o.pos.x, o.pos.y)) {
if (BuildMode & BuildModeMove) {
for (Object o : Selected) {
o.pos.x = SnapToGrid(o.pos.x, BuildModeSnapToGrid/2);
o.pos.y = SnapToGrid(o.pos.y, BuildModeSnapToGrid/2);
BuildModeDragX = SnapToGrid(mouseX, BuildModeSnapToGrid);
BuildModeDragY = SnapToGrid(mouseY, BuildModeSnapToGrid);
BuildModeXDrag = SnapToGrid(BuildModeX, BMS);
BuildModeYDrag = SnapToGrid(BuildModeY, BMS);
for (int i = Selected.size()-1; i > -1; i--) {
Object o = Selected.get(i);
float SizeX = SnapToGrid((mouseX - (BuildModeDragX - BuildModeXDrag) - SnapToGrid(BuildModeX, BMS)), BuildModeSnapToGrid);
float SizeY = SnapToGrid((mouseY - (BuildModeDragY - BuildModeYDrag) - SnapToGrid(BuildModeY, BMS)), BuildModeSnapToGrid);
float PosX = lerp(BuildModeDragX - BuildModeXDrag, (BuildModeDragX - BuildModeXDrag) + SizeX, 0.5);
float PosY = lerp(BuildModeDragY - BuildModeYDrag, (BuildModeDragY - BuildModeYDrag) + SizeY, 0.5);
if (SizeX > 0 && SizeY > 0) {
obs.add(new Object(PosX, PosY, SizeX, SizeY, color(0), true, false, 0, 0, false));