Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (472)
Games in Android Showcase (105)
games submitted by our members
Games in WIP (524)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Possible to make an enum of anonymous inner classes?  (Read 3796 times)
0 Members and 1 Guest are viewing this topic.
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Posted 2012-12-05 20:06:25 »

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.
Offline Regenuluz
« Reply #1 - Posted 2012-12-05 20:15:10 »

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. ^^
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #2 - Posted 2012-12-05 20:16:54 »

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.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproingie

JGO Kernel


Medals: 201



« Reply #3 - Posted 2012-12-05 20:18:49 »

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.

Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #4 - Posted 2012-12-05 20:22:55 »

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.
Offline sproingie

JGO Kernel


Medals: 201



« Reply #5 - Posted 2012-12-05 20:30:01 »

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"

Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #6 - Posted 2012-12-05 21:27:13 »

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

JGO Kernel


Medals: 201



« Reply #7 - Posted 2012-12-05 22:20:10 »

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?
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #8 - Posted 2012-12-05 22:27:42 »

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.
Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 128
Projects: 4
Exp: 3 years



« Reply #9 - Posted 2012-12-06 05:01:43 »

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.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #10 - Posted 2012-12-06 05:26:27 »

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.
Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 128
Projects: 4
Exp: 3 years



« Reply #11 - Posted 2012-12-06 05:32:25 »

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.
Offline sproingie

JGO Kernel


Medals: 201



« Reply #12 - Posted 2012-12-06 05:57:52 »

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.

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.
Offline masteryoom

JGO Coder


Medals: 5
Projects: 2


If you look closely, you might see it turning...


« Reply #13 - Posted 2012-12-06 07:16:01 »

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 Grin).
P.S. The x and y are your variables for the weapons (Reload might not be applicable Grin)

Smiley
Offline cylab

JGO Knight


Medals: 38



« Reply #14 - Posted 2012-12-06 10:00:20 »

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:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
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

Mathias - I Know What [you] Did Last Summer!
Offline Roquen
« Reply #15 - Posted 2012-12-06 10:09:12 »

As opposed to?
 
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
public enum Weapon
{
  SHOTGUN {
    (...)
  },
   
  RIFLE {
    (...)
  },
   
  FLAMETHROWER {
    (...)
  },

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

 
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #16 - Posted 2012-12-06 15:06:08 »

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.

1  
2  
3  
4  
public interface Weapon {
    public void update();
    public void draw(Graphics2D g2d);
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
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
   }
}


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 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.
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #17 - Posted 2012-12-06 15:12:33 »

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 Grin).
P.S. The x and y are your variables for the weapons (Reload might not be applicable Grin)

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.
Offline Roquen
« Reply #18 - Posted 2012-12-06 15:28:16 »

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
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #19 - Posted 2012-12-06 15:48:42 »

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.
Offline PaulCunningham

Junior Member


Medals: 2



« Reply #20 - Posted 2012-12-06 15:48:49 »

I'm working on a simple game in Java...

So make a simple weapon system.

*Disclaimer* I'm no Java guy but I'd do...

IWeapon {
    Some behaviours here like shoot or load, etc
}

Weapon : IWeapon {
    Some common functions for all weapons

  //virtual shoot() : spawn a simple bullet based on some data file (speed, effect, sound, damage)
}

//Weapons are data driven
standardWeapon = new Weapon(DATA FOR THE WEAPON)
flamerWeapon = new Weapon(DATA FOR THE WEAPON)

//Only need a sub class when BEHAVIOUR is different
ShotgunWeapon : Weapon {
  //Override shoot() to spawn x many bullets in an arc - randomise pellet speed
}

Something::setWeapon(IWeapon newWeapon) {
   etc
}
Offline Roquen
« Reply #21 - Posted 2012-12-06 16:09:42 »

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.
Ah, but it is.  Parametrizing a single effect type was simply an example.
Offline saifix

Senior Newbie


Medals: 1



« Reply #22 - Posted 2012-12-06 16:12:44 »

If I understand correctly, you want to be able to define various types of weapons and new behaviors for them at runtime? If so you could do something like below.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
interface Weapon {
    void fire(...);
 
    void reload(...);
}

class DefaultWeapon implements Weapon {
   
    private final WeaponMetaData meta;

