Processing beginner

13

Answers

  • Post entire code

    What values do the vars have?

  • // First ball parameters
    float posX1, posY1; // Position
    float speedX1, speedY1; // Movement (linear)
    int radius1; // Radius of the ball
    color ballColor1; // And its color
    
    // Second ball parameters
    float posX2, posY2;
    float speedX2, speedY2;
    int radius2;
    color ballColor2;
    
    void setup()
    {
      size(600, 400);
      smooth();
    
      // Initialize the ball's data
      posX1 = 120;
      posY1 = 50;
      speedX1 = -2;
      speedY1 = 3;
      radius1 = 24;
      ballColor1 = #002277;
    
      // Again for the second ball
      posX2 = 220;
      posY2 = 150;
      speedX2 = 2;
      speedY2 = -3;
      radius2 = 32;
      ballColor2 = #007722;
    }
    
    void draw()
    {
      // Erase the sketch area with some light color
      background(#AAFFEE);
      // Compute the new ball position
      moveBall(speedX1, speedY1, posX1, posY1, radius1);
      moveBall(speedX2, speedY2, posX2, posY2, radius2);
    
      // And display it
      displayBall(ballColor1, posX1,posY1, radius1);
       displayBall(ballColor2, posX2,posY2, radius2);
    
    }
    
    void moveBall(float speedX, float speedY, float posX, float posY, int radius)
    {
      // Move by the amount determined by the speed
      posX += speedX;
      // Check the horizontal position against the bounds of the sketch
      if (posX < radius || posX > width - radius)
      {
        // We went out of the area, we invert the h. speed (moving in the opposite direction)
        // and put back the ball inside the area
        speedX = -speedX;
        posX += speedX;
      }
      // Idem for the vertical speed/position
      posY += speedY;
      if (posY < radius || posY > height - radius)
      {
        speedY = -speedY;
        posY += speedY;
      }
    }
    
    void displayBall(color ballColor, float posX, float posY, int radius)
    {
      noStroke();
      fill(ballColor);
      ellipse(posX, posY, radius * 2, radius * 2);
    }
    
  • edited May 2014

    Doesn't matter probably

    Move on to arrays and objects pls, that's what you really need

    P.S.

    The reason it doesn't work is that in the functiojn moveBall there are copies of the variables used and changed - and not the global vars.

    That's different when you'll use a class. Then it will work.

  • edited May 2014

    Yeah, so it can't work without a class? Only way it would work without a class is by using an Array?

    Here is my arrays attempt:

    float[] posX = new float [10];
    float[] posY;
    // Movements (linear)
    float[] speedX;
    float[] speedY; 
    // Radius of the balls
    int[] radius;
    // And the colors
    color[] ballColor; 
    
    void setup()
    {
      size(600, 400);
      smooth();
     posY = new float [10];
     speedX= new float [10];
     speedY = new float [10];
      radius = new int [10];
      ballColor = new color [10];
      // Initialize the ball's data
      posX[0] = 120;
      posY[0] = 50;
      speedX[0] = -2;
      speedY[0] = 3;
      radius[0] = 24;
      ballColor[0] = #002277;
    
      // Ball 2
    
        posX[1] = 190;
      posY[1] = 50;
      speedX[1] = -4;
      speedY[1] = 3;
      radius[1] = 24;
      ballColor[1] = #002222;
    
      //ball 3
    
        posX[2] = 30;
      posY[2] = 50;
      speedX[2] = -4;
      speedY[2] = 3;
      radius[2] = 24;
      ballColor[2] = #000033;
    
        posX[3] = 80;
      posY[3] = 50;
      speedX[3] = -4;
      speedY[3] = 3;
      radius[3] = 24;
      ballColor[3] = #001133;
    }
    
    
    
    void draw()
    {
      // Erase the sketch area
      background(#AAFFEE);
      // Compute the new ball position
      moveBall(0);
      // And display it
      displayBall(0);
       moveBall(1);
      // And display it
      displayBall(1);
        moveBall(2);
      // And display it
      displayBall(2);
        moveBall(3);
      // And display it
      displayBall(3);
    }
    
    void moveBall(int n)
    {
      // Move by the amount determined by the speed
      posX[n] += speedX[n];
      // Check the horizontal position against the bounds of the sketch
      if (posX[n] < radius[n] || posX[n] > width - radius[n])
      {
        // We went out of the area, we invert the h. speed (moving in the opposite direction)
        // and put back the ball inside the area
        speedX[n] = -speedX[n];
        posX[n] += speedX[n];
      }
      // Idem for the vertical speed/position
      posY[n] += speedY[n];
      if (posY[n] < radius[n] || posY[n] > height - radius[n])
      {
        speedY[n] = -speedY[n];
        posY[n] += speedY[n];
      }
    }
    
    void displayBall(int n)
    {
      // Simple filled circle
      noStroke();
      fill(ballColor[n]);
      ellipse(posX[n], posY[n], radius[n] * 2, radius[n] * 2);
    }
    
  • edited May 2014

    the reason why the 1st attempt didn't work (quote by quark)

    Java passes everything by value (only copies of the global vars) to the functions so the parameters are local to the method and does not change the actual elements in the draw() function.

    that's actually quite good to know...

    BTW

    the text

    http://wiki.processing.org/w/From_several_variables_to_arrays

    btw just mentioned it as a side note and does not follow that path.

    workaround

    this is a workaround that uses the fact that a function can return a value... line 60 and 69.... but pls don't be distracted by that

    // First ball parameters
    float posX1, posY1; // Position
    float speedX1, speedY1; // Movement (linear)
    int radius1; // Radius of the ball
    color ballColor1; // And its color
    
    // Second ball parameters
    float posX2, posY2;
    float speedX2, speedY2;
    int radius2;
    color ballColor2;
    
    void setup()
    {
      size(600, 400);
      smooth();
    
      // Initialize the ball's data
      posX1 = 120;
      posY1 = 50;
      speedX1 = -2;
      speedY1 = 3;
      radius1 = 24;
      ballColor1 = #002277;
    
      // Again for the second ball
      posX2 = 220;
      posY2 = 150;
      speedX2 = 2;
      speedY2 = -3;
      radius2 = 32;
      ballColor2 = #007722;
    }
    
    void draw()
    {
      // Erase the sketch area with some light color
      background(#AAFFEE);
      // Compute the new ball position
      PVector temp = moveBall(speedX1, speedY1, posX1, posY1, radius1);
      posX1 = temp.x;
      posY1 = temp.y; 
      temp = moveBall(speedX2, speedY2, posX2, posY2, radius2);
      posX2 = temp.x;
      posY2 = temp.y;
    
      // -------------------------
      temp = collisionBall(speedX1, speedY1, posX1, posY1, radius1);
      speedX1 = temp.x;
      speedY1 = temp.y; 
      temp = collisionBall(speedX2, speedY2, posX2, posY2, radius2);
      speedX2 = temp.x;
      speedY2 = temp.y;
    
      // And display it
      displayBall(ballColor1, posX1, posY1, radius1);
      displayBall(ballColor2, posX2, posY2, radius2);
    }
    
    PVector moveBall(float speedX, float speedY, float posX, float posY, int radius)
    {
      // Move by the amount determined by the speed
      posX += speedX;
      posY += speedY;
    
      return new PVector (posX, posY);
    }
    
    PVector collisionBall(float speedX, float speedY, float posX, float posY, int radius)
    {
      // Check the horizontal position against the bounds of the sketch
      if (posX < radius || posX > width - radius)
      {
        // we invert the h. speed (moving in the opposite direction)
        // 
        speedX = -speedX;
      }
      // Idem for the vertical speed/position
      if (posY < radius || posY > height - radius)
      {
        speedY = -speedY;
      }
      return new PVector (speedX, speedY);
    }
    
    void displayBall(color ballColor, float posX, float posY, int radius)
    {
      noStroke();
      fill(ballColor);
      ellipse(posX, posY, radius * 2, radius * 2);
    }
    
  • edited May 2014

    I understand "pass by copy"/"pass by value". The original value of the global variable, doesn't change, as a copy has been passed, not it's original value. I won't bother with the workaround, as it's beyond the level I'm at, at the moment. I will focus on making a class now.

  • Yes pls

  • Lol.

  • edited May 2014

    The array example with the balls you wrote works. That is because you just pass the index n as a parameter to the function (a copy of n if you like) and the function works with the global array directly, changing its values. So it doesn't matter that n is only a copy.

    very clever!

  • Answer ✓

    One of the things I'm unsure of:

    int [] a = new int [3];

    Does this mean, we will have ONE variable (reference), labelled a, which will contain the reference to the 1st physical memory location of the array?

    Or THREE variables, each labelled a, with each pointing to the 3 memory locations where each of the three slots in the array is?

    Does this question make sense? I hope so!

    Let's split the statement above:

    1. int[] a
    2. new int[3]

    • 1st part is a variable declaration. it means a tiny portion of memory is gonna be reserved to express a single value.
    • That portion is gonna be labeled a. And since its type is int[],
      which is an object type, it's either 4 bytes in 32-bit mode or 8 bytes in 64-bit mode!
    • That # of bytes is enough to express a physical memory address. Which is commonly called reference or pointer!

    Whew! 2nd part now: :D

    • Keyword new instantiates an object. The [] operator means it's an array type object.
    • A contiguous block of memory is allocated/reserved for that object. Its size is enough to store all of its non-static fields.
    • An array object has a field called length, plus the "slots". Those "slots" are of the type the array was declared.

    • The final process involves the assignment operator =, which transfers the result from the expression at the right side
      to the variable at the left side!
    • Thus, variable a ends up storing the 1st memory address of the instantiated object.
    • Even though the variable isn't the object itself, it can act as its "avatar" in order to access the object's members!

  • edited May 2014

    Okay, while working on the class, I struggled with the idea of overloaded constructors. Back to the earlier example:

    PVector() { //does nothing
      }
    
      PVector(float xx, float yy) { //passes the first 2 parameters when the constructor is called in setup() to "this" & 3rd constructor? 
        this(xx, yy, 0.0); // this does?
      }
    
      PVector(float xx, float yy, float zz) { // receives a call from the 2nd constructor, and the 2 parameters. Then assigns it to x, y. Since it received no 3rd parameter for float zz, z is assigned with 0.0f
        x = xx;
        y = yy;
        z = zz;
      }
    }
    
    • First constructor calls the second. Since the first constructor is devoid of parameters, it does nothing (i.e passes nothing to the second constructor).

    • "this(xx,yy,0.0)", the values xx and yy is from the parameters in the second constructor, as it's within that method.

    • Second constructor, calls the third, passing the values in float xx & float yy, to float xx and float yy in the third constructor. Since it has no 3rd parameter, float zz in the third constructor will be equal to 0.0f by default.

    • I didn't understand the purpose of the following, in the second parameter:

    this(xx, yy, 0.0);

    I also didn't see the point of having the second constructor, as the third constructor does the job.

  • edited May 2014

    Neither understood this code:

      Ball(int r, color c)
      {
        // This actually calls the other constructor, providing the missing values
        this(random(r, width - r), random(r, height - r), random(-7, 7), random(-7, 7), r, c);
      }
    
      Ball(float x, float y, float sx, float sy, int r, color c)
      {
        posX = x;
        posY = y;
        speedX = sx;
        speedY = sy;
        radius = r;
        ballColor = c;
      }
    
  • edited May 2014 Answer ✓
    • Main objective of a constructor is to accept parameters and initialize the object fields w/ them.
    • There are times we want to have default values for some fields rather than asking the caller to provide everything.
    • That's when overloaded constructors w/ diff. # of parameters &/or types comes into play.
    • For each overloaded constructor we can either initialize each field or delegate that task to another constructor using this().

    PVector(float xx, float yy) {
      // either delegate another constructor to initialize the fields:
      this(xx, yy, 0.0);
    
      // or initialize them right here:
      x = xx;
      y = yy;
    }
    
  • edited May 2014

    "this" calls an overloaded constructor with "float xx, float yy, float zz" as it's argument? It basically calls the constructor with the same number of parameter and type, as it has?

    And you can only call another constructor using "this" ?

  • Answer ✓

    When a class has multiple overloaded constructors, we choose which 1 to call in order to instantiate an object outta it.
    The chosen constructor can call another 1 by its own discretion.

  • edited May 2014 Answer ✓

    In regarding what's actually inside an object, I've made some cropped shots from BlueJ.
    BlueJ and its derivative GreenFoot project are the best way to visually understand objects!

    • Objects are made outta non-static fields off its class.
    • Each object has its own dynamically allocated memory.
    • Therefore, objects can't store other objects.
    • In case of array objects, its 1st memory address isn't necessarily its 1st "slot" field!

    ArrayPrimitive

    • In case the array stores reference "slots", we can notice a long arrow in the picture, indicating it's an address of an object.
    • We gotta inspect further in order to reach the contents of the object.
    • If the "slot" was not initialized, its value is the default null!

    ArrayObject

  • edited May 2014

    Thanks.

    So as I'm currently working on a class:

    final int BALL_NB = 5;
    Ball[] balls = new Ball[BALL_NB];
    
    • This creates an array of references to Ball Objects (5 'slots', index from 0 -> 4, as that's the current value of the variable BALL_NB).

    • So balls[0] to ball[4] are all null by default? They don't have the reference/point to, any objects?

    • So by doing balls[0] = new Ball(), we are instantiating a Ball object, and in balls[0], will contain the address of the 1st physical memory location of the created object?

    • If we don't instantiate the object, then balls[0] = null?

      int BALL_NB = 5;
          int balls = new int[BALL_NB];
      
    • The 'slots' in the array above, will all have an initial value of 0?

  • edited May 2014

    Finally you've got it all right! :D The array's slots are initialized according to its chosen data-type!
    Primitive type int is 0. While reference type Ball is null.

    Just to add to it, variable balls, being a reference type, starts out w/ null.
    Until you instantiate an array and assign it to balls.
    Only then you can start accessing the array's slots through balls. =:)

    P.S.: Just a tiny correction in your example:
    You've forgotten the [] after int -> int balls = new int[BALL_NB];

  • edited May 2014

    Thanks.

    Just to add to it, variable balls, being a reference type, starts out w/ null.

    So that means:

    Ball[] balls // null ?

    Until:

    balls = new Ball[BALL_NB] //instantiates an array and assigns it (the reference) to variable balls ?

    • Chrisir, here is my code from the task you set:

      final int numOfLines = 8;
      
      Linemine [] linemines = new Linemine[numOfLines];
      
      
      void setup() {
      
        size (200, 200);
      
      for (int i = 0; i < 8; i++){
      
      
        linemines[i] = new Linemine();
      }
      
      }
      
      void draw() { 
      
        background(255);
      
        for (int i = 0 ; i < 7; i++) {
      
      
          linemines[i].display(color (random(255), random(255), random(255)), 50, 25*i, 100, random(5));
        }
      }
      
      class Linemine{
      
        color c;
        float posX;
        float posY;
        float lineLength;
        float lineWeight;
      
        Linemine(){
      
         c = color (random(255), random(255), random(255));
         posX = random(width);
         posY = random(height);
         lineLength = random(width);
         lineWeight = random(3);
      
      }
      
      Linemine(color c, float posX, float posY, float lineLength, float lineWeight){
      
        this.c = c;
        this.posX = posX;
        this.posY = posY;
        this.lineLength = lineLength;
        this.lineWeight = lineWeight;
      
      }
      
      
        void display(color c, float posX, float posY, float lineLength, float lineWeight){
      
          stroke(c);
          strokeWeight(lineWeight);
          line(posX,posY, lineLength,posY);
      
      
      }
      }
      
  • edited May 2014

    Why don't you check that out for yourself? It's as simple as using println():

    // forum.processing.org/two/discussion/4736/processing-beginner
    
    class Ball {
    }
    
    static final int NUM = 3;
    Ball[] balls;
    
    void setup() {
      println(balls);  // Prints out "null".
      println();
    
      balls = new Ball[NUM];
      println(balls);  // Prints out the array's slots.
      println();       // Which are themselves "null" for now!
    
      for ( int i = 0; i != NUM; balls[i++] = new Ball() );
    
      println(balls);  // Prints out the array's slots again.
      exit();          // Now filled up w/ Ball object references!
    }
    
  • edited May 2014

    First print, didn't print out "null". Instead said NullPointerException.

    And last print, didn't print.

  • edited May 2014

    First print, didn't print out "null". Instead said NullPointerException.

    You doesn't seem to be using Processing's own IDE? :-/
    Or something got so frigging diff. w/ v2.1.x series! X(

  • edited May 2014

    Just to make sure, place System.out. before println(),
    in order to use the original Java's version:
    System.out.println(arrays);

  • edited May 2014

    I am using Processing's own IDE (version 2.1.1). Worked with "System.out.println".

  • edited May 2014

    I can't believe they made println() throw an NPE for a null argument! [-(
    While even the original System.out.println() doesn't! 8-}
    Alas! Seems like we gotta type in a lengthy println() from now on! 8-|

  • edited May 2014

    OOP

    I think your code can be improved.

    It is not the real OOP thinking.

    Obviously, display shouldn't take parameters. Instead it should use the values stored in the class. That's what they are for. You don't use the values stored in the class at the moment.

    line 25 should be

    linemines[i].display();

    To achieve this, you need to put the values into the class (its properties).

    To do so, I recommend that you use the longer constructor in setup:

    ( Linemine(color c, float posX, float posY, float lineLength, float lineWeight) )

    and not the short one. So you define each line once and use it often.

    Now the lines color flickers and they have the same length. Both is wrong. ;-)

    numOfLines

    in line 10 and 22 you want to use numOfLines. Thus when you want to change it, you need to do so only in one place and not in three.

    formatting

    Also use ctrl-T in the processing IDE to format the code (indent).

  • final int numOfLines = 8;
    
    Linemine [] linemines = new Linemine[numOfLines];
    
    
    void setup() {
    
      size (200, 200);
    
      for (int i = 0; i < numOfLines; i++) {
    
    
        linemines[i] = new Linemine();
      }
    }
    
    void draw() { 
    
      background(255);
    
      for (int i = 0 ; i < numOfLines; i++) {
    
        linemines[i].display();
      }
    }
    
    class Linemine {
    
      color c;
      float posX;
      float posY;
      float lineLength;
      float lineWeight;
    
      Linemine() {
    
        c = color (random(255), random(255), random(255));
        posX = random(width);
        posY = random(height);
        lineLength = random(width);
        lineWeight = random(3);
      }
    
      Linemine(color c, float posX, float posY, float lineLength, float lineWeight) {
    
        this.c = c;
        this.posX = posX;
        this.posY = posY;
        this.lineLength = lineLength;
        this.lineWeight = lineWeight;
      }
    
    
    
    
      void display() {
    
        stroke(c);
        strokeWeight(lineWeight);
        line(posX, posY, lineLength, posY);
      }
    }
    
  • edited May 2014

    that's much better.

    now I want the length of the lines be like this

    *
    **
    ***
    ****
    *****
    

    remember, that's where we started

    please use the longer constructor (as I said) in setup()

  • edited May 2014

    You want me to use?

        void setup() {
    
          size (200, 200);
    
          for (int i = 0; i < numOfLines; i++) {
    
    
            linemines[i] = new Linemine (color c, float posX, float posY, float lineLength, float lineWeight);
          }
        }
    
  • yes---

  • but it looks different of course since you want to pass values into the class

  • final int numOfLines = 8;
    
    Linemine [] linemines = new Linemine[numOfLines];
    
    
    void setup() {
    
      size (200, 200);
    
      for (int i = 0; i < numOfLines; i++) {
    
    
        linemines[i] = new Linemine(color (random(255), random(255), random(255)), random(width), random(height), random(width), random(5));
      }
    }
    
    void draw() { 
    
      background(255);
    
      for (int i = 0 ; i < numOfLines; i++) {
    
        linemines[i].display();
      }
    }
    
    class Linemine {
    
      color c;
      float posX;
      float posY;
      float lineLength;
      float lineWeight;
    
      Linemine() {
    
        c = color (random(255), random(255), random(255));
        posX = random(width);
        posY = random(height);
        lineLength = random(width);
        lineWeight = random(3);
      }
    
      Linemine(color c, float posX, float posY, float lineLength, float lineWeight) {
    
        this.c = c;
        this.posX = posX;
        this.posY = posY;
        this.lineLength = lineLength;
        this.lineWeight = lineWeight;
      }
    
    
    
    
      void display() {
    
        stroke(c);
        strokeWeight(lineWeight);
        line(posX, posY, lineLength, posY);
      }
    }
    
  • *
    **
    ***
    ****
    *****
    

    remember, that's where we started

  • I then want the lines to move left and right and bounce at the screen border

  • final int numOfLines = 8;
    
    Linemine [] linemines = new Linemine[numOfLines];
    
    
    void setup() {
    
      size (200, 200);
    
      for (int i = 0; i < numOfLines; i++) {
    
    
        linemines[i] = new Linemine(color (random(255), random(255), random(255)), 10, i*10, i*10, random(5));
      }
    }
    
    void draw() { 
    
      background(255);
    
      for (int i = 0 ; i < numOfLines; i++) {
    
        linemines[i].display();
      }
    }
    
    class Linemine {
    
      color c;
      float posX;
      float posY;
      float lineLength;
      float lineWeight;
    
      Linemine() {
    
        c = color (random(255), random(255), random(255));
        posX = random(width);
        posY = random(height);
        lineLength = random(width);
        lineWeight = random(3);
      }
    
      Linemine(color c, float posX, float posY, float lineLength, float lineWeight) {
    
        this.c = c;
        this.posX = posX;
        this.posY = posY;
        this.lineLength = lineLength;
        this.lineWeight = lineWeight;
      }
    
    
    
    
      void display() {
    
        stroke(c);
        strokeWeight(lineWeight);
        line(posX, posY, lineLength, posY);
      }
    }
    
  • this

    line(posX, posY, lineLength, posY);
    

    should be

    line(posX, posY, posX + lineLength, posY);
    
  • well done!

  • edited May 2014

    also you can place the lines a bit lower (using + 10 and longer using + 15)

    linemines[i] = new Linemine(color (random(255), random(255), random(255)), 
        10, i*10 + 10, 
        i*10 + 15, 
        random(5));
    
  • edited May 2014

    Obviously, display shouldn't take parameters. Instead it should use the values stored in the class. That's what they are for. You don't use the values stored in the class at the moment.

    I didn't understand fully, the reason why I should not put anything in:

    linemines[i].display();

    or

    void display()

    And only in:

    linemines[i] = new Linemine(color (random(255), random(255), random(255)), 10, i*10, i*10, random(5));
    
  • edited May 2014

    Objects contain fields w/ data, w/ methods which operate over them!
    For example, once an object is initialized w/ the color we want, that data is saved in 1 of its fields.
    We shouldn't need to keep telling it which color to use every time. The object already got that data store!

  • well explained, gotoloop ;-)

    xb, I really feel you're making progress!

  • edited May 2014

    I then want the lines to move left and right and bounce at the screen border

    In order to do that, we must access the posX field, in each object (linemines[0].posX?), and update it with a constant value (i.e speedx = 3), and then reverse the value of speedx when posX is less than 0 or greater than width?

  • edited May 2014

    You can expand the class to do more actions. Like move(), bounce(), etc.
    Here are 2 online examples w/ bouncing objects:

    http://studio.processingtogether.com/sp/pad/export/ro.989GaZC5t7EkE/latest
    http://studio.processingtogether.com/sp/pad/export/ro.9oyKfI9kOIa77/latest

  • that's the idea...

  • edited May 2014

    I'm not at that level yet.

    But will give it an attempt, and post my effort on here. Meanwhile, I was trying to do this exercise, as I'm practising with arrays:

    http://www.learningprocessing.com/exercises/chapter-9/exercise-9-8/

    But I didn't manage it, it was close, but not perfect, as you will see:

    final int numberOfBoxes = 6;
    
    Button [] boxes = new Button [numberOfBoxes];
    
    
    void setup() {
    
      size(800, 800);
    
      for (int i = 0; i < numberOfBoxes; i++) {
    
        boxes[i] = new Button(i*width/8 +10, width/2, width/10, width/10);
      }
    }
    
    void draw() {
    
      background(255);
    
      for (int i = 0; i < numberOfBoxes; i++) {
    
        boxes[i].display();
        boxes[i].mousePressed();
      }
    }
    
    
    class Button {
    
      float x;
      float y;
      float w;
      float h;
      boolean button;
    
    
      Button() {
    
        x = 50;
        y = 50;
        w = 100;
        h = 100;
        button = false;
      }
    
      Button(float x_, float y_, float w_, float h_) {
    
        x = x_;
        y = y_;
        w = w_;
        h = h_;
        button = false;
      }
    
    
      void display() {
    
    
        if (button) {
    
          fill(155);
        }
        else {
          fill(0);
        }
    
        rect(x, y, w, h);
      }
    
    
      void mousePressed() {
    
        if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h && mousePressed) {
    
          button = !button;
        }
      }
    }
    
  • edited May 2014

    ignore the links by gotoloop and follow your own idea.

    you're at that level now.

    we can proceed from there.

  • edited May 2014

    you can't know this, but the clicking is registered more stable when you use the function mousePressed() outside the class (it registers each mouse click only once which makes it more stable and calm). It gets called automatically when you press the mouse. Call the other function mousePressed inside the class from there.

    final int numberOfBoxes = 6;
    
    Button [] boxes = new Button [numberOfBoxes];
    
    
    void setup() {
      size(800, 800);
      for (int i = 0; i < numberOfBoxes; i++) {
        boxes[i] = new Button(i*width/8 +10, width/2, width/10, width/10);
      }
    }
    
    void draw() {
      background(255);
      for (int i = 0; i < numberOfBoxes; i++) {
        boxes[i].display();
      }
    }
    
    void mousePressed() { 
      for (int i = 0; i < numberOfBoxes; i++) {
        boxes[i].mousePressed();
      }
    }
    
    class Button {
    
      float x;
      float y;
      float w;
      float h;
      boolean button;
    
    
      Button() {
    
        x = 50;
        y = 50;
        w = 100;
        h = 100;
        button = false;
      }
    
      Button(float x_, float y_, float w_, float h_) {
    
        x = x_;
        y = y_;
        w = w_;
        h = h_;
        button = false;
      }
    
    
      void display() {
    
        if (button) {
          fill(155);
        }
        else {
          fill(0);
        }
        rect(x, y, w, h);
      }
    
      void mousePressed() {
        if (mouseX > x && mouseX < x+w && mouseY > y && mouseY < y+h && mousePressed) {
          button = !button;
        }
      }
    }
    //
    
  • to avoid confusion you can call mousePressed() within the class also mouseOver or mouseToggle or so. Then they have different names.

    why did you say "not perfect"?

  • edited May 2014

    why did you say "not perfect"?

    Because I wanted each click, to change the fill color. It took several clicks to change it.

    I was doing a revision quiz that we have:

    What is printed:

    Ball a = new Ball();
    a.pos = 2;
    Ball b = a;
    Ball c = b;
    b = new Ball();
    b.pos = 3;
    print(c.pos);
    

    Select one: a. 2 Incorrect b. 1 c. 3 d. throws an error

    The correct answer is: 3

    • 'a' is a reference variable of type "Ball", and in it, it contains the address to the instantiated object.

    • The field 'pos' in the new object, is set to '2'

    • 'b' is a reference variable, that contains the same address within a? To the instantiated object? Or does 'b' contain the memory address of 'a'? I got confused at this stage.

  • edited May 2014

    Is that actually some school quiz? ^#(^

    // forum.processing.org/two/discussion/4736/processing-beginner
    
    class Ball {
      int pos;
    }
    
    void setup() {
      Ball a = new Ball();
      a.pos = 2;
    
      Ball b = a;
      Ball c = b;
    
      b = new Ball();
      b.pos = 3;
    
      println(c.pos);  // prints out 2!
      exit();
    }
    
    • Until line #12, all 3 variables still share the same 1st instantiated object's reference.
    • @ line #14, a new Ball is instantiated. But only variable b gets its reference assigned.
    • Next line, field pos of the 2nd object is assigned 3. Obviously, that doesn't interfere w/ the state of other Ball objects.
    • B/c each Ball object got its own fields (instance variables)! They're separate copies in diff. blocks of memory!
    • Finally, since both a & c still refers to the 1st object, both a.pos & c.pos access the same instance variable!
Sign In or Register to comment.