Skip to content

Instantly share code, notes, and snippets.

@ubuntor
Last active June 20, 2020 06:53
Show Gist options
  • Save ubuntor/0acb74a5a2201f90b9caee266c0e51cc to your computer and use it in GitHub Desktop.
Save ubuntor/0acb74a5a2201f90b9caee266c0e51cc to your computer and use it in GitHub Desktop.
parabox mockup in processing
int frame = 0;
int depth_limit = 6;
int ti = -1;
String world = "";
String world_ending = "...";
int world_length = 3;
PVector main = new PVector(400, 400, 90);
PVector ba;
PVector bb;
PVector bc;
PVector p;
PImage stage1;
PImage stage2;
// x,y,s vectors
PVector atargets[] = {
new PVector(400, 400, 30),
new PVector(400-30, 400, 30),
new PVector(400-90*1, 400, 90)
};
PVector btargets[] = {
new PVector(400, 400+30, 30),
new PVector(400, 400+30, 30),
new PVector(400, 400+30, 30)
};
PVector ctargets[] = {
new PVector(400-10, 400+30, 10),
new PVector(400-10, 400+30, 10),
new PVector(400-30, 400+30, 30)
};
PVector ptargets[] = {
new PVector(400+30, 400, 30),
new PVector(400, 400, 30),
new PVector(400-30, 400, 30)
};
void setup() {
rectMode(CENTER);
ellipseMode(CENTER);
size(800, 800);
// convert from svg and crop
stage1 = loadImage("stage_1.png");
stage2 = loadImage("stage_2.png");
}
boolean approx_equal(float x, float y) {
return abs(x-y) < 0.01;
}
void clipped_rect(float x, float y, float s) {
if (x + s/2 <= 0 || x - s/2 >= 800 || y + s/2 <= 0 || y - s/2 >= 800) {
return;
}
rect(x, y, s, s);
}
void draw_box(float x, float y, float s, float colorscale, String label, int depth, boolean cloned) {
boolean is_main = approx_equal(x, main.x) && approx_equal(y, main.y) && approx_equal(s, main.z);
if (is_main) {
stroke(255, 255, 255);
} else {
stroke(0, 0, 0);
}
fill(80*colorscale, 100*colorscale, 200*colorscale);
clipped_rect(x, y, s);
textAlign(CENTER, CENTER);
textSize(s);
fill(255, 255, 255, 128);
text(label, x, y - textAscent()*0.08);
fill(100*colorscale, 160*colorscale, 250*colorscale);
clipped_rect(x+s/3, y+s/3, s/3);
float ratio = s/main.z;
PVector ad = PVector.sub(ba, main);
PVector bd = PVector.sub(bb, main);
PVector cd = PVector.sub(bc, main);
PVector pd = PVector.sub(p, main);
draw_player(x + ratio*pd.x, y + ratio*pd.y, ratio*p.z, colorscale);
if (depth > 0) {
if (!cloned) {
draw_box(x + ratio*ad.x, y + ratio*ad.y, ratio*ba.z, colorscale + 0.1, "A", depth-1, cloned);
draw_box(x + ratio*bd.x, y + ratio*bd.y, ratio*bb.z, colorscale + 0.1, "B", depth-1, cloned);
} else {
if (label.equals("A")) {
draw_box(x + ratio*ad.x, y + ratio*ad.y, ratio*ba.z, colorscale + 0.1, "A", depth-1, cloned);
draw_box(x + ratio*bd.x, y + ratio*bd.y, ratio*bb.z, colorscale + 0.1, "B", depth-1, cloned);
draw_box(x + ratio*cd.x, y + ratio*cd.y, ratio*bc.z, colorscale + 0.1, "C", depth-1, cloned);
} else {
draw_box(x + ratio*bd.x, y + ratio*bd.y, ratio*bb.z, colorscale + 0.1, "B", depth-1, cloned);
draw_box(x + ratio*cd.x, y + ratio*cd.y, ratio*bc.z, colorscale + 0.1, "C", depth-1, cloned);
}
}
}
}
void draw_player(float x, float y, float s, float colorscale) {
stroke(0, 0, 0);
fill(242*colorscale, 134*colorscale, 228*colorscale);
clipped_rect(x, y, s);
fill(10*colorscale, 10*colorscale, 10*colorscale);
ellipse(x-2.8*s/10, y-0.8*s/10, s/5, s/5);
ellipse(x+2.8*s/10, y-0.8*s/10, s/5, s/5);
}
PVector interp(PVector a, PVector b, float t) {
return PVector.add(PVector.mult(a, 1-t), PVector.mult(b, t));
}
void draw() {
boolean cloned = frame >= 240+120;
if (frame % 240 == 0) {
ti += 1;
if (ti == atargets.length) {
println("done");
noLoop();
return;
}
}
if (frame % 60 == 0) {
String new_world = world;
while (new_world.equals(world)) {
new_world = "";
if (cloned) {
world_ending = "...";
for (int i = 0; i < world_length; i++) {
int r = (int)(random(5));
if (r == 0) {
new_world += "A";
world_ending = "∞";
break;
} else if (r <= 2) {
new_world += "B";
} else if (r <= 4) {
new_world += "C";
}
}
} else {
for (int i = 0; i < world_length; i++) {
if ((int)(random(2)) == 0) {
new_world += "A";
} else {
new_world += "B";
}
}
}
}
world= new_world;
}
if (frame % 240 >= 120 && ti < atargets.length-1) {
float t = (frame % 240 - 120.0)/120;
ba = interp(atargets[ti], atargets[ti+1], t);
bb = interp(btargets[ti], btargets[ti+1], t);
bc = interp(ctargets[ti], ctargets[ti+1], t);
p = interp(ptargets[ti], ptargets[ti+1], t);
} else {
ba = atargets[ti];
bb = btargets[ti];
bc = ctargets[ti];
p = ptargets[ti];
}
background(0);
float outerx = main.x;
float outery = main.y;
float outers = main.z;
for (int i = 0; i < world.length(); i++) {
PVector parent;
switch (world.charAt(i)) {
case 'A':
default:
parent = ba;
break;
case 'B':
parent = bb;
break;
case 'C':
parent = bc;
break;
}
PVector d = PVector.sub(main, parent);
outerx += outers/parent.z * d.x;
outery += outers/parent.z * d.y;
outers *= main.z/parent.z;
}
if (world.charAt(world.length()-1) == 'A' && cloned) {
for (int i = 0; i < world_length - world.length(); i++) {
PVector d = PVector.sub(main, ba);
outerx += outers/ba.z * d.x;
outery += outers/ba.z * d.y;
outers *= main.z/ba.z;
}
}
draw_box(outerx, outery, outers, 0.8, world.substring(world.length()-1), depth_limit, cloned);
textSize(36);
textAlign(LEFT);
fill(255, 255, 255, 255);
text("World: "+world+world_ending, 500, 750);
if (cloned) {
image(stage2, 50, 508);
} else {
image(stage1, 50, 525);
}
//saveFrame("/tmp/parabox-######.png");
frame += 1;
}
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment