Interfaces to allow unit’s ability to attack ground, air, or both in Java using Design Patterns

Im making a text game that has an abstract Fighter class. within Fighter I have a variable called protected boolean isGround. then I have 2 abstract classes that extend Fighter called AirFighter and GroundFighter that basically set that isGround to be True or False, depending on if they are ground units or not.

I then want to set up the game so that in my battle phase the game checks if player 1’s speed is faster then player 2, and depending on who is faster to then do like p1.attack(p2), and print out the stats of that battle, like the remaining health of each player or something like that.

I want a way for some airFighters to attack air, or attack air and ground, and I want some groundFighters to attack ground only, or ground and air. How would I go about doing this while staying loosely coupled? It is for a design pattern’s class and its frustrating me. Is there a design pattern to help me with this?

Think of the game starcraft, that’s basically what my game is mimicing, certain units like a marine can attack ground and air, some air units can only attack air, some can do both. I want to be able to do this without having some nasty if else checking statement.

Answer

An easy way to do this is to have a method in the base Fighter that can be used to check if that Fighter can attack another:

public abstract class Fighter {
    public abstract boolean isGround ();
    public abstract boolean canAttack (Fighter target);
}

Subclasses can then override canAttack and make an appropriate decision. For example:

public class SurfaceToAirLauncher extends Fighter {
    @Override public boolean isGround () {
        // missile launcher is on the ground
        return true; 
    }
    @Override public boolean canAttack (Fighter target) {
        // we can only attack air targets
        return (target != null && !target.isGround());
    }
}

public class Dragon extends Fighter {
    @Override public boolean isGround () {
        // dragons are in the air
        return false; 
    }
    @Override public boolean canAttack (Fighter target) {
        // dragons can attack every target.
        return (target != null);
    }
}

public class Knight extends Fighter {
    @Override public boolean isGround () {
        // knights are on the ground
        return true; 
    }
    @Override public boolean canAttack (Fighter target) {
        // knights can only attack dragons
        return (target != null && target instanceof Dragon);
    }
}

You could remove the check for null if you know target will never be null. I included it for completeness.

Leave a Reply

Your email address will not be published. Required fields are marked *