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 › A Little Help With OOP
Page Index Toggle Pages: 1
A Little Help With OOP (Read 1065 times)
A Little Help With OOP
Jan 23rd, 2010, 11:47am
 
I'm new to object orientated programming and there is an exercise where I need to implement OOP. I'm a little bit stuck. The premise of my code is onmousepress the mouse coordinates will generate a piece of food. Where by a creature will then move towards the food and eats it. I'm trying to write the update portion of the creature class to change it's x and y and move towards the food object sequentially. However, the variables I'm calling into the update to change the coordinate doesn't seem to be the write one. A little help is greatly appreciated.

Here's my code:
Code:

Creature creature1;
int numFood = 20;
Food[] food;
int counter;

boolean[] isAlive = new boolean [numFood]; //state of ellipses, true in the beginning

void setup() {
 size (600,600);
 creature1 = new Creature (-10,-10,15,15);                //starting position x & y, initial size
 food = new Food[numFood];
 for (int i=0; i < numFood; i++)  {
   float pelX = -1000;
   float pelY = -1000;
   food[i] = new Food (10,10, pelX, pelY);          //initial size, position of food x & y

   isAlive[i] = true;
 }
}

void draw ()  {
 background (255);
 creature1.display();
 for (int i=0; i < numFood; i++)  {
   food[i].display();
 }
}

class Creature {
 float x;
 float y;
 float cWidth;
 float cHeight;

 Creature (float xp, float yp, float cw, float ch)
 {
   x = xp;
   y = yp;
   cWidth = cw;
   cHeight = ch;
 }

 void update ()
 {
   for (int i=0; i < numFood; i++)  {
     x = x+(pelX[i]-x)/35 ; // which variable do I call? DM 012010
     y = y+(pelY[i]-y)/35;  //
   }  
 }

 void display() {
   stroke(0);
   fill(200,50,50);
   rectMode(CENTER);                //comment out, corner can represent a head
   rect(x,y,cWidth,cHeight);
 }
}

class Food{
 float sizeX;
 float sizeY;
 float posX;
 float posY;

 Food (float sx, float sy, float px, float py)
 {
   sizeX = sx;
   sizeY = sy;
   posX = px;
   posY = py;
 }

 void update (int tempMouseX, int tempMouseY)
 {
   posX = tempMouseX;
   posY = tempMouseY;
 }

 void display ()
 {
   fill (50,200,50);
   ellipse (posX, posY, sizeX, sizeY);  
 }
}


void mousePressed(){
 food[counter].update(mouseX, mouseY);
 counter++;
}


Re: A Little Help With OOP
Reply #1 - Jan 23rd, 2010, 1:11pm
 
You get an error with the code you posted because you declare 'pelX' and 'pelY' in setup.  To avoid the error you'd declare them outside of setup and populate them inside (without including the variable type).  Some code probably makes more sense:

Code:
// declare the variables - makes them 'global'
float pelX;
float pelY;

void setup() {
 size(600,600);
// populate the variables
// If you declare the type here then you create new variables (with the same name) only accessible within setup...
 pelX = -1000;
 pelY= -1000;
}


Having said that I've got no idea what these variables are for...   Shocked

If you want the creature to move towards food then why not just use the position of a piece of food?  So you might have a variable you use to set the current target in the food array and move towards that piece of food:

Code:
class Creature {
 // <snip />
 void update ()  {
     x += x+(food[currentTarget]-x)/35 ;
     y += y+(food[currentTarget]-y)/35;
 }


A couple of things to notice in the update() method:

1.  you need to use x += [amount]; and the same for y
2.  (food[currentTarget]-x) needs to be in brackets otherwise you're actually doing: food[currentTarget] - (x/35);

You'll also need to call the creature update method in draw Wink

The next step would be to handle what happens when the creature reaches some food.  For example you might want to add an 'eaten' property to food, hide it when it's eaten and increment 'currentTarget'...
Re: A Little Help With OOP
Reply #2 - Jan 23rd, 2010, 3:32pm
 
Thanks for the help blindfish. I got it to do what I want to do more or less. However, I want the creature class to move to each food item sequentially. I just realize by having multiple arrays, it just places the x and y coordinates of the creature in a mid-point. Is there a method of telling it to move sequentially? Here's my current code

Quote:
Creature creature1;
int numFood = 5;
Food[] food;
int counter;

boolean[] isAlive = new boolean [numFood]; //state of ellipses, true in the beginning
boolean col;

void setup() {
 size (600,600);
 creature1 = new Creature (10,10,15,15);                //starting position x & y, initial size
 food = new Food[numFood];
 for (int i=0; i < numFood; i++)  {
   float pelX = -1000;
   float pelY = -1000;
   food[i] = new Food (10,10, pelX, pelY);          //initial size, position of food x & y

   isAlive[i] = true;
 }
}

void draw ()  {
 background (255);
 for (int i=0; i < numFood; i++)  {
   food[i].display();
 }
 creature1.update();
 creature1.display();

 println (creature1.x);
 println (creature1.y);

}

class Creature {
 float x;
 float y;
 float cWidth;
 float cHeight;

