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 4019 times)
Classes, classes, classes! (and games)
Jan 1st, 2010, 9:20pm
 
This is a general topic, about organising an algorithm using classes.
I have been using classes for quite some time in c++, and now I am doing some simple stuff with processing, mainly game-like applications.
The thing is that, I am not quite sure that I get the most out of what "classes" can offer. Being self-taught and all...
For example when I make a game where there are about 100 balls moving around, and things happening, I make a class called "ball" and then use an ArrayList to handle the balls in a "for-loop".
Something like that:
Quote:
for(int j = balls.size() -1; j>=0; j--){
 ball bl = (ball) balls.get(j); //get every single ball
 bl.handle();                      //do stuff to it
}

But this piece of code could be much more complex, and balls could be one of the many things I use in a game.
So I have a main game-loop which stands for the "game engine", (in our case the void Draw(){} loop), and in which all the checks of conditions and actions are happening.
This looks alot like the traditional game loop, the only difference being that some very low-level entities have been turned into classes, and thus the code is quite more readable and simple.
But what I am missing is the way to organize the whole project using classes, one including another, and so on... Perhaps using a class as the game engine?
Say again, I have never taken a class on classes, and would like some help as to how to use them more efficiently.
Any help or any useful links would be greatly appreciated!
Re: Classes, classes, classes! (and games)
Reply #1 - Jan 2nd, 2010, 12:33am
 
You should probably read up on inheritance: http://java.sun.com/docs/books/tutorial/java/concepts/inheritance.html

If you have objects in your game which on a high level could be treated the same (balls, blocks, beams, ...) you let them all inherit from the same class. In your for loop you could then iterate over all "game objects" instead of all balls.
Re: Classes, classes, classes! (and games)
Reply #2 - Jan 2nd, 2010, 1:49am
 
Object orientation is so much more than creating classes it is a way to help design your software. It is one of the most successful programming paradigms especially for medium-large scale software development and I suggest that you might find out more about OO. This might be a good starting point.
http://www.codeproject.com/KB/architecture/OOP_Concepts_and_manymore.aspx

Quote:
For example when I make a game where there are about 100 balls moving around, and things happening, I make a class called "ball" and then use an ArrayList to handle the balls in a "for-loop".
Something like that:

Code:
for(int j = balls.size() -1; j>=0; j--){
ball bl = (ball) balls.get(j); //get every single ball
bl.handle();                      //do stuff to it
}


But this piece of code could be much more complex, and balls could be one of the many things I use in a game.

Considering your scenario it is fairly obvious that a Ball class would be a benefit, the class would hold colour, size, position, speed, direction etc for each ball object. So the Ball class is responsible for every attribute and action of a 'single' Ball object.
So how do we manage the 100 balls? Managing a collection of objects is an extremely common problem in programming that many languages have there own set of classes to do this. For instance Java has the ArrayList, LinkkedList, Hashmap etc and each of these classes have methods to add, remove, search ... objects.
As you have discovered some of the things we want to do with our collection of balls require us to iterate through all the objects and do something with each object. The code for that can be quite complex and we might want to perform that action at several places in our code. What happens if we have 2 collections of balls do we have 2 ArrayLists and duplicate the code for each one? I think not. The solution is to create a class to manage a set of balls and use one of the Java collections as an attribute in this class.
Code:

public class BallGroup {
  public ArrayList balls;

  public BallGroup(){
     balls = new ArrayList();
  }

  // various methods to manage a group of balls

}


The methods could include sorting, collision detection anything that relates to the collection of balls.
It also solves the problem of multiple ArrayLists and duplicating code because we can have any number of BallGroup objects.

Just a few thoughts on a huge topic.
Smiley
Re: Classes, classes, classes! (and games)
Reply #3 - Jan 2nd, 2010, 2:25am
 
