How to make a game with many different objects (ArrayList)

Hello forum, I’m not sure how to make many unique objects that can all be defined in a single class.

The problem stems from the fact that I’m trying to put many different entities into a single ArrayList for efficiency.

For instance: I can create an enemy class to represent all enemies, and that’s fine and all for collisions, depth sort, etc, but each different monster needs unique code for their behavior and I have to somehow incorporate it into the non-unique code and it makes things very convoluted.

This is currently how I’m dealing with it. Each different behavior ends up having a lot of repetitive code, and there may be many different types. I’ve tried using inheritance to no avail.

class monster {
  byte type;
  monster(byte Type) {
    //create moster of user choice
    type = Type;
  }
  void update() {
    //basic behaviour goes here
    if (type==0) {
      //behaviour 1...
    } else if (type==1) {
      //behaviour 2...
    } else if (type==2) {
      //behaviour 3...
    }
  }
}

Is there a more efficient way to do this?

For these cases, it’s possible to inherit from other interfaces. Interfaces only define methods abstract. You can make a interface, like this:

interface IMonster {
  void attack(Player player);
  void update();
  boolean isAlive();
  ... // Whatever your 'basic monster' could do
}

and then

class Gnome extends IMonster {
  Gnome() {

  }

  void attack(Player player) {
    ... // How your Gnome attacks
  }
  

  void update() {
    ... // How your Gnome moves 
  }

  boolean isAlive() {
    ... // Check if your Gnome is dead, probably not other
  }
  ...
}

And then finally:

ArrayList<IMonster> monsters;

void setup() {
  monsters  = new ArrayList<IMonster>();
}

When you override Methods from other Classes you need to use @Override:

class Quark extends BasicMonster {
  @Override
  void equals(Object other) {
    ...
  }
}
3 Likes

Thanks for the insight! I have tried interfaces but I guess I didn’t understand the concept fully. I will try this and see how it works.

As has already been suggested, Interfaces can be quite useful. Using an Interface handily solves putting stuff into the same list as well as being able to make the same method call on each without knowing what you’ve pulled out of the list. And if you keep this project simple it may well be more than sufficient.

You can however take this all a step further if you want to by utilizing Composition by moving “behavior” out into another class entirely. For example you could create a Behavior class and adding a Behavior field to your Monster(s). This will be particularly useful if you end up needing two kinds of say, Gnome(s), which attack differently and you don’t want to either add a tier to your inheritance tree or copy-paste into another class. Right now you have a model where the type of creature and the way it attacks are synonymous.

2 Likes

Because I can’t edit any more, I want to write it here: I used the wrong keyword. The extends keyword is used for classes, the implements keyword is used for interfaces.

3 Likes

here is an example

using interface and implements


// demo for interface and implements
// Interface allows to bring different kinds of objects in one ArrayList

ArrayList<BasicItem3D> list = new ArrayList(); 

void setup() {
  size(950, 650, P3D);

  for (int x=0; x<7; x++) {
    for (int y=0; y<7; y++) {
      if (random(100) > 50) 
        list.add(new ClassBox( 300.0+x*74, 100.0+y*74, random(-150, 150)));
      else
        list.add(new ClassSphere( 300.0+x*74, 100.0+y*74, random(-150, 150)));
    }//for
  }//for
  //
}//func

void draw() {
  background(0);
  lights();

  for (BasicItem3D item : list) {
    item.display();
  }//for
}//func

//=============================================================================

interface BasicItem3D {
  void display();
  void move();
}//interface

//=============================================================================

class ClassSphere implements BasicItem3D {
  PVector pos   = new PVector(0, 0, 0); 

  // constr 
  ClassSphere(float x, float y, float z) {
    pos.set(x, y, z);
  }// constr 

  void display() {
    noStroke();
    fill(255, 0, 0);
    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    sphere (39);
    popMatrix();
  } 

  void move() {
  }
  //
}//class

//=============================================================================

class ClassBox implements BasicItem3D {
  PVector pos   = new PVector(0, 0, 0); 

  // constr 
  ClassBox(float x, float y, float z) {
    pos.set(x, y, z);
  }// constr 

  void display() {
    stroke(0);
    fill(200);
    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    box (39);
    popMatrix();
  } 

  void move() {
  }
  //
}//class
//
2 Likes