课程作业《代码本色》0-4章

第0章(引言)

本章主要讲解了如何实现随机游走。
传统的随机游走用random()生成一定范围内的随机数来实现,而本章中则引进了一个新的生成随机的方法:Perlin噪声。
柏林噪声被称为自然噪声生成算法,因为它可以很好的模拟一些自然效果,如云啊雾啊。因为它产生的效果是平滑的,因此非常自然,而用random()生成的呢,可能最大值接着最小值,整体来说数值变化相对跳跃。
本次实验中,简单地实现了一下随机游走:用一维的柏林噪声随机生成前进方向,用二维的柏林噪声随机生成小球颜色。

不进行刷新,保留轨迹:


class Walker{
  float x;
  float y;
  float t1=3;
  float t2=3;
  float t3=3;
  Walker(){
    t1=3;
    t2=12;
  }
  
  void display(){
    //RGB分量随机生成
    float bright=map(noise(t1,t2),0,1,0,255);
    float bright1=map(noise(t2,t3),0,1,0,255);
    float bright2=map(noise(t3,t1),0,1,0,255);
   stroke(color(bright,bright1,bright2));
   fill(color(bright,bright1,bright2));
   //ellipse(mouseX, mouseY, 20, 20);
   ellipse(x, y, 40, 40);
  }
  
  void step(){
  //位置随机生成
   x=map(noise(t1),0,1,0,width);
   y=map(noise(t2),0,1,0,height);
   t1=t1+0.01;
   t2=t2+0.013;
   t3=t2+0.016;
  }
  
}

//调用上面的类实现随机游走
Walker w;
float t1=3;
float t2=3;
void setup(){
 size(640,360);
 w=new Walker();
 background(255);
}

void draw(){
//background(255);
 w.step();
 w.display();
}

第1章(向量)

本章主要引入了数学中向量的概念,并演示了如何通过使用向量来改变物体的位置。具体操作主要是通过封装PVector类及其方法来实现。
本次实验中,尝试了通过使用向量的方法来使物体运动,并且物体碰到边界之后,向量反向,造成碰撞的效果。

主程序:


Mover[] movers = new Mover[20];

void setup() {
  size(500,500);
  //生成很多个小球
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(); 
  }
}

void draw() {  
  background(222);
  for (int i = 0; i < movers.length; i++) {
    movers[i].update();
    movers[i].display(); 
  }
}

Mover类:


class Mover {

  PVector location;
  PVector velocity;
  PVector acceleration;
  float topspeed;
  float color1;
  float color2;
  float color3;
  float size;
  Mover() {
  	//大小、颜色、位置、速度随机生成
    size=random(20,40);
    color1=random(0,255);
    color2=random(0,255);
    color3=random(0,255);
    location = new PVector(random(width),random(height));
    velocity = new PVector(random(0,2),random(0,2));
    topspeed = 5;
  }

  void update() {
    
    PVector mouse = new PVector(mouseX,mouseY);
    acceleration = PVector.sub(mouse,location); 
    acceleration.normalize();
    acceleration.mult(0.04); 
    
    velocity.add(acceleration);
    velocity.limit(topspeed);
    location.add(velocity);
    //实现边界碰撞效果
    if ((location.x > width) || (location.x < 0)) {
      velocity.x = velocity.x * -1;
    }
    if ((location.y > height) || (location.y < 0)) {
      velocity.y = velocity.y * -1;
    }
  }

  void display() {
    noStroke();
    fill(color1,color2,color3);
    ellipse(location.x,location.y,size,size);
  }
}

第2章(力)

本章主要讲述了如何通过代码来展现力的效果。
这里引入了速度、加速度、施加力等概念和方法。
这里主要实现了中心球体的万有引力效果,并且鼠标左键可拖拽,右键则是另一种与距离成正比的引力效果。
在这里插入图片描述
主程序:

Mover[] movers = new Mover[10];

Attractor a;
boolean choose;
void setup() {
  size(640, 360);
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(random(0.1, 2), random(width), random(height));
  }
  choose=true;
  a = new Attractor();
}