    public DefaultWeapon(WeaponMetaData data /* type specific data such as bullet style, speed, etc. */) { this.meta = data; }

    void fire(...) {
    } // fire off a single bullet for default behavior

    void reload(...) {
    }
}

class FlamethrowerWeaponImpl extends DefaultWeapon {
 
    public FlamethrowerWeaponImpl(WeaponMetaData meta) {
        super(meta);
    }  

    @Override
    void fire(...) {
    } //do what has to be done for a specialized implementation.
}

This way you can create specialized implementations for weapons that don't follow the standard "spawn an accelerated particle" behavior.
1  
2  
3  
static Weapon PISTOL = new DefaultWeapon(pistolMetaData);
static Weapon RIFLE = new DefaultWeapon(rifleMetaData);
static Weapon FLAMETHROWER = new FlamethrowerWeaponImpl(flamethrowerMetaData);
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #23 - Posted 2012-12-06 16:44:38 »

If I understand correctly, you want to be able to define various types of weapons and new behaviors for them at runtime? If so you could do something like below.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
interface Weapon {
    void fire(...);
 
    void reload(...);
}

class DefaultWeapon implements Weapon {
   
    private final WeaponMetaData meta;

    public DefaultWeapon(WeaponMetaData data /* type specific data such as bullet style, speed, etc. */) { this.meta = data; }

    void fire(...) {
    } // fire off a single bullet for default behavior

    void reload(...) {
    }
}

class FlamethrowerWeaponImpl extends DefaultWeapon {
 
    public FlamethrowerWeaponImpl(WeaponMetaData meta) {
        super(meta);
    }  

    @Override
    void fire(...) {
    } //do what has to be done for a specialized implementation.
}

This way you can create specialized implementations for weapons that don't follow the standard "spawn an accelerated particle" behavior.
1  
2  
3  
static Weapon PISTOL = new DefaultWeapon(pistolMetaData);
static Weapon RIFLE = new DefaultWeapon(rifleMetaData);
static Weapon FLAMETHROWER = new FlamethrowerWeaponImpl(flamethrowerMetaData);


Well at least you get it... but the whole point of this was I don't want to have to create 20 different classes for 20 different weapon types. Meanwhile, everyone else still thinks I mean I want different parameters to define damage, speed, etc...
Offline saifix

Senior Newbie


Medals: 1



« Reply #24 - Posted 2012-12-06 16:51:58 »

If I understand correctly, you want to be able to define various types of weapons and new behaviors for them at runtime? If so you could do something like below.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
interface Weapon {
    void fire(...);
 
    void reload(...);
}

class DefaultWeapon implements Weapon {
   
    private final WeaponMetaData meta;

    public DefaultWeapon(WeaponMetaData data /* type specific data such as bullet style, speed, etc. */) { this.meta = data; }

    void fire(...) {
    } // fire off a single bullet for default behavior

    void reload(...) {
    }
}

class FlamethrowerWeaponImpl extends DefaultWeapon {
 
    public FlamethrowerWeaponImpl(WeaponMetaData meta) {
        super(meta);
    }  

    @Override
    void fire(...) {
    } //do what has to be done for a specialized implementation.
}

This way you can create specialized implementations for weapons that don't follow the standard "spawn an accelerated particle" behavior.
1  
2  
3  
static Weapon PISTOL = new DefaultWeapon(pistolMetaData);
static Weapon RIFLE = new DefaultWeapon(rifleMetaData);
static Weapon FLAMETHROWER = new FlamethrowerWeaponImpl(flamethrowerMetaData);


Well at least you get it... but the whole point of this was I don't want to have to create 20 different classes for 20 different weapon types. Meanwhile, everyone else still thinks I mean I want different parameters to define damage, speed, etc...

The only cases which you would need to define a different class is if you need a weapon which implements non-standard behavior (standard defined as whatever is in DefaultWeapon.) What the others were saying is that if you feed the default implementation enough data then you won't need to create specialized implementations. For example, I have a class named DefaultWeapon which fires a single shot and a specialized implementation named SpreadShotWeapon. I can eliminate the need for SpreadShotWeapon type if I introduce three new parameters: angle, particle count and shot type.
Offline PaulCunningham

Junior Member


Medals: 2



« Reply #25 - Posted 2012-12-06 16:52:03 »

