文章目录
引言
大家都知道,樱花是日本的国花,他们对于樱花十分的喜爱,所以在日本最常见的就是樱花。其中尤其以富士山的樱花最为美丽。每年在三四月份,日本人就开始去富士山看樱花。
现在不是三四月,大家可能也都不在日本的富士山。但是这并不能阻止我们去赏花!正巧Jason Labbe老师的Cherry blossom fractals就给了我们一个机会看樱花从树上纷纷而落,效果如下。
通过观察不难得到,当我们按下键盘的时候,鼠标周围就会出一下一种类似“爆炸”的效果:树枝震动,花瓣飘落,这也是该作品的亮点之一。
废话不多说,那么接下来我们就一起去看看如何用用Processing实现该效果吧。
代码
大体结构
现在我们就正式来看代码。这个作品的结构很清晰,在setup函数中生成一棵新的树,并且在draw函数对构成这个树的树枝和叶子进行更新和绘制。
// 全局变量
// 存储所有的树枝和叶子
ArrayList<Branch> branches = new ArrayList<Branch>();
ArrayList<Leaf> leaves = new ArrayList<Leaf>();
// 树的最大层级数
int maxLevel = 9;
void setup() {
size(800, 700);
colorMode(HSB, 100);
generateNewTree();
}
void draw() {
background(100);
// 对每一个树枝进行刷新和绘制
for (int i = 0; i < branches.size(); i++) {
Branch branch = branches.get(i);
branch.move();
branch.display();
}
// 对每一片叶子进行刷行和绘制
for (int i = leaves.size()-1; i > -1; i--) {
Leaf leaf = leaves.get(i);
leaf.move();
leaf.display();
// 不显示屏幕外的叶子
leaf.destroyIfOutBounds();
}
}
generateNewTree
接下来我们来看看如何生成一棵新的树。
在generateNewTree函数首先清空已经有的树枝和树叶,然后生成在第一个树枝(这个树枝在屏幕底部,并且长度是在一定范围里面随机),接着递归调用subDivide这个方法生成整棵树。
在初始化时除了传入该树枝起始点和结束点的坐标,还要传入当前层级数和它的父亲。
void generateNewTree() {
// 清空已经存在的树枝和树叶
branches.clear();
leaves.clear();
// 生成第一个树枝
float rootLength = random(80.0, 150.0);
branches.add(new Branch(width/2, height, width/2, height-rootLength, 0, null));
// 递归生成整个树
subDivide(branches.get(0));
}
在subDivide函数中给指定的树枝添加1到3个树枝或者叶子。添加树枝还是添加叶子取决于当前的层级数。同于对于添加叶子的树枝还要特别注意:对每一个添加的叶子要设置一个位置的偏移量,否者它们会重叠。
void subDivide(Branch branch) {
// 用来存储新的树枝
ArrayList<Branch> newBranches = new ArrayList<Branch>();
// 确定这个树枝连接的分支的数量
int newBranchCount = (int)random(1, 4);
// 新的树枝的长度比例范围
float minLength = 0.7;
float maxLength = 0.85;
// 添加新的树枝
switch(newBranchCount) {
// if(newBranchCount == 2)
case 2:
newBranches.add(branch.newBranch(random(-45.0, -10.0), random(minLength, maxLength)));
newBranches.add(branch.newBranch(random(10.0, 45.0), random(minLength, maxLength)));
break;
// else if(newBranchCount == 3)
case