 Creature (float xp, float yp, float cw, float ch)
 {
   x = xp;
   y = yp;
   cWidth = cw;
   cHeight = ch;
 }

 void update ()
 {
   for (int i=0; i < numFood; i++)  {
     x += ((food[i].posX)-x)/35;
     y += ((food[i].posY)-y)/35;
   }
 }

 void display() {
   stroke(0);
   fill(200,50,50);
   rectMode(CENTER);                //comment out, corner can represent a head
   rect(x,y,cWidth,cHeight);
 }
}

class Food{
 float sizeX;
 float sizeY;
 float posX;
 float posY;

 Food (float sx, float sy, float px, float py)
 {
   sizeX = sx;
   sizeY = sy;
   posX = px;
   posY = py;
 }

 void update (int tempMouseX, int tempMouseY)
 {
   posX = tempMouseX;
   posY = tempMouseY;
 }

 void display ()
 {
   fill (50,200,50);
   ellipse (posX, posY, sizeX, sizeY);  
 }
}

void mousePressed(){
 food[counter].update(mouseX, mouseY);
 counter++;
 if  (counter >= numFood) {
   counter = 0;
 }
}

Re: A Little Help With OOP
Reply #3 - Jan 24th, 2010, 2:08am
 
Roll Eyes
Read all of my previous post again and look properly at the suggested code for the creature update method - it does exactly what you want...
Re: A Little Help With OOP
Reply #4 - Jan 24th, 2010, 4:25am
 
As far as I can tell, your creature moves towards all of your food objects at once, and that will probably make some movement, but probably not how you want it to move. Maybe find a way to pick out one of the food objects, say the closest one for instance, and then move towards that object only. After eating that, it can move on to the next one ...
Re: A Little Help With OOP
Reply #5 - Jan 24th, 2010, 9:13am
 
blindfish wrote on Jan 24th, 2010, 2:08am:
Roll Eyes
Read all of my previous post again and look properly at the suggested code for the creature update method - it does exactly what you want...


So I should set up a currenttarget like variable before it goes into the update for creature
Re: A Little Help With OOP
Reply #6 - Jan 24th, 2010, 9:39am
 
Here's what I added so far. I'm not sure where to place the boolean function for when the food is eaten. Thanks for the help thus far.

Quote:
Creature creature1;
int numFood = 1;
Food[] food;
int counter;

//int ctX,ctY;

boolean[] isAlive = new boolean [numFood]; //state of ellipses, true in the beginning
boolean col;

void setup() {
 size (600,600);
 creature1 = new Creature (-10,-10,15,15);                //starting position x & y, initial size
 food = new Food[numFood];
 for (int i=0; i < numFood; i++)  {
   float pelX = 1000;
   float pelY = 1000;
   food[i] = new Food (10,10, pelX, pelY);          //initial size, position of food x & y

   isAlive[i] = true;
 }
}

void draw ()  {
 background (255);
 for (int i=0; i < numFood; i++)  {
   food[i].display();
 }
 creature1.update();
 creature1.display();

 println (creature1.x);
 println (creature1.y);

}

class Creature {
 float x;
 float y;
 float cWidth;
 float cHeight;

 Creature (float xp, float yp, float cw, float ch)
 {
   x = xp;
   y = yp;
   cWidth = cw;
   cHeight = ch;
 }

 void update ()
 {
   for (int i=0; i < numFood; i++)  {
     if (food[i].posX > width && food[i].posY > height){
       x = x;
       y = y;
     }
     else{
       x += ((food[i].posX)-x)/10;
       y += ((food[i].posY)-y)/10;
     }
   }
 }

 void display() {
   stroke(0);
   fill(200,50,50);
   noFill();
   rectMode(CENTER);                //comment out, corner can represent a head
   rect(x,y,cWidth,cHeight);
 }
}

class Food{
 float sizeX;
 float sizeY;
 float posX;
 float posY;

 Food (float sx, float sy, float px, float py)
 {
   sizeX = sx;
   sizeY = sy;
   posX = px;
   posY = py;
 }

