Rufr
Rufr

Reputation: 43

Multiple type custom arraylist

I currently am trying to make a simple RPG-ish game. I want monsters to spawn randomly on the map. I have it set up so that when I want one to spawn it is added to an ArrayList called monsters. I will be having many different types of monsters by the time I am done, and each one has its own class (ex. Zombie, Ghost...) each class will have a method to draw the monster called draw. I want to know how I can do this.

Monsters is an ArrayList<Object> so it will be able to have the different classes in it, but It won't let my do Monsters.get(i).draw(); Is this actually possible, or am I being stupid.

Upvotes: 2

Views: 164

Answers (3)

Constantin
Constantin

Reputation: 1506

Yes, it is possible, first you need to create an interface, like IMonster which contains a draw method. Then, have each monster type implement this interface.

Your ArrayList will look like this:

List<IMonster> monsters = new ArrayList<IMonster>();

monsters.add(new Ghost());
monsters.add(new Goblin());

So here is an example:

import java.util.ArrayList;
import java.util.List;

public class Monsters {
    private static List<IMonster> monsters = new ArrayList<IMonster>();

    public static void main(String[] args) {
        monsters.add(new Ghost());
        monsters.add(new Goblin());
        monsters.add(new Devil());  

        for (IMonster monster : monsters) {
            monster.draw();
        }
    }
}

interface IMonster {
    public void draw();
}

abstract class AbstractMonster implements IMonster {
    @Override
    public void draw() {
        System.out.println("Shared drawing code for all monsters");
    } 
}

class Ghost extends AbstractMonster {
    @Override
    public void draw() {
        super.draw();
        System.out.println("Ghost drawing code");
    }
}

class Goblin extends AbstractMonster {
    @Override
    public void draw() {
        super.draw();
        System.out.println("Goblin drawing code");
    }
}

class Devil extends AbstractMonster {
    @Override
    public void draw() {
        super.draw();
        System.out.println("Devil drawing code");
    }
}

Upvotes: 3

Jay Harris
Jay Harris

Reputation: 4271

You failed to cast the object ArrayList<Object> back to Monster

// Monster.get(i)            == Object
// (Monster) Monsters.get(i) == Monster

// cast the list item i from Object to Monster
((Monster) Monsters.get(i)).draw();

A better solution:

interface Monster {
   void draw();
}

// implement draw on each
class Zombie implements Monster {}
class Ghost implements Monster {}

ArrayList<Monster> monsters = new ArrayList<>();
// legal
monsters.add(new Zombie());
monsters.add(new Ghost());

// legal
monsters.get(i).draw();

You can go with class -> extends solution or this interface -> implements. Either way this is a very bare bones example of a better way to implement your Monsters.

Upvotes: 3

Razib
Razib

Reputation: 11163

You have to cast your item get from the ArrayList like this -

Object item = Monsters.get(i);
Monster monster = (Monster) item;
monster.draw();  

Or better you may use some Interface. You may use an interface (for example Drawable ). Your Monsterand other drawable class would implement it. Then use the ArrayList of Drawable.

interface Drawable{
   public void draw();
} 

public class Monster implements Drawable {

   public void draw(){
      //implementation of monster's draw
   } 
} 
...
... 

ArrayList<Drawable> monsters = new ArrayList<Drawable>();
...
...
monsters.get(i).draw();

Upvotes: 1

Related Questions