matin mortazavi
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
# ⚔️ Java RPG Game
|
||||
|
||||
A text-based role‑playing game built in Java, demonstrating core Object‑Oriented Programming principles such as inheritance, polymorphism, interfaces, abstraction, and encapsulation.
|
||||
|
||||
The player chooses a hero (Knight, Wizard, or Assassin), equips weapons and armour, and battles various enemies (Skeleton, Vampire, Goblin) in a simple turn‑based loop. Locations and consumable items are also partially implemented.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Project Structure
|
||||
---
|
||||
|
||||
## 🎮 Gameplay Overview
|
||||
|
||||
1. Character Selection – Enter your name, pick a class (Assassin, Wizard, Knight), choose a weapon and armour.
|
||||
2. Combat Loop – You face random enemies from a list. Each turn you can:
|
||||
- Light Attack
|
||||
- Heavy Attack (normal attack)
|
||||
- Defend
|
||||
- Heal
|
||||
- Use Special Ability
|
||||
3. Enemy AI – Enemies randomly choose between light and heavy attacks. Some enemies (e.g. Goblin) have special behaviours.
|
||||
4. Progression – After defeating an enemy, the player's maximum HP and MP increase, and both player and enemy stats are refreshed.
|
||||
5. Relocation – You can choose to move to another location (currently selecting a random enemy from the list).
|
||||
|
||||
---
|
||||
|
||||
## 🧱 Class Hierarchy & Interfaces
|
||||
|
||||
### Interface Entity
|
||||
Defines the contract for all living beings in the game.
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| void attack(Entity target) | Basic attack on a target. |
|
||||
| void LightAttack(Entity target, int base_damage) | A weaker attack with fixed damage. |
|
||||
| void defend(Entity me, int damage) | Defensive action (confusing signature, see Player). |
|
||||
| String getName() | Returns the entity's name. |
|
||||
| void heal(int health) | Restores health points. |
|
||||
| void fillMana(int mana) | Restores mana points. |
|
||||
| void takeDamage(int damage) | Applies damage after armour reduction. |
|
||||
| int getMaxHP() | Returns maximum health. |
|
||||
| int getMaxMP() | Returns maximum mana. |
|
||||
| boolean ISLive() | Checks if the entity is alive (HP > 0). |
|
||||
|
||||
### Interface Item
|
||||
Defines usable items.
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| void use(Entity target) | Apply the item's effect to the target. |
|
||||
| String getName() | Returns the item's name. |
|
||||
|
||||
---
|
||||
|
||||
## 🧙 Abstract Classes
|
||||
|
||||
### Player (extends Entity)
|
||||
Common base for all player characters.
|
||||
|
||||
Fields:
|
||||
- name, weapon, armor, hp, maxHP, mp, maxMP, baseDamage (unused)
|
||||
|
||||
Constructors:
|
||||
- Player(String name, int hp, int mp, Weapon weapon, Armor armor, int baseDamage)
|
||||
- Player(String name, int hp, int mp, Weapon weapon, Armor armor) – sets maxHP/maxMP equal to initial hp/mp.
|
||||
|
||||
Methods:
|
||||
- void attack(Entity target) – Deals weapon damage.
|
||||
- void defend(Entity me, int damage) – Heals the entity itself (unusual).
|
||||
- void takeDamage(int damage) – Reduces damage by armour defence.
|
||||
- void heal(int health) – Adds health, capped at maxHP.
|
||||
- void fillMana(int mana) – Adds mana, capped at maxMP.
|
||||
- abstract void specialAttack(Entity target) – Each subclass defines its own special move.
|
||||
- boolean IsLive() – Returns true if HP > 0.
|
||||
- void LightAttack(Entity target, int base_damage) – Deals flat damage.
|
||||
- void UpGradeMaxHP() / UpGradeMaxMP() – Increases max stats by 20% (used after battle).
|
||||
- void freshFactors() – Fully restores HP and MP.
|
||||
|
||||
### Enemy (extends Entity)
|
||||
Base for all enemy types.
|
||||
|
||||
Fields:
|
||||
- weapon, hp, mp, maxHp, maxMp
|
||||
|
||||
Constructor:
|
||||
- Enemy(int hp, int mp, Weapon weapon) – Initialises stats and weapon.
|
||||
|
||||
Methods:
|
||||
- int getHp(), int getMp(), Weapon getWeapon(), void setNewHp(int newhp)
|
||||
- void takeDamage(int damage) – Direct HP reduction.
|
||||
- abstract void attack(Entity target)
|
||||
- abstract void check_hp() – Intended for death/recovery checks.
|
||||
- abstract void defend() – Normal defend.
|
||||
- abstract String getName()
|
||||
- void heal(int health), void fillMana(int mana) – Standard recovery.
|
||||
- boolean IsLive() – HP > 0.
|
||||
- void LightAttack(Entity target, int base_damage) – Flat damage.
|
||||
- int getMaxHP(), int getMaxMp()
|
||||
- void freshFactors() – Resets HP/MP to max.
|
||||
|
||||
### Consumable (implements Item)
|
||||
Base for consumable items.
|
||||
|
||||
- Consumable(String name) – Sets the item name.
|
||||
- String getName()
|
||||
|
||||
### Weapon (abstract)
|
||||
Base for all weapons.
|
||||
|
||||
Fields:
|
||||
- int damage, int manaCost
|
||||
|
||||
Constructor: Weapon(int damage, int manaCost)
|
||||
|
||||
Methods:
|
||||
- int getDamage(), int getManaCost()
|
||||
- (No use method – not implementing Item)
|
||||
|
||||
### Armor (abstract)
|
||||
Base for all armour pieces.
|
||||
Fields:
|
||||
- defense, maxDefense, durability, maxDurability, isBroke (private)
|
||||
|
||||
Constructors:
|
||||
- Armor(int defense, int durability) – Main constructor (does not initialise max values correctly).
|
||||
- Armor(int maxDefense, int maxDurability, boolean isBroke) – Unused overload.
|
||||
|
||||
Methods:
|
||||
- void checkBreak() – If durability ≤ 0, sets isBroke = true and defense = 0.
|
||||
- void repair() – Restores defence/durability to max values.
|
||||
- int getDefense(), int getDurability(), boolean isBroke()
|
||||
- void setMaxDefense(int max)
|
||||
- void newDurability() – Decrements durability (does not auto‑call checkBreak).
|
||||
|
||||
---
|
||||
|
||||
## 🧝♂️ Concrete Player Classes
|
||||
|
||||
### Knight
|
||||
- Base stats: HP=40, MP=20
|
||||
- specialAttack(Entity target) – Deals 5 damage.
|
||||
|
||||
### Wizard
|
||||
- Base stats: HP=40, MP=20
|
||||
- specialAttack(Entity target) – Deals 5 damage and heals self for 10 HP (capped at max).
|
||||
|
||||
### Assassin
|
||||
- Base stats: HP=20, MP=40
|
||||
- specialAttack(Entity target) – Deals weapon damage.
|
||||
|
||||
All three override ISLive() to always return false (bug – should use IsLive() from Player).
|
||||
|
||||
---
|
||||
|
||||
## 👹 Concrete Enemy Classes
|
||||
|
||||
### Skeleton
|
||||
- HP=10, MP=2
|
||||
- attack(Entity target) – Weapon damage.
|
||||
- check_hp() – If HP ≤ 0 and not yet revived, sets HP to Max_hp/2 (5). (Bug: ISLive() returns false, so this may not work as intended.)
|
||||
- getName() returns "Skeleton".
|
||||
|
||||
### Vampire
|
||||
- HP=12, MP=5
|
||||
- attack(Entity target) – Weapon damage, heals self by damage/3, capped at Max_hp.
|
||||
- getName() returns "Vampire".
|
||||
|
||||
### Goblin
|
||||
- HP=6, MP=18
|
||||
- attack(Entity target) – Weapon damage.
|
||||
- getName() returns "Gobblin".
|
||||
|
||||
### Dragon
|
||||
- Extends Enemy but currently all methods are empty/return default values – not fully implemented.
|
||||
|
||||
---
|
||||
|
||||
## ⚔️ Weapons
|
||||
|
||||
### Sword
|
||||
- damage=3, manaCost=4 (constants, but constructor accepts parameters that are ignored)
|
||||
- Copy constructor: Sword(Weapon other) copies damage and manaCost from another weapon.
|
||||
- uniqueAbility(ArrayList<Entity> targets) – deals weapon damage to all targets.
|
||||
|
||||
### SwordPro
|
||||
- damage=4, manaCost=3
|
||||
- Same copy constructor and unique ability.
|
||||
|
||||
### SwordProMax
|
||||
- damage=5, manaCost=2
|
||||
- Same pattern.
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Armors
|
||||
|
||||
### KnightArmor
|
||||
- defense=3, durability=2 (constructor ignores parameters, always uses static constants)
|
||||
- No copy constructor.
|
||||
|
||||
### ArmorNormal
|
||||
- defense=1, durability=2
|
||||
|
||||
### ArmorPro
|
||||
- defense=2, durability=2
|
||||
|
||||
### ArmorProMax
|
||||
- defense=1, durability=5
|
||||
|
||||
All armours use the same pattern: a static final value passed to super().
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Consumables
|
||||
|
||||
### Flask (extends Consumable)
|
||||
- Flask(String name) – calls super.
|
||||
- use(Entity target) – Heals target by 10% of its max HP.
|
||||
|
||||
Currently unused in gameplay; the Main loop does not reference flasks.
|
||||
|
||||
---
|
||||
|
||||
## 📍 Location
|
||||
|
||||
- Fields: name, enemies (ArrayList<Enemy>), locations (ArrayList<Location>)
|
||||
- Constructor takes locations and enemies, but does not assign name (remains null).
|
||||
- Not integrated into the main game loop yet.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Main Class (Game Loop)
|
||||
|
||||
The main method contains:
|
||||
|
||||
1. Setup: Creates weapon instances, enemy list (Skeleton, Vampire, Goblin), scanner, random.
|
||||
2. Player creation: Asks for name, class (1‑3), weapon (1‑3), armour (1‑4). Uses copy constructors for weapons.
|
||||
3. Game loop: While player is alive (checks player.ISLive() – currently buggy, always false so loop never enters). Inside:
|
||||
- Displays current enemy name.
|
||||
- Offers two options: Fight (1) or Move (2). Moving picks a random enemy from the list.
|
||||
- When fight is selected, calls playerMove() (player attacks), then if enemy lives, enemyMove() (enemy attacks).
|
||||
- After enemy dies, player’s max HP/MP increase, both are refreshed.
|
||||
4. Helper methods:
|
||||
- playerMove(Player, Enemy) – Displays a menu of actions (Light Attack, Heavy Attack, Defend, Heal, Special) and calls the corresponding method.
|
||||
- enemyMove(Player, Enemy, int) – Randomly chooses Light Attack or normal Attack for the enemy.
|
||||
- showDetails(Player, Enemy) – Prints current stats.
|
||||
- pause(double seconds) – Sleeps the program for a given time.
|
||||
|
||||
---
|
||||
|
||||
## 🐞 Known Issues / Quirks
|
||||
|
||||
- Player.ISLive() always returns false because overridden incorrectly in subclasses; the loop condition is never satisfied.
|
||||
- Armor constructors do not properly initialise maxDefense/maxDurability.
|
||||
- Entity interface contains defend(Entity me, int damage) which doesn’t match the usual defend() signature.
|
||||
- Many ISLive() overrides just return false, while the correct logic is in IsLive() (non‑interface method). The game uses ISLive() (interface method) which clashes with the intended behaviour.
|
||||
- Location is not used; its name field is never set.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 How to Run
|
||||
|
||||
1. Compile all .java files inside the org/project package.
|
||||
2. Run org.project.Main.
|
||||
3. Follow the console prompts to play.
|
||||
|
||||
---
|
||||
|
||||
## 📚 OOP Concepts Demonstrated
|
||||
|
||||
- Inheritance: Player and Enemy extend Entity; weapons extend Weapon; armours extend Armor.
|
||||
- Polymorphism: Entity references used for both players and enemies in combat.
|
||||
- Encapsulation: Private fields with getters/setters (though some fields could be better protected).
|
||||
- Abstraction: Abstract classes Player, Enemy, Weapon, Armor define common behaviour; subclasses fill in specifics.
|
||||
|
||||
---
|
||||
|
||||
Enjoy the game! Contributions and fixes are welcome.
|
||||
Reference in New Issue
Block a user