Processing学习笔记三剖析.docx
《Processing学习笔记三剖析.docx》由会员分享,可在线阅读,更多相关《Processing学习笔记三剖析.docx(25页珍藏版)》请在冰豆网上搜索。
Processing学习笔记三剖析
5/响应
那些响应鼠标、键盘和其他设备输入的代码应该连续地运行。
要做到这样,在draw()函数中写下这些更新的代码。
示例5-1:
draw()函数
要看看draw()函数是怎么运行的,试着运行这个程序:
voiddraw()
{
//在控制台显示帧数
println("I'mdrawing");
println(frameCount);
}
将会看到:
它是动态的
示例5-2:
setup()函数
为了完成循环的draw()函数,Processing有一个setup()函数,在程序运行开始时运行一遍。
voidsetup()
{
println("I'mdrawing");
}
voiddraw()
{
println("I'mrunning");
}
代码运行时,在控制台上会有如下输出:
文本“I’mrunning”会一直持续地被写到控制台上,直到程序结束。
示例5-3:
当setup()遇到draw()函数
下面的例子把以上讲的两个函数都放在一起:
intx=280;
inty=-100;
intdiameter=380;
voidsetup()
{
size(480,120);
smooth();
fill(102);
}
voiddraw()
{
background(204);
ellipse(x,y,diameter,diameter);
}
图示:
跟随
既然我们可以让我们的程序持续地运行了,那么我们就可以跟踪鼠标的位置然后使用得到的这些数值来移动屏幕上的元素。
示例5-4:
跟踪鼠标
mouseX变量保存着X轴的值,mouseY变量保存着Y轴的值。
代码:
voidsetup()
{
size(480,120);
fill(0,152);
smooth();
noStroke();
}
voiddraw()
{
ellipse(mouseX,mouseY,9,9);
}
图示:
当鼠标移动的很快时,圆圈会被放置的十分分散。
示例5-5:
跟随你的点
在这个示例中,当每次draw()函数运行时,一个新的圆就被画在窗口上。
为了刷新屏幕,并且每次只有最新画上的圆显示在上面,我们需要在draw()函数一开始就调用background()函数,这要在形状被绘制之前做好。
代码:
voidsetup()
{
size(480,120);
fill(0,152);
smooth();
noStroke();
}
voiddraw()
{
background(205);
ellipse(mouseX,mouseY,9,9);
}
图示:
background()函数会清空屏幕,所以一定要保证它被放在draw()函数中,并且在其他函数之前。
否则,画上的形状会被清空的。
示例5-6:
连续作画
pmouseX和pmouseY两个变量存储着前一帧鼠标的位置。
像mouseX和mouseY一样,这些特殊的变量是在每次draw()函数运行的时候都更新的。
当它们被联合在一起使用时,我们可以通过连接当前位置和最近一次的位置来绘制连续的线。
代码:
voidsetup()
{
size(480,120);
strokeWeight(4);
smooth();
stroke(0,102);
}
voiddraw()
{
line(mouseX,mouseY,pmouseX,pmouseY);
}
图示:
示例5-7:
连续设置厚度
PmouseX和pmouseY两个变量也可以用来计算鼠标移动的速度。
这是通过测量当前点和鼠标经过的上一个位置的距离来做到的。
如果鼠标移动较慢,那么这个距离也很小,但是如果鼠标开始加速移动,那么距离就会增加。
就像例子中使用的一样,dist()函数简化了计算。
在这里,在这里,用鼠标移动的速度来表示线的厚度。
代码:
voidsetup()
{
size(480,120);
smooth();
stroke(0,102);
}
voiddraw()
{
floatweight=dist(mouseX,mouseY,pmouseX,pmouseY);
strokeWeight(weight);
line(mouseX,mouseY,pmouseX,pmouseY);
}
图示:
示例5-8:
轻随(easing)
用easing技术,我们可以活的两个值:
当前和向前变化的值。
在程序的每一步,当前值仅仅是向目标值移动了一小步。
代码:
floatx;
floateasing=0.01;
floatdiameter=12;
voidsetup()
{
size(480,120);
smooth();
}
voiddraw()
{
floattargetX=mouseX;
x+=(targetX-x)*easing;
ellipse(x,40,12,12);
println(targetX+":
"+x);
}
图示:
X变量的值总是越来越向targetX接近的。
追上targetX的速度是由easing这个变量表示的,范围是0~1.easing的值越小,延迟就会越大。
如果值大到1,那么就不存在延迟了。
运行5-8,确切的值是通过控制台在函数println()中输出的。
当你移动了鼠标,注意数字是如何让分离的,但是当鼠标停止移动,那么X值会越来越接近targetX.
示例5-9:
用easing作出平滑的曲线
在这个示例中,“轻随”技术被运用到了示例5-7上,比较之下,可以看出线条更加平滑了:
代码:
floatx,y,px,py;
floateasing=0.05;
voidsetup()
{
size(480,120);
smooth();
stroke(0,102);
}
voiddraw()
{
floattargetX=mouseX;
x+=(targetX-x)*easing;
floattargetY=mouseY;
y+=(targetY-y)*easing;
floatweight=dist(x,y,px,py);
strokeWeight(weight);
line(x,y,px,py);
px=x;
py=y;
}
图示:
映射
当数字被画到屏幕上时,把值从一个范围转换到另一个范围总是很有用的。
示例5-10:
将值映射到范围
变量mouseX经常在0和窗口的宽度之间,当然你想将这些值映射到其他坐标范围也是可行的。
你可以使用一个数来分割mouseX以减少范围,然后增加或者减少一个数来左移火右移,以做到这种效果。
代码:
voidsetup()
{
size(480,480);
strokeWeight(12);
smooth();
}
voiddraw()
{
background(204);
stroke(255);
line(240,240,mouseX,mouseY);//白线
stroke(0);
floatmx=mouseX/2+60;
line(240,240,mx,mouseY);//黑线
}
图示:
map()函数是一个更通用的方法来实现这样的效果。
它将一个变量从它的范围转换到另一个范围。
第一个参数是一个需要转换的变量,第二个和第三个分别是它的最小值和最大值。
第四个和第五个参数是需要转换到的目的范围的最小值和最大值。
map()函数将背后的数学转换隐藏了。
示例5-11:
通过map()函数来映射
这个示例将5-10示例使用map()函数重写了。
代码:
voidsetup()
{
size(240,120);
strokeWeight(12);
smooth();
}
voiddraw()
{
background(204);
stroke(255);
line(120,60,mouseX,mouseY);//白线
stroke(0);
floatmx=map(mouseX,0,width,60,180);
line(120,60,mx,mouseY);//黑线
}
图示:
map()函数使代码更容易阅读了。
因为最小值和最大值被清除地写成了参数。
在这个示例中,mouseX值从原来的0~width转换成了60~80。
点击
除了鼠标的位置,Processing同样跟踪者鼠标按键是否被按下的信息。
mousePressed变量在当鼠标按键按下和放松时有着不同的值。
mousePressed变量是一个布尔型变量,就是它只有两个值:
真和假。
当鼠标按下时,mousePressed值变为真。
示例5-12:
点击鼠标
mousePressed变量的使用是通过if语句来决定一行代码运行与否的。
代码:
voidsetup()
{
size(240,120);
smooth();
strokeWeight(30);
}
voiddraw()
{
background(204);
stroke(102);
line(40,0,70,height);
if(mousePressed==true)
{
stroke(0);
}
line(0,70,width,50);
}
图示:
敲击前敲击后
在这个程序中,if模块中的代码只有当鼠标按键按下时才执行。
当按键没有被按下时,这行代码是被忽略的。
示例5-13:
当没有点击检测
if拓展一下,加个else
代码:
voidsetup()
{
size(340,120);
smooth();
strokeWeight(30);
}
voiddraw()
{
background(204);
stroke(102);
line(40,0,70,height);
if(mousePressed)
{
stroke(0);
}
else
{
stroke(255);
}
line(0,70,width,50);
}
图示:
点击前
点击后
示例5-14:
鼠标不同键位点击
如果你的鼠标有多个键位,Procrssing同样会追踪是点击了哪个键。
mouseButton变量可以是下面任意3种值之一:
LEFT、CENTER、RIGHT。
为了确认是哪个键被按下了,==号是必须的,就像下面的例子:
代码:
voidsetup()
{
size(120,120);
smooth();
strokeWeight(30);
}
voiddraw()
{
background(204);
stroke(102);
line(40,0,70,height);
if(mousePressed)
{
if(mouseButton==LEFT)
{
stroke(255,0,0);
}
elseif(mouseButton==RIGHT)
{
stroke(0);
}
else
{
stroke(255);
}
line(0,70,width,50);
}
}
图示:
未点击左击中击右击
一个程序可以有许多个if….else….结构,可以比这些简单地程序多得多。
它们可以被连接在一起,成为一个长长的序列(并列的,分别为不同的选择判断)。
也可以被嵌套的存在,如果在if中需要更多的if来判断更复杂的情况的话。
一个if结构可以和mouseX和mouseY一起使用来决定鼠标在窗口的位置。
示例5-15:
寻找鼠标
这个示例检测了鼠标是在这根线的左侧还是右侧,然后像鼠标的位置移动。
代码:
floatx;
intoffset=10;
voidsetup()
{
size(240,120);
smooth();
x=width/2;
}
voiddraw()
{
background(204);
if(mouseX>x)
{
x+=0.5;
offset=-10;
}
if(mouseX{
x-=0.5;
offset=10;
}
line(x,0,x,height);
line(mouseX,mouseY,mouseX+offset,mouseY-10);
line(mouseX,mouseY,mouseX+offset,mouseY+10);
line(mouseX,mouseY,mouseX+offset*3,mouseY);
}
图示:
示例5-16:
圆的边界
对于圆形测试,我们使用dist()函数来获得从圆心到鼠标的距离,然后我们检验它是否比半径更小。
如果是这样,我们知道鼠标在圆之内。
在这个示例中,当鼠标在圆姓区域内,圆就变大。
代码:
intx=120;
inty=60;
intradius=12;
voidsetup()
{
size(240,120);
smooth();
ellipseMode(RADIUS);
}
voiddraw()
{
background(204);
floatd=dist(mouseX,mouseY,x,y);
if(d{
radius++;
fill(0);
}
else
{
fill(255);
}
ellipse(x,y,radius,radius);
}
图示:
原始状态鼠标移动后
示例5-17:
矩形的边界
我们使用另一种方法来测试鼠标是否在一个矩形之内。
我们做4个独立的测试来检验鼠标是否在符合条件的边上,然后我们比较每一次测试的值,如果它们都是真,那么我们确定鼠标是在矩形之内的。
代码:
intx=80;
inty=30;
intw=80;
inth=60;
voidsetup()
{
size(240,120);
}
voiddraw()
{
background(204);
if((mouseX>x)&&(mouseXy)&&(mouseY{
fill(0);
}
else
{
fill(255);
}
rect(x,y,w,h);
}
图示:
前
后
类型
Processing跟踪键盘上的任何一个键被按下与否,同样也包括最后一个按下的键。
像mousePressed变量一样,当有任何键按下时keyPressed变量,为真,为真。
当没有键按下时,它为假。
示例5-18:
按下一个键
在这个示例中,第二条线只有当某一键被按下时才会被画出。
代码:
voidsetup()
{
size(240,120);
smooth();
}
voiddraw()
{
background(204);
line(20,20,220,100);
if(keyPressed)
{
line(220,20,20,100);
}
}
图示:
Key变量保存了最近依次按下的键的信息。
它的数据类型是char字符型,这是character的简写。
一个字符型的变量可以存储任何单个字符,包括字母表的字母,数字和符号。
不像string字符串型的值,string是用双引号引起来的,而char字符型使用单引号。
下面是一个声明和赋值字符变量的例子。
Charc=’A’;//声明并指定变量
不像keyPressed是布尔型,当一个按键每次放开时就转化成假,而key这个变量会一直保留它的结果,知道另一个键被按下。
接下来的示例是使用key的值在屏幕上画出这些字符的。
每次当一个新的键被按下的时候,它的值就被更换成一个新的字符,然后画出来。
一些案件,数Shift和Alt没有一个可见的字符表示,所以当你按下它们时,没有东西会被画出来。
示例5-19:
画一些字符
这个示例介绍用textSize()函数来设置字母的大小。
textSize()函数把文本放置在X坐标轴的中间位置,然后text()函数来绘制这个字母。
代码:
voidsetup()
{
size(120,120);
textSize(64);
textAlign(CENTER);
}
voiddraw()
{
background(0);
text(key,60,80);
}
图示:
示例5-20:
检验特殊的键
在这个示例中,我们输入的H或者N。
我们使用比较操作,==符号,来看按下的键所代表的字符是否为我们想要的。
代码:
voidsetup()
{
size(120,120);
smooth();
}
voiddraw()
{
background(204);
if(keyPressed)
{
if((key=='h')||(key=='H'))
{
line(30,60,90,60);
}
if((key=='n')||(key=='N'))
{
line(30,20,90,100);
}
line(30,20,30,100);
line(90,20,90,100);
}
}
图示:
示例5-21:
用方向键来移动
参考资料《爱上Processing》人民邮电出版社
2013-7-10