xxxxxxxxxx
//fractals 是一個看的到的型,一種重複的物件、有著相似的結構
let _numChildren = 2; //分成二支
let _maxLevels = 5; //最終分層
let _trunk;
function setup() {
createCanvas(500, 500);
background(255);
noFill();
newTree();
}
function draw() {
//background(255);
_trunk.updateMe(width/2, height/2); //不用重新製造樹,僅是讓樹幹不停重畫
_trunk.drawMe();
}
function newTree() {
_trunk = new Branch(1, 0, width/2, height/2); //將Branch物件存入_trunk的變數裡面 //製造一個叫作Branch的物件(執行contructor的函式)
_trunk.drawMe(); //利用trunk去呼叫Branch裡的drawMe
}
// ========== object =============
class Branch {
constructor(lev, ind, ex, ey) {
this.level = lev;
this.index = ind;
this.x;
this.y;
this.endx;
this.endy;
this.radius = random(5);
this.children = []; //本程式核心的地方!!! 在自己的物件中,還會引用到自己(定義自己在用自己來定義自己 adding self-reference)
if (this.level < _maxLevels) { //這是讓程式停止的層級 (程式最終的層級maxLevels)
for (let i=0; i<_numChildren; i++) { //分層
let nb = new Branch(this.level+1, i, 0, 0); //每個分層都長出一個分支 branch 長出分支的端點又成為新的起點
this.children.push(nb);
}
}
this.updateMe(ex, ey); //樹根還有小孩都長出來之後再update
}
updateMe(nx, ny) { //重新給定一個起點
this.x = nx;
this.y = ny;
this.endx = this.x + (this.level*(random(100)-50)); //讓變化更寬一點
this.endy = this.y + (this.level*random(50)-50);//新的端點的座標
for (let i=0; i<this.children.length; i++) {
this.children[i].updateMe(this.endx, this.endy);
}
}
drawMe() {
stroke(random(255),random(80));
strokeWeight(_maxLevels-this.level+1);
line(this.x, this.y, this.endx, this.endy);
fill(50, random(80));
ellipse(this.x, this.y, this.radius);
ellipse(this.endx, this.endy, this.radius);
ellipse(this.x, this.y, 5, 5);
for (let i=0; i<this.children.length; i++) {
this.children[i].drawMe();
}
}
}