Processing:数组(上)

1. 一个数组(Array)就是包含了一串变量列(list of variables)的一个阵列。当程序需要诸多相似数据的例子的时候,就是使用数组的时候,比如画100辆上一课中的小车。

2. 列(list)因两个重要的原因显得非常有用:i、列记录列内元素的踪迹;ii、列保持那些元素的顺序。后一点至关重要,因为在很多程序中,信息的顺序与信息本身一样重要。

3. 一个列的第一位是0。

4. 申明一个列:列类型 [ ] 列名称

5. 每个列都有一个固定的数目,不可更改。

6. 创造一个新的列:列类型 [ ] 列名称 = new 类型 [列数目]

7. 几个例子:
// 一个由四个浮点数组成的列
float[] scores = new float[4];

// 一个由100个Humen对象组成的列
Human[] people = new Human[100];

// 用一个变量来指定数目
int num = 50;
Car[] cars = new Car[num];

// 用一个表达式来指定数目
Spaceship[] ships = new Spaceship[num*2 + 3];

8. 重复一千次,每个在0~10间随机:
float[] values = new float[1000];

for (int i = 0; i < 1000; i ++ ) {
values[i] = random(0,10);
}

9. 这么搞的话,我们就不必每次都在原括号内指定列的数目了:
float[] values = new float[100];

for (int i = 0; i < values.length; i ++ ) {
values[i] = 0;
}

是的,关键就在于values.length

pr9-1
pr9-1

10. 捕捉鼠标运动轨迹的一个例子(list的储存功能):
// 申明两个具有50个元素的数组.
int[] xpos = new int[50];
int[] ypos = new int[50];

void setup() {
size(200,200);

smooth();
// 初始化每个数组内的所有元素为0.
for (int i = 0; i < xpos.length; i ++ ) {
xpos[i] = 0;
ypos[i] = 0;
}
}

void draw() {
background(255);

// 变化数组的值
for (int i = 0; i < xpos.length-1; i ++ ) {
// 将所有原素向下移动一个位置.
// xpos[0] = xpos[1], xpos[1] = xpos = [2], 等等. 在倒数第二个元素的位置停止.
xpos[i] = xpos[i+1];
ypos[i] = ypos[i+1];
}

// 新位置
xpos[xpos.length-1] = mouseX; // 用鼠标位置更新数组的上一个位置.
ypos[ypos.length-1] = mouseY;

// 绘制一切
for (int i = 0; i < xpos.length; i ++ ) {
// 为数组内的每一个元素画一个圆.
// 颜色与大小同循环的计数器(i)挂钩.
noStroke();
fill(255-i*5);
ellipse(xpos[i],ypos[i],i,i);
}
}

11. 解读一下上边那个例子:
首先,申明两个数组
int[] xpos = new int[50];
int[] ypos = new int[50];

其次,在setup()内,我们必须初始化数组。因为一开始并没有任何鼠标运动,因此我们将数组填入0
for (int i = 0; i < xpos.length; i ++ ) {
xpos[i] = 0;
ypos[i] = 0;
}

在draw()内每个主要的循环,我们想要用当前鼠标的位置更新数组。让我们选择将鼠标当前位置放入数组被最后一个位置。数组的长度是50,意味着数目从0~49。最后一个数目是49,或者说,数组的长度减1。
xpos[xpos.length-1] = mouseX;
ypos[ypos.length-1] = mouseY;

现在进入难点。我们仅仅想要保存最后50个鼠标的位置。随着我们在数组末尾将鼠标位置储存进去,我们便改写了之前存储在那里的信息。如果鼠标前一帧位于(10,10)后一帧位于(15,15),我们就会想要将10,10)放在数组倒数第二位,而将(15,15)放在最后一位。解决方法是:在更新当前位置之前将所有元素向下移动一个位置。如图pr9-2。

pr9-2
pr9-2

第49位的元素移动到48位,48移动到47,如此往复。我们可以在将每个元素i设置为i+1的基础上循环这个数组,而达到效果。注意我们必须在倒数第二位的时候停止,因为对于长度为50的数组来说,没有元素50。换句话说,相较
i < xpos.length;
我们必须将它替换为:
i < xpos.length-1;

因此,此部分整段代码应写为:
for (int i = 0; i < xpos.length-1; i ++ ) {
xpos[i] = xpos[i+1];
ypos[i] = ypos[i+1];
}

最后,我们可以利用之前的鼠标位置记录画出一系列圆形。在整个xpos和ypos数组内,基于每个元素的值绘制一个圆形:
for (int i = 0; i < xpos.length; i ++ ) {
noStroke();
fill(255);
ellipse(xpos[i],ypos[i],32,32);
}

为了让它看起来更牛逼一些,我们可以选择将圆形的亮度和大小与数组的位置挂钩,即,较早的(因此更老)值将更亮而较晚(更新)的值则更大更暗。这可以由不断记数中的变量i赋值给color和size来实现。
for (int i = 0; i < xpos.length; i ++ ) {
noStroke();
fill(255-i*5);
ellipse(xpos[i],ypos[i],i,i);
}

学到这里:Daniel爷爷残酷的出了一道题:用面向对象的方式以Snake类重写上边这个例子。。。(一个更进一步的问题:创建一个包含x和y坐标的类Point,每个对象snake都含有一个Point对象的数组,而不是上边两个单独的x与y值的数组。。。。)。well,我承认我完全傻逼和晕乎了,如果你和我一样,那么就停下来稍后再想这个问题吧,如果你想来想去还是想不出来,那么可以点击这里下载答案。

Be Sociable, Share!

《Processing:数组(上)》有2个想法

  1. 我也是。。一上二元就想死。。
    不过记得看到过有这样的…顿时觉得我好笨哦…

    float[] x;
    float[] y;
    array[][] point = {x,y};

    Reply

    ww Reply:

    一学这些我就觉得自己智商不够花

    Reply

发表评论

电子邮件地址不会被公开。 必填项已用*标注