0

I have the following GameObject interface:

public interface GameObject {
     void viewDetails();    
}

Character Interface:

interface Character{   
    void pickUp(Weapon weapon);
    void use(Weapon weapon);
}

and abstract Weapon class:

public abstract class Weapon implements GameObject {

  //left out constructor to focus on methods

   @Override
   public abstract void viewDetails();
   public abstract void attack(Enemy enemyObj);
   //Could be bullets, could be a mystical item.
   public abstract void replenish(ReplenishItem rpItem);
}

The problem with this is, a GameObject sometimes can be used in different ways. For example, the primary use of a game weapon is to attack a target, but what if I wanted to reload? How do I let my character interface reload or beware that reload is an option?

  • It's unclear how implementations of `Character` will interact with your `Weapon` class - what does the `use()` method do? –  May 05 '17 at 13:53
  • @patrick-hainge - Like I said, attack a target, but Weapon could also be reloaded, how would I restructure it? So that my character interfaces knows this? –  May 05 '17 at 13:58
  • What else implements `GameObject` in your program? –  May 05 '17 at 13:59
  • 2
    I think it is better to redesign your hierarchy of classes/interfaces to make a set of more specific classes/interfaces rather than having one general purpose interface. For example: `Armament`, `Food`, `Potion`, etc etc. –  May 05 '17 at 14:00
  • @patrick-hainge - Everything, not just weapons. Which means I have to get more specific –  May 05 '17 at 14:00
  • @RafaelOsipov - Take the example code above, how would you restructure it, so that Character is aware that a Weapon has two functions? –  May 05 '17 at 14:01
  • @Nexusfactor I will respond to your question later today. Now I have some urgent things to do. –  May 05 '17 at 14:13
  • Similar to your GameObject interface, I would add a Reloadable interface, then implement that interface in whatever weapons would need it. Character can then check through instanceof whether the Weapon is Reloadable – Lewis_McReu May 05 '17 at 14:20
  • @Lewis_McReu - is instanceOf okay to use outside of equals method? I've read you should avoid that if you can. –  May 05 '17 at 14:23
  • It's true that use of instanceof isn't recommended. An alternative would be to implement a reload method in Weapon, without any actions, and override it in the relevant subclasses. That way Character can always call reload(), without having to worry about it being relevant. – Lewis_McReu May 05 '17 at 14:30

1 Answers1

0

I would use the following approach.

I would declare interfaces:

interface MeleeWeapon {
    void hit();
    void cut();
}

interface FirearmWeapon {
   void fire();
   void reload();
}

interface MagicWeapon {
   void throw();
   void apply();
   void recharge();
}

Then implement classes, like these:

class Knife implements MeleeWeapon {
     public void hit() {

     } 

     public void cut() {

     } 
}

class Dagger implements MeleeWeapon {
     public void hit() {

     } 

     public void cut() {

     }     
}

class GarandRifle implements FirearmWeapon {
     public void fire() {

     } 

     public void reload() {

     }     
}

class Fireball implements MagicWeapon {
     public void throw() {

     } 

     public void apply() {

     }     

     public void recharge() {

     }     
}

Then, I would declare these interfaces:

interface MeleeWeaponUser {
    void use(MeleeWeapon weapon);
}

interface  FirearmWeaponUser {
    void use(FirearmWeapon weapon);
}

interface MagicWeaponUser {
    void use(MagicWeapon weapon);
}

And, I would declare character classes:

class Peasant implements MeleeWeaponUser {
    public void use(MeleeWeapon weapon) {

    }
}

class Marine implements MeleeWeaponUser, FirearmWeaponUser {
    public void use(FirearmWeapon weapon) {

    }

    public  void use(MeleeWeapon weapon) {

    }
}

class Sorcerer implements MeleeWeaponUser, MagicWeaponUser {
    public  void use(MeleeWeapon weapon) {

    }

    public  void use(MagicWeapon weapon) {

    }
}

This approach let us add new weapons and characters without sufficient effort later.

In your use() method you can call reload() if there is no more ammo in the weapon dispenser.

But if your game character receives signal from outside, for example, reload the gun, even there is enough ammo to fire, then have an Event->Listener approach implemented.

Create a WeaponEvent class, extend this class to have FirearmWeaponEvent, MeleeWeaponEvent etc.

Make your game character class(es) as a listener to WeaponEvent events, then in your game character class have a method processEvent(WeaponEvent event), and act accordingly to the event you have received.

Community
  • 1
  • 1
  • In the use method for Marine, how would I be able to call the reload method, if I wanted to reload my gun? –  May 08 '17 at 22:53
  • @Nexusfactor I've edited my answer and added more infos. –  May 09 '17 at 09:05