深入理解Processing中的函数使用
1. 函数的复用
在编程中,函数的复用是一项非常实用的特性。以绘制气球为例,我们可以通过定义一个绘制气球的函数,然后多次调用该函数来在画布上绘制多个气球。
首先,我们有一个简单的绘制单个气球的程序:
void setup()
{
size(200, 200);
balloon();
}
void balloon()
{
int lineLength = 50;
int diameter = 20;
int column = int( random(width) );
int row = int( random(height) );
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
当
setup()
函数中的
balloon()
函数调用完成后,程序执行结束。
若要绘制多个气球,我们可以多次调用
balloon()
函数。例如,绘制三个气球的代码如下:
void setup()
{
size(200, 200);
balloon();
balloon();
balloon();
}
void balloon()
{
int lineLength = 50;
int diameter = 20;
int column = int( random(width) );
int row = int( random(height) );
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
每次调用
balloon()
函数时,执行流程如下:
1. 执行流程跳转到
balloon()
函数。
2. 执行
balloon()
函数体内的绘制气球的语句。
3. 执行流程返回到调用
balloon()
函数的位置。
另外,我们还可以使用
for
循环来实现绘制多个气球的功能。例如,绘制五个气球的代码如下:
void setup()
{
size(200, 200);
for (int count = 1; count <= 5; count = count + 1)
{
balloon();
}
}
void balloon()
{
int lineLength = 50;
int diameter = 20;
int column = int( random(width) );
int row = int( random(height) );
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
每次
for
循环执行时,都会调用
balloon()
函数,从而在画布上绘制一个随机位置的气球。
2. 函数的参数和参数传递
在前面的例子中,
balloon()
函数的参数列表为空。但实际上,函数可以定义参数,以便在调用时传递所需的信息。参数是函数定义中要求传递的信息项,而在调用函数时提供的对应信息项则称为参数。
2.1 添加单个参数
以
BalloonDraw
程序为例,当前气球的直径是在
balloon()
函数内部通过赋值语句和局部变量指定的:
void setup()
{
size(200, 200);
balloon();
}
void balloon()
{
int lineLength = 50;
int diameter = 20;
int column = int( random(width) );
int row = int( random(height) );
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
为了使气球的直径可以根据我们的需求进行调整,我们需要为
balloon()
函数添加一个参数。在函数头中声明参数变量,就像定义其他变量一样,先指定变量的类型,再指定变量的名称。因此,我们将
balloon()
函数的头修改为:
void balloon(int diameter)
此时,我们有了一个名为
diameter
的参数变量,用于存储调用
balloon()
函数时传递的直径参数值。
由于参数变量是局部变量,其作用域仅限于函数内部。因此,我们需要删除
balloon()
函数体内原来的
int diameter = 20;
语句,修改后的代码如下:
void balloon(int diameter)
{
int lineLength = 50;
int column = int( random(width) );
int row = int( random(height) );
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
然而,当修改了函数定义后,调用
balloon()
函数时会出现错误,因为现在调用函数时必须提供一个参数。错误信息为:
The function balloon() expects parameters like "balloon(int)"
。
为了解决这个问题,我们需要在调用
balloon()
函数时提供一个参数。例如,传递直径为40的参数:
void setup()
{
size(200, 200);
balloon(40);
}
这样,当程序运行时,
setup()
函数被自动调用,执行到
balloon(40)
时,执行流程跳转到
balloon()
函数,参数值40被传递给
diameter
参数变量,然后执行
balloon()
函数体内的语句,绘制一个直径为40像素的气球。
2.2 添加多个参数
如果我们希望气球可以绘制在指定的像素位置,而不是随机位置,我们需要为
balloon()
函数添加更多的参数。在函数头中添加
column
和
row
参数:
void balloon(int column, int row, int diameter)
添加参数后,
balloon()
函数体内原来的随机生成
column
和
row
的语句会出现错误,因为现在有了同名的局部变量。我们需要删除这些语句,修改后的代码如下:
void setup()
{
size(200, 200);
balloon(40); // 这里会报错,后续会修改
}
void balloon(int column, int row, int diameter)
{
int lineLength = 50;
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
此时,调用
balloon()
函数时会再次出现错误,错误信息为:
The function balloon() expects parameters like "balloon(int, int, int)"
。
为了解决这个问题,我们需要在调用
balloon()
函数时提供三个参数。例如,绘制一个中心位于像素列75、像素行100,直径为30像素的气球:
void setup()
{
size(200, 200);
balloon(75, 100, 30);
}
在调用函数时,参数的顺序和类型必须与函数定义中的参数列表匹配。第一个参数75会被赋值给
column
参数变量,第二个参数100会被赋值给
row
参数变量,第三个参数30会被赋值给
diameter
参数变量。
下面是函数调用和参数传递的流程图:
graph TD;
A[开始] --> B[调用setup()函数];
B --> C[调用size()函数设置画布大小];
C --> D[调用balloon(75, 100, 30)函数];
D --> E[跳转到balloon()函数];
E --> F[将参数75赋值给column,100赋值给row,30赋值给diameter];
F --> G[执行balloon()函数体内的语句];
G --> H[绘制气球];
H --> I[返回调用处];
I --> J[setup()函数执行结束];
J --> K[程序结束];
3. Processing中的其他特殊void函数
在Processing中,除了我们自定义的函数外,还有一些特殊的
void
函数,这些函数会自动调用或在特定的鼠标或键盘事件发生时调用。这些函数对于创建动画和交互性非常有用,但对于初学者来说可能会有些困惑。
3.1
draw()
函数
setup()
函数是一个特殊的
void
函数,当我们定义了
setup()
函数时,Processing会自动调用它,且只调用一次。而
draw()
函数是另一个特殊的Processing函数,它提供了一种不同类型的重复机制。
如果我们定义了
draw()
函数,当程序运行且
setup()
函数的操作完成后,Processing会自动反复调用
draw()
函数,直到我们停止程序。这种自动重复调用
draw()
函数的特性在大多数编程语言中是没有的,但它对于创建动画和交互性至关重要。
下面是一个简单的示例,展示了
setup()
函数和
draw()
函数的使用:
void setup()
{
println("setup() was called");
}
void draw()
{
println("draw() was called");
}
当运行这个程序时,Processing会先调用
setup()
函数,输出
setup() was called
,然后开始反复调用
draw()
函数,不断输出
draw() was called
,直到我们停止程序。
在使用
draw()
函数时,需要考虑以下两个关键事实:
1.
draw()
函数会在
setup()
函数调用完成后立即自动调用。
2.
draw()
函数会被反复调用,因此其中包含的语句会不断执行。
综上所述,通过函数的复用、参数传递以及特殊函数的使用,我们可以在Processing中实现更加复杂和灵活的程序。函数的复用可以提高代码的可维护性和可扩展性,参数传递可以使函数更加通用,而特殊函数则为创建动画和交互性提供了强大的支持。
深入理解Processing中的函数使用
4. 特殊函数在动画和交互中的应用
特殊函数在Processing中为动画和交互的实现提供了强大的支持,下面我们将进一步探讨它们在实际应用中的具体用法。
4.1
draw()
函数实现简单动画
draw()
函数的自动重复调用特性非常适合用于创建动画。我们可以通过在
draw()
函数中不断更新图形的位置、大小或颜色等属性,来实现动画效果。
以下是一个简单的动画示例,让一个圆形在画布上不断移动:
int x = 0; // 圆形的初始x坐标
void setup() {
size(400, 400);
}
void draw() {
background(255); // 每次绘制前清除画布
ellipse(x, height/2, 50, 50); // 绘制圆形
x = x + 2; // 更新圆形的x坐标
if (x > width) {
x = 0; // 如果圆形移出画布,重置x坐标
}
}
在这个示例中,
setup()
函数用于设置画布的大小。
draw()
函数会不断被调用,每次调用时,先清除画布,然后绘制一个圆形,接着更新圆形的
x
坐标,使其向右移动。当圆形移出画布时,将
x
坐标重置为0,从而实现圆形在画布上循环移动的动画效果。
4.2 鼠标和键盘事件相关的特殊函数
除了
setup()
和
draw()
函数外,Processing还提供了一些与鼠标和键盘事件相关的特殊函数,这些函数会在特定的鼠标或键盘事件发生时自动调用。
-
mousePressed():当鼠标按钮被按下时调用。 -
mouseReleased():当鼠标按钮被释放时调用。 -
keyPressed():当键盘上的某个键被按下时调用。 -
keyReleased():当键盘上的某个键被释放时调用。
以下是一个简单的示例,展示了
mousePressed()
函数的使用:
void setup() {
size(400, 400);
}
void draw() {
background(255);
}
void mousePressed() {
fill(random(255), random(255), random(255)); // 随机填充颜色
ellipse(mouseX, mouseY, 50, 50); // 在鼠标点击位置绘制圆形
}
在这个示例中,
setup()
函数设置画布大小,
draw()
函数不断清除画布。当鼠标按钮被按下时,
mousePressed()
函数会被调用,它会随机生成一种颜色,并在鼠标点击的位置绘制一个圆形。
下面是这些特殊函数的调用时机总结表格:
| 函数名 | 调用时机 |
| ---- | ---- |
|
setup()
| 程序开始时自动调用,且只调用一次 |
|
draw()
|
setup()
函数执行完成后,自动反复调用,直到程序停止 |
|
mousePressed()
| 鼠标按钮被按下时调用 |
|
mouseReleased()
| 鼠标按钮被释放时调用 |
|
keyPressed()
| 键盘上的某个键被按下时调用 |
|
keyReleased()
| 键盘上的某个键被释放时调用 |
5. 函数使用的最佳实践
在使用函数时,遵循一些最佳实践可以提高代码的可读性、可维护性和可扩展性。
5.1 函数的单一职责原则
每个函数应该只负责完成一个明确的任务。例如,在前面的气球绘制示例中,
balloon()
函数只负责绘制一个气球,这样可以使函数的功能更加清晰,便于理解和维护。如果一个函数承担了过多的任务,会导致代码变得复杂,难以调试和修改。
5.2 参数的合理使用
在定义函数时,要合理使用参数。参数应该是函数完成任务所必需的信息,避免使用过多不必要的参数。同时,要确保参数的类型和顺序在函数定义和调用时保持一致,以避免出现错误。
5.3 注释和文档
为函数添加适当的注释和文档是非常重要的。注释可以帮助其他开发者(也包括未来的自己)理解函数的功能、参数的含义和返回值等信息。例如,在
balloon()
函数前添加注释,说明该函数的作用和参数的用途:
/**
* 绘制一个气球
* @param column 气球中心的列坐标
* @param row 气球中心的行坐标
* @param diameter 气球的直径
*/
void balloon(int column, int row, int diameter) {
int lineLength = 50;
line(column, row, column, row + lineLength);
fill(255, 0, 0);
ellipse(column, row, diameter, diameter);
}
下面是函数使用最佳实践的流程图:
graph TD;
A[定义函数] --> B[遵循单一职责原则];
B --> C[合理使用参数];
C --> D[添加注释和文档];
D --> E[函数调用];
E --> F[检查参数匹配];
F --> G[执行函数];
G --> H[返回结果];
通过遵循这些最佳实践,我们可以编写出更加健壮、易于维护的代码,提高编程效率和代码质量。
综上所述,Processing中的函数使用涵盖了函数的复用、参数传递、特殊函数的应用以及最佳实践等多个方面。掌握这些知识和技巧,可以帮助我们更好地利用Processing进行编程,创建出更加复杂、有趣的程序,实现动画和交互效果。
超级会员免费看
5518

被折叠的 条评论
为什么被折叠?



