只是为了增加凯文的伟大答案,这里有几个相同的想法(保持轨道,如果大小增加或不)的变化。
第一种方法涉及使用使用增长速度变量,当达到限制时简单地翻转标志。如果尺寸太小(下限)或太大(上限),翻转符号(乘以-1的生长速度)将改变日益萎缩,反之亦然:
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 1.5;
void setup()
{
size(640, 480);
}
void draw()
{
//if the size is either too small, or too big, flip the size speed sign (if it was positive (growing) - make it negative (shrink) - and vice versa)
if(size < minSize || size > maxSize) {
sizeSpeed *= -1;
}
//increment the size with the size speed (be it positive or negative)
size += sizeSpeed;
background(255);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, size,size);
}
注意,运动相当线性。由于您想随着时间的推移逐渐缩小圆圈,因此您可以使用sin()函数获得更平滑的动画。它将角度作为参数,并基于角度值返回-1.0和1.0之间的值。您可以使用map()功能重定向这种范围内所需的椭圆形尺寸:
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
void setup()
{
size(640, 480);
}
void draw()
{
size = map(sin(frameCount * sizeSpeed),-1.0,1.0,minSize,maxSize);
background(255);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, size,size);
}
更新在课程方面,你就可以开始封装用于绘制椭圆到一个类中的变量。语法不那么复杂:
- 使用
class
关键字,那么类的名称(按照惯例大写)和内{}
添加类成员 - 类范围
- 创建类的实例使用
new
关键字,并使用.
符号来访问实例成员
下面是一个使用上面的一个非常简单的例子:
Ellipse e = new Ellipse();
void setup()
{
size(640, 480);
}
void draw()
{
e.size = map(sin(frameCount * e.sizeSpeed),-1.0,1.0,e.minSize,e.maxSize);
background(255);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, e.size,e.size);
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
}
这是一个不错的简单的开始,但绘图部分没有封装。 与在类中声明和使用变量的方式相同,您可以声明和使用函数。这里有一个简单的移动椭圆绘图功能整合到一个功能一个基本的例子:
Ellipse e = new Ellipse();
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
e.render();
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
void render(){
size = map(sin(frameCount * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(random(255), random(255), random(255));
ellipse(width/2, height/2, size,size);
}
}
你可能注意到了,现在只需2行初始化并呈现来自主草图的椭圆。还有些东西可以改进。如果创建了第二个椭圆,则x和y是相同的,因此它们会掩盖对方。将x,y属性添加到该类将意味着每个实例将具有独立的坐标。 在类似的说明中,frameCount
是全局的,也就是说,每个椭圆使用相同的角度/大小 。我们也可以做到这一点。
Ellipse e1 = new Ellipse(320,240);
Ellipse e2 = new Ellipse(20,20);
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
e1.render();
e2.render();
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
//position
float x,y;
//internal frameCount replacement
int tick;
//constructor
Ellipse(float x,float y){
this.x = x;//copy x argument value to the instance (this) x property
this.y = y;//copy x argument value to the instance (this) x property
}
void render(){
tick++;
size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(random(255), random(255), random(255));
ellipse(x,y, size,size);
}
}
通知,我们还增加了一个构造。构造函数是非常特殊的:它就像是一个新实例的入口点。无论何时创建类的新实例,都会调用构造函数,这通常会初始化数据。前面的例子没有明确地定义一个构造函数,但Processing默认提供了一个没有参数的例子。采取上述概念更进了一步,我们创建具有x构造函数,y坐标:
Ellipse e1 = new Ellipse(320,240);
Ellipse e2 = new Ellipse(20,20);
void setup()
{
size(640, 480);
}
void draw()
{
background(255);
e1.render();
e2.render();
}
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
//position
float x,y;
//internal frameCount replacement
int tick;
//constructor
Ellipse(float x,float y){
this.x = x;//copy x argument value to the instance (this) x property
this.y = y;//copy x argument value to the instance (this) x property
}
void render(){
tick++;
size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(random(255), random(255), random(255));
ellipse(x,y, size,size);
}
}
这是一个非常快速概述。有关更多详情,请务必查看Daniel Shiffman's Objects tutorial。
考虑到这一点,你可以使用一个ArrayList在运行时创建新的椭圆,并有一些有趣的随机化椭圆参数:
ArrayList<Ellipse> ellipses = new ArrayList<Ellipse>();
void setup()
{
size(640, 480);
ellipses.add(new Ellipse(width/2, height/2));
}
void draw()
{
background(255);
for(Ellipse e : ellipses){
e.render();
}
}
//add an ellipse every 5th frame if mouse is dragged
void mouseDragged(){
if(frameCount % 5 == 0) ellipses.add(new Ellipse(mouseX,mouseY));
}
//remove all ellipses if SPACE is pressed
void keyPressed(){
if(key == ' ') ellipses.clear();
}
//ellipse class
class Ellipse{
//current size - continuously updated
float size = 10;
//minimum size
float minSize = 10;
//maximum size
float maxSize = 240;
//change speed for size (how much will the size increase/decrease each frame)
float sizeSpeed = 0.025;
//position
float x,y;
//internal frameCount replacement
int tick;
int fill;
//constructor
Ellipse(float x,float y){
this.x = x;//copy x argument value to the instance (this) x property
this.y = y;//copy x argument value to the instance (this) x property
fill = color(random(32,192));
sizeSpeed = random(0.025,0.01);
maxSize = random(120,240);
}
void render(){
tick++;
size = map(sin(tick * sizeSpeed),-1.0,1.0,minSize,maxSize);
fill(fill);
ellipse(x,y, size,size);
}
}