I am trying to code a factory style game in which recources travel on belts and factory buildings craft them into other recources. I've got the belts and the most of the general building functionality running, but I can't think of a way to export(--> put on belt) a recource of which I don't know the exact class of. I only know that every Recources superior class is the recoruce class, which is enough to sort the input, however, I have to create the specific type of recource that the crafting recepie produces. In the worst case I had to put all the information about the different recoruces into the recource class and not use subclasses, but I had to rewrite a lot of the code for the input and storage buffer.
Here's the building class code, which all actual buildings are going to extend from:
Tip: The important part is in the act method;-)
If you need the other classes too, I can put the source code here, too, but I think this should be enough. Here's the hirarchy:
Actor
->Connectible(abstract)
--->Building(abstract)
----->Smelter
--->ConveyorBelt
->Recource(abstract)
--->IronOre
--->IronIngot
Recepie
I hope you can help me!
import greenfoot.*; import java.util.HashMap; public abstract class Building extends Connectible{ private HashMap<Class<? extends Recource>, Integer> inputBuffer; private HashMap<Class<? extends Recource>, Integer> outputBuffer; protected final Recepie recepie; private int counter; public Building(Recepie recepie){ super(ConveyorBelt.CONVEYOR_SPEED); this.recepie = recepie; inputBuffer = new HashMap<Class<? extends Recource>, Integer>(); outputBuffer = new HashMap<Class<? extends Recource>, Integer>(); for(Class<? extends Recource> r : recepie.input.keySet()){ inputBuffer.put(r, 0); } for(Class<? extends Recource> r : recepie.output.keySet()){ outputBuffer.put(r, 0); } GreenfootImage image = new GreenfootImage(20, 20); image.setColor(Color.RED); image.fill(); setImage(image); } public void act(){ //try crafting a new object craft(); //manage crafting time if(--counter==0){ for(Class<? extends Recource> r : recepie.output.keySet()){ produce(r, recepie.output.get(r)); } } else if(counter<0)counter = 0; //try to export onto belt or similar if(getNext()!=null&& outputBuffer.keySet().size()>0&& getNext().canInput()&& export((Class<? extends Recource>)(outputBuffer.keySet().toArray()[0]))){ //This is where I want to add the recource that is being produced //by this recepie. However, I can't think of a way to do so. For //simplicity, I just want to export the first recource in the output. getWorld().addObject(new Recource(getNext()){}, 0, 0); } } private Class<? extends Recource> getFirst(){ return null; } public String toString(){ return getClass() + ":" + recepie + ",{" + inputBuffer + "," + outputBuffer + "}"; } public void craft(){ if(counter!=0){ System.out.println("Crafting is running"); return; } for(Class<? extends Recource> r : recepie.input.keySet()){ if(inputBuffer.get(r) < recepie.input.get(r)){ System.out.println("Too little input"); return; } } for(Class<? extends Recource> r : recepie.output.keySet()){ if(outputBuffer.get(r) + recepie.output.get(r) > Recource.STACKSIZE){ System.out.println("Too little output space"); return; } } for(Class<? extends Recource> r : recepie.input.keySet()){ use(r, recepie.input.get(r)); } counter = recepie.craftTime; System.out.println("Crafting..."); } public boolean input(Class<? extends Recource> r){ if(inputBuffer.containsKey(r)&&inputBuffer.get(r) < Recource.STACKSIZE){//r.STACKSIZE){ inputBuffer.put(r, inputBuffer.get(r) + 1); return true; } return false; } protected boolean use(Class<? extends Recource> r, int count){ if(inputBuffer.containsKey(r)&&inputBuffer.get(r) >= count){ inputBuffer.put(r, inputBuffer.get(r) - count); return true; } return false; } protected void produce(Class<? extends Recource> r, int count){ outputBuffer.put(r, outputBuffer.get(r) + count); } public boolean export(Class<? extends Recource> r){ if(outputBuffer.containsKey(r)&&outputBuffer.get(r) > 0){ outputBuffer.put(r, outputBuffer.get(r) - 1); return true; } return false; } @Override public int X(){ return getX(); } @Override public int Y(){ return getY(); } }