首页 > 未分类 > 第三期boss学习及分析
2017
08-06

第三期boss学习及分析

首先,也是来为虎牙大大的代码加上注释。

FlowField flow;
ArrayList<Vehicle> vlist;				
PVector center;						//中心点
void setup() {
  size(1200, 600);
  flow = new FlowField();
  vlist = new ArrayList<Vehicle>();
  for (int i = 0; i<70; i++) {
    vlist.add(new Vehicle(random(width), random(height)));//vlist的初始化
  }
  center = new PVector(width/2, height/2);//窗口中心
}

void draw() {
  background(175);
  for (Vehicle v : vlist) {		//更新vlist
    v.follow(flow);
    v.run(center, flow);
  }
}

void mousePressed() {
  vlist.add(new Vehicle(mouseX, mouseY));//添加一条新的曲线
}

class FlowField {			

  PVector [][] field;			//创建一个二维数组,其中,PVector是二维的,即(x,y)
  int cols, rows;			//列,行
  int sulotion;							

  FlowField() {				//构造函数
    sulotion = 10;
    cols = width/sulotion;
    rows = height/sulotion;
    field = new PVector [cols][rows];	//此时拥有cols * rows个二维向量
    init();				//为field赋初始值
  }

  PVector lookUp(PVector lookup) {		//获取数组中的一个向量值
    //对行列值得一个范围限定
    int xrow = int(constrain(lookup.x/sulotion, 0, cols-1));//约束
    int ycol = int(constrain(lookup.y/sulotion, 0, rows-1));//约束
    return field[xrow][ycol].get();
  }

  public void init() {					//初始化
    for (int i=0; i<cols; i++) {
      for (int j = 0; j<rows; j++) {
        field[i][j] = new PVector(random(cos(0)), random(sin(1))); 		
      }
    }
  }
  
}

class Vehicle {							
  PVector location;						//位置
  PVector velocity;						//速率
  PVector acceleration;					        //加速度
  float maxSpeed;						//最大速度
  float maxforce;						//最大力
  float mass;							//质量
  float r;
  float w;							//边线宽度
  float xoffset;						//水平偏移量
  float yoffset;						//垂直偏移量
  color c;							//边线颜色

  Vehicle(float x, float y) {
    location = new PVector(x, y);		        //初始位置
    acceleration = new PVector(0, 0);	                //加速度初始为0
    velocity = new PVector(0, 0);		        //速率初始为0
    r = 7.0;
    maxSpeed = 4;					//最大速率
    maxforce = 0.1;					//最大力
    mass = 2;						//质量
    xoffset = random(width);			        //随机偏移
    yoffset = random(height);			        //随机偏移
    c = color(random(255), random(255), random(255));	//随机颜色
    w = random(1, 2);					//随机线宽
  }

  void update() {				//更新位置
    velocity.add(acceleration);			//v = v + at;v为速度,a为加速度
    location.add(velocity);			//s = s + vt;s为位移,v为速度
    velocity.limit(maxSpeed);			//当速度加速到最大速度就不在加速
    acceleration.mult(0);			//清0
  }

  void applyForce(PVector f) {			//更新加速度
    PVector force= f.get();
    force.div(mass);				//a = f/m;a为加速度,f为施加的力,m为质量
    acceleration.add(force);			//为加速度赋值
  }

  void follow(FlowField f) {			//实时计算所需力的大小
    PVector desire =f.lookUp(location);				
    desire.mult(maxSpeed);							
    PVector steer = PVector.sub(desire, velocity);	
    steer.limit(maxforce);
    applyForce(steer);
  }

  public void display(PVector center, FlowField f) {//绘图
    PVector temp;
    temp = f.lookUp(new PVector(random(width), random(height)));//随机获取一个点
    beginShape();
    noFill();
    stroke(c);
    strokeWeight(w);
    vertex(center.x, center.y);						//设定第一个锚点
    bezierVertex(temp.x, temp.y, temp.x+xoffset, temp.y+yoffset, this.location.x, this.location.y);//贝塞尔曲线(第一控制点,第二控制点,锚点)
    endShape(CLOSE);
  }

  void run(PVector center, FlowField f) {//更新并绘制
    update();
    display(center, f);
  }
}

注释写的不是很详细,有些变量的值我也不知道是做什么的,因此我就没加注释。但大概思想是明了的。

个人认为最中心的地方就是绘制贝塞尔曲线那一行代码,剩下的均是为其做铺垫。从开头看有一个可变数组vlist,初始大小为70,也就是刚开始有70条曲线(我没数过)。再往下有一个鼠标点击新建一条曲线,是将鼠标坐标作为参数传进去的。

我看函数说明上说,bezierVertex涉及四个点,两个锚点,两个控制点,这四个点的具体含义是什么我不能准确描述,按照我的理解:锚点是线条的起点和终点,控制点是控制线条弯曲的。但是在程序运行中线条是闭合的,所以我的理解应该是错误的。等有大佬看到了请在评论里解惑,在此谢过大佬。

线条会整理自己的方向,是因为Vehicle类中update、applyForce、follow一起作用的结果,至于原理么,可以参考高中物理中的运动部分,但我写不了,因为我说不明白(没有深入研究)。

期间也问了度娘很多,flowField意为流体,Vehicle意为传播媒介,是的,我不明白这个意义。

作为官方示例都没有学习完表示抱歉,会随着学习更新。



最后编辑:
作者:fishVD
知识就是金钱

第三期boss学习及分析》有 1 条评论

kunard的回复 取消回复

你的email不会被公开。