Jr, thanks for the link, (http://java.sun.com/docs/books/tutorial/java/concepts/inheritance.html) I checked it out. Inheritance seems to be easy to understand and apply. Say I have three kinds of enemies in my game, I make a class called enemy and extend it for each kind, so I don't need to write the same stuff three or more times.

QUark, the BallGroup case seems also very interesting. I did not know I could do that...  Shocked

Anyway, I'm going to describe a simple game and ask you about the general strategy which is best to use to take good advantage of classes without considering the code. Just the "main idea".
So... Say I have these objects:
1) A level (a space to include the player and the enemies)
2) A player that can move around
3) Some enemies that try to kill the player in someway
4) Some other neutral objects (like walls or trees or whatever)
But I also have
5) A set of rules in which the player reacts with the environment (enemies and neutral objects)
And on top of all that,
6) A user interface, a menu, some other options the user might want to access at the beginning or any time.

What I am missing is a class to control all of this stuff.
Something like the "public class BallGroup{}" that Quark mentioned.
But I have no idea on how to express that with code or without.
Should I try to include everything in one class
Kinda lost here.

In the meanwhile I will be strolling around in the java tutorials on OOP.
Re: Classes, classes, classes! (and games)
Reply #4 - Jan 2nd, 2010, 3:08am
 
Nothing like jumping in at the deep end. Wink

You have made a good start identifying the types of object (classes) now you have to consider what are the class attributes and responsibilities. We can think of the attributes as being nouns - the things we want to know about the object e.g. colour, size, position. The responsibilities can be thought of as verbs i.e. the doing things e.g. changing position.
The hardest part then is we have all these classes so how do they interact. One way would be to create objects of each type in setup() and in draw() do all the communication between the objects. A better way is to use aggregation, association and Inheritance (OO concepts).

So we have the following classes
Player
Enemy
EnemyGroup (collection of Enemy objects)
Artifact (like walls or trees or whatever)
ArtifactGroup (collection of Artifact objects)
World describes the play area - a level could just be a different arrangement
Game contains the rules of play and will have objects of type Player, EnemyGroup, ArtifactGroup and World.

The main processing sketch could then create a Game object and manage user input in the sense of getting user input and passing that to the Game object to handle.

I would also have a draw() method in the Game method which would handle the actual drawing to the screen.

For the classes to have access to all the methods available in Processing then pass the PApplet object to the class constructor e.g.

Code:

// Main processing sketch

Game g;

void setup(){
  size(300,300);
  g = new Game(this);
}

void draw(){
  g.draw();
}


and the Game class
Code:

public class Game {
  private PApplet app;

  public Game(PApplet app){
     this.app = app;
  }

  public void draw(){
     app.fill(255,0,0);
     app.rect(10,30,100,200);
     // etc.
  }

}

 
When using Processing I recommend that you keep each class in its own tab.

Anyway hope this helps get you started.

Smiley
Re: Classes, classes, classes! (and games)
Reply #5 - Jan 2nd, 2010, 4:33am
 
I can't say I quite understand the PApplet case scenario yet...
But let me get back to the basic stuff:
Suppose I am trying to organize my classes a bit like that:
Quote:
class lvlobject { //level object
  //**fields
  PVector pos;
  //**constructor
  lvlobject (PVector inpos){ //set x,y values, only
    pos = inpos;
  }
  //**methods defined in sub classes
}

class canon extends lvlobject { //sub class of level object
  //**fields
  PVector target; //target position vector
  PVector lookat; //vector from canon to target
  float angle;    //angle from canon to target
  //**constructor inherited from lvlobject
  //**methods
  void setTarget(PVector intarget){
    target = intarget;
    lookat = PVector.sub(target,pos);
    lookat.normalize();
  }
  void display(){
    //display canon
  }
}

class bullet extends canon{ //subclass of canon
  //**fields
  float speed;
  //**constructor inherited
  //**methods
  void move(){
    pos.add(lookat.mult(speed));
  }
  void display(){
    //display bullet
  }
}


