Processing 加工中如何改变椭圆的速度

Processing 加工中如何改变椭圆的速度,processing,Processing,我正在尝试创建一个圆圈数组,所有圆圈都以不同的速度移动,并且使用类具有不同的颜色,但是在运行它大约5秒钟后,由于某种原因,椭圆都会出现在窗口的边缘,代码无法正常工作。下面我提供了我的代码,包括类和设置: circle circles = new circle(1, 8); void setup() { size(800, 600); } void draw() { background(255); circles.display(); circles.bounce(); }

我正在尝试创建一个圆圈数组,所有圆圈都以不同的速度移动,并且使用类具有不同的颜色,但是在运行它大约5秒钟后,由于某种原因,椭圆都会出现在窗口的边缘,代码无法正常工作。下面我提供了我的代码,包括类和设置:

circle circles = new circle(1, 8);

void setup() {
  size(800, 600);
}

void draw() {
  background(255);
  circles.display();
  circles.bounce();
}

class circle {
  int[] posX = new int [10];
  int[] posY = new int [10];
  float[] speedX = new float[10];
  float[] speedY = new float[10];
  int[] red = new int [10];
  int[] green = new int [10];
  int[] blue = new int [10];
  circle(float start, float end) {
    for (int i = 0; i < 10; i++) {
      speedX[i] = random(start, end);
      speedY[i] = random(start, end);
      posX[i] = int(random(500, 800));
      posY[i] = int(random(500, 600));
      red[i] = int(random(0, 255));
      green[i] = int(random(0, 255));
      blue[i] = int(random(0, 255));
    }
  }
  void display() {
    for (int i = 0; i < 10; i++) {
      fill(red[i], green[i], blue[i]);
      ellipse(posX[i], posY[i], 50, 50);
    }
  }
  void bounce() {

    for (int i = 0; i < 10; i++) {
      posX[i] += speedX[i];
      posY[i] += speedY[i];
      if (posX[i] - 50 < 0 || posX[i] + 50 > width) {
        speedX[i] = -speedX[i];
      }
      if (posY[i] - 50 < 0 || posY[i] + 50 > height) {
        speedY[i] = -speedY[i];
      }
    }
  }
}
圆圈=新圆圈(1,8);
无效设置(){
尺寸(800600);
}
作废提款(){
背景(255);
display();
圆圈。反弹();
}
班级圈子{
int[]posX=新的int[10];
int[]posY=新的int[10];
浮动[]速度x=新浮动[10];
浮动[]快速=新浮动[10];
int[]红色=新int[10];
int[]绿色=新int[10];
int[]蓝色=新int[10];
圆(浮动起点、浮动终点){
对于(int i=0;i<10;i++){
speedX[i]=随机(开始、结束);
快速[i]=随机(开始、结束);
posX[i]=int(随机(500800));
posY[i]=int(随机(500600));
红色[i]=int(随机(0255));
绿色[i]=int(随机(0255));
蓝色[i]=int(随机(0255));
}
}
无效显示(){
对于(int i=0;i<10;i++){
填充(红色[i],绿色[i],蓝色[i]);
椭圆(posX[i],posY[i],50,50);
}
}
无效反弹(){
对于(int i=0;i<10;i++){
posX[i]+=speedX[i];
posY[i]+=speedY[i];
if(posX[i]-50<0 | | posX[i]+50>宽度){
speedX[i]=-speedX[i];
}
if(posY[i]-50<0 | | posY[i]+50>高度){
speedY[i]=-speedY[i];
}
}
}
}

主要问题是您没有再次将球设置在屏幕内!这是一个非常常见的问题,Dan Shiffman用它来解决这个问题

但是因为我已经找到了很多关于你的代码的东西,我也会评论其他可能帮助你编程的东西

但首先让我向您展示工作代码:

int n_of_circles = 10;
Circle[] circles = new Circle[n_of_circles];

void setup() {
  size(800, 600);
  for (int i = 0; i < n_of_circles; i++) {
    circles[i] = new Circle(1, 8);
  }
}