void draw() {
  background(255);
  a.display();
  a.drag();
  a.hover(mouseX, mouseY);

  for (int i = 0; i < movers.length; i++) {
    //如果鼠标按下
    if(mousePressed){
      if(mouseButton==LEFT){
      //如果左键单击,中心物体拖动
      a.clicked(mouseX, mouseY);
      }
      //如果右键单击,另一种效果的力
      if(mouseButton==RIGHT){
        choose=false;
        PVector force = a.bounce(movers[i]);
        movers[i].applyForce(force);
      }
    }
    //如果没有鼠标时间,那么万有引力
    if(choose==true){
      PVector force = a.attract(movers[i]);
      movers[i].applyForce(force);
    }
    movers[i].update();
    movers[i].display();
  }
}

void mouseReleased() {
  a.stopDragging();
  choose=true;
}

Attractor类:

class Attractor {
  float mass;    
  float G;       
  PVector location;  
  boolean dragging = false; 
  boolean rollover = false; 
  PVector dragOffset;  

  Attractor() {
    location = new PVector(width/2,height/2);
    mass = 20;
    G = 1;
    dragOffset = new PVector(0.0,0.0);
  }

   //计算万有引力
  PVector attract(Mover m) {
    PVector force = PVector.sub(location,m.location);  
    float d = force.mag();                              
    d = constrain(d,5.0,25.0);                       
    force.normalize();                                  
    float strength = (G * mass * m.mass) / (d * d);    
    force.mult(strength);                                
    return force;
  }
  
  //计算另一种效果力
  PVector bounce(Mover m){
    PVector force=new PVector(0,0);
    //float d = dist(m.location.x,m.location.y,location.x,location.y);
    //if (d <=mass) {
         force = PVector.sub(location,m.location);
         force.mult(0.001);
    //}       
    return force;
  }
 
 //中心物体对于光标位置改变的响应
  void display() {
    ellipseMode(CENTER);
    strokeWeight(1);
    stroke(0);
    if (dragging) fill (255,1,100);
    else if (rollover) fill(100);
    else fill(127,255,11);
    ellipse(location.x,location.y,mass*2,mass*2);
  }

  //实现中心物体鼠标拖拽
  void clicked(int mx, int my) {
    float d = dist(mx,my,location.x,location.y);
    if (d < mass) {
      dragging = true;
      dragOffset.x = location.x-mx;
      dragOffset.y = location.y-my;
    }
  }

  void hover(int mx, int my) {
    float d = dist(mx,my,location.x,location.y);
    if (d < mass) {
      rollover = true;
    } 
    else {
      rollover = false;
    }
  }

  void stopDragging() {
    dragging = false;
  }
  
  void drag() {
    if (dragging) {
      location.x = mouseX + dragOffset.x;
      location.y = mouseY + dragOffset.y;
    }
  }
}

Mover类:

class Mover {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float mass;
  float color1;
  float color2;
  float color3;
  //随机颜色
  Mover(float m, float x, float y) {
    mass = m;
    color1=random(0,255);
    color2=random(0,255);
    color3=random(0,255);
    location = new PVector(x, y);
    velocity = new PVector(1, 0);
    acceleration = new PVector(0, 0);
  }

  void applyForce(PVector force) {
    PVector f = PVector.div(force, mass);
    acceleration.add(f);
  }

  void update() {
    velocity.add(acceleration);
  
    location.add(velocity);
    acceleration.mult(0);
  }

  void display() {
    stroke(0);
    strokeWeight(1);
    fill(color1,color2,color3);
    ellipse(location.x, location.y, mass*25, mass*25);
  }
}

第3章(振荡)

本章设计到的内容比较多,有角速度、角加速度、正弦函数等。
这类主要在上一章引力效果的基础上进行改进。围绕中心物体旋转的小物体如今也可以旋转了,中心物体用鼠标左键拖拽,右键点击小物体则会停下旋转,同时按下“UP”键的话会统一顺时针旋转,按下“DOWN”键的话则会统一逆时针旋转。

在主程序中调用Attract类和Mover类:

Mover[] movers = new Mover[20];

Attractor a;
boolean choose;
void setup() {
  choose=true;
  size(640,360);
  background(255);
  //生成小物体
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(random(0.1,2),random(width),random(height)); 
  }
  a = new Attractor();
}

