《代码本色》编程练习
C h a p Chap Chap 0 0 0 引言
效果
实现了0.5的概率朝鼠标移动的效果以及Perlin噪声的应用。
代码解释
案例参考:
- 0.6 Perlin噪声 n o i s e noise noise 函数示例
- 0.6.1 映射噪声 m a p map map 函数、示例代码0-5
- 0.3 概率和非均匀分布课后练习0.3提出的思考
关键代码
不断变化的颜色的生成,用到了Perlin平滑噪声和对它的映射噪声。
void render()
{
float t=random(1000);
float n=noise(t);
float co=map(n,0,1,0,255);//产生随机的颜色参数
float r=map(n,0,1,0,100);//产生随机的半径
noFill();
stroke(co,random(255),150);
strokeWeight(3);
ellipse(x,y,r,r);
}
使运动对象有50%的概率向着鼠标所在的方向移动,另一半的概率运动情况随意定义了x与y方向的前进。
void step()
{
float r = random(1);
if (r < 0.5)//如果r小于0.5,朝着鼠标方向移动
{
if((x<mouseX) && (y<mouseY)){
x+=3;//间隔设置较大
y+=3;
}
else if((x<mouseX) && (y>mouseY)){
x+=3;
y-=3;
}
else if((x>mouseX) && (y>mouseY)){
x-=3;
y-=3;
}
else if((x>mouseX) && (y<mouseY)){
x-=3;
y+=3;
}
}
else//另外一半的概率
{
x+=random(3);
y+=random(3);
}
x = constrain(x,1,width-1);//固定区域
y = constrain(y,1,height-1);
}
整体代码
Walker w;//游走对象
void setup()
{
size(600,600);
w = new Walker();
background(0);
}
float t=3;
void draw()
{
w.step();
w.render();
}
class Walker
{
float x,y;
Walker()
{
x = random(0, width);
y = random(0, height);
}
void render()
{
……}
void step()
{
……}
}
C h a p Chap Chap 1 1 1 向量
效果
实现了朝鼠标加速、靠近鼠标时减速、互相连线的效果。
代码解释
案例参考:
- 想法来自于平时在浏览网页时看到的效果
- 1.9 静态函数和非静态函数 示例代码1-11——实现朝鼠标加速的效果
- 1.4.1 向量的减法 示例代码1-3——实现求屏幕中心点与鼠标所在点之间的差并连成线
关键代码
Mover类,定义了位置、速度、加速度、最大速度、与鼠标的距离、距离界限。 - 通过与鼠标位置的向量差等赋予移动点加速度;
- 通过比较与鼠标的距离和定义的界限距离的大小,判断移动点应该向鼠标加速还是减速;
- 给鼠标与移动点连线;
- 详见代码注释。
class Mover
{
PVector location;
PVector velocity;
PVector acceleration;
float maxspeed;//最大速度
float distance;//与鼠标的距离
float closedistance;//距离界限,用于调整加速度
Mover()
{
location = new PVector(random(width),random(height));
velocity = new PVector(0,0);
maxspeed = 5;
closedistance = 200;
}
void update()
{
PVector mouse = new PVector(mouseX,mouseY);
acceleration = PVector.sub(mouse,location);
distance = location.dist(mouse);
if(distance < closedistance)//如果与鼠标的距离小于距离界限,减速
{
acceleration.normalize();//单位化向量,使其长度为1
acceleration.mult(-0.2);//反向加速即减速
}
if(distance > closedistance)//如果与鼠标的距离大于距离界限,加速
{
acceleration.normalize();
acceleration.mult(0.2);
}
velocity.add(acceleration);//执行加速度调整
velocity.limit(maxspeed);//限制速度上限
location.add(velocity);//移动
location.x = constrain(location.x,1,width-1);//限制活动区域
location.y = constrain(location.y,1,height-1);
}
void display()
{
fill(127,200,150);
rectMode(CENTER);
rect(location.x,location.y,15,15);//每一个移动点都是一个小正方形
stroke(127,200,150);
line(location.x,location.y,mouseX,mouseY);//与鼠标连成线模拟吸引
}
}
主程序
- 定义了12个移动点对象组成组;
- 将所有移动点两两连线,形成牵制效果;
- d r a w draw draw 函数的前几行很关键,用于画布等大的白色矩形实现刷屏效果,这样视觉上就不会看到对象以及它们连线的运动轨迹了;
- 详见代码注释。
Mover[] movers = new Mover[12];//新建12个对象组成的组
void setup()
{
size(1000,800);
background(255);
for (int i = 0; i < movers.length; i++)
{
movers[i] = new Mover();
}
}
void draw()
{
fill(255,255);
rectMode(CENTER);
rect(width/2,height/2,width,height); //每次执行draw的时候都用等大的白色矩形刷屏,不会有轨迹的重合
for (int i = 0; i < movers.length; i++)
{
movers[i].update();
movers[i