-Does that seem right?
Now as for grouping... and control!
Lets say that every canon fires one bullet towards the player if the player gets close to the canon (distance < firedistance) and does not fire another one until the bullet has reached the player or has exploded anyway.
-These are, apparently, conditions of the game play. So they should be handled by the game class?
What I mean is:
-Should there be a "void fire(){}" method in the canon, so the bullet would be created inside the canon, or would the game class decide when a bullet is created?

*Inheritance I quite get...
**Aggregation and association?
***Also, when is it necessary to use "public" before a class?
****Too many questions... thanks for your effort up to now!
Re: Classes, classes, classes! (and games)
Reply #6 - Jan 2nd, 2010, 4:58am
 
Seems like you misunderstood class heritage. Extending a class only make sense if mother and child classes should have parameters in common. For example, a class Ape could extend the class Animal.

Thus, extending your Canon class to create a Bullet class does not make sense (unless a bullet is a specific type of canon, which I guess is not what you mean). A bullet can be thrown by a canon, so you may want to refer to the parent canon in the Bullet class :

Code:
class Bullet {
 
 Canon canon;
 
 public Bullet(Canon thrownBy) {
   this.canon = thrownBy;
 }  
 
}


Same thing with LvlObject and Canon. Your level contains canons, so just put an arraylist of Canon objects into LvlObject (which I would simply call Level, btw) :

Code:
class Level {

 ArrayList canons;
 
}
Re: Classes, classes, classes! (and games)
Reply #7 - Jan 2nd, 2010, 5:39am
 
Perhaps it is a bizzare way of looking at things, but I considered the bullet as a canon that moves. They both have a target, they turn towards it, but the bullet also moves towards it. At least thats how it would work in this example.

As for the lvlobject, it is suposed to be a general class with fields shared by the canon and other types of enemies. It is not an object representing the level.

The whole paradigm was a pointless example to demonstrate class inheritance in my example and see when/if it makes sense.

Anyway, I will try to use some of the stuff mentioned here, such as
-arraylist of classes within other classes to make groups,
-inherritance
-perhaps I might also try the game class...

Thank you all for now... see you after a bit of coding!

*Also, this piece of code:
Quote:
class Bullet {
 
 Canon canon;
 
 public Bullet(Canon thrownBy) {
   this.canon = thrownBy;
 }  
 
}

is driving me crazy.
Re: Classes, classes, classes! (and games)
Reply #8 - Jan 2nd, 2010, 9:38am
 
Quote:
Perhaps it is a bizzare way of looking at things, but I considered the bullet as a canon that moves. They both have a target, they turn towards it, but the bullet also moves towards it. At least thats how it would work in this example.


Yes it is bizarre but only to those who are more familiar with OO. OO is about creating software constructs (classes) that represent real world things.

Inheritance, aggregation and association and the OO concepts that describe different interactions between classes.

For example inheritance describes the 'is a kind of' relationship so
we might have a class called Weapon and that class has methods to set the position, load, aim and fire the weapon.
So a Canon is a kind of weapon so is Rifle, Revolver, MissileLauncher etc so all these can inherit from Weapon. These are all the same kind of thing because 'they fire projectiles'.
A bullet does not fire projectiles so is not a kind of Weapon/Canon so should not inherit from these classes.

Aggregation means 'is made of' or 'comprises of. So from my original reply the EnemyGroup is an aggregation of Enemy.

Association means 'is related to' so the Canon might have a Person to load, aim and fire it. The Person is not 'a kind of' or 'a part of' a Canon so inheritance and aggregation don't describe the relationship but there is a link between Canon<>Person and that is association.

Quote:
-Should there be a "void fire(){}" method in the canon, so the bullet would be created inside the canon, or would the game class decide when a bullet is created?


A really good question since there is no truly correct answer, the game class could create the bullet and pass it to the canon to get the bullets direction based on the orientation of the canon, or the bullet is created when the canon is fired. Take your pick - personally I like the second option and you could implement it like this

Code:
public class Cannon {
 
  public Bullet fire(){
      Bullet b = new Bullet();
      // set the various bullet values e.g. direction and speed
     // based on Canon attributes
     return b;
  }
}


