// 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);
}
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.
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.
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.
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:
int[] a
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!
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.
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;
}
"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" ?
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.
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!
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!
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?
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];
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!
}
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-|
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:
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:
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!
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?
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;
}
}
}
//
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.
// 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!
Answers
Post entire code
What values do the vars have?
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.
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:
the reason why the 1st attempt didn't work (quote by quark)
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
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.
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!
Let's split the statement above:
int[] a
new int[3]
int[]
,which is an object type, it's either 4 bytes in 32-bit mode or 8 bytes in 64-bit mode!
Whew! 2nd part now: :D
new
instantiates an object. The[]
operator means it's an array type object.=
, which transfers the result from the expression at the right sideto the variable at the left side!
Okay, while working on the class, I struggled with the idea of overloaded constructors. Back to the earlier example:
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.
Neither understood this code:
"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" ?
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.
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!
null
!Thanks.
So as I'm currently working on a class:
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?
The 'slots' in the array above, will all have an initial value of 0?
Finally you've got it all right! :D The array's slots are initialized according to its chosen data-type!
Primitive type
int
is0
. While reference type Ball isnull
.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
[]
afterint
->int balls = new int[BALL_NB];
Thanks.
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:
Why don't you check that out for yourself? It's as simple as using println():
First print, didn't print out "null". Instead said NullPointerException.
And last print, didn't print.
You doesn't seem to be using Processing's own IDE? :-/
Or something got so frigging diff. w/ v2.1.x series! X(
Just to make sure, place
System.out.
before println(),in order to use the original Java's version:
System.out.println(arrays);
I am using Processing's own IDE (version 2.1.1). Worked with "System.out.println".
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-|
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).
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()
You want me to use?
yes---
but it looks different of course since you want to pass values into the class
remember, that's where we started
I then want the lines to move left and right and bounce at the screen border
this
should be
well done!
also you can place the lines a bit lower (using + 10 and longer using + 15)
I didn't understand fully, the reason why I should not put anything in:
linemines[i].display();
or
void display()
And only in:
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!
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?
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...
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:
ignore the links by gotoloop and follow your own idea.
you're at that level now.
we can proceed from there.
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.
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"?
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:
'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.
Is that actually some school quiz? ^#(^
3
. Obviously, that doesn't interfere w/ the state of other Ball objects.a.pos
&c.pos
access the same instance variable!