RPG Game System with Interfaces and Inheritance
Complete game system demonstrating interfaces, abstract classes, inheritance, and polymorphism
classDiagram
class Movable {
<<interface>>
+goUp(int speed) void
+goDown(int speed) void
+goRight(int speed) void
+goLeft(int speed) void
}
class Attacker {
<<interface>>
+attack(target) void
}
class DistantAttacker {
<<interface>>
+distantAttack(target, int) void
}
class Flying {
<<interface>>
+takeOff() boolean
+land() boolean
}
class Adopt {
<<interface>>
+adopt(candidate MovableBeing) boolean
+revoke(candidate Object) boolean
}
class SpacialElement {
#String name
#int x
#int y
+SpacialElement(String name, int x, int y)
}
class Being {
-int maxHealth
#int health
#double resistance
+receiveDamage(int amount) void
+getLuckLevel() int
}
class MovableBeing {
<<abstract>>
#int maxSpeed
#int force
#boolean inAir
+canMove(String direction) boolean
+communicate() void
}
class Humanoid {
<<abstract>>
}
class Animal {
<<abstract>>
+getMaxSpeed() int
}
class Pack {
-int maxSize
+String name
+Pack(MovableBeing chief)
+isInPack(Object being) boolean
}
class Warrior {
}
class Archer {
+int range
+int dexterity
}
class Dragon {
-int power
+int range
}
class Eagle {
+int vision
}
class Wolf {
}
class Tree {
}
class Rock {
}
class Map {
+String$ WIDTH
+String$ HEIGHT
+add(SpacialElement element) void
}
class Exporter {
+serialize(Object map, String path) void
+deserialize(String path) Object
-filter(Object m) void
}
SpacialElement ..|> Movable
Being --|> SpacialElement
MovableBeing --|> Being
MovableBeing ..|> Attacker
MovableBeing ..|> Movable
Humanoid --|> MovableBeing
Animal --|> MovableBeing
Warrior --|> Humanoid
Archer --|> Humanoid
Archer ..|> DistantAttacker
Dragon --|> Animal
Dragon ..|> Flying
Dragon ..|> DistantAttacker
Eagle --|> Animal
Eagle ..|> Flying
Wolf --|> Animal
Tree --|> Being
Rock --|> SpacialElement
Pack --|> SpacialElement
Pack ..|> Adopt
Pack ..|> Movable
Pack ..|> Attacker
Pack "0..1" --> "1..*" MovableBeing : contains
Pack "0..1" --> "1" MovableBeing : chief
Map "1" --> "0..*" SpacialElement
SpacialElement (Base Class)
Section titled “SpacialElement (Base Class)”Base class for all elements that exist in the game world.
- name: Name of the element (protected)
- x: X coordinate on the map (protected)
- y: Y coordinate on the map (protected)
- SpacialElement(String name, int x, int y): Constructor to place element at coordinates
- Implements
Movableinterface - All game elements inherit from this class
Movable (Interface)
Section titled “Movable (Interface)”Interface for elements that can move in four directions.
- goUp(int speed): Move up by speed units
- goDown(int speed): Move down by speed units
- goRight(int speed): Move right by speed units
- goLeft(int speed): Move left by speed units
Attacker (Interface)
Section titled “Attacker (Interface)”Interface for entities that can attack.
- attack(target): Attack a target entity
DistantAttacker (Interface)
Section titled “DistantAttacker (Interface)”Interface for entities that can attack from a distance.
- distantAttack(target, int): Attack a target from distance with range parameter
Flying (Interface)
Section titled “Flying (Interface)”Interface for entities that can fly.
- takeOff(): Take off from ground, returns success status
- land(): Land on ground, returns success status
Adopt (Interface)
Section titled “Adopt (Interface)”Interface for entities that can adopt other beings (like packs).
- adopt(candidate MovableBeing): Adopt a movable being into the group, returns success
- revoke(candidate Object): Remove a being from the group, returns success
Living entity with health and resistance.
- maxHealth: Maximum health points (private)
- health: Current health points (protected)
- resistance: Damage resistance (protected)
- Extends
SpacialElement - receiveDamage(int amount): Reduces health by damage minus resistance
- getLuckLevel(): Returns a luck value affecting outcomes
- Base class for all living entities
MovableBeing (Abstract Class)
Section titled “MovableBeing (Abstract Class)”Abstract base class for all creatures that can move and fight.
- maxSpeed: Maximum movement speed (protected)
- force: Attack strength (protected)
- inAir: Whether the being is currently airborne (protected)
- Extends
Being - Implements
AttackerandMovableinterfaces - canMove(String direction): Checks if movement in direction is possible
- communicate(): Makes sounds or communicates with others
- Cannot be instantiated directly
Humanoid (Abstract Class)
Section titled “Humanoid (Abstract Class)”Abstract base class for human-like creatures.
- Extends
MovableBeing - No additional attributes or methods in base form
- Template for warrior, archer, wizard types
- Cannot be instantiated directly
Animal (Abstract Class)
Section titled “Animal (Abstract Class)”Abstract base class for animal creatures.
- Extends
MovableBeing - getMaxSpeed(): Returns maximum speed (animals tend to be fast)
- Template for dragons, eagles, wolves, etc.
- Cannot be instantiated directly
Group of creatures that moves and acts together.
- maxSize: Maximum number of members (private)
- name: Name of the pack (public)
- Extends
SpacialElement - Implements
Adopt,Movable, andAttackerinterfaces - Pack(MovableBeing chief): Creates pack with a leader
- isInPack(Object being): Checks if a being is member of this pack
- Contains 1 or more
MovableBeingmembers - Has exactly 1 chief (leader)
- Pack moves as a unit and can attack as a group
Warrior
Section titled “Warrior”Melee fighter class.
- Extends
Humanoid - No special attributes beyond inherited ones
- Strong in close combat
Archer
Section titled “Archer”Ranged attacker with bow and arrows.
- range: Maximum attack range (public)
- dexterity: Skill level with ranged weapons (public)
- Extends
Humanoid - Implements
DistantAttackerinterface - Can attack from distance
Dragon
Section titled “Dragon”Powerful flying creature with breath weapon.
- power: Attack power multiplier (private)
- range: Distance of breath attack (public)
- Extends
Animal - Implements
FlyingandDistantAttackerinterfaces - Can fly and attack from distance with breath weapon
Flying bird of prey.
- vision: Range of sight (public)
- Extends
Animal - Implements
Flyinginterface - High speed and vision, can fly
Ground-based pack animal.
- Extends
Animal - No special attributes
- Typically part of a Pack
Static vegetation obstacle.
- Extends
Being(has health, can be damaged/destroyed) - No movement or attack capabilities
- Blocks movement
Static terrain obstacle.
- Extends
SpacialElement(not Being - cannot be damaged) - No health or combat properties
- Permanent obstacle
Game world that contains all spatial elements.
- WIDTH: Map width in tiles (static public constant)
- HEIGHT: Map height in tiles (static public constant)
- add(SpacialElement element): Adds element to the map
- Maintains collection of all elements in the game world
Exporter
Section titled “Exporter”Utility for saving and loading game state.
- serialize(Object map, String path): Saves map to file
- deserialize(String path): Loads map from file, returns Map object
- filter(Object m): Private method to filter elements before export
Practice Exercise: Implement the RPG Game System
Section titled “Practice Exercise: Implement the RPG Game System”Objective: Implement the complete game system matching the UML diagram precisely.
Requirements:
- Create all 5 interfaces:
Movable,Attacker,DistantAttacker,Flying,Adopt - Create base class
SpacialElementimplementingMovable - Create
BeingextendingSpacialElementwith health system - Create abstract
MovableBeingextendingBeingand implementingAttackerandMovable - Create abstract
HumanoidandAnimalclasses - Implement all concrete classes:
Warrior,Archer,Dragon,Eagle,Wolf,Tree,Rock,Pack - Implement
MapandExporterutility classes - Demonstrate polymorphism with pack mechanics
💡 Click to see suggested implementation
// Movable interfacepublic interface Movable { void goUp(int speed); void goDown(int speed); void goRight(int speed); void goLeft(int speed);}
// Attacker interfacepublic interface Attacker { void attack(Object target);}
// DistantAttacker interfacepublic interface DistantAttacker { void distantAttack(Object target, int range);}
// Flying interfacepublic interface Flying { boolean takeOff(); boolean land();}
// Adopt interfacepublic interface Adopt { boolean adopt(MovableBeing candidate); boolean revoke(Object candidate);}
// SpacialElement base classpublic class SpacialElement implements Movable { protected String name; protected int x; protected int y;
public SpacialElement(String name, int x, int y) { this.name = name; this.x = x; this.y = y; }
@Override public void goUp(int speed) { y -= speed; }
@Override public void goDown(int speed) { y += speed; }
@Override public void goRight(int speed) { x += speed; }
@Override public void goLeft(int speed) { x -= speed; }
public String getName() { return name; } public int getX() { return x; } public int getY() { return y; }}
// Being classpublic class Being extends SpacialElement { private int maxHealth; protected int health; protected double resistance;
public Being(String name, int x, int y, int maxHealth, double resistance) { super(name, x, y); this.maxHealth = maxHealth; this.health = maxHealth; this.resistance = resistance; }
public void receiveDamage(int amount) { int actualDamage = (int) (amount - resistance); if (actualDamage > 0) { health -= actualDamage; if (health < 0) health = 0; } System.out.println(name + " received " + actualDamage + " damage. HP: " + health); }
public int getLuckLevel() { return (int) (Math.random() * 10); // Random luck 0-9 }
public int getHealth() { return health; } public boolean isAlive() { return health > 0; }}
// MovableBeing abstract classpublic abstract class MovableBeing extends Being implements Attacker { protected int maxSpeed; protected int force; protected boolean inAir;
public MovableBeing(String name, int x, int y, int health, double resistance, int force) { super(name, x, y, health, resistance); this.force = force; this.maxSpeed = 5; this.inAir = false; }
public boolean canMove(String direction) { return isAlive(); // Can only move if alive }
public void communicate() { System.out.println(name + " communicates!"); }
// Abstract attack method - each type implements differently @Override public abstract void attack(Object target);
public int getForce() { return force; }}
// Humanoid abstract classpublic abstract class Humanoid extends MovableBeing { public Humanoid(String name, int x, int y) { super(name, x, y, 100, 5.0, 15); // Standard humanoid stats }}
// Animal abstract classpublic abstract class Animal extends MovableBeing { public Animal(String name, int x, int y, int health, double resistance, int force) { super(name, x, y, health, resistance, force); this.maxSpeed = 8; // Animals tend to be faster }
public int getMaxSpeed() { return maxSpeed; }}
// Warrior classpublic class Warrior extends Humanoid { public Warrior(String name, int x, int y) { super(name, x, y); this.force = 20; // Warriors are strong }
@Override public void attack(Object target) { if (target instanceof Being && isAlive()) { System.out.println(name + " attacks with sword!"); ((Being) target).receiveDamage(force); } }}
// Archer classpublic class Archer extends Humanoid implements DistantAttacker { public int range; public int dexterity;
public Archer(String name, int x, int y) { super(name, x, y); this.range = 10; this.dexterity = 15; this.force = 12; }
@Override public void attack(Object target) { if (target instanceof Being && isAlive()) { System.out.println(name + " shoots arrow!"); ((Being) target).receiveDamage(force); } }
@Override public void distantAttack(Object target, int distance) { if (target instanceof Being && isAlive() && distance <= range) { int damage = force + dexterity / 2; System.out.println(name + " shoots from distance " + distance + "!"); ((Being) target).receiveDamage(damage); } }}
// Dragon classpublic class Dragon extends Animal implements Flying, DistantAttacker { private int power; public int range;
public Dragon(String name, int x, int y) { super(name, x, y, 200, 15.0, 30); this.power = 40; this.range = 15; }
@Override public boolean takeOff() { if (!inAir) { inAir = true; System.out.println(name + " takes off!"); return true; } return false; }
@Override public boolean land() { if (inAir) { inAir = false; System.out.println(name + " lands!"); return true; } return false; }
@Override public void attack(Object target) { if (target instanceof Being && isAlive()) { System.out.println(name + " breathes fire!"); ((Being) target).receiveDamage(power); } }
@Override public void distantAttack(Object target, int distance) { if (target instanceof Being && isAlive() && distance <= range) { System.out.println(name + " breathes fire from distance!"); ((Being) target).receiveDamage(power + 10); } }}
// Eagle classpublic class Eagle extends Animal implements Flying { public int vision;
public Eagle(String name, int x, int y) { super(name, x, y, 50, 2.0, 8); this.vision = 20; }
@Override public boolean takeOff() { if (!inAir) { inAir = true; System.out.println(name + " soars into the sky!"); return true; } return false; }
@Override public boolean land() { if (inAir) { inAir = false; System.out.println(name + " lands gracefully!"); return true; } return false; }
@Override public void attack(Object target) { if (target instanceof Being && isAlive()) { System.out.println(name + " dives and strikes!"); ((Being) target).receiveDamage(force); } }}
// Wolf classpublic class Wolf extends Animal { public Wolf(String name, int x, int y) { super(name, x, y, 80, 3.0, 12); }
@Override public void attack(Object target) { if (target instanceof Being && isAlive()) { System.out.println(name + " bites!"); ((Being) target).receiveDamage(force); } }
@Override public void communicate() { System.out.println(name + " howls!"); }}
// Tree classpublic class Tree extends Being { public Tree(String name, int x, int y) { super(name, x, y, 100, 0.0); }
@Override public void goUp(int speed) { System.out.println("Trees cannot move!"); }
@Override public void goDown(int speed) { System.out.println("Trees cannot move!"); }
@Override public void goRight(int speed) { System.out.println("Trees cannot move!"); }
@Override public void goLeft(int speed) { System.out.println("Trees cannot move!"); }}
// Rock classpublic class Rock extends SpacialElement { public Rock(String name, int x, int y) { super(name, x, y); }
@Override public void goUp(int speed) { System.out.println("Rocks cannot move!"); }
@Override public void goDown(int speed) { System.out.println("Rocks cannot move!"); }
@Override public void goRight(int speed) { System.out.println("Rocks cannot move!"); }
@Override public void goLeft(int speed) { System.out.println("Rocks cannot move!"); }}
// Pack classimport java.util.ArrayList;import java.util.List;
public class Pack extends SpacialElement implements Adopt, Attacker { private int maxSize; public String name; private MovableBeing chief; private List<MovableBeing> members;
public Pack(MovableBeing chief) { super("Pack of " + chief.getName(), chief.getX(), chief.getY()); this.chief = chief; this.maxSize = 10; this.members = new ArrayList<>(); this.members.add(chief); this.name = "Pack"; }
@Override public boolean adopt(MovableBeing candidate) { if (members.size() < maxSize && !members.contains(candidate)) { members.add(candidate); System.out.println(candidate.getName() + " joined the pack!"); return true; } return false; }
@Override public boolean revoke(Object candidate) { if (candidate instanceof MovableBeing && candidate != chief) { boolean removed = members.remove(candidate); if (removed) { System.out.println(((MovableBeing) candidate).getName() + " left the pack!"); } return removed; } return false; }
public boolean isInPack(Object being) { return members.contains(being); }
@Override public void attack(Object target) { System.out.println("Pack attacks together!"); for (MovableBeing member : members) { member.attack(target); } }
@Override public void goUp(int speed) { super.goUp(speed); for (MovableBeing member : members) { member.goUp(speed); } }
@Override public void goDown(int speed) { super.goDown(speed); for (MovableBeing member : members) { member.goDown(speed); } }
@Override public void goRight(int speed) { super.goRight(speed); for (MovableBeing member : members) { member.goRight(speed); } }
@Override public void goLeft(int speed) { super.goLeft(speed); for (MovableBeing member : members) { member.goLeft(speed); } }
public MovableBeing getChief() { return chief; } public List<MovableBeing> getMembers() { return new ArrayList<>(members); }}
// Map classimport java.util.ArrayList;import java.util.List;
public class Map { public static final String WIDTH = "100"; public static final String HEIGHT = "100"; private List<SpacialElement> elements;
public Map() { this.elements = new ArrayList<>(); }
public void add(SpacialElement element) { elements.add(element); System.out.println("Added " + element.getName() + " to map at (" + element.getX() + ", " + element.getY() + ")"); }
public List<SpacialElement> getElements() { return new ArrayList<>(elements); }}
// Exporter classimport java.io.*;
public class Exporter { public void serialize(Object map, String path) { try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path))) { out.writeObject(filter(map)); System.out.println("Map exported to " + path); } catch (IOException e) { System.err.println("Export failed: " + e.getMessage()); } }
public Object deserialize(String path) { try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(path))) { Object map = in.readObject(); System.out.println("Map imported from " + path); return map; } catch (IOException | ClassNotFoundException e) { System.err.println("Import failed: " + e.getMessage()); return null; } }
private Object filter(Object m) { // Filter out temporary or invalid elements before export return m; }}
// Game demopublic class RPGGameDemo { public static void main(String[] args) { System.out.println("=== RPG Game System Demo ===\n");
// Create map Map gameMap = new Map();
// Add terrain gameMap.add(new Tree("Oak", 10, 10)); gameMap.add(new Rock("Boulder", 15, 15));
// Create characters Warrior warrior = new Warrior("Aragorn", 5, 5); Archer archer = new Archer("Legolas", 7, 5); Dragon dragon = new Dragon("Smaug", 50, 50); Eagle eagle = new Eagle("Gwaihir", 60, 5);
gameMap.add(warrior); gameMap.add(archer); gameMap.add(dragon); gameMap.add(eagle);
// Create wolf pack Wolf alpha = new Wolf("Alpha", 20, 20); Wolf beta = new Wolf("Beta", 21, 20); Wolf gamma = new Wolf("Gamma", 20, 21);
Pack wolfPack = new Pack(alpha); wolfPack.adopt(beta); wolfPack.adopt(gamma); gameMap.add(wolfPack);
System.out.println("\n=== Combat Demo ===");
// Warrior attacks dragon warrior.attack(dragon);
// Archer uses distant attack archer.distantAttack(dragon, 8);
// Dragon flies and attacks dragon.takeOff(); dragon.distantAttack(warrior, 10); dragon.land();
// Pack attacks together System.out.println("\nWolf pack attacks:"); wolfPack.attack(warrior);
// Eagle flies eagle.takeOff(); eagle.attack(gamma);
System.out.println("\n=== Movement Demo ==="); System.out.println("Pack position: (" + wolfPack.getX() + ", " + wolfPack.getY() + ")"); wolfPack.goRight(3); System.out.println("Pack moved to: (" + wolfPack.getX() + ", " + wolfPack.getY() + ")");
System.out.println("\n=== Pack Info ==="); System.out.println("Pack members: " + wolfPack.getMembers().size()); System.out.println("Pack chief: " + wolfPack.getChief().getName()); }}Key Implementation Points:
SpacialElementis the base class for ALL game elementsBeingextendsSpacialElementand adds health/resistanceMovableBeingis abstract and implements bothAttackerand inheritsMovableHumanoidandAnimalare abstract templatesPackextendsSpacialElement(notBeing) and implements 3 interfacesTreeextendsBeing(can be damaged) butRockextendsSpacialElement(indestructible)- Static constants in
Mapare public Strings - Multiple interface implementation shown (Dragon, Archer, Pack)
- Pack contains and moves members together
- Protected members allow subclass access

