基于《代码本色》0到4章内容的编程学习
程序员文章站
2022-05-14 08:48:45
...
本学期第三个艺工交叉实验内容。基于对代码本色的前四章内容(引言、向量、力、振荡、粒子系统)的学习进行拓展和改编。本次实验采用processing编程软件。接下来一一总结实验的重点部分。
0、引言
随机和噪声
定义一个类的对象,在类中定义一些行为,在主函数中对类进行调用。
例如:
class Walker {
float x, y;
float tx, ty;
Walker() {
tx = 0;
ty = 10000;
x = map(noise(tx), 0, 1, 0, width);
y = map(noise(ty), 0, 1, 0, height);
}
void step() {
x = map(noise(tx), 0, 1, 0, width);
y = map(noise(ty), 0, 1, 0, height);
tx += 0.02;
ty += 0.02;
}
void render() {
line(x,y,x,y);
ellipse(x,y,5,20);
ellipse(x,y,20,5);
}
}
主函数中的部分代码选取
Walker w2;
w2=new Walker();
w2.step();
fill(0,255,0);
w2.render();
在类的构造函数中对变量进行赋值,使用noise在step()函数中对x,y的值进行修改,在render函数中画图。在主函数中定义类的对象w2,通过w2调用类中的函数。(x,y),通过柏林噪声生成随机位置,由于柏林噪声的范围的(0,1),因此通过map函数将(0,1)映射到背景画布的宽、高相对应的位置。柏林噪声生成的随机数字更加和谐自然。
效果图
1、向量
向量通俗来讲就是一个位置与另一个位置之间的差异,就是一个位置到另一个位置发生的移动。例如向东走3步,向北走4步可表示为(3,4)
一个二维向量,拥有两个参数,分别代表x轴和y轴。下面简单介绍一下二维向量的赋值和使用方式。
PVector position//定义一个二维向量
position= new PVector(width/2, height/2);//给二维向量赋初值
ellipse(position1.x,position1.y,16,16);//二维向量的使用方式
下面是我根据本章内容做的小动图
代码如下:
PVector velocity,velocity2,velocity3;
PVector position, position1, position2;
int a=2;
int b=2;
void setup() {
size(600, 600);
position= new PVector(width/2, height/2);
position1= new PVector(width/2, height/2);
position2= new PVector(width/2, height/2);
velocity2 = new PVector(0,3);
velocity=new PVector(2,2);
velocity3=new PVector(3,0);
}
void draw(){
noStroke();
fill(255,5);
rect(0,0,width,height);
position.add(velocity2);
position1.add(velocity);
position2.add(velocity3);
if ((position.x > width) || (position.x < 0)) {
velocity2.x = velocity2.x * -1;
}
if ((position.y > height) || (position.y < 0)) {
velocity2.y = velocity2.y * -1;
}
fill(255,0,0);
ellipse(position.x,position.y,16,16);
fill(255,0,255);
ellipse(width-position.x, height-position.y,16,16);
fill(0,255,255);
ellipse((width-position.x), position.y,16,16);
fill(0,0,255);
ellipse(position.x, height-position.y,16,16);
if ((position1.x > width) || (position1.x < 0)) {
velocity.x = velocity.x * -1;
}
if ((position1.y > height) || (position1.y < 0)) {
velocity.y = velocity.y * -1;
}
fill(0,255,0);
ellipse(position1.x,position1.y,16,16);
fill(255,255,0);
ellipse(width-position1.x, height-position1.y,16,16);
fill(255,0,255);
ellipse((width-position1.x), position1.y,16,16);
fill(222,122,255);
ellipse(position1.x, height-position1.y,16,16);
if ((position2.x > width) || (position2.x < 0)) {
velocity3.x = velocity3.x * -1;
}
if ((position2.y > height) || (position2.y < 0)) {
velocity3.y = velocity3.y * -1;
}
fill(255,0,0);
ellipse(position2.x,position2.y,16,16);
fill(100,210,0);
ellipse(width-position2.x, height-position2.y,16,16);
PVector center = new PVector(width/2, height/2);
noStroke();
//fill(255,0,50,2);
if ((a<width)||(b<height)){
fill(random(255),0,random(255),2);
a=a+3;
b=b+3;
ellipse(center.x,center.y,a,b);
}
if ((a>width)||(b>height)){
a=2;
b=2;
}
}
2、力
本章实验我设计的是一个鼠标的吸引力,点击鼠标,小球会重新散开,再追随鼠标聚拢。
首先定义一个小球的类。包含小球的创建,速度和加速度的改变。
class Mover {
// The Mover tracks position, velocity, and acceleration
PVector position;
PVector velocity;
PVector acceleration;
// The Mover's maximum speed
float topspeed;
float mass;
Mover(float m) {
// Start in the center
mass = m;
position = new PVector(random(width),random(height));
velocity = new PVector(0,0);
topspeed = 5;
}
void update() {
// Compute a vector that points from position to mouse
PVector mouse = new PVector(mouseX,mouseY);
acceleration = PVector.sub(mouse,position);
acceleration.normalize();
acceleration.mult(0.2);
velocity.add(acceleration);
velocity.limit(topspeed);
position.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
ellipse(position.x,position.y,mass*16,mass*16);
}
}
定义一个类对象的数组,调用这个类,创建和移动小球。同时定义一个鼠标行为,点击鼠标会重新创建小球。
Mover[] movers = new Mover[20];
void setup() {
size(600,600);
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.6,4));
}
}
void draw() {
background(255);
noStroke();
fill(random(255),random(255),random(255));
for (int i = 0; i < movers.length; i++) {
if (i%5==1) fill(123,0,0);
if (i%5==2) fill(0,255,255);
if (i%5==3) fill(23,44,56);
if (i%5==4) fill(255,255,0);
if (i%5==5) fill(0,25,0);
if (i%5==6) fill(0,125,145);
if (i%5==7) fill(0,147,255);
if (i%5==8) fill(0,0,255);
if (i%5==9) fill(196,0,125);
if (i%5==0) fill(178,12,96);
movers[i].update();
movers[i].display();
}
if(mousePressed){
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.1,4));
}
}
}
效果图
3、振荡
让物体出现旋转效果必须不断改变角度。本次实验中旋转前进的小链条的旋转速度会越来越快,因为我设置了旋转角度变化的速度会越来越快。同时,当这个小链条走出页面的时候,会重新开始进行旋转前进这个过程。
类定义:
class Mover {
PVector position;
PVector velocity;
PVector acceleration;
// The Mover's maximum speed
float topspeed;
float mass;
Mover() {
// Start in the center
}
void update() {
// Compute a vector that points from position to mouse
PVector mouse = new PVector(mouseX,mouseY);
acceleration = PVector.sub(mouse,position);
acceleration.normalize();
acceleration.mult(0.2);
// Velocity changes according to acceleration
velocity.add(acceleration);
// Limit the velocity by topspeed
velocity.limit(topspeed);
// position changes by velocity
position.add(velocity);
}
void display() {
stroke(0);
strokeWeight(2);
// fill(127,200);
//fill(random(255),random(255),random(255),10);
ellipse(position.x,position.y,mass*16,mass*16);
}
}
主函数定义:
float angle = 0;
float aVelocity = 0;
float aAcceleration = 0.0005;
float startAngle = 0;
float angleVel = 0.23;
float x=1;
float x2=width;
void setup() {
size(800, 200);
smooth();
//for (int i = 0; i < movers.length; i++) {
// movers[i] = new Mover(random(0.6,4));
//}
}
void draw() {
background(255);
fill(127);
xingzhuang2();
xingzhuang1();
}
void xingzhuang2(){
startAngle += 0.015;
float angle2 = startAngle;
for (int x = 0; x <= width; x += 2) {
float y = map(sin(angle2),-1,1,height/2-60,height/2+60);
if (x<width/4){ fill(0,255,255);}
else if (x<width/2){fill(255,0,255);}
else{fill(255,255,0);}
noStroke();
ellipse(x,y,7,7);
angle2 += angleVel;
}
startAngle+=0.005;
}
void xingzhuang1()
{
translate(x, height/2);
//translate(mouseX,mouseY);
rectMode(CENTER);
rotate(angle);
noStroke();
strokeWeight(2);
fill(255,0,0);
ellipse(60, 0, 16, 16);
ellipse(30, 0, 16, 16);
ellipse(-30, 0, 16, 16);
ellipse(0, 0, 16, 16);
ellipse(-60, 0, 16, 16);
stroke(2);
line(-60, 0, 60, 0);
x+=1;
if( x<width-16){
angle += aVelocity;
aVelocity += aAcceleration;
}
if (x>width-16){
x=0;angle = 0;
aVelocity = 0;
}
}
效果图
4、粒子系统
粒子系统本质上也是一个类,需要定义好这个类,然后在主函数中调用。
定义一个粒子系统的类函数,
效果图
推荐阅读