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 › Classes, classes, classes! (and games)
Pages: 1 2 3 
Classes, classes, classes! (and games) (Read 4016 times)
Re: Classes, classes, classes! (and games)
Reply #15 - Jan 3rd, 2010, 4:51am
 
Quote:
This also seems right, but i tested it, and it will not run! Says something about static... something... exception... I cant remember right now. Did you try to run the code like that?

Just copy/pasted your code above, applied my proposed changes on both sub-classes and ran it. No compilation error...

Another proposed change:
Code:
class ballgroup{
 //parameters
 ArrayList redballs;
 ArrayList blueballs;
 //constructor
 ballgroup(){
   redballs = new ArrayList();
   blueballs = new ArrayList();
 }
 // Private methods
 private void update(ArrayList balls) {
   for (int j = balls.size() - 1; j >= 0; j--) {
ball bb = (ball) balls.get(j);
if (bb.x > 400) balls.remove(j);
else bb.update();
   }
 }
 void display(ArrayList balls) {
   for (int j = balls.size() - 1; j >= 0; j--) {
ball rb = (ball) balls.get(j);
rb.display();
   }
 }
 //methods
 void update() {
   if (mbleft && !mbright) redballs.add(new redball(mouseX,mouseY));
   update(redballs);
   if (!mbleft && mbright) blueballs.add(new blueball(mouseX,mouseY));
   update(blueballs);
 }
 void display() {
   display(redballs);
   display(blueballs);
 }
}

That's one of the nice things with inheritance: you treat things in the array list as the generic type (you can even mix them up), but when calling methods, Java will call the most specialized one. And if not present, the generic one. That's why you don't need to do:
void update() { super.update(); }
because it is done anyway.
Re: Classes, classes, classes! (and games)
Reply #16 - Jan 3rd, 2010, 7:33am
 
kostino wrote on Jan 3rd, 2010, 4:26am:
This seems right... but I will have to find some way to put the blueball or redball class into the ballgroup from outside (as a data type). Otherwise I will have a case check inside the class (if (something...) blueballs...) so I will have code duplication again.


No, just treat them all as balls.

Instead of:
Code:
blueball bb = (blueball) blueballs.get(j); 


use:
Code:
ball b = (ball) balls.get(j); 

Re: Classes, classes, classes! (and games)
Reply #17 - Jan 3rd, 2010, 8:27am
 
kostino wrote on Jan 3rd, 2010, 4:26am:
In the meanwhile, any thoughts on "association" between player and ballgroup Cry