void draw() {
  background(255);
  for (int i = 0; i < n_of_circles; i++) {
    circles[i].display();
    circles[i].move();
  }
}

class Circle {
  float posX = random(0, width); //no need to set these value in constructor
  float posY = random(0, height); //we can set it here
  float speedX = 666; //we will change these on constructor
  float speedY = 666; //666 is just a personal convention that i use to indicate that :p

  //Similarly, no need to set the color variable in the constructor
  //also, lets use a color variable instead of 3 separate variables
  color circ_color = color(
      (int) random(0, 255), 
      (int) random(0, 255),
      (int) random(0, 255)
    );
  //defining circle diameter instead of using a literal ("50", in our case)
  int diameter = 50;
  int radius = diameter/2;


  Circle(float min_speed, float max_speed) {
      // The purpose of "min_speed" and "max_speed" are clearer than "start" and "end"
      speedX = random(min_speed, max_speed);
      speedY = random(min_speed, max_speed);
  }

  void display() {
      //this push an pop commands ensure that this fill command won't 
      //interfere with any other stuff, if you ever reuse this code
      pushStyle();
        fill( circ_color );
        ellipse(posX, posY, diameter, diameter);    
      popStyle();
  }

  //notice how i separated the move declartions form the bounce. It's good programming practice
  //to keep stuff simpler. Functions should always have one single responsibility.
  //In this case it won't help´much, but we're yoru move function more complex, it would!

  void move(){    
    posX += speedX;
    posY += speedY;
    bounce();

  }

  void bounce() {
      //note that you were using the diameter, but you should really use the radius!

      //if it's touching left or side edges
      if (posX - radius < 0 || posX + radius > width) {
        speedX *= -1; //inverts the sign

        //Here's the actual missing bits!
        if (posX - radius < 0 ){ posX = radius; }
        if (posX + radius > width ){ posX = width-radius; }
      }

      //if it's touching top or bottom edges
      if (posY - radius < 0 || posY + radius > height) {
        speedY *= -1; //inverts the sign

        //Here's the actual missing bits!
        if (posY - radius < 0 ){ posY = radius; }
        if (posY + radius > height ){ posY = height-radius; }
      }

  }

} //end of class Circle
int n_/u圆=10;
圆圈[]圆圈=新圆圈[n个圆圈];
无效设置(){
尺寸(800600);
for(int i=0;i宽度){
speedX*=-1;//反转符号
//这是实际丢失的部分!
如果(posX-radius<0){posX=radius;}
如果(posX+半径>宽度){posX=宽度半径;}
}
//如果它接触顶部或底部边缘
如果(位置-半径<0 | |位置+半径>高度){
speedY*=-1;//反转符号
//这是实际丢失的部分!
如果(posY-radius<0){posY=radius;}
如果(posY+radius>height){posY=height-radius;}
}
}
}//课程结束循环
我只想提出几点建议:

  • 按照惯例,类名是大写的。这就是你的圆=新的圆(1,5);这更清楚
  • 避免使用文字!(写硬编码的数字)例如,我们使用的是“椭圆(posX[i],posY[i],50,50);”。通过对直径使用变量,您的代码变得更加模块化。如果你改变圆的直径,你只需要改变一行代码
  • 使用对象数组而不是包含其他内容的类。这是很好的编程实践,因为它使代码更容易理解。现在,如果需要对许多圆进行分组,可以使用数组,也可以为ex创建另一个类“groupofcircles”
  • 我知道我已经提出了一些新的概念/语法,并对您的代码做了很多更改,但我试图对所有内容进行注释,以使其清晰明了并具有指导意义
  • 因为我已经改变了很多东西,我没有使用任何向量,但是当处理位置时,你真的应该使用PVectors!有一个伟大的章节,他们
尝试寻找关于软件开发的好教程。他们将教授godo编程实践,比如让代码尽可能模块化等等。但别担心,随着时间的推移,它会自然而然地出现在你的脑海中

试试learncpp.com,教程1-10a和1-4b。这2个是C++教程的一部分,但是是一个很好的起点,通常指的是编程。