void draw() {
  background(255);
  for (int i = 0; i < movers.length; i++) {
    PVector force = a.attract(movers[i]);
    movers[i].applyForce(force);
    if(mousePressed){
      if(mouseButton==LEFT){
          a.clicked(mouseX,mouseY); 
       }
       if(mouseButton==RIGHT){
         choose=false;
         movers[i].update1();
         if(keyPressed){
             if(keyCode==UP){
               movers[i].turn(0.1);
             }else if(keyCode==DOWN){
               movers[i].turn(-0.1);
             }
         }
         a.drag();
         a.hover(mouseX,mouseY);
         a.display();
         movers[i].display1();
       }     
    } 
    if(choose==true){
         movers[i].update();
         a.drag();
         a.hover(mouseX,mouseY);
         a.display();
         movers[i].display();
    }       
  }
}

void mouseReleased() {
  a.stopDragging(); 
  choose=true;
}

Attractor类:


class Attractor {
  float mass;         
  PVector location;   
  float g;
  boolean dragging = false; 
  boolean rollover = false;
  PVector dragOffset; 
  
  Attractor() {
    location = new PVector(width/2, height/2);
    mass = 20;
    g = 0.4;
    dragOffset = new PVector(0.0,0.0);
  }


  PVector attract(Mover m) {
    PVector force = PVector.sub(location, m.location);           
    float distance = force.mag();                                 
    distance = constrain(distance, 5.0, 25.0);                             
    force.normalize();                                            
    float strength = (g * mass * m.mass) / (distance * distance); 
    force.mult(strength);                                        
    return force;
  }

  // Method to display
  void display() {
    stroke(33,1,1);
    strokeWeight(2);
    //noStroke();
    if (dragging) fill(255,1,100);
    else if (rollover) fill(100);
    else  fill(127,255,11);
    ellipse(location.x, location.y, mass*2,mass*2);
  }
  
  void clicked(int mx, int my) {
    float d = dist(mx,my,location.x,location.y);
    if (d < mass) {
      dragging = true;
      dragOffset.x = location.x-mx;
      dragOffset.y = location.y-my;
    }
  }

  void hover(int mx, int my) {
    float d = dist(mx,my,location.x,location.y);
    if (d < mass) {
      rollover = true;
    } 
    else {
      rollover = false;
    }
  }

  void stopDragging() {
    dragging = false;
  }


  void drag() {
    if (dragging) {
      location.x = mouseX + dragOffset.x;
      location.y = mouseY + dragOffset.y;
    }
  }
}

第4章(粒子系统)

粒子系统首先要有单个的粒子类,用于生成粒子。然后在构造函数中对它的位置,加速度,速度等参数进行初始化,这里采用了随机范围内的速度和加速度。并且设置了两种粒子类型,通过随机数n的大小范围确定种类。

构造函数初始化:

  Particle(PVector l,float n) {
    choose=n;
    acceleration = new PVector(random(-0.015,0.015),random(-0.01,0.01));
    velocity = new PVector(random(-1,1),random(-1,1));
    location = l.get();
    lifespan = 255.0;
  }

给与粒子速度和加速度:

  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan -= 2.0;
  }

粒子类型随机确定,choose是传进来的随机数

  void display() {
    stroke(0,lifespan);
    strokeWeight(2);
    fill(127,lifespan,255);
    if(choose<0.6){
    ellipse(location.x,location.y,20,20);
    }else{
      rect(location.x,location.y,10,10);
    }
  }

粒子是否消亡判断:

  boolean isDead() {
    if (lifespan < 0.0) {
      return true;
    } else {
      return false;
    }
  }
}

单一的粒子类之后,要继续构造一个ParticleSystem类,用来统一生成粒子


class ParticleSystem {
  ArrayList<Particle> particles;
  PVector origin;

  ParticleSystem(PVector location) {
    origin = location.get();
    particles = new ArrayList<Particle>();
  }
  void addParticle() {
    particles.add(new Particle(origin,random(0,1)));
  }
  void addParticle(float x, float y) {
    particles.add(new Particle(new PVector(x, y),random(0,1)));
  }
  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
}

最后在主函数中调用粒子系统类就可以啦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值