一、前言

本系列教程共三篇:
1、《Processing创意编程(入门篇)》
2、《Processing创意编程(进阶篇)》
3、《Processing创意编程(熟练篇)》

二、练习

2.1 弹弹球

首先查看效果图:
在这里插入图片描述
只需要在小球要出边界时改变坐标运动方向即可。

代码如下:

void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
}

int x=300,y=300,r=25,x_speed=5,y_speed=8;
//x、y圆的是坐标,x,y移动速度不一样
//r是半径

void draw(){ 
  background(0);
  ellipse(x,y,r*2,r*2);
  
  if(x+r>=width || x-r<=0){
      x_speed=-x_speed;
  }
  if(y+r>=height || y-r<=0){
      y_speed=-y_speed;
  }
  x+=x_speed;
  y+=y_speed;
}

2.2 向量

向量用PVector类实现,参数为x,y,上面案例的代码可以写成这样,效果是一样的:

void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
}

PVector loc=new PVector(300,300);  //坐标
PVector v=new PVector(5,8);        //速度
int r=25;

void draw(){ 
  background(0);
  ellipse(loc.x,loc.y,r*2,r*2);
  
  if(loc.x+r>=width || loc.x-r<=0){
      v.x=-v.x;
  }
  if(loc.y+r>=height || loc.y-r<=0){
      v.y=-v.y;
  }
  
  loc.add(v);
}

向量的使用有如下方法:
在这里插入图片描述

例:跟随鼠标移动的圆:

void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
}

PVector loc=new PVector(300,300);  //坐标
PVector v;        //速度
int r=25;

void draw(){ 
  background(0);
  ellipse(loc.x,loc.y,r*2,r*2);
  
  //计算圆心到鼠标位置的向量差,并正则化
  v=new PVector(mouseX,mouseY).sub(loc).normalize();
  
  loc.add(v);
}

运行效果:
在这里插入图片描述

2.3 三角函数与圆

圆的三角函数公式为:
x = 圆 心 x + 半 径 ∗ s i n θ x=圆心x+半径*sinθ x=x+sinθ
y = 圆 心 y + 半 径 ∗ c o s θ y=圆心y+半径*cosθ y=y+cosθ
在这里插入图片描述
现在我们制作一个动态画圆的动画:

float t=0;
PVector loc;//圆心坐标
float r=200;//半径
void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
  background(0);//背景色
  noStroke();//取消描边
  frameRate(50);//帧率
  
  loc=new PVector(width/2,height/2);
}


void draw(){ 
  // x= 圆心.x + r*cosθ
  // y= 圆心.y + r*sinθ
  t+=0.01;
  ellipse(loc.x+r*cos(t),loc.y+r*sin(t),10,10);
  //ellipse(loc.x+r*cos(t),loc.y+r/2*sin(t),10,10);//椭圆
}

随着角度变量t的变化,圆上的点的位置 ( x , y ) (x,y) (x,y)也在不断变化。

运行效果如下:
在这里插入图片描述

我们再变一下,同时圆的半径同时也在不断缩小,这是什么效果呢?
代码:

float t=0;
PVector loc;//圆心坐标
float r=200;//半径
void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
  background(0);//背景色
  noStroke();//取消描边
  frameRate(200);//帧率
  
  loc=new PVector(width/2,height/2);
}


void draw(){ 
  // x= 圆心.x + r*cosθ
  // y= 圆心.y + r*sinθ
  t+=0.01;
  r-=0.04;//同时减少半径
  ellipse(loc.x+r*cos(t),loc.y+r*sin(t),10,10);
}

是个蚊香的模样:
在这里插入图片描述

运行到最后的效果:
在这里插入图片描述

注意:pocessing里的sin和cos里的参数是弧度,而不是角度(0~360°),换算公式为:
360 ° = 2 π 360°=2π 360°=2π
1°=π/180π=180°

那么,怎么确保刚好10秒钟把圆画完呢?
只需要每秒渲染36次:frameRate(36)
每次t增加就可以了:t+=PI/180

在Processing里,有现成的角度转弧度函数radians,代码如下:

float t=0;
PVector loc;//圆心坐标
float r=200;//半径
void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
  background(0);//背景色
  noStroke();//取消描边
  frameRate(36);//帧率
  
  loc=new PVector(width/2,height/2);
}


void draw(){ 
  t+=1;
  ellipse(loc.x+r*cos(radians(t)),loc.y+r*sin(radians(t)),10,10);
}

2.4 小尾巴效果

代码:

float t=0;
PVector loc;//圆心坐标
float r=200;//半径
void setup(){//启动时执行一次的函数
  size(600,600);//画布大小
  background(0);//背景色
  noStroke();//取消描边
  frameRate(36);//帧率
  
  loc=new PVector(width/2,height/2);
}


void draw(){ 
  fill(0,50);
  rect(0,0,width,height);
  t+=1;
  fill(255);
  ellipse(loc.x+r*cos(radians(t)),loc.y+r*sin(radians(t)),10,10);
}

效果如下:
在这里插入图片描述

2.5综合练习

先上效果视频:

Processing创意编程练习-律动的海洋

再看代码:

Ball[] balls=new Ball[2000];
float r=200;
void setup(){//启动时执行一次的函数
  //size(800,800);//画布大小
  fullScreen();
  background(0);//背景色
  noStroke();//取消描边
  for(int i=0;i<balls.length;i++){
    PVector loc=new PVector(random(0,width),random(0,height));//随记位置
    float r=random(10,20);//随机半径
    balls[i]=new Ball(loc,r);
  }
}


void draw(){ 
  fill(0,20);
  rect(0,0,width,height);
  for(int i=0;i<balls.length;i++){
    balls[i].update();
    balls[i].check();
    balls[i].display();
  }
}

class Ball{
  PVector loc;//位置
  PVector v=new PVector(0,0);//移动量
  float r;//半径
  float angle=0;//移动角度
  float R,G,B;//颜色
  
  Ball(PVector loc,float r){//构造函数
    this.loc=loc;
    this.r=r;
    R=map(loc.x,0,width,0,255);
    G=map(loc.x,0,width,255,0);
    B=map(loc.y,0,height,0,255);
  }
  
  void update(){
    angle+=0.02*noise(0.001*loc.x,0.001*loc.y);//海拔的变化是线性的,因此作为移动角度
    v.x=2*sin(angle);
    v.y=2*cos(angle);
    
    loc=loc.add(v);
    
  }
  
  void check(){
     if(loc.x<0){loc.x=width;}
     if(loc.x>width){loc.x=0;}
     if(loc.y<0){loc.y=height;}
     if(loc.y>height){loc.y=0;}
  }
  
  void display(){
     fill(R,G,B);
     ellipse(loc.x,loc.y,r,r);
  }
}

//按任意键退出
void keyPressed()
{
   exit();
}

三、参考资料

二锅头【Processing零基础中文教程】3、熟练篇

【转载请注明出处: https://leytton.blog.csdn.net/article/details/122784454
如果本文对你有帮助,请点个赞让我知道哦 😃

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