Quote:
***Also, when is it necessary to use "public" before a class?


In Processing you can ignore the public keyword and it is probably better to do so.

Hope this helps some.

Smiley
Re: Classes, classes, classes! (and games)
Reply #9 - Jan 3rd, 2010, 1:11am
 
Hi there, again!
I have just managed to make a working example using inheritance and aggregation.
Here it is:
Code:

//classes example 1:
//Inheritance and Aggregation
player p  = new player(100,100,24.0);
ballgroup bg = new ballgroup();

boolean kup = false;
boolean kdown = false;
boolean kleft = false;
boolean kright = false;
boolean mbleft = false;
boolean mbright = false;

void setup(){
 size(500,500);
 frameRate(60);
}

void draw(){
 p.update();
 bg.update();
 background(0);
 p.display();
 bg.display();
}
///////////////////////////////////////////////////////////
//classes
///////////////////////////////////////////////////////////
class ball{
 float x,y;
 float w = 5;
 float step = 8;
 //constructor
 //methods
 void update(){
   x+=step;
 }
 void display(){
   noStroke();
   ellipseMode(CENTER);
   ellipse(x, y, w, w);
 }
}

class redball extends ball{
 //fields
 color cr;
 //constructor
 redball(float inx, float iny){
   x = inx; y = iny;  
   cr = color(255,0,0);
 }
 //methods
 void update(){
   super.update();
 }
 void display(){
   fill(cr);
   super.display();
 }
}

class blueball extends ball{
 //fields
 color cb;
 //constructor
 blueball(float inx, float iny){
   x = inx; y = iny;
   cb = color(0,0,255);
 }
 //methods
 void update(){
   x+=step;
 }
 void display(){
   fill(cb);
   super.display();
 }
}
class ballgroup{
 //parameters
 ArrayList redballs;
 ArrayList blueballs;
 //constructor
 ballgroup(){
   redballs = new ArrayList();
   blueballs = new ArrayList();
 }
 //methods
 void update(){
   if (mbleft && !mbright) redballs.add(new redball(mouseX,mouseY));
   if (mbright && !mbleft) blueballs.add(new blueball(mouseX,mouseY));
   for(int j = redballs.size() -1; j>=0; j--){
     redball rb = (redball) redballs.get(j);
     if (rb.x > 400) redballs.remove(j);
     else rb.update();
   }
   for(int j = blueballs.size() -1; j>=0; j--){
     blueball bb = (blueball) blueballs.get(j);
     if (bb.x > 400) blueballs.remove(j);
     else bb.update();
   }
 }
 void display(){
   for(int j = redballs.size() -1; j>=0; j--){
     redball rb = (redball) redballs.get(j);
     rb.display();
   }
   for(int j = blueballs.size() -1; j>=0; j--){
     blueball bb = (blueball) blueballs.get(j);
     bb.display();
   }
 }
}
class player{
 float x,y,tx,ty;
 float w;     //size
 float step = 2;
 player(float inx, float iny, float inw){
   x = inx;
   y = iny;
   w = inw;
 }
 void update(){
   if (kup) y -= step;
   if (kdown) y += step;
   if (kleft) x -= step;
   if (kright) x += step;
   tx = mouseX;
   ty = mouseY;
 }
 void display(){
   fill(255,255,255);
   ellipse(tx, ty, 4, 4);
   stroke(255);
   line(x,y,mouseX,mouseY);
   fill(255,255,0);
   noStroke();
   ellipseMode(CENTER);
   ellipse(x, y, w, w);
 }
}
//////////////////////////////////////////////////////
//interrupts
///////////////////////////////////////////////////////
void keyPressed(){
 if (keyCode == UP) kup = true;
 if (keyCode == DOWN) kdown = true;
 if (keyCode == LEFT) kleft = true;
 if (keyCode == RIGHT) kright = true;
}
void keyReleased(){
 if (keyCode == UP) kup = false;
 if (keyCode == DOWN) kdown = false;
 if (keyCode == LEFT) kleft = false;
 if (keyCode == RIGHT) kright = false;
}
void mousePressed(){
 if (mouseButton == LEFT) mbleft = true;
 if (mouseButton == RIGHT) mbright = true;
}
void mouseReleased(){
 if (mouseButton == LEFT) mbleft = false;
 if (mouseButton == RIGHT) mbright =false;
}


