Processing 案例 | 去“富士山”看樱花从树上纷纷而落

引言

大家都知道,樱花是日本的国花,他们对于樱花十分的喜爱,所以在日本最常见的就是樱花。其中尤其以富士山的樱花最为美丽。每年在三四月份,日本人就开始去富士山看樱花。
在这里插入图片描述
现在不是三四月,大家可能也都不在日本的富士山。但是这并不能阻止我们去赏花!正巧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 
  • 12
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值