Loading...
Logo
Processing Forum
Hi,
I've been trying to solve this for a few days and can't seem to so I figured I'd come and ask to see if anyone knew where I was going wrong and what I should be doing.

Basically I'm creating an array of Objects, which are balls that travel back and forth on the screen. I've added a random number feature in the code and when the random number generated equals 3 then I want to update the array of objects, expanding it by one and adding a new ball into the Array and then onto the screen.

My current main script looks like this:

Copy code

  1. int numBalls = 8; // variable to hold the initial size of array
    Ball[] balls = new Ball[numBalls]; // array to hold ball objects
    Ball addOneBall;

    void setup()
    {
      // set up screen
      size(500, 500);
      smooth();
      noStroke();

      // for loop to fill array with  balls
      for (int i = 0; i < balls.length; i++)
      {
        balls[i] = new Ball();
      }
    }

    void draw()
    {
      fill(255, 200); //white see-through background
      rect(0, 0, width, height); // draw rect instead of background so we can use alpha to give comet tail effect on balls

      int addOne = int(random(100)); //generate a random number to use in a conditional in a moment
      println("random number is " + addOne); //print random number to terminal to monitor

      //conditional statement if random number is three...
      if (addOne == 3)
      {
        int currentLength = balls.length; // Create and int of the value of the current length of the array
        println("Current length of balls array is " + currentLength); ///print value to terminal
       
        balls = (Ball[]) expand(currentLength+1); //extend the current array by one
        addOneBall = new Ball(); // Create new Ball
        balls = splice(balls, addOneBall, currentLength); //splice addOneBall and balls array, placing addOneBall in the last position of the array
      }

      //
      for (int i = 0; i < balls.length; i++)
      {
        balls[i].move();
        balls[i].updateMe();
        balls[i].display();
      }
    }


my Class for the Ball looks like this:

Copy code
  1. class Ball
    {
      float x, y;
      float diam;
      float radius;
      float speed;
      int dir =1;
      int decision = int(random(-1, 1));
      color shade;

      int addABall = 1;

        Ball()
      {
        x = random(width);
        y = random(height);
        diam = (random(10)+10);
        radius = diam/2;
        speed = random(5);
      }


      void move()
      {
        x+=(speed * dir);
        if ((x > width) || (x< 0))
        {
          dir *= -1;
        }
      }

      void updateMe()
      {
        boolean touching = false;
        for (int i = 0; i< balls.length; i++)
        {
          Ball otherBall = balls[i];
          if (otherBall != this)
          {
            float dis = dist(x, y, otherBall.x, otherBall.y);
            if ((dis - radius - otherBall.radius) < 0)
            {
              touching = true;
              break;
            }
          }
        }
        if (touching)
        {
          shade = color(200);
          display();
        }
        else
        {
          shade = color(0);
          display();
        }
      }

      void display()
      {

        fill(shade);
        ellipse(x, y, diam, diam);
      }
    }   


When I initially tried to solve this problem I figured I'd have to reiterate the for loop in setup every time I wanted to lengthen the array. Then I realised that 1. this was a bad idea because its inefficient & I'd loose the location of the balls on screen and 2. a more sensible thing to do would be to simply extend the size of the Array by one and then stick a new ball object in the new empty slot. I try to do this in the main code with the following code inside the if statement in void loop:

Copy code
  1. int currentLength = balls.length; // Create an int of the value of the current length of the array
        println("Current length of balls array is " + currentLength); ///print value to terminal
       
        balls = (Ball[]) expand(currentLength+1); //extend the current array by one
        addOneBall = new Ball(); // Create new Ball
        balls = splice(balls, addOneBall, currentLength); //splice addOneBall and balls array, placing addOneBall in the last position of the array

but when I try to do this I get an error telling me I can't convert from Object to addOneBall.Ball[]; I don't fully understand the error message. I've took the syntax of the code from the example given in the processing reference for the expand() method which is available here: http://www.processing.org/reference/splice_.html
and the expand() method which is available here: file:///Applications/Processing.app/Contents/Resources/Java/modes/java/reference/expand_.html

Can someone tell me how to make my code work in the way I want it and where I'm going wrong in terms of how I'm approaching this problem?

Thanks for reading

Bunzy
 

Replies(5)

Indirect, yet relevant answer: take a look at the Why use ArrayList instead of array with append()? article, it might simplify your life...



sticking to arrays first:

when you look at
http://www.processing.org/reference/append_.html

you'll see :

When using an array of objects, the data returned from the function must be cast to the object array's data type. For example: SomeClass[] items = (SomeClass[]) append(originalArray, element)

So e.g.
Copy code
  1.   logEinzelnesSpiel = ( byte [] ) append ( logEinzelnesSpiel, LokalesSpielfeld );


So for your case without using expand or splice:

Copy code
  1.     addOneBall = new Ball(); // Create new Ball
  2.     balls = (Ball[]) append (balls, addOneBall); // append it

Thank you both for your responses,

PhilLo, I will read the article you pointed out. It looks very useful.

Chrisir, Thanks for explaining how to do this. I had looked at the append() option but the example given with the explanation in the documentation seemed to suggest that I'd have to create a second object that would be an amalgamation of the original and the appended. I guess I got confused when looking at it with Strings being immutable and the example using an array of strings. Also, the example could be helped with the kind of example you've given me here, which is clearer.

I don't fully understand the notion of casting. could you explain a bit?

In terms of syntax is this a correct understanding of what you just showed me:

Copy code

  1. Array  to be modified = (the type of object the array is) append(the array, what I want added to it);
" I don't fully understand the notion of casting. could you explain a bit?"
Casting allows to change or to specify a type.
When you do int x = (int) someFloat; the casting changes the type of the value, from float to int, and alter the value if it has decimal digits (by removing them).
When you do String s = (String) genericObject; you specify the type from the very generic Object type (the root type of all classes) to the specific type String. This can work only of genericObject is really a String: all Strings, arrays, ArrayList and other classes are Object (they extend it), but not all Object are String or ArrayList, etc.
If you cast to a type the object isn't, you get a ClassCastException.

append() is able to take an array of any type of Object, so its parameter is Object[]: any array of object, whatever its particular type, is accepted. But then its return type is necessarily Ojbect[] too. So you have to cast back the result to its original type for the assignment to work.

Hi PhilLo,

Thanks for explaining, that's a very clear definition. That make's what's happening much clearer and more manageable for me. Cheers!!