 void update (int tempMouseX, int tempMouseY)
 {
   posX = tempMouseX;
   posY = tempMouseY;
 }

 void display ()
 {
   fill (50,200,50);
   ellipse (posX, posY, sizeX, sizeY);  
 }
}


boolean eaten (int i, int ctX, int ctY) {
 if (isAlive[i] == true) ellipse(food[i].posX, food[i].posY, food[i].sizeX, food[i].sizeY);
 ctX = food[i].posX;
 ctY = food[i].posY
   if (collision == true) {
   isAlive [i] = false;
   food[i].posX = 1000; //int(random(width-30))+10;
   food[i].posY = 1000; //int(random(height-30))+10;
 }
}

boolean collision(int i) {
 if (abs(creature1.x-food[i].posX) <= 15 && abs(creature1.y-food[i].posY) <= 15) {
   col = true;
   creature1.cWidth += 1;
   creature1.cHeight += 1;    
 }
 else {
   col = false;
 }
 return col;
}

void mousePressed(){
 food[counter].update(mouseX, mouseY);
 counter++;
 if  (counter >= numFood) {
   counter = 0;
 }
}


Re: A Little Help With OOP
Reply #7 - Jan 24th, 2010, 1:09pm
 
So far I worked on other interactions I want in the code. Where if the creature makes contact with the food it disappears, and when the creature eats the food it grows. However I can't think of a way to make it go sequentially. :/


Quote:
Creature creature1;
int numFood = 2;
Food[] food;
int counter;

//int ctX,ctY;

boolean[] isAlive = new boolean [numFood]; //state of ellipses, true in the beginning
boolean col;

void setup() {
 size (600,600);
 creature1 = new Creature (-10,-10,15,15);                //starting position x & y, initial size
 food = new Food[numFood];
 for (int i=0; i < numFood; i++)  {
   float pelX = 1000;
   float pelY = 1000;
   food[i] = new Food (10,10, pelX, pelY);          //initial size, position of food x & y

   isAlive[i] = true;
 }
}

void draw ()  {
 background (255);
 for (int i=0; i < numFood; i++)  {
   food[i].display();
 }
 creature1.update();
 creature1.display();

 println (creature1.x);
 println (creature1.y);

}

class Creature {
 float x;
 float y;
 float cWidth;
 float cHeight;

 Creature (float xp, float yp, float cw, float ch)
 {
   x = xp;
   y = yp;
   cWidth = cw;
   cHeight = ch;
 }

 void update ()
 {
   for (int i=0; i < numFood; i++)  {
     if (food[i].posX > width && food[i].posY > height){
       x = x;
       y = y;
     }
     else{
       x += ((food[i].posX)-x)/10;
       y += ((food[i].posY)-y)/10;
     }

     if (abs((food[i].posX)-(x)) <= 15 && abs((food[i].posY)-(y)) <= 15) {
       cWidth += 10;
       cHeight += 10;
       
       food[i].posX = 1000;
       food[i].posY = 1000;
     }

     if (cWidth >= 15 && cHeight >= 15){
     cWidth -= .01;
     cHeight -= .01;
     }else{
     cWidth = 15;
     cHeight = 15;
     }
   }
 }

 void display() {
   stroke(0);
   fill(200,50,50);
   noFill();
   rectMode(CENTER);                //comment out, corner can represent a head
   rect(x,y,cWidth,cHeight);
 }
}

class Food{
 float sizeX;
 float sizeY;
 float posX;
 float posY;

 Food (float sx, float sy, float px, float py)
 {
   sizeX = sx;
   sizeY = sy;
   posX = px;
   posY = py;
 }

 void update (int tempMouseX, int tempMouseY)
 {
   posX = tempMouseX;
   posY = tempMouseY;
   /*
   if (abs((posX)-(creature1.x)) <= 15 && abs((posY)-(creature1.y)) <= 15) {
   posX = 1000;
   posY = 1000
   }
*/
 }

