Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Class that creates another new superclass at runtime  (Read 1770 times)
0 Members and 1 Guest are viewing this topic.
Offline seismic
« Posted 2013-06-19 12:53:41 »

Hi,

ok topic sucks and this is kinda hard to explain, but here we go:

In my game I have this workshop thing, which should be able to create items. For every item in game there is a different class, for example:

Item (Base class)
ItemDoor
ItemChair
ItemFence
ItemTree
...

Now, I have this list that my workshop holds, called buildableItems. It currently holds a string like "Build Door" (for the UI) and the information on what is required to build that thing.

Here is an example of the carpenter:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public class W_Carpenter extends Workshop {
    public W_Carpenter(AssetManager assets, Map map) {
        super(assets, "data/carpenter3.png", "data/carpenter0.png", "data/carpenter1.png", "data/carpenter2.png", map);
        MaterialsRequired r1 = new MaterialsRequired(ItemList.ITEM_LOG, 2);
        MaterialsRequired r2 = new MaterialsRequired(ItemList.ITEM_RAWSTONE, 1);
        requiredForConstruction.add(r1);
        requiredForConstruction.add(r2);
        name = "Carpenter";
        // ^^ this is only what's required to build the workshop

        BuildableItem itemDoor = new BuildableItem();
        itemDoor.name = "Build Door";
        MaterialsRequired b1 = new MaterialsRequired(ItemList.ITEM_LOG, 2);
        itemDoor.matsRequired.add(b1);
        buildableItems.add(itemDoor);


Now in that buildableItem object I want to hold the endProduct, which would be the class ItemDoor. How would I go about that?

Here's buildableItem FYI
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public class BuildableItem {
    public String name;
    public ArrayList<MaterialsRequired> matsRequired;
    // HERE I need something like
    // Item endProduct;

    public BuildableItem() {
        matsRequired = new ArrayList<MaterialsRequired>();
        name = null;
    }
}


But I can't just go "Item endProduct" there, because then I would have to instantiate (?) the ItemDoor, which I don't want to do (because it holds reference to the texture etc)...yet. If I don't create the object I can't even go through thousands of instanceof lines, because it would probably result in a null pointer exception I guess.

The endProduct (ItemDoor) should be created when all the requirements are fulfilled. So that the future code would look something like this

1  
Item endProduct = new buildableItem.endProduct;


I hope I have explained that ok, any ideas on how to accomplish this? Cheesy


Offline Danny02
« Reply #1 - Posted 2013-06-19 13:13:18 »

want you need is a item factory. You can use your BuildableItem class as a basis for it.
you would need to add a method which builds the item and some way to check if all the requiremnts are met.

You could implement this factory method in two ways, either subclass BuildableIteam for every Item class you have, our work with factory functions.

i.e.
1  
2  
3  
4  
5  
6  
7  
public  abstract  class BuildableItem {
  abstract Item build();
}

//and then

BuildableItem bi = new BuildableItem(...){ Item build(){return new CoolItem();} }
Offline seismic
« Reply #2 - Posted 2013-06-19 13:23:31 »

Thanks for the help, but I don't think I get this.

Quote
You could implement this factory method in two ways, either subclass BuildableIteam for every Item class you have,
I get that, and that'd probably be easy, but it's not quite the solution I'm looking for.

Quote
our work with factory functions.
Yes please, but I don't get it ->

Take a look at my class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public class BuildableItem {
    public String name;
    public ArrayList<MaterialsRequired> matsRequired;

    public BuildableItem() {
        matsRequired = new ArrayList<MaterialsRequired>();
        name = null;
    }

    public Item buildItem() {
        // how do I know what kind of item to return here?
        // I need to store this information somehow in the class?
        // return new ItemDoor;
       // return new ItemChair;
    }
}


edit:
I could probably check the name and return the according item? But that's a lot of
if( name.compareTo("Door") ) {
// bla
} else .......

Not sure if that's the right way
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline actual

JGO Coder


Medals: 23



« Reply #3 - Posted 2013-06-19 17:56:16 »

One way to get rid of the if/then/else checks is to use the Class object.

Some items:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public abstract class Item {
   public abstract String getName();
}

public class DoorItem extends Item {
   public String getName() {
      return "Door";
   }
}


public class  WallItem extends Item {
   public String getName() {
      return "Wall";
   }
}


Now create a BuildableItem that takes the class object you want it to create:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
public class BuildableItem {

        // We use generics to make sure we only have classes that extend Item.
   private Class<? extends Item> itemClass;
   

   BuildableItem(Class<? extends Item> itemClass) {
      this.itemClass = itemClass;
   }
   

       // Here we are instantiating a class based on its Class Object.
      // NOTE: We are assuming these are all 0 argument constructors.
   public Item buildItem() {
     
      Item item = null;
      try {
         item =  itemClass.newInstance();
      } catch (Exception e) {
         e.printStackTrace();  
      }  
      return item;
   }
}



Now you can use the code like this:

1  
2  
3  
4  
5  
   BuildableItem buildableDoor = new BuildableItem(DoorItem.class);

  Item item = buildableDoor.build();

  System.out.println(item.getName());  // <-- Will print out Door



EDIT: I read Danny's post more carefully and I like his approach. It's a bit more wordy on the usage end but you aren't messing around with class objects.

Looking at your BuildableItem class, it would look like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
// We don't create BuildableItems directly any more.
public abstract class BuildableItem {
    public String name;
    public ArrayList<MaterialsRequired> matsRequired;

    public BuildableItem() {
        matsRequired = new ArrayList<MaterialsRequired>();
        name = null;
    }

    public abstract Item buildItem();
}


Now, when you want a BuildableItem of a specific type, you create an anonymous class and override the buildItem method.

1  
2  
3  
4  
5  
6  
7  
8  
BuildableItem buildableDoor = new BuildableItem() {
      public Item buildItem() {
          return new ItemDoor();
      }
}


Item item = buildableDoor.buildItem();  //  <-- This will return an ItemDoor.






Offline seismic
« Reply #4 - Posted 2013-06-19 19:15:12 »

Thank you very much. Will try it tomorrow
Offline quew8

JGO Coder


Medals: 31



« Reply #5 - Posted 2013-06-20 08:25:29 »

Just to say, an imo cleaner, neater way to do this would be for BuildableItem to store an instance of the class it describes. Then when you need a new instance, class has a newInstance() method, or even better, a getConstructor() returning a specific constructor which can be called to return an instance.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (43 views)
2014-10-16 15:22:06

Norakomi (33 views)
2014-10-16 15:20:20

lcass (38 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (86 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!