We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › How do I allow for *.method()
Page Index Toggle Pages: 1
How do I allow for *.method()? (Read 433 times)
How do I allow for *.method()?
Oct 25th, 2009, 1:28pm
 
Hi, I'm new to Processing & Java in general.
I've built a planet and moon thing as my first attempt. I've been trying to keep it OO as much as possible, and here's my question:
In the display method of the Moon class, I want to read in the planet variable from when I instantiated the moon, and then use it as such:
Code:

...
String var;

Moon(var_){
var = var_;
}
void display(){
xpos = orbitRadius * cos(theta) + var.xpos;
}
...


However, whenever I try "variable of a class instance"."variable inside class instance" it throws the following error: var.xpos cannot be resolved or is not a field.

Here's my full code:
Code:
Planet planet1;
Moon moon1;
Moon moon2;
PFont fontA;
float easing = .05;

void setup(){
 size(400,400);
 smooth();
 ellipseMode(RADIUS);
 planet1 = new Planet(width/2,height/2,25,color(255));
 moon1 = new Moon(0.0f, .05f, 8, 100, color(128),planet1);
 moon2 = new Moon(20.0f, .02f, 9, 150, color(0), planet1);
 fontA = loadFont("Serif-48.vlw");
 textAlign (CENTER);

}

void draw(){
 background(0,60,60);
 planet1.display();
 planet1.move();
 moon1.display();
 moon1.move();
 moon2.display();
 moon2.move();

}

class Planet {
 float xpos;
 float ypos;
 float targetX;
 float targetY;
 int rad;
 color c;
 
 Planet(float xpos_, float ypos_, int rad_, color c_) {
   xpos = xpos_;
   ypos = ypos_;
   rad  = rad_;
   c    = c_;
 }
 
 void display(){
   noStroke();
 fill(c);
 ellipse(xpos,ypos,rad,rad);
 textFont (fontA, rad);
 text ("x "+ int(xpos),xpos,ypos+(rad*2));
 text ("y "+ int(ypos),xpos,ypos+(rad*2)+rad);
 }
 
 void move(){
     
 targetX = mouseX;
 float dx = targetX - xpos;
 if(abs(dx) > 1) {
  xpos += dx * easing;
   }
 
 targetY = mouseY;
 float dy = targetY - ypos;
 if(abs(dy) > 1) {
   ypos += dy * easing;
 }
 }
 
}

class Moon {
 float xpos;
 float ypos;
 float theta;
 float vel;
 int rad;
 int orbitRad;
 color c;
 Object planet;
 
 Moon(float theta_, float vel_, int rad_, int orbitRad_, color c_, Object planet_) {
   theta = theta_;
   vel = vel_;
   rad  = rad_;
   orbitRad = orbitRad_;
   c    = c_;    
   planet = planet_;
 }
 
 void display(){
   xpos = orbitRad * cos(theta) + planet1.xpos;
   ypos = orbitRad * sin(theta) + planet1.ypos;
   noStroke();
   fill(c);
   ellipse(xpos,ypos,rad,rad);
  textFont (fontA, rad);
  text ("x "+ int(xpos),xpos,ypos+(rad*2));
  text ("y "+ int(ypos),xpos,ypos+(rad*2)+rad);
 }
 
 void move(){
   theta += vel;
 }
}


How can I fix this?


Thanks in advance,

Evan.
Re: How do I allow for *.method()?
Reply #1 - Oct 25th, 2009, 10:57pm
 
The obvious error is that you declare Object planet;
You declare a generic object, and even if you can assign any object to it (as you do in the constructor), Java will only see (at compilation time) the generic object without particular method (other than those common to all objects, like toString()).

Now, somehow you got a good idea to make a generic object (Planet) and specialized one. But, even if using composition instead of inheritance is often recommended, in this case I think you should make your moon to derive from the Planet.
It should be something like (untested, that's just a rough approximation):
Code:
class Moon extends Planet {
 float theta;
 float vel;
 int orbitRad;
 
 Moon(float theta_, float vel_, int rad_, int orbitRad_, color c_) {
   super(width/2,height/2, rad_, c_);
   theta = theta_;
   vel = vel_;
   orbitRad = orbitRad_;
 }
 
 void display(){
   // These two lines belong more to move()
   xpos += orbitRad * cos(theta);
   ypos += orbitRad * sin(theta);
   super.display();
 }
 
 void move(){
   theta += vel;
 }
}

Note the extends which tell to reuse Planet's variables (fields) and functions (methods).
In one case (display()) I reuse Planet's method, in another case (move) I use replace it.

Looking more, perhaps they were different objects for you...
So instead, you should make a generic object common to both Planet and Moon: say, CelestialObject having most of Planet's content, except perhaps the move() method. You can even make the CelestialObject an abstract class, not defining move() but with a default display() method and a generic constructor.
I leave code above as it illustrates some ideas, but here is something more like what you wanted (still untested!):
Code:
abstract class CelestialObject {
float xpos;
float ypos;
int rad;
color c;

CelestialObject(float xpos_, float ypos_, int rad_, color c_) {
xpos = xpos_;
ypos = ypos_;
rad = rad_;
c = c_;
}

void display(){
noStroke();
fill(c);
ellipse(xpos,ypos,rad,rad);
textFont (fontA, rad);
text ("x "+ int(xpos),xpos,ypos+(rad*2));
text ("y "+ int(ypos),xpos,ypos+(rad*2)+rad);
}

abstract void move();
}

class Planet extends CelestialObject {
float targetX;
float targetY;

Planet(float xpos_, float ypos_, int rad_, color c_) {
super(xpos_, ypos_, rad_, c_);
}

void move(){
targetX = mouseX;
float dx = targetX - xpos;
if(abs(dx) > 1) {
xpos += dx * easing;
}

targetY = mouseY;
float dy = targetY - ypos;
if(abs(dy) > 1) {
ypos += dy * easing;
}
}
}

class Moon extends CelestialObject {
float theta;
float vel;
int orbitRad;
Planet planet; // This moon orbits around this planet

Moon(float theta_, float vel_, int rad_, int orbitRad_, color c_) {
super(planet.xpos, planet.ypos, rad_, c_);
theta = theta_;
vel = vel_;
orbitRad = orbitRad_;
}

void move(){
xpos = orbitRad * cos(theta) + planet.xpos;
ypos = orbitRad * sin(theta) + planet.ypos;
theta += vel;
}
}
Page Index Toggle Pages: 1