Possible to make an enum of anonymous inner classes?

I’m working on a simple game in Java, and I’ve hit a bit of a roadblock. I don’t know anything about scripting, such as using LUA, so I’m trying to think of a way to handle this. I need to add different weapons to my game, but as far as the weapon class goes, I need to make it flexible enough to handle any type of weapon… so what I was thinking of doing is to make a simple class with some general parameters, and then make an interface for it to implement that will have the functions that need to be specific.

From there, I was hoping I could create an enumerator containing anonymous inner classes. This way, I could create a separate file with mappings of IDs like “FLAMETHROWER” to an anonymous inner class where I could hard-code the effects that those weapons would display. Is this possible? If so, how could I do this?

If this isn’t possible / a good idea, what would you recommend? I can provide a link to the project on Github if you need to see the code.

Why not just go with the interface you suggested yourself, and then make classes for each weapon you want(which of course implement the weapon interface)?

Seems like a simpler approach, than trying to write an enum with anonymous inner classes. ^^

Because I want something elegant that doesn’t require writing a different class for each type of weapon. I know the alternative would be easier, but I want something customizable. Eventually, I might add the ability to script your own weapons if I can figure out how.

If you’re looking for an object model that’s expandable at runtime, e.g. through a script, you don’t want to restrict the possible instances by assigning them to enums. All the instances of an enum have to be declared up front, and the enum class can’t be subclassed or otherwise instantiated.

Enums are more for things that aren’t going to change at runtime: if you only ever deal with four compass directions for example, it makes sense to stick them in an enum (NORTH,SOUTH,EAST,WEST), since new directions aren’t going to be invented anytime soon. But if you’re making a scriptable game, chances are you’re not going to anticipate every instance of every weapon, in which case you’re probably looking for a Map<String,Weapon> instead.

Scripting is a POSSIBLE feature for the future. Right now, I’m just adding a few different weapons that will be defined at compile time, so an enum is fine… I’m just asking if it’s possible to do it the way I described, and if so, how?

If anyone has a link to a tutorial for scripting in the way I described, I’d be glad to read it.

If you’re defining all your weapons at compile-time, you could certainly go with making them enums. An Enum is a class like any other, it can have methods and fields – the latter you’d typically set through the Enum’s constructor.

As for scripting, if Lua is your bag, check out JNLua, which has its own scripting interface as well as a JSR223-compliant one. For other languages, check out javax.script and google for “JSR223 languages”

So can you show me an example of how I might attribute an ID to an anonymous inner class in an enumerator?

You can’t make anonymous enum instances. Why do you feel you need to use anonymous inner classes here? Can you describe your design in terms of what you’re actually trying to do instead of the code you want to use?

Say I have an interface for a weapon, and I want to be able to use that to define any type of weapon, not just a simple one projectile weapon. For example, if I want to define behaviors for how the projectiles act, or even what kinds of projectiles the weapon fires. I want to have an enum of defined weapon types, such as flamethrower or machine gun or shotgun, so that when I select that weapon, the program will use that behavior for the weapon.

The only problem is I don’t know how to create an enum that refers to these kinds of things.

Also, there’s the problem that I need to be able to define the weapon’s behavior very generally so I can just call this function when the weapon “fires” and it will perform the necessary functions to handle the weapon’s projectiles and graphical behavior.

So…still not getting why you have to use an enum. Do you just want a “type” of weapon behavior? If so a class should still be fine.

Because the behavior of the functions for each weapon would need to be different, hence, anonymous inner classes, where I can rewrite the functions for the weapon for each weapon.

That’s bad design in my book, having everything in one file. Can you not rewrite functions in a normal class too? Not to mention that it is much more easily reused.

This conclusion of “hence, anonymous inner classes” does not follow. You can determine different behaviors in a data-driven way, by changing the parameters of the behaviors in fields and keeping the hierarchy flat, or you can subclass and override. I don’t see a really compelling use case here for anonymous inner classes or enums. It looks to me like you’re fixating on some fairly advanced features of OO design before you have a firm grasp on the basics of polymorphism. For your initial design, just use plain old classes and write lots of subclasses, then see what you can make declarative and data-driven with fields instead of overrides. You need neither enums nor anonymous instances to make this happen.