Still having some trouble inherriting the constructor from the ball class, but I think I might work it through.
Now in this example how could I use "association" between the player class and the ballgroup class?
Some hint? some piece of code?
Re: Classes, classes, classes! (and games)
Reply #10 - Jan 3rd, 2010, 1:51am
 
Note: you can drop the update() methods of redball and blueball since they just duplicate what ball does: that's the point of inheritance - if Java doesn't find a method in the child class, it automatically calls the parent's method (and up if needed).

And you can add:
Code:
class ball {
// [...]
//constructor
ball(float inx, float iny) {
x = inx; y = iny;
}
// [...]
class blueball extends ball {
// [...]
//constructor
blueball(float inx, float iny) {
super(inx, iny);
cb = color(0,0,255);
}

That said, if blueball and redball have same behavior, there is little point (except for educational purpose, which is fine) in making these sub-classes, as color could be moved to ball() and color made distinct in the constructor...
Re: Classes, classes, classes! (and games)
Reply #11 - Jan 3rd, 2010, 2:17am
 
The best way to know if you have a good design is to look for code duplication. In your ballgroup class you have duplicate code for the red balls array list and the blue balls array list. You should make a ballgroup class with only one array list and then make two ballgroup objects, one for blue balls and one for red balls.
Re: Classes, classes, classes! (and games)
Reply #12 - Jan 3rd, 2010, 2:22am
 
Although it is definitely not wrong to write constructor code like this, I would write:

Code:

 player(float x, float y, float w){
   this.x = x;
   this.y = y;
   this.w = w;
 }

instead of:
Code:

 player(float inx, float iny, float inw){
   x = inx;
   y = iny;
   w = inw;
 }

Re: Classes, classes, classes! (and games)
Reply #13 - Jan 3rd, 2010, 2:38am
 
Another property of good software design is that when the code changes (and it will!) the changes are local and are not propagated from one area of the code to another.

For example:
Code:

if (mbleft && !mbright) redballs.add(new redball(mouseX,mouseY));

and
Code:

class Player
{
...
 void update(){
   if (kup) y -= step;
   if (kdown) y += step;
   if (kleft) x -= step;
   if (kright) x += step;
   tx = mouseX;
   ty = mouseY;
 }
}


It is obvious that the spawning location of the ball and the location of the turret (is it the turret?) (tx, ty) should be the same.
And they both use (mouseX, mouseY) so now they are the same. But suppose something else will control the location of the turret (not the mouse) then you will have to do the change in more than one area of the code. If you change the code to:
Code:

if (mbleft && !mbright) redballs.add(new redball(p.tx, p.ty));

Only one piece of code will change. I agree in this case the changes are quite trivial, but as your code grows, these things become really important.
Re: Classes, classes, classes! (and games)
Reply #14 - Jan 3rd, 2010, 4:26am
 
JR: Quote:
The best way to know if you have a good design is to look for code duplication. In your ballgroup class you have duplicate code for the red balls array list and the blue balls array list. You should make a ballgroup class with only one array list and then make two ballgroup objects, one for blue balls and one for red balls.

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.

Philho: Quote:
class ball {
// [...]
//constructor
ball(float inx, float iny) {
 x = inx; y = iny;
}
// [...]
class blueball extends ball {
// [...]
//constructor
blueball(float inx, float iny) {
 super(inx, iny);
 cb = color(0,0,255);
}

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?
Also: Yes, for now having two types of ball classes doesn't make sense, but I'm just trying to figure out how things work... Thanks, anyway!

Sorry for being inaccurate at the moment. I am away from my pc. I will be back soon.
In the meanwhile, any thoughts on "association" between player and ballgroup? Cry
Pages: 1 2 3