Well at least you get it... but the whole point of this was I don't want to have to create 20 different classes for 20 different weapon types. Meanwhile, everyone else still thinks I mean I want different parameters to define damage, speed, etc...

You don't have to create 20 different classes - you only create a NEW CLASS when you need BEHAVIOUR that is different.
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #26 - Posted 2012-12-06 17:12:35 »

Well at least you get it... but the whole point of this was I don't want to have to create 20 different classes for 20 different weapon types. Meanwhile, everyone else still thinks I mean I want different parameters to define damage, speed, etc...

You don't have to create 20 different classes - you only create a NEW CLASS when you need BEHAVIOUR that is different.

Right, but the amount of classes I'll need is equivalent to the number of uniquely different weapons, which is a lot, considering the behavior of a machine gun, flamethrower, rocket launcher, and shotgun are all different. Besides... how do you know how many different weapon types I'll have?
Offline Icecore

Senior Member


Medals: 5



« Reply #27 - Posted 2012-12-06 17:15:56 »

Try do components object : (crazy and flexible ^^)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
   class Bullet_Dmg implements Bulet_Procces {
      int Dmg;  
      public Bullet_Dmg(int dmg){
         Dmg = dmg;
      }
     
       @Override
        public void update(){
          if(bulet hit do damage)
        }
       public Bullet_Dmg set_Dmg(int dmg){Dmg = dmg;return this;}
   }
   class Bullet_Heal implements Bulet_Procces {}
   class Bullet_Time_Explode implements Bulet_Procces {}
   
   class Weapon_Pistrol_Graphics implements Weapon_Graphics {
        @Override
        public void draw(Graphics g2d) {
            // draw each particle in the particles list
       }
   }
   class WeaponObj{
      Bulet_Procces proc;
      Weapon_Graphics graph;
     
      public WeaponObj(Bulet_Procces Proc, Weapon_Graphics Gra(){
         proc = Proc;
         graph = Gra;
      }
        public void draw(Graphics g2d){
           graph.draw(g2d);
        }
        public void update(){
           proc.update();
        }
     
      public WeaponObj set_New_Proc(Bulet_Procces Proc){proc = Proc; return this;}
   }
   
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  Bullet_Dmg pistol_Bullet = new Bullet_Dmg(10);
   Weapon_Pistrol_Graphics pistol_GR = new Weapon_Pistrol_Graphics();
   
   WeaponObj pistol = new WeaponObj(pistol_Bullet, pistol_GR);
   
   Bullet_Heal pistol_Bullet_2 = new Bullet_Heal(30);
   pistol.set_New_Proc(pistol_Bullet_2);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
Offline PaulCunningham

Junior Member


Medals: 2



« Reply #28 - Posted 2012-12-06 17:20:06 »

Right, but the amount of classes I'll need is equivalent to the number of uniquely different weapons, which is a lot, considering the behavior of a machine gun, flamethrower, rocket launcher, and shotgun are all different.

Not necessarily. If the standard weapon behaviour is to fire (a) number of (b) projectiles, in an arc from -(c) to +(c) radians with a reload factor of (d) milliseconds then they'd all have the same BEHAVIOUR wouldn't they. But your data would be different - that is the point.
Offline packetpirate

Junior Member


Medals: 1
Projects: 1



« Reply #29 - Posted 2012-12-06 17:21:14 »

I already know HOW to make an anonymous inner class to implement the weapons the way I want... the only reason I asked this was to determine if I could somehow put the declarations for these in a separate file and be able to just import them and use an ID to refer to the object without cluttering up my main code.
Pages: [1] 2
  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.

Riven (17 views)
2014-07-10 20:20:18

CopyableCougar4 (20 views)
2014-07-10 02:26:14

CopyableCougar4 (27 views)
2014-07-09 02:55:38

Code Mage (27 views)
2014-07-08 23:57:00

Code Mage (13 views)
2014-07-08 23:49:08

AppleSauce (22 views)
2014-07-08 19:25:32

CopyableCougar4 (23 views)
2014-07-06 01:51:26

ipe369 (28 views)
2014-07-05 14:18:25

vastrolorde (39 views)
2014-07-04 18:45:44

theagentd (56 views)
2014-07-02 22:19:37
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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!