To make this advice less abstract, start with “class Flamethrower extends Weapon”, then once you have several weapons under your belt, figure out what aspects are varying across the subclasses and what’s invariant, after which you can move to something like “Weapon flamethrower = new Weapon(DamageType.FIRE, RangeType.RANGED, …etc…)” Start with the simplest thing that actually works, then as you need more flexibility, start abstracting things.

You could use an .properties file to import the weapons script into the game eg. for flamethrower:

Weapon Name: FLAMETHROWER
Weapon Type: FIRE
Weapon Damage: x
Weapon Reload: y
Weapon Range: RANGED

You could do it like that (in the .properties file ;D).
P.S. The x and y are your variables for the weapons (Reload might not be applicable ;D)

You can’t assign derived instances to enum constants, just pass parameters to the constructor. If you design your weapon class and it’s interaction with the game carefully, this should be all you need.

What you are asking for is only achievable using the “old” static constants pattern:


class Weapon
{
    public static Weapon SHOTGUN=new Weapon(){
        (...)
    };
    public static Weapon RIFLE=new Weapon(){
        (...)
    };
    public static Weapon FLAMETHROWER=new Weapon(){
        (...)
    };
    etc.
}

Edit: stand corrected… actually I should have read the language specification before making a fool of myself: http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2 -> Example 8.9.2-4. Enum Constants with Class Bodies

As opposed to?


public enum Weapon
{
  SHOTGUN {
    (...)
  },
    
  RIFLE {
    (...)
  },
    
  FLAMETHROWER {
    (...)
  },

  (etc)
    
  ;
    
  // abstract & utility methods here  
}

Ok, nobody seems to be following me here, so here’s a code example.
Since you’ve told me I can’t bind an enum ID to an anonymous inner class the way I wanted, this is just to demonstrate what I meant.


public interface Weapon {
    public void update();
    public void draw(Graphics2D g2d);
}


public class WeaponObj implements Weapon {
    // some weapon vars, including name, image and other things not related to behavior
    // constructor initializing those vars
    @Override
    public void update() {
        // left blank, will be defined by anonymous inner class
    }
    @Override
    public void draw(Graphics2D g2d) {
        // same as above
    }
}


public enum WeaponType {
    FLAMETHROWER = new WeaponObj() {
        @Override
        public void update() {
            // update the particle vectors and positions, etc.
            // add new particles if weapon is held down
        }
        @Override
        public void draw(Graphics g2d) {
            // draw each particle in the particles list
        }
    };
    ROCKET_LAUNCHER = new WeaponObj() {
        @Override
        public void update() {
            // update positions of individual rockets fired, etc.
            // if a rocket has reached its destination or hit a target, 'explode', destroying the rocket and creating particles that shoot off in every direction to randomly chosen coordinates in a circle around the original target
        }
        @Override
        public void draw(Graphics g2d) {
            // draw each of the rockets
        }
    };
}

Now do you see what I mean by “different behavior”? That’s not something you can do with simple parameters. Or rather, it would be unnecessarily complicated.

No I couldn’t. I’m not just talking about different parameters. Each weapon would have to have a different update method. What if one weapon just shoots simple projectiles, another is a spray weapon, and another explodes and creates more particles that shoot outward when it reaches its destination?

If it helps, I also need to figure out how to create a spell system for a game with magic in the future, if that’s any indication as to the level of “customization” I need with each of these weapons.

I’m a big fan of composition/data-driven. See here for a semi-write-up for a set of schemes that deal with the possibility of many individual behaviors: http://www.java-gaming.org/topics/archtypes-composition-and-code-is-data/26554/view.html

But that’s not an example of different behaviors… that was an example of the same behavior and the class being designed to do the same thing but with different parameters. What I’m trying to do is create a different method to handle what the weapon actually does for each weapon object. This way, I can make a flamethrower create a spray of particles, whereas a machine gun would just shoot bullets really fast, or a napalm gun would fire a projectile that when it hits its target, small flame particles spread out around the impact site and burn for a short time, doing damage to any that touch it, before extinguishing.