背景及创作
想用交互来控制一个物体的运动,控制颜色。我就想到了模拟LED灯,来实现融入动画技术的交互应用。城市的夜晚灯光璀璨,有在运动的灯光,比如,车尾灯、飞机雷达灯、也有万千家庭的灯火是静止的。亦静异动,令人神怡,然而都离不开每个小小的LED灯。
《代码本色》中运用到的技术
第一章 向量
第三章 震荡
代码展示
ArrayList<LED> ledlist;
int ledwidth = 75;
boolean ispressed = false;
void setup()
{
size(500, 500);
ledlist = new ArrayList<LED>();
LED led1 = new LED(width/2-ledwidth-100, height/2-ledwidth-100, ledwidth);
LED led2 = new LED(width/2-ledwidth-100, height/2, ledwidth);
LED led3 = new LED(width/2-ledwidth-100, height/2+ledwidth+100, ledwidth);
LED led4 = new LED(width/2, height/2-ledwidth-100, ledwidth);
LED led5 = new LED(width/2, height/2, ledwidth);
LED led6 = new LED(width/2, height/2+ledwidth+100, ledwidth);
LED led7 = new LED(width/2+ledwidth+100, height/2-ledwidth-100, ledwidth);
LED led8 = new LED(width/2+ledwidth+100, height/2, ledwidth);
LED led9 = new LED(width/2+ledwidth+100, height/2+ledwidth+100, ledwidth);
ledlist.add(led1);
ledlist.add(led2);
ledlist.add(led3);
ledlist.add(led4);
ledlist.add(led5);
ledlist.add(led6);
ledlist.add(led7);
ledlist.add(led8);
ledlist.add(led9);
}
void draw()
{
background(0);
for(int i=0;i < ledlist.size(); i++)
{
LED led = ledlist.get(i);
led.draw();
}
}
void mousePressed()
{
for(int i=0;i < ledlist.size(); i++)
{
LED led = ledlist.get(i);
led.update();
}
}
class LED {
int x;
int y;
int state;
int k;
int w;
int degs;
int c;
LED(int x_, int y_, int w_) {
x = x_;
y = y_;
w = w_;
c = (int)random(0,360);
state = 0;
k = 0;
degs = 0;
}
void update()
{
if (overRect(x-w/2, y-w/2, w, w))
{
state ++;
if (state >= 3)
{
state = 0;
}
}
}
void draw()
{
colorMode(HSB,360,100,100);
if (state == 0)
{
pushMatrix();
translate(x, y);
rotate(radians(degs));
fill(c,100,100);
noStroke();
rectMode(CENTER);
rect(0, 0, w, w);
popMatrix();
} else if (state == 1)
{
pushMatrix();
translate(x, y);
rotate(radians(++degs));
fill(c,100,100);
noStroke();
rectMode(CENTER);
rect(0, 0, w, w);
popMatrix();
} else if (state == 2)
{
pushMatrix();
translate(x, y);
rotate(radians(degs));
if (k == 0)
c ++;
if (k == 1)
c --;
if (c <=0)
{
c = 0;
k = 0;
}
if (c >= 360)
{
c = 360;
k = 1;
}
fill(c,100,100);
noStroke();
rectMode(CENTER);
rect(0, 0, w, w);
popMatrix();
}
}
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}
}
效果
感想
首先,动画是对象显示对象的不断更新来实现的,如位置、大小、形状等。因此,我只要能在显示之前更新显示对象的这些属性就可以了。
Processing的draw()函数是显示对象更新和绘制的主要场所,我可以把更新和绘制放在draw()函数中进行。绘制由显示对象自己负责,而更新则由专门的更新类负责了。关键是更新类如何确定更新的时机。如果每加入一个对显示对象的更新类型就要在draw()中添加代码肯定是不符合软件的可扩展性原则的,因为这修改了原程序的代码。
如何在不修改原程序的基础上来更新呢。首先显示对象的更新和绘制我都放在显示对象的同一个方法中updateDraw()。这样在draw()函数中只要调用显示对象的一个方法。但在显示对象的updateDraw()方法中不能由显示对象自己实现更新,而必须由更新对象进行更新。这就必须由更新对象在其内部对显示对象进行设置,而这又进一步要求显示对象要通知更新对象何时进行更新。可以说是一个复杂的过程,我觉得我的完成情况也没有那么好,能力确实有限,但是尽力做好了。