m.hussain
m.hussain

Reputation: 23

How to change speed of ellipses in processing

I am trying to create an array of circles which all move at different speeds and have different colours using classes which i have done however about 5 seconds into running it for some reason the ellipses all go to the edges of the window and the code doesn't work properly. Below I have provided my code including the class and setup:

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];
      }
    }
  }
}

Upvotes: 0

Views: 1662

Answers (1)

Henri Augusto
Henri Augusto

Reputation: 339

The main problem is that you were not setting the balls to be inside the screen again! This is a very common problem, and Dan Shiffman used it to show the new Processing 3 Debugger.

But since i've found many stuff about your code i will also comment other stuff that might help you with programming.

But first let me show you the working code:

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

Just i few suggestions:

  • The convention is that Class names are upper case. This you you have Circle circles = new Circle(1,5); This is clearer.
  • Avoid using literals! (writing hard-coded numbers) For example, you we're using "ellipse(posX[i], posY[i], 50, 50);". By using a variable for diameter your code becomes more modular. Should you change the circles diameter, you just alter one line of code!
  • Use arrays of objects instead of classes that contains other stuff. That's good programming practice as it makes your code easier to understand. Now if you need to group lots of circles you use an array, or you can create another class "Group_of_circles" for ex.
  • I know i've presented some new concepts/syntaxes and changed a lot to your code, but i tried to comment everything to make it clear and instructive
  • Since i've already changed much thing i didn't use any Vectors, but when dealing with positions , you really should use PVectors! This free book have a great chapter on them!

Try to find good tutorials about software development. They will teach about godo programming practices like keeping your code as modular as possible and etc. But don't worry, it will come to you natrually over time!

Try learncpp.com, tutorialss 1-10a and 1-4b. Those 2 are part of a c++ tutorial, but are a good starting point and refer to programming in general.

Upvotes: 0

Related Questions