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
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="800" height="600" version="1.1" xmlns="http://www.w3.org/2000/svg">
<ellipse stroke="white" stroke-width="1" fill="none" cx="461.5" cy="238.5" rx="30" ry="30"/>
<text fill="white" x="454.5" y="244.5" font-family="Times New Roman" font-size="20">A</text>
<ellipse stroke="white" stroke-width="1" fill="none" cx="461.5" cy="347.5" rx="30" ry="30"/>
<text fill="white" x="455.5" y="353.5" font-family="Times New Roman" font-size="20">B</text>
<ellipse stroke="white" stroke-width="1" fill="none" cx="569.5" cy="292.5" rx="30" ry="30"/>
<text fill="white" x="563.5" y="298.5" font-family="Times New Roman" font-size="20">C</text>
<polygon stroke="white" stroke-width="1" points="461.5,268.5 461.5,317.5"/>
<polygon fill="white" stroke-width="1" points="461.5,317.5 466.5,309.5 456.5,309.5"/>
<polygon stroke="white" stroke-width="1" points="488.333,251.916 542.667,279.084"/>
<polygon fill="white" stroke-width="1" points="542.667,279.084 537.748,271.034 533.276,279.978"/>
<path stroke="white" stroke-width="1" fill="none" d="M 474.725,374.297 A 22.5,22.5 0 1 1 448.275,374.297"/>
<polygon fill="white" stroke-width="1" points="448.275,374.297 439.527,377.83 447.618,383.708"/>
<path stroke="white" stroke-width="1" fill="none" d="M 479.051,323.296 A 104.997,104.997 0 0 1 539.602,292.46"/>
<polygon fill="white" stroke-width="1" points="539.602,292.46 530.977,288.638 532.387,298.538"/>
<path stroke="white" stroke-width="1" fill="none" d="M 553.796,317.91 A 93.294,93.294 0 0 1 491.287,349.744"/>
<polygon fill="white" stroke-width="1" points="491.287,349.744 499.685,354.041 498.83,344.078"/>
<path stroke="white" stroke-width="1" fill="none" d="M 596.297,279.275 A 22.5,22.5 0 1 1 596.297,305.725"/>
<polygon fill="white" stroke-width="1" points="596.297,305.725 599.83,314.473 605.708,306.382"/>
<path stroke="white" stroke-width="1" fill="none" d="M 448.275,211.703 A 22.5,22.5 0 1 1 474.725,211.703"/>
<text fill="white" x="455" y="162.5" font-family="Times New Roman" font-size="20">∞</text>
<polygon fill="white" stroke-width="1" points="474.725,211.703 483.473,208.17 475.382,202.292"/>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment