Processing编程:void函数与返回值函数的使用
1. draw()函数的图形示例
首先,我们尝试使用
draw()
函数进行重复绘图。操作步骤如下:
1. 选择
File > New
开始一个新程序,并将其保存为
Circles
。
2. 使用
setup()
函数设置画布大小为150像素宽、200像素高,并在画布上随机位置绘制一个直径为30像素的圆,代码如下:
void setup()
{
size(150, 200);
ellipse(random(width), random(height), 30, 30);
}
多次运行该程序,每次运行时,圆都会在画布的随机位置绘制。
接下来,我们向程序中添加
draw()
函数:
void setup()
{
size(150, 200);
ellipse( random(width), random(height), 30, 30);
}
void draw()
{
}
运行程序时,Processing会自动调用
setup()
函数一次,执行完
setup()
函数中的所有语句后,会自动调用
draw()
函数。当
draw()
函数中的所有语句执行完毕后,Processing会再次调用
draw()
函数,这种重复自动调用会一直持续,直到我们停止程序。
由于当前
draw()
函数没有包含任何语句,我们将
ellipse()
函数的调用从
setup()
函数移到
draw()
函数中:
void setup()
{
size(150, 200);
}
void draw()
{
ellipse(random(width), random(height), 30, 30);
}
再次运行程序,Processing会不断在随机位置绘制圆,直到我们停止程序。
当使用
draw()
函数时,我们还可以创建响应鼠标指针在画布上移动的程序。Processing提供了两个
int
类型的内置变量
mouseX
和
mouseY
,每次调用
draw()
函数时,它们会存储鼠标指针尖端在画布上的当前像素位置:
-
mouseX
:存储鼠标指针尖端当前所在的画布像素列位置。
-
mouseY
:存储鼠标指针尖端当前所在的画布像素行位置。
我们可以修改程序中
ellipse()
函数的调用,使用这两个变量来指定每次调用
draw()
函数时绘制圆的位置:
void setup()
{
size(150, 200);
}
void draw()
{
ellipse(mouseX, mouseY, 30, 30);
}
运行该程序,无论我们将鼠标指针移动到画布的哪个位置,都会在该位置绘制圆。保存
Circles
程序,后续还会用到。
2. 使用draw()函数为气球动画
我们尝试在绘制气球的程序中使用
draw()
函数以及
mouseX
和
mouseY
变量。操作步骤如下:
1. 返回
BalloonDraw
程序,选择
File > Save As
,将程序另存为
BalloonMove
。
2. 由于Processing的内置变量
mouseX
和
mouseY
都是
int
类型,它们可以作为参数传递给
balloon()
函数。我们在程序中插入
draw()
函数,并将
balloon()
函数的调用放在
draw()
函数的主体中:
void setup()
{
size(200, 200);
}
void draw()
{
balloon(mouseX, mouseY, 30);
}
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);
}
运行该程序,每次执行
draw()
函数时,都会调用
balloon()
函数,因此每次
draw()
函数重复执行时,都会在鼠标指针的当前位置绘制一个气球。
接着,我们在
draw()
函数中插入对
background()
函数的调用:
void draw()
{
background(200, 200, 200);
balloon(mouseX, mouseY, 30);
}
每次
draw()
函数重复执行时,会先调用
background()
函数,生成一个空白的灰色画布,然后调用
balloon()
函数,在鼠标指针的当前位置再次绘制一个气球,这样就会产生我们用鼠标在画布上移动单个气球的错觉。
如果对程序进行如下修改:
void setup()
{
size(200, 200);
cursor(HAND);
}
void draw()
{
background(200, 200, 200);
balloon(mouseX, mouseY, 30);
}
void balloon(int column, int row, int diameter)
{
int lineLength = 50;
line(column, row, column, row - lineLength);
fill(255, 0, 0);
ellipse(column, row - lineLength, diameter, diameter);
}
看起来就好像一只手在绳子末端拿着气球。
使用重复的
draw()
函数产生的效果有时很难提前预测,因此在Processing中使用
draw()
函数编程通常需要一些尝试和错误,但这种不可预测性也增加了使用
draw()
函数的乐趣。保存并关闭
BalloonMove
程序。
3. Processing中与鼠标和键盘相关的特殊void函数
我们已经了解了Processing的两个特殊
void
函数:
setup()
和
draw()
。如果在程序中定义了
setup()
函数,当我们启动程序时,Processing会自动调用该函数一次;如果还定义了
draw()
函数,在
setup()
函数执行完毕后,Processing会自动重复调用
draw()
函数。
如果定义了
draw()
函数,我们还可以选择定义Processing中与鼠标和键盘使用相关的其他特殊
void()
函数。
draw()
函数的重复执行(即使其主体中没有语句)会使Processing“监听”鼠标和键盘事件的发生,例如移动鼠标、按下鼠标按钮或按下键盘上的键。
例如,如果定义了
void mousePressed()
函数,每当我们将鼠标指针放在画布上并按下鼠标按钮时,Processing会调用该函数一次,并执行该函数主体中的任何语句。之后,Processing会恢复对
draw()
函数的重复调用。我们回到
Circles
程序,插入包含对
background()
函数调用的
mousePressed()
函数定义:
void setup()
{
size(150, 200);
}
void draw()
{
ellipse(mouseX, mouseY, 30, 30);
}
void mousePressed()
{
background(200, 200, 200);
}
运行该程序,和之前一样,无论我们将鼠标指针移动到画布的哪个位置,都会在该位置绘制圆。但是,每当我们按下鼠标按钮时,会调用
mousePressed()
函数,执行其中对
background()
函数的调用,将画布上的所有像素重置为
background()
函数调用中指定的颜色。之后,
mousePressed()
函数执行完毕,执行流程返回到
draw()
函数,Processing继续重复调用
draw()
函数,再次开始在鼠标指针的当前位置重复绘制圆。
Processing还包含一个类似的
void
函数
keyPressed()
。顾名思义,每当我们在画布窗口被选为活动窗口时按下键盘上的键,Processing会调用
keyPressed()
函数一次,执行该函数主体中的语句,然后执行流程返回到
draw()
函数,Processing继续重复调用
draw()
函数。
例如,我们修改程序以使用
keyPressed()
函数:
void setup()
{
size(150, 200);
}
void draw()
{
ellipse(mouseX, mouseY, 30, 30);
}
void keyPressed()
{
background(200, 200, 200);
}
这样,当我们按下键盘上的键时,会使用
background()
函数将画布清空。保存并关闭
Circles
程序。
4. 创建返回值的函数
在Processing中,我们可以创建自己的返回值函数,这与创建
void
函数有相似之处,但也有一些关键区别。
4.1 非void函数的概念
我们可以用一个类比来理解非
void
函数。假设每年家长都会要求青少年“了解本赛季踢足球需要花费多少钱”,这实际上转化为一系列具体的指令,如“了解所需足球鞋的成本”“了解所需护腿板的成本”等,最后要求青少年汇报总费用。与“准备上学”的指令不同,这个指令要求带回一项信息,即本赛季踢足球的总费用。
在Processing中,非
void
函数类似于这个类比,它执行一系列命名的语句,并带回由指令描述的结果信息。我们在Processing中使用过许多返回值的内置函数,例如
sqrt()
函数,它计算我们作为参数提供的任何值的平方根,并将结果作为
float
值返回给我们。
需要注意的是,当我们调用非
void
函数时,需要立即使用返回的值。例如,如果我们编写语句
sqrt(9.0);
,该函数调用返回的平方根会丢失。一个好的方法是将返回的值赋给一个变量,例如:
float root;
root = sqrt(9.0);
println("Square root: " + root);
这样,函数返回的结果值就存储在变量中,我们可以进一步使用它。
4.2 创建自己的返回值函数
我们以模拟掷骰子的程序为例。操作步骤如下:
1. 选择
File > New
创建一个新程序,将其保存为
RollingFunction
。
2. 我们需要在Processing的活动模式下工作,以创建返回值的函数。首先定义
setup()
函数:
void setup()
{
int die;
die = int( random(1, 7) );
println(die);
}
运行该程序,我们会在控制台看到一个1到6之间的整数。
如果我们想模拟使用五个骰子的游戏中的掷骰子过程,一种方法是在程序中使用五个类似的语句,但每次模拟掷骰子都编写嵌套的
int()
和
random()
函数调用有些繁琐。我们可以创建一个函数来执行这个模拟。
定义函数时,函数头需要三个信息:
1.
返回值的类型
:在模拟掷骰子的函数中,我们需要返回一个1到6之间的随机整数,所以返回值的类型是
int
,函数头以
int
开头。
2.
函数的名称
:我们使用
roll
作为函数的名称。
3.
函数的参数列表
:该函数目前不需要任何参数,所以我们只写一对空括号。
函数头完成后,我们定义
roll()
函数的主体:
int roll()
{
int result;
result = int( random(1, 7) );
return result;
}
在函数主体中,我们声明一个局部变量
result
来存储1到6之间的随机整数值,并将其作为每次调用
roll()
函数的结果返回。需要注意的是,由于
roll()
函数的返回类型是
int
,我们必须使用
return
语句返回一个
int
类型的值。
我们将
roll()
函数应用到程序中:
void setup()
{
int die;
die = roll();
println(die);
}
int roll()
{
int result;
result = int( random(1, 7) );
return result;
}
运行该程序,我们会在控制台看到一个1到6之间的值。
下面是程序执行流程的mermaid流程图:
graph TD;
A[开始运行程序] --> B[调用setup()函数];
B --> C[声明die变量];
C --> D[调用roll()函数];
D --> E[进入roll()函数];
E --> F[声明result变量];
F --> G[为result变量赋值随机整数];
G --> H[执行return result语句];
H --> I[返回setup()函数,将result值赋给die];
I --> J[调用println(die)输出结果];
5. 练习
以下是一些相关的练习,帮助我们巩固所学知识:
1. 输入以下程序:
void setup()
{
}
void smiley()
{
println( ":-)" );
}
修改该程序,使
setup()
函数调用
smiley()
函数,运行程序应输出
:-)
。
2. 修改上一个程序,多次调用
smiley()
函数,输出:
:-)
:-)
:-)
:-)
:-)
-
修改上一个程序,使用
for语句调用smiley()函数,产生相同的输出。 -
编写一个名为
qwerty()的void函数,显示QWERTY键盘上每行的字母。让setup()函数在控制台显示Keyboard Letters:,然后调用qwerty()函数,运行程序应产生以下控制台输出:
Keyboard Letters:
QWERTYUIOP
ASDFGHJKL
ZXCVBNM
-
编写一个名为
days()的void函数,在控制台显示一周的天数。让setup()函数在控制台显示Days of the week:,然后调用days()函数,运行程序应产生以下控制台输出:
Days of the week:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
-
在Processing中,
month()函数返回月份数,day()函数返回日期,year()函数返回年份。编写一个名为today()的void函数,在控制台显示当前的月份、日期和年份。让setup()函数在控制台显示TODAY:,然后调用today()函数,运行程序应产生类似以下的控制台输出:
TODAY:
Month: 5
Day: 28
Year: 2017
-
编写一个名为
hashtags()的void函数,在控制台的一行显示一个井号,但之后不换行。让setup()函数在控制台显示hashtags:,然后调用hashtags()函数,运行程序应产生以下控制台输出:
hashtags:
#
-
修改上一个程序,使
hashtags()函数有一个名为quantity的int参数变量,指定函数应显示的井号数量。在hashtags()函数中插入for语句来实现这一点。例如,调用hashtags(5)应产生以下输出:
hashtags:
#####
调用
hashtags(10)
应产生以下输出:
hashtags:
##########
-
编写一个名为
square()的void函数,在200像素×200像素的画布的左上角绘制一个边长为50像素的正方形。从setup()函数调用该函数。 -
修改上一个程序,使
square()函数有一个int参数变量side,用于指定正方形的边长。例如,调用square(100)应绘制相应边长的正方形。 -
修改上一个程序,使
square()函数还有一个int参数变量column和一个int参数变量row,用于指定正方形左上角的列和行。例如,调用square(100, 25, 50)应绘制相应位置和边长的正方形。 -
修改上一个程序,在
setup()函数中插入for语句,调用square()函数五次,使用20作为边长,并使用随机值作为列和行号。 -
编写一个名为
yoyo()的void函数,在200像素×300像素的画布的顶部中心到画布中心绘制一条线,并在画布中心绘制一个直径为50像素的圆。从setup()函数调用该函数。 -
修改上一个程序,使
yoyo()函数有一个名为row的int参数变量,指定悠悠球的垂直位置。例如,调用yoyo(220)应将悠悠球放置在相应的垂直位置。 -
修改上一个程序:
-
在
setup()函数中声明一个名为randomRow的int变量。 -
为
randomRow分配一个从0到画布高度的随机整数。 -
使用
randomRow作为调用yoyo()函数的参数。运行该程序,每次悠悠球会放置在不同的垂直位置。
-
在
Processing编程:void函数与返回值函数的使用
6. 练习解答思路与示例代码
6.1 练习1
void setup()
{
smiley();
}
void smiley()
{
println( ":-)" );
}
在这个程序中,我们在
setup()
函数里调用了
smiley()
函数,这样运行程序时就会输出
:-)
。
6.2 练习2
void setup()
{
smiley();
smiley();
smiley();
smiley();
smiley();
}
void smiley()
{
println( ":-)" );
}
通过多次调用
smiley()
函数,实现了输出多行
:-)
的效果。
6.3 练习3
void setup()
{
for(int i = 0; i < 5; i++) {
smiley();
}
}
void smiley()
{
println( ":-)" );
}
使用
for
循环来控制
smiley()
函数的调用次数,达到与练习2相同的输出效果。
6.4 练习4
void setup()
{
println("Keyboard Letters:");
qwerty();
}
void qwerty()
{
println("QWERTYUIOP");
println("ASDFGHJKL");
println("ZXCVBNM");
}
qwerty()
函数按行输出QWERTY键盘上的字母,
setup()
函数负责显示提示信息并调用
qwerty()
函数。
6.5 练习5
void setup()
{
println("Days of the week:");
days();
}
void days()
{
println("Sunday");
println("Monday");
println("Tuesday");
println("Wednesday");
println("Thursday");
println("Friday");
println("Saturday");
}
days()
函数依次输出一周的天数,
setup()
函数显示提示信息并调用
days()
函数。
6.6 练习6
void setup()
{
println("TODAY:");
today();
}
void today()
{
println("Month: " + month());
println("Day: " + day());
println("Year: " + year());
}
today()
函数利用Processing的
month()
、
day()
和
year()
函数获取当前日期信息并输出,
setup()
函数显示提示信息并调用
today()
函数。
6.7 练习7
void setup()
{
println("hashtags:");
hashtags();
}
void hashtags()
{
print("#");
}
hashtags()
函数使用
print()
函数输出井号且不换行,
setup()
函数显示提示信息并调用
hashtags()
函数。
6.8 练习8
void setup()
{
println("hashtags:");
hashtags(5);
}
void hashtags(int quantity)
{
for(int i = 0; i < quantity; i++) {
print("#");
}
}
hashtags()
函数接收一个整数参数
quantity
,使用
for
循环根据该参数输出相应数量的井号。
6.9 练习9
void setup()
{
size(200, 200);
square();
}
void square()
{
rect(0, 0, 50, 50);
}
square()
函数使用
rect()
函数在画布左上角绘制边长为50像素的正方形,
setup()
函数设置画布大小并调用
square()
函数。
6.10 练习10
void setup()
{
size(200, 200);
square(100);
}
void square(int side)
{
rect(0, 0, side, side);
}
square()
函数接收一个整数参数
side
,用于指定正方形的边长,
setup()
函数设置画布大小并调用
square()
函数。
6.11 练习11
void setup()
{
size(200, 200);
square(100, 25, 50);
}
void square(int side, int column, int row)
{
rect(column, row, side, side);
}
square()
函数接收三个整数参数,分别指定正方形的边长、左上角的列和行,
setup()
函数设置画布大小并调用
square()
函数。
6.12 练习12
void setup()
{
size(200, 200);
for(int i = 0; i < 5; i++) {
int col = (int)random(200);
int row = (int)random(200);
square(20, col, row);
}
}
void square(int side, int column, int row)
{
rect(column, row, side, side);
}
在
setup()
函数中使用
for
循环调用
square()
函数五次,每次使用随机的列和行号以及固定的边长20。
6.13 练习13
void setup()
{
size(200, 300);
yoyo();
}
void yoyo()
{
line(100, 0, 100, 150);
ellipse(100, 150, 50, 50);
}
yoyo()
函数在画布顶部中心到中心绘制一条线,并在中心绘制一个直径为50像素的圆,
setup()
函数设置画布大小并调用
yoyo()
函数。
6.14 练习14
void setup()
{
size(200, 300);
yoyo(220);
}
void yoyo(int row)
{
line(100, 0, 100, row);
ellipse(100, row, 50, 50);
}
yoyo()
函数接收一个整数参数
row
,用于指定悠悠球的垂直位置,
setup()
函数设置画布大小并调用
yoyo()
函数。
6.15 练习15
void setup()
{
size(200, 300);
int randomRow = (int)random(height);
yoyo(randomRow);
}
void yoyo(int row)
{
line(100, 0, 100, row);
ellipse(100, row, 50, 50);
}
在
setup()
函数中声明一个随机整数变量
randomRow
,其值在0到画布高度之间,然后将该变量作为参数调用
yoyo()
函数,使得每次运行程序悠悠球的垂直位置不同。
7. 总结
通过以上内容,我们学习了在Processing中创建
void
函数和返回值函数的方法。
void
函数可以用于执行一系列操作,而返回值函数则可以带回执行结果供我们进一步使用。同时,我们还了解了Processing中与鼠标和键盘相关的特殊
void
函数,如
mousePressed()
和
keyPressed()
,它们可以让程序对用户的输入做出响应。通过练习,我们巩固了所学的知识,提高了编程能力。
以下是一个总结表格:
| 函数类型 | 特点 | 示例 |
| ---- | ---- | ---- |
|
void
函数 | 不返回值,用于执行一系列操作 |
setup()
、
draw()
、
smiley()
等 |
| 返回值函数 | 执行操作并返回结果 |
roll()
、
sqrt()
等 |
| 特殊
void
函数(鼠标和键盘相关) | 响应鼠标和键盘事件 |
mousePressed()
、
keyPressed()
|
希望这些知识和练习能帮助你更好地掌握Processing编程,开启更多有趣的创意编程之旅!
graph LR
A[开始学习] --> B[掌握void函数]
B --> C[了解返回值函数]
C --> D[学习特殊void函数]
D --> E[通过练习巩固知识]
E --> F[提升编程能力]
超级会员免费看
1520

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



