We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello, I made raining balls but I would like to make them stop in the end of the window, well I mean I want pile them up While it keeps going. I thought that I need an If statement When they reach one another?? But I really don't know How I am going to set the statement. Here is my code:
Ball [] balls=new Ball[100];
float a;
void setup(){
size(600,600);
for(int i=0;i<balls.length;i++){
balls[i]=new Ball();
}
}
void draw(){
background(230,230,250);
for(int i=0;i<balls.length;i++){
balls[i].display();
balls[i].fall();
}
}
class Ball{
float x=random(width);
float y=random(-200,100);
float yspeed=random(3,4);
float a=random(40);
void fall(){
y=y+yspeed;
if (y>height){
y=random(-200,100);
}
}
void display(){
fill(random(255),random(255),random(255),random(255));
ellipse(x,y,a,a);
}
}
Answers
Good start. You have 100 balls. They all fall(), and they all get display()ed.
When a ball falls down a little, it does so because the fall() method for the Ball class is being called.
Look at the fall() method. Do you understand what it is doing? How does it change the Ball's position?
Can you change this method so that it stops falling when it gets to the bottom of the screen? Try attempting this yourself, and post your attempt at it for more help.
Well, fall function makes them falling and create new ones but it starts When y exceed the height. That's the weird part. ( I couldn't find another way to keep them come down) For accumulation part, I thought that If y == height (at the end of the window) they should stop. It sounds make sense for me but it didn't work so Where did I make mistake? By the way thanks for wordily guidance.
so with this change, they just jump back and stop falling constantly:
Good. Another approach is to only make them fall if they aren't yet at the bottom:
The next thing to do is to stop using an Array of Balls and start using an ArrayList. An ArrayList is different from an Array in that it does not have a fixed length - and you an easily add and remove items from an ArrayList, something that is not easy to do with an Array. Your best bet to learn about ArrayLists is to find the Example sketch that comes with processing:
File > Examples... > Topics > Advanced Data > ArrayListClass
This example is also adding ball objects!
http://studio.SketchPad.cc/sp/pad/view/ro.98wJk9FLLhbUE/latest
http://studio.SketchPad.cc/sp/pad/view/ro.9l84$2z--gWui/latest
Now, you were right, this is What I was looking for. Thanks for leading me,all balls flows like a river, but still they pile them up on the ground. I mean they all are at the ground level.
Thanks, GoToLoop but the real problem is accumulation layer by layer
Okay. So tell us, how will a Ball know when it should stop falling?
Provide details. What conditions must be true?
Well I am not good at either English or Processing but let me try. I think when a ball is on the top another one, I mean it should be related with radius, but all balls have random radiuses. So here I guess I need an extra variable??
So there are two situations that would cause a Ball to stop falling:
1) The Ball has reached the bottom of the screen. This means that the Ball's y position is greater than the height of the sketch.
2) The Ball is now touching another Ball that is already frozen. Two Balls are touching if the distance between them is less than the sum of their radiuses.
We do not need to check these conditions for Balls that are already Frozen - they will simply remain frozen. Performing the first check is simple - we simply compare the position of each Ball against the height of the sketch, as we have already done.
Performing the second check is a little bit more difficult. We need to check each Ball against every other Ball. So we will need to loop over all the Balls to check it for just one Ball! You should try using a for loop to do this yourself - post your code of your attempt for more help.
Improving over TfGuy44's answer, you only need to check each non-Frozen ball against each frozen one.
Hi again, to determine the distance value I set a boolean variable ( Actually I found it in some of examples and videos and add mousePressed condition by the way) and then create an overlapping function to loop over all the balls, but I couldn't figure out the second for and after if condition Which specify the accumulation so I am not sure that I am on the right direction?? Here is the code again;
Attempt it. Post the code of your ATTEMPT.
This may not be the most correct/conventional method, but I'd recommend using two ArrayLists - one for Not Frozen Balls and one for Frozen Balls. Then, you only draw the frozen balls, and leave them alone. But the not frozen balls have to be checked for -
In either condition, they should be removed from Not Frozen Balls and added to Frozen Balls.
Hi again, I've been trying to sort this out for hours, since yesterday. I'm afraid I just don't know programming technique well enough so that I quit for this project. Maybe later I can figure it out. Many thanks.
You're nearly there. Why do you want to quit?
Well, I pushed my brain till here step by step but it didn't work. I got the idea what you said even but I can't make it in coding language so this shows that maybe I should work more on coding techniques. Even it doesn't work with the background statement this means something goes wrong in for loop. (I am more sure the boolean part. I mean it seems right)
Well....
I'll just give some advice - if you don't get the answer for something, don't quit just yet. Learn new techniques and try again. Try everything you can. Once you start quitting, it'll become a habit soon.
Best of Luck, and hope you try again after learning new techniques.
You have an ArrayList balls in the class! Don't.
Have a 2nd ArrayList frozen on sketch level, but not in the class.
I can only emphasize what lord of the galaxy said. And: here are people to help you through
Many many thanks guys for help and support. If I get through this, I am going to run around my home with 'eye of the tiger'. Anyway, first I want to make something clear : I have an Ball class ( In another topic Lord_of_the_Galaxy advised me to not to named a class with object but I keep the Ball class) so that İf I create another ArrayList it would be full of with Ball object too but called ballsf (for frozen balls) right? like:
I am asking this question because I don't get the ArrayList fully. If this new ArrayList consist in another way like:
ArrayList<Ballf>ballsf
(Which means frozen balls need Ballsf class like Balls class) I should make functions ''public'' in Ball class (thanks too some of Java tutorial) because ballsf should get through the process fall() and display() functions in Ball class, but I follow the first step it works but as a blank page and here is the new code with lots of confusion:
Ctrl + t. This fixes your indenting, and formats your code.
Immediately worrying: Your Ball class creates a new ArrayList when its constructor is called. This can not be right. The Ball class should represent one Ball - it should not be able to wipe away the ArrayList of all Balls! Removing offending lines.
Immediately worrying: checkOverlapping() calls background(0) instead of doing anything useful. Removing entire function and anything that called it.
Immediately confusing: You have two ArrayLists of Balls. If this was some sort of an attempt to have two classes, one for frozen Balls and one for still-falling ones, that's great, but in the current implementation, having two ArrayLists makes no sense. Removing ballsf and all references to it.
Confusing: Why would you need a global variable for radius? Who's radius? A Ball's radius? No, the Ball class should have that. A stray radius variable could be troublesome. Removing it too.
Result:
Thanks TfGuy44. You scares me with your sharp short reply but I am sure that I will learn a lot from you.
At this point TRY RUNNING THE SKETCH.
WHOA.
WHAT. IS. GOING. ON?
Problem is obvious with better function names. When draw() runs, it does a for loop over all the Balls. So the body of this loop is called, say, 200 times. That means that the function checkballs() is called 200 times EACH FRAME. But checkballs() isn't doing any checking. It's simulating all the Balls! First it makes them ALL fall a bit, and it draws them ALL. Thus we are looping over all the Balls TWICE - not good - which gives us the hyperspace falling effect.
Remove the offending loop in draw() and rename the function.
Result:
Time for some cleaning up. The initialization of a Ball's variables can go in the constructor. The simulate_and_draw_all_balls() function can be merged with draw(). Various name changes. Logical clean-up in overlaps().
At this point you want to add additional behavior to the Balls. So you know, immediately, that you need to make changes in simulate().
What changes will need to be made? Well, you want to have this idea that a Ball can become FROZEN. A frozen Ball no longer falls.
How will a Ball know that it is frozen? YOU NEED A VARIABLE TO REMEMBER IT.
Add a frozen variable.
How will a frozen Ball's behavior differ from a non-frozen Balls? They will obviously be different. Let's split simulate() into two parts - one part that does the behavior for falling balls and one part that does behavior for frozen Balls. Let's also pull out the check that causes Balls to freeze when they hit the bottom of the sketch into its own check that happens first.
All that's left is to add the logic that checks if a Ball is overlapping a frozen Ball.
You could write this into the ball class, but it's a pain.
Instead, it's much easier to do it with a few loops at the end of draw(), after the Balls have all updated. By doing two loops, we can compare the ith Ball with the jth ball (for every pair of Balls).
Notice the conditions that are being checked.
i!=j
means that they are two different Balls.balls.get(j).frozen
means that the second Ball is frozen.balls.get(i).overlaps( balls.get(j) )
means that the first Ball overlaps the second.The result is that the first ball we are comparing becomes frozen.
Also notice that there are some changes to overlaps(). Specifically, a bogus check requiring that the distance be exactly 40 has been removed, and the distance is now doubled, because the radius variables are actually storing diameters, not radiuses.
You may also have noticed that Balls now start in the range (-200,-100) for their y position, so new balls do not pop into existence at the top of the screen, but do so above the screen where they can not be seen.
There are three final things I would add.
First, clicking the mouse should reset the entire sketch. This seemed like something you had tried to add before.
Second, I would stop new Balls from being created when a Ball has frozen above -100 y-position.
Third, if all the Balls are frozen, I would stop re-rendering the scene.
@TfGuy44 So many replies in so little time... Woah there man. Give us some time to take it all in.
Now let me answer one of your questions-
Why two ArrayLists? One for frozen balls and other for falling balls.
This way, no need for checking balls against each other. Which equals a small performance boost even over your already optimised sketch.
This also means no need for a frozen variable.
Thanks for all your efforts, now I have to figure out all of it and derive lessons from my mistakes. I am going to be around this forum with lots of question, stupidity and confusion (I hope this makes sense). Thanks again.
As long as you ask questions instead of opening contextless threads, we will answer you or advice you.