I am having some difficulty placing assets and objects into my sketch. Currently the two issues that I am having are that the plant needs to display in front of the plane, and that there is a slight issue without how I am clearing the canvas.
For the first issue, I have tried rearranging the order of the code a bit, but for some reason the plant is always behind the plane, when it should be in front of it.
I tried implementing createGraphics for the second issue in order to preserve the drawing created by the class after it had drawn one iteration of the plant. However, I am not sure how to implement the background or how to clear it so that the plant is always displayed. I don't want to implement noLoop(), because the plant will eventually grow.
Any help would be appreciated, thanks!
let gui;
let ui;
let plantGraphics;
const len = 4;
const ang = 25;
let drawRules;
let word = "X";
let rules = {
X: [
// Original rule
{ rule: "F[+X][-X]FX", prob: 0.5 },
// Fewer limbs
{ rule: "F[-X]FX", prob: 0.05 },
{ rule: "F[+X]FX", prob: 0.05 },
// Extra rotation
{ rule: "F[++X][-X]FX", prob: 0.1 },
{ rule: "F[+X][--X]FX", prob: 0.1 },
// Berries/fruits
{ rule: "F[+X][-X]FA", prob: 0.1 },
{ rule: "F[+X][-X]FB", prob: 0.1 },
],
F: [
// Original rule
{ rule: "FF", prob: 0.85 },
// Extra growth
{ rule: "FFF", prob: 0.05 },
// Stunted growth
{ rule: "F", prob: 0.1 },
],
};
const planeWidth = 200;
const planeHeight = 200;
let platformRotation = 0;
let sapling;
let saplingPlanted = false;
function setup() {
createCanvas(400, 400, WEBGL);
background(220);
ui = {
// regrow: function() {
// console.log('button clicked')
// growPlant();
// },
// Camera Settings
X: 0,
Y: -150,
Z: -400,
centerX: 0,
centerY: 0,
centerZ: 0,
upX: 0,
upY: 1,
upZ: 0,
};
gui = new dat.GUI();
// gui.add(ui, 'regrow').name('Click Me!');
let cameraFolder = gui.addFolder('Camera Settings');
cameraFolder.add(ui, 'X', -2000, 400);
cameraFolder.add(ui, 'Y', -2000, 400);
cameraFolder.add(ui, 'Z', -2000, 400);
cameraFolder.add(ui, 'centerX', -2000, 400);
cameraFolder.add(ui, 'centerY', -2000, 400);
cameraFolder.add(ui, 'centerZ', -2000, 400);
cameraFolder.add(ui, 'upX', -1, 1);
cameraFolder.add(ui, 'upY', -1, 1);
cameraFolder.add(ui, 'upZ', -1, 1);
drawRules = {
"A": () => {
// Draw circle at current location
// noStroke();
// fill("#E5CEDC");
stroke("#E5CEDC");
strokeWeight(5);
// circle(0, 0, len*2);
point(0, 0, len*2)
},
"B": () => {
// Draw circle at current location
// noStroke();
// fill("#FCA17D");
// circle(0, 0, len*2);
stroke("#FCA17D");
strokeWeight(2);
point(0, 0, len*2)
},
"F": () => {
// Draw line forward, then move to end of line
// const nextY = currentY - len;
// if (nextY > -maxY) {
stroke("#9ea93f");
line(0, 0, 0, -len);
// beginShape();
// vertex(0, 0, 0);
// vertex(0, 0, -len);
// endShape();
translate(0, -len);
// }
},
"+": () => {
// Rotate right
rotate(PI/180 * -ang);
},
"-": () => {
// Rotate right
rotate(PI/180 * ang);
},
// Save current location
"[": push,
// Restore last location
"]": pop,
};
plantGraphics = createGraphics(width, height, WEBGL);
plantGraphics.sapling = new Plant(0, 0, 0);
}
function draw() {
if (
mouseIsPressed &&
mouseX >= 0 &&
mouseX <= width &&
mouseY >= 0 &&
mouseY <= height) {
platformRotation += mouseX - pmouseX;
}
rotateX(PI / 2);
rotateZ(radians(platformRotation));
push();
noStroke();
fill(255)
plane(planeWidth, planeHeight);
pop();
// background(211, 217, 219);
// sapling.plantSapling();
plantGraphics.sapling.grow();
image(plantGraphics, -width/2, -height/2);
// sapling.translate(-width/2, -height/2, 0); // center graphics buffer
// image(sapling.pg, 0, 0);
// background(211, 217, 219);
let cameraZ = ui.Z;
let cameraX = ui.X;
let cameraY = ui.Y;
let centerX = ui.centerX;
let centerY = ui.centerY;
let centerZ = ui.centerZ;
let upX = ui.upX;
let upY = ui.upY;
let upZ = ui.upZ;
camera(cameraX, cameraY, cameraZ, centerX, centerY, centerZ, upX, upY, upZ);
}
class Plant {
constructor(x, y, z) {
this.pos = createVector(x, y, z);
this.vel = createVector();
this.acc = createVector();
this.grown = false;
this.len = 3;
this.angle = 25;
this.numGens = 6;
this.word = "X";
// this.next = ""
this.next;
this.drawRules = {
A: () => {
// Draw circle at current location
// noStroke();
// fill("#E5CEDC");
// circle(0, 0, this.len * 2);
stroke("#E5CEDC");
strokeWeight(this.len * 2);
point(this.pos.x, this.pos.y, this.pos.z);
},
B: () => {
// Draw circle at current location
// noStroke();
// fill("#FCA17D");
// circle(0, 0, this.len * 2);
stroke("#FCA17D");
strokeWeight(this.len * 2);
point(this.pos.x, this.pos.y, this.pos.z);
},
F: () => {
// Draw line forward, then move to end of line
stroke("#9ea93f");
// line(0, 0, 0, -this.len);
// translate(0, -this.len);
line(this.pos.x, this.pos.y, this.pos.z, this.pos.x, this.pos.y, -this.len);
translate(this.pos.x, this.pos.y, this.len);
},
"+": () => {
// Rotate right
rotate((PI / 180) * -this.angle);
},
"-": () => {
// Rotate right
rotate((PI / 180) * this.angle);
},
// Save current location
"[": push,
// Restore last location
"]": pop,
};
}
grow() {
if (this.grown) return;
let next = "";
let word = "X";
for (let i = 0; i < this.numGens; i++) {
word = this.generateWord(word);
}
for (let i = 0; i < word.length; i++) {
let c = word[i];
if (c in this.drawRules) {
this.drawRules[c]();
}
}
this.grown = true;
}
generateWord(word) {
let next = "";
for (let i = 0; i < word.length; i++) {
let c = word[i];
if (c in rules) {
let rule = rules[c];
if (Array.isArray(rule)) {
next += this.chooseOne(rule);
} else {
next += rules[c];
}
} else {
next += c;
}
}
return next;
}
chooseOne(ruleSet) {
let n = random(); // Random number between 0-1
let t = 0;
for(let i = 0; i < ruleSet.length; i++) {
t += ruleSet[i].prob; // Keep adding the probability of the options to total
if(t > n) { // If the total is more than the random value
return ruleSet[i].rule; // Choose that option
}
}
return "";
}
}
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/addons/p5.sound.min.js"></script>
<!-- import dat.gui -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
<script src="sketch.js"></script>
</body>
</html>