 void display ()
 {
   fill (50,200,50);
   ellipse (posX, posY, sizeX, sizeY);  
 }
}

/*
boolean eaten (int i, int ctX, int ctY) {
if (isAlive[i] == true) ellipse(food[i].posX, food[i].posY, food[i].sizeX, food[i].sizeY);
ctX = food[i].posX;
ctY = food[i].posY
if (col == true) {
isAlive [i] = false;
food[i].posX = 1000;
food[i].posY = 1000;
}
}
*/
/*
boolean collision(int i) {
if (abs((food[i].posX)-(creature1.x)) <= 15 && abs((food[i].posY)-(creature1.y)) <= 15) {
col = true;
creature1.cWidth += 100;
creature1.cHeight += 100;    
}
else {
col = false;
}
return col;
}
*/
void mousePressed(){
 food[counter].update(mouseX, mouseY);
 counter++;
 if  (counter >= numFood) {
   counter = 0;
 }
}





Re: A Little Help With OOP
Reply #8 - Jan 24th, 2010, 3:15pm
 
Shocked

Why do you insist on looping through the food array?  The update code I posted works just fine:

Code:
Creature creature1;
int numFood = 10;
Food[] food;
int counter;
int currentTarget = -1;
//int ctX,ctY;

boolean[] isAlive = new boolean [numFood]; //state of ellipses, true in the beginning
boolean col;

void setup() {
size (600,600);
creature1 = new Creature (-10,-10,15,15);                //starting position x & y, initial size
food = new Food[numFood];
for (int i=0; i < numFood; i++)  {
  float pelX = 1000;
  float pelY = 1000;
  food[i] = new Food (10,10, pelX, pelY);          //initial size, position of food x & y

  isAlive[i] = true;
}
}

void draw ()  {
background (255);

for (int i=0; i < numFood; i++)  {
  food[i].display();
}
creature1.update();
creature1.display();


}

class Creature {
float x;
float y;
float cWidth;
float cHeight;

Creature (float xp, float yp, float cw, float ch) {
  x = xp;
  y = yp;
  cWidth = cw;
  cHeight = ch;
}

void update () {
  // if currentTarget is a kludge - what you really need is a boolean
  // to determine whether there are any eatable foods on screen...
  if(currentTarget != -1) {
      x += ((food[currentTarget].posX)-x)/10;
      y += ((food[currentTarget].posY)-y)/10;
 

    if (abs((food[currentTarget].posX)-(x)) <= 15 && abs((food[currentTarget].posY)-(y)) <= 15) {
      cWidth += 10;
      cHeight += 10;
     
      food[currentTarget].posX = 1000;
      food[currentTarget].posY = 1000;
      if(currentTarget < numFood-1) {
        currentTarget++;
      }
      else {
        currentTarget = 0;
      }
    }
  }



    if (cWidth >= 15 && cHeight >= 15){
    cWidth -= .01;
    cHeight -= .01;
    }else{
    cWidth = 15;
    cHeight = 15;
    }
 
}

void display() {
  stroke(0);
  fill(200,50,50);
  noFill();
  rectMode(CENTER);                //comment out, corner can represent a head
  rect(x,y,cWidth,cHeight);
}
}

class Food{
float sizeX;
float sizeY;
float posX;
float posY;

Food (float sx, float sy, float px, float py) {
  sizeX = sx;
  sizeY = sy;
  posX = px;
  posY = py;
}

void update (int tempMouseX, int tempMouseY) {
  posX = tempMouseX;
  posY = tempMouseY;

}

void display ()
{
  fill (50,200,50);
  ellipse (posX, posY, sizeX, sizeY);  
}
}


void mousePressed(){
food[counter].update(mouseX, mouseY);
counter++;
// this is a bit of a kludge for demonstration purposes:
if(currentTarget == -1) {
  currentTarget = 0;
}
if  (counter >= numFood) {
  counter = 0;
}
}



There are still a lot of improvements to make to this, but it at least demonstrates the principle: don't iterate over the whole food array, just target one at a time.  As I said in the comments you really need a boolean to determine whether there are currently any food items on screen and better integration between adding food and setting the next target...

You'll quickly notice that the main problem with this as it stands is that once there aren't any food items on screen the creature goes off and gobbles those off-screen.  Rather than simply moving the food objects offscreen, give them a boolean property to determine if they're 'active' (just check against this in the display method and don't draw them if they're not).  When you increment 'currentTarget' you can check against the active state of the food - if it's not active simply increment currentTarget until it finds an active food item.  Well that's one crude and slightly inefficient solution anyway...
Re: A Little Help With OOP
Reply #9 - Jan 24th, 2010, 4:27pm
 
Thanks a bunch. I'll break this down and digest it in a bit. Though, I don't want the creature to move off screen as well, that's why I wrote

if (food[i].posX > width && food[i].posY > height){
       x = x;
       y = y;
     }

What will be the equivalent?
Re: A Little Help With OOP
Reply #10 - Jan 24th, 2010, 4:28pm
 
Nevermind I saw your boolean statement. Or the need of a boolean.
Page Index Toggle Pages: 1