They both have access to each other because they both are 'global' variables in your sketch (that's not entirely accurate, but you can treat them as such in processing). So creating an association is not strictly needed.
Re: Classes, classes, classes! (and games)
Reply #18 - Jan 3rd, 2010, 11:39am
 
Here is the latest update on ball classes and ballgroup class.
Not changed the "ball b = (ball) balls.get(j); " case (JR) yet.

Anyway, it starts to be fun now...
Code:

class ball{
 float x,y,tx,ty;
 PVector target;
 PVector pos;
 PVector go;
 int nob;
 //constructor
 ball(float x, float y, float tx, float ty){
   this.x = x; this.y = y;
   this.tx = tx; this.ty = ty;
   nob = 0;
 }
 //methods
 void update(){
   pos.add(go);
   if (pos.x > 500){
     pos.x = 500;
     go.x *= -1;
     nob++;
   }
   if (pos.x < 0){
     pos.x = 0;
     go.x *= -1;
     nob++;
   }
   if (pos.y > 500){
     pos.y = 500;
     go.y *= -1;
     nob++;
   }
   if (pos.y < 0){
     pos.y = 0;
     go.y *= -1;
     nob++;
   }
 }
 void display(){
   noStroke();
   ellipseMode(CENTER);
   ellipse(pos.x, pos.y, 5, 5);
 }
}

class redball extends ball{
 //fields
 color cr;
 float speed;
 int nobmax;
 //constructor
 redball(float x, float y, float tx, float ty){
   super(x,y,tx,ty);
   pos = new PVector(x,y);
   target = new PVector(tx,ty);
   go = PVector.sub(target,pos);
   go.normalize();
   cr = color(255,0,0);
   speed = 10;
   go.mult(speed);
 }
 //methods
 void update(){
   super.update();
 }
 void display(){
   fill(cr);
   super.display();
 }
}

class blueball extends ball{
 //fields
 color cb;
 float speed;
 int nobmax;
 //constructor
 blueball(float x, float y, float tx, float ty){
   super(x,y,tx,ty);
   pos = new PVector(tx,ty);
   target = new PVector(x,y);
   go = PVector.sub(target,pos);
   go.normalize();
   cb = color(0,0,255);
   speed = 10;
   go.mult(speed);
 }
 //methods
 void update(){
   super.update();
 }
 void display(){
   fill(cb);
   super.display();
 }
}
class ballgroup{
 //parameters
 ArrayList redballs;
 ArrayList blueballs;
 //constructor
 ballgroup(){
   redballs = new ArrayList();
   blueballs = new ArrayList();
 }
 // Private methods
 private void update(ArrayList balls) {
   for (int j = balls.size() - 1; j >= 0; j--) {
ball b = (ball) balls.get(j);
       b.update();
       if (b.nob > 3) balls.remove(j);
       if (balls.size()>50) balls.remove(balls.size()-1);
       //^^remove the last one (don't create any more)
   }
 }
 void display(ArrayList balls) {
   for (int j = balls.size() - 1; j >= 0; j--) {
ball b = (ball) balls.get(j);
b.display();
   }
 }
 //methods
 void update() {
   if (mbleft /*&& !mbright*/) redballs.add(new redball(p.x,p.y,mouseX,mouseY));
   update(redballs);
   if (/*!mbleft &&*/ mbright) blueballs.add(new blueball(p.x,p.y,mouseX,mouseY));
   update(blueballs);
 }
 void display() {
   display(redballs);
   display(blueballs);
 }
}

Next step... something to shoot!
Re: Classes, classes, classes! (and games)
Reply #19 - Jan 3rd, 2010, 11:41am
 
Also, this masterpiece should not be kept private, so I uploaded it on OpenProcessing!
http://www.openprocessing.org/visuals/?visualID=6801
Re: Classes, classes, classes! (and games)
Reply #20 - Jan 3rd, 2010, 3:00pm
 
As someone getting to grips with more complex use of classes myself I'd suggest one other benefit of using inheritance and something else worth knowing about:  When you inherit from a parent class it ensures your subclass contains all relevant properties (since you have to call super() in the Constructor) (which is perhaps a little obvious)...  But you can also ensure you implement certain methods in your subclasses either by using an Interface or using an abstract class.

An interface defines a template for a class with all properties and methods it must implement.  So if you want to create several classes for different types of aliens you might want to ensure each one includes an attack() method and collisionDetect() method - for instance because these are required by your main Game class when it refers to aliens - in which case you create an Interface and make sure all aliens classes implement it.  Note that you can extend one class and also implement an interface at the same time.

Having gone through that description I have to say thus far I prefer the 'abstract class' approach.  If you declare a class as abstract you can't instantiate it as an object: you can only inherit from it.  If in your abstract class you also declare a method as 'abstract' this method must be implemented in the child class (matching any return types, parameters etc.).  The benefit here is you can implement some generic methods in the parent class but also force some methods to be implemented in the child.  In effect this is perhaps a shortcut to extending one class and implementing an Interface...

Not sure how well I've described those but if it's any help here are a couple of projects I worked on to get my head round the concepts (I'm not saying I've done things 'the Right Way', but these might give you some ideas):

http://www.openprocessing.org/visuals/?visualID=5921
http://www.openprocessing.org/visuals/?visualID=6412
Re: Classes, classes, classes! (and games)
Reply #21 - Jan 4th, 2010, 2:27am
 
One thing that just occurred to me...  As JR says above when you need an array to contain a group of related objects (i.e. all extended from the same parent class) you can simply declare it as being of the parent type.  One slight problem I have encountered with this approach is, if you call a class method from the array (e.g. b[i].bounce() ), this method must exist in the parent class.  Not sure if there is a way around this - I've just added empty methods as necessary to the parent, but that seems like a kludge.

As an aside - apparently you can use an interface to group a set of unrelated classes (i.e. not extended from the same parent).  So if you needed to include unrelated classes in a single array you can have them all implement an empty Interface and use this as the type for the array...
Re: Classes, classes, classes! (and games)
Reply #22 - Jan 4th, 2010, 6:25am
 
blindfish wrote on Jan 4th, 2010, 2:27am:
One slight problem I have encountered with this approach is, if you call a class method from the array (e.g. b[i].bounce() ), this method must exist in the parent class.

You can use instanceof to check if this is the sub-class you target, then cast the generic class to the sub-class, then call the specialized method.

Quote:
So if you needed to include unrelated classes in a single array you can have them all implement an empty Interface and use this as the type for the array...

Just add() them, since in Processing/old Java, they are stored as Objects, ie. hyper-generic stuff. Again, you can use instanceof (or other methods) to check what kind of class it is when retrieving them.
Re: Classes, classes, classes! (and games)
Reply #23 - Jan 4th, 2010, 8:31am
 
PhiLho  wrote on Jan 4th, 2010, 6:25am:
blindfish wrote on Jan 4th, 2010, 2:27am:
One slight problem I have encountered with this approach is, if you call a class method from the array (e.g. b[i].bounce() ), this method must exist in the parent class.

You can use instanceof to check if this is the sub-class you target, then cast the generic class to the sub-class, then call the specialized method.


Thanks - that makes sense Smiley
Re: Classes, classes, classes! (and games)
Reply #24 - Jan 4th, 2010, 9:52am
 
PhiLho  wrote on Jan 4th, 2010, 6:25am:
You can use instanceof to check if this is the sub-class you target, then cast the generic class to the sub-class, then call the specialized method.



The use of instanceof is frowned upon, as it bypasses the fundamentals of inheritance. In general: if you need instanceof, you are doing it wrong.
Re: Classes, classes, classes! (and games)
Reply #25 - Jan 4th, 2010, 9:54am
 
blindfish wrote on Jan 4th, 2010, 2:27am:
As an aside - apparently you can use an interface to group a set of unrelated classes (i.e. not extended from the same parent).  So if you needed to include unrelated classes in a single array you can have them all implement an empty Interface and use this as the type for the array...


All objects inherit from one superclass: Object.
(Edit: Philho already mentioned this Smiley )
So you really don't need and empty interface, that's just pointless Smiley

It is, however, very useful to group "unrelated" objects (but if they are unrelated, why would you group them...) by implementing an interface.

Suppose you have objects you want to draw, but all that binds them, is that they are drawable, you can let them implement the same interface.

Code:

interface Drawable
{
 void draw();
}

class Ball implements Drawable
{
 public void draw()
 {
   ...
 }
}

class Player implements Drawable
{
 public void draw()
 {
  ...
 }
}
Re: Classes, classes, classes! (and games)
Reply #26 - Jan 4th, 2010, 3:37pm
 
Again that helps clarify things.  I knew there was a reason for using an Interface in that way, but not having done it wasn't in the best position to explain it Smiley

Coming back to the issue of grouping objects by their parent class, but wanting to call methods that have only been implemented in the child classes...  Surely that's not so unusual?  In my asteroids game I had various classes extend 'Body' (i.e. a body in space with position and movement handling), but some classes needed distinct methods not directly related to the parent class.  Is there a 'Right Way' to handle this situation or is it more a matter of constructing things differently?
Re: Classes, classes, classes! (and games)
Reply #27 - Jan 5th, 2010, 12:38am
 
There are ways to avoid using instanceof, but they depend on the specific problem.

If you can give me a concrete example, I could probably come up with a cleaner solution.
Re: Classes, classes, classes! (and games)
Reply #28 - Jan 5th, 2010, 12:57am
 
Shocked
Needless to say - now you ask for an example I can't come up with one, but I'm sure this has caused me problems in the past...   If something crops up during my experiments I'll post it Wink
Re: Classes, classes, classes! (and games)
Reply #29 - Jan 5th, 2010, 1:46am
 
A common way to tactle the complex cases where instanceof is seemingly needed is the visitor design pattern: http://en.wikipedia.org/wiki/Visitor_pattern

I've implemented an example:

Code:

ArrayList bodyList = new ArrayList();
Animator animator = new Animator();
CollisionDetector detector = new CollisionDetector();

void setup()
{
 bodyList.add(new Square());
 bodyList.add(new Ball());
 
 
 for(int i = 0; i < bodyList.size(); i++)
 {
   Body b = (Body)bodyList.get(i);
   
   b.visit(animator);
   b.visit(detector);
 }
}
abstract class Body
{
 //...
 
 abstract void visit(Visitor visitor);
}

class Ball extends Body
{
 //...
 
 void visit(Visitor visitor)
 {
   visitor.visit(this);
 }
}

class Square extends Body
{
 //...
 
 void visit(Visitor visitor)
 {
   visitor.visit(this);
 }
}

interface Visitor
{
 void visit(Ball ball);
 void visit(Square square);
}

class Animator implements Visitor
{
 void visit(Ball ball)
 {
   //Animate ball
 }
 
 void visit(Square square)
 {
   //Animate square
 }
}

class CollisionDetector implements Visitor
{
 void visit(Ball ball)
 {
   //Do collision detection on ball
 }
 
 void visit(Square square)
 {
   //Do collision detection on square
 }
}


At first this might seem overkill, and this also assumes the Body object does not have enough information to do it's own collision detection of animation (which in a clean design would most likely be true), but it is quite easy to add a new Body or a new Visitor (a Visitor is just a class that does something with a Body).

You could even make an array of visitors to visit the bodies Cool
Pages: 1 2 3