Java-Knight

This commit is contained in:
2026-05-12 00:48:33 +03:30
parent 78d4bedb08
commit 0fb22c9db1
18 changed files with 1058 additions and 198 deletions
+373 -9
View File
@@ -1,15 +1,379 @@
package org.project; package org.project.main;
import org.project.location.Location; import org.project.entity.Entity;
import org.project.entity.players.Knight;
import org.project.entity.enemies.*; // import همه دشمنان
import org.project.location.Location; // import کلاس Location
import java.util.ArrayList; import java.util.*;
import java.util.List;
public class Main { public class Main
public static void main(String[] args) { {
// TODO: ADD LOCATIONS TO YOUR GAME private static final Scanner scanner = new Scanner(System.in);
List<Location> locations = new ArrayList<>(); private static final Random random = new Random();
private static Knight player;
private static List<Location> gameLocations = new ArrayList<>();
private static Location currentLocation;
private static Set<String> keys = new HashSet<>();
private static boolean castleUnlocked = false;
// TODO: IMPLEMENT GAMEPLAY public static void main(String[] args)
{
System.out.println("Welcome to Java Knight RPG!");
System.out.print("Enter your hero's name: ");
String name = scanner.nextLine();
player = new Knight(name);
initializeLocations();
if (!gameLocations.isEmpty())
{
currentLocation = gameLocations.get(0);
System.out.println("Your adventure begins in the " + currentLocation.getName() + "!");
}
else
{
System.out.println("Error: No locations initialized. Exiting.");
System.exit(1);
}
gameLoop();
}
private static void initializeLocations()
{
Location forest = new Location(new ArrayList<>(), new ArrayList<>());
forest.setName("Dark Forest");
Location cave = new Location(new ArrayList<>(), new ArrayList<>());
cave.setName("Mysterious Cave");
Location castle = new Location(new ArrayList<>(), new ArrayList<>());
castle.setName("Dragon's Castle");
forest.addEnemy(new Goblin());
forest.addEnemy(new Skeleton());
cave.addEnemy(new Vampire());
cave.addEnemy(new Skeleton());
forest.addAdjacentLocation(cave);
cave.addAdjacentLocation(forest);
cave.addAdjacentLocation(castle);
castle.addAdjacentLocation(cave);
gameLocations.add(forest);
gameLocations.add(cave);
gameLocations.add(castle);
}
private static void gameLoop()
{
while (true)
{
if (currentLocation != null && currentLocation.hasLivingEnemies())
{
System.out.println("\n\u001B[33mEnemies detected in " + currentLocation.getName() + "!\u001B[0m");
}
System.out.println("\n====== Main Menu ======");
if (currentLocation != null)
{
System.out.println("Current Location: " + currentLocation.getName());
}
else
{
System.out.println("Current Location: Unknown");
}
System.out.println("1. Fight enemy");
System.out.println("2. Move to another location");
if (castleUnlocked)
{
System.out.println("3. Enter the Castle (Final Boss)");
}
else
{
System.out.println("3. Enter the Castle (Locked - Collect all keys!)");
}
System.out.println("4. Show player info");
System.out.println("5. Exit game");
System.out.print("Choose an option: ");
int choice = readInt(1, 5);
switch (choice)
{
case 1 ->
{
if (currentLocation != null && currentLocation.hasLivingEnemies())
{
fightEnemy();
}
else
{
System.out.println("No enemies here to fight.");
}
}
case 2 -> moveLocation();
case 3 ->
{
if (currentLocation != null && currentLocation.getName().equals("Dragon's Castle") && castleUnlocked)
{
fightBoss();
}
else if (castleUnlocked)
{
System.out.println("You must be at the Castle entrance to enter.");
}
else
{
System.out.println("You need to collect all keys before entering the Castle.");
}
}
case 4 -> showPlayerInfo();
case 5 ->
{
System.out.println("Thanks for playing! Goodbye.");
scanner.close();
System.exit(0);
}
}
}
}
private static void fightEnemy()
{
if (currentLocation == null || !currentLocation.hasLivingEnemies())
{
System.out.println("No enemies here to fight.");
return;
}
Enemy enemy = null;
for (Enemy e : currentLocation.getEnemies())
{
if (e.isAlive())
{
enemy = e;
break;
}
}
if (enemy == null)
{
System.out.println("No living enemies found.");
return;
}
System.out.println("\nA wild " + enemy.getName() + " appears!");
boolean playerTurn = true;
while (player.isAlive() && enemy.isAlive())
{
printStatus(player, enemy);
if (playerTurn)
{
System.out.println("\nYour turn! Choose action:");
System.out.println("1. Attack");
System.out.println("2. Defend");
System.out.print("Option: ");
int act = readInt(1, 2);
if (act == 1)
{
player.attack(enemy);
}
else
{
player.defend();
}
}
else
{
enemy.attack(player);
}
playerTurn = !playerTurn;
}
if (!player.isAlive())
{
System.out.println("\u001B[31mYou died! Game over.\u001B[0m");
scanner.close();
System.exit(0);
}
else
{
System.out.println("\u001B[32mYou defeated " + enemy.getName() + "!\u001B[0m");
tryDropKey(enemy);
int xpGain = getXPGain(enemy);
player.addXP(xpGain);
player.checkLevelUp();
player.setHP(player.getMaxHP());
player.setMP(player.getMaxMP());
System.out.println("\u001B[36mYour HP and MP are fully restored.\u001B[0m");
currentLocation.getEnemies().remove(enemy);
}
}
private static void moveLocation()
{
if (currentLocation == null)
{
System.out.println("You are in an unknown location.");
return;
}
ArrayList<Location> adjacent = currentLocation.getLocations();
if (adjacent == null || adjacent.isEmpty())
{
System.out.println("There are no other locations connected to this place.");
return;
}
System.out.println("\nAvailable locations to move:");
for (int i = 0; i < adjacent.size(); i++)
{
System.out.println((i + 1) + ". " + adjacent.get(i).getName());
}
System.out.print("Choose a location to move to (or 0 to cancel): ");
int choice = readInt(0, adjacent.size());
if (choice == 0)
{
System.out.println("Movement cancelled.");
return;
}
currentLocation = adjacent.get(choice - 1);
System.out.println("You moved to " + currentLocation.getName());
if (currentLocation.hasLivingEnemies())
{
System.out.println("\u001B[33mWatch out! There are enemies here.\u001B[0m");
}
}
private static void fightBoss()
{
if (currentLocation == null || !currentLocation.getName().equals("Dragon's Castle"))
{
System.out.println("You must be in the Dragon's Castle to fight the boss.");
return;
}
Dragon dragon = new Dragon();
System.out.println("\nYou enter the Dragon's Lair!");
boolean playerTurn = true;
while (player.isAlive() && dragon.isAlive())
{
printStatus(player, dragon);
if (playerTurn)
{
System.out.println("\nYour turn! Choose action:");
System.out.println("1. Attack");
System.out.println("2. Defend");
System.out.print("Option: ");
int act = readInt(1, 2);
if (act == 1)
{
player.attack(dragon);
}
else
{
player.defend();
}
}
else
{
dragon.attack(player);
}
playerTurn = !playerTurn;
}
if (player.isAlive())
{
System.out.println("\u001B[32mCongratulations! You defeated the Dragon and won the game!\u001B[0m");
scanner.close();
System.exit(0);
}
else
{
System.out.println("\u001B[31mYou died fighting the Dragon. Game over.\u001B[0m");
scanner.close();
System.exit(0);
}
}
private static void showPlayerInfo()
{
System.out.println("\n--- Player Info ---");
System.out.println("Name: " + player.getName());
System.out.println("Level: " + player.level);
System.out.println("XP: " + player.xp + " / " + player.xpToNextLevel);
System.out.println("HP: " + player.getHP() + "/" + player.getMaxHP());
System.out.println("MP: " + player.getMP() + "/" + player.getMaxMP());
System.out.println("Keys collected: " + keys);
}
private static int readInt(int min, int max)
{
int input;
while (true)
{
try
{
input = Integer.parseInt(scanner.nextLine());
if (input < min || input > max)
{
throw new NumberFormatException("Input out of bounds.");
}
break;
}
catch (NumberFormatException e)
{
System.out.print("Invalid input. Please enter a number between " + min + " and " + max + ": ");
}
}
return input;
}
private static void tryDropKey(Entity enemy)
{
double dropChance = 0.20;
String enemyName = enemy.getName();
if (keys.contains(enemyName + " Key")) {return;}
if (random.nextDouble() < dropChance)
{
keys.add(enemyName + " Key");
System.out.println("\u001B[36mYou obtained the " + enemyName + " Key!\u001B[0m");
}
if (keys.contains("Goblin Key") && keys.contains("Skeleton Key") && keys.contains("Vampire Key"))
{
castleUnlocked = true;
System.out.println("\u001B[35mAll keys collected! The Castle is now unlocked!\u001B[0m");
}
}
private static int getXPGain(Entity enemy)
{
return switch (enemy.getName())
{
case "Goblin" -> 50;
case "Skeleton" -> 40;
case "Vampire" -> 60;
case "Dragon" -> 500;
default -> 50;
};
}
private static void printStatus(Entity player, Entity enemy)
{
System.out.println("\n[player HP: " + player.getHP() + " / " + player.getMaxHP() +
" | MP: " + player.getMP() + " / " + player.getMaxMP() + "]");
System.out.println("[enemy HP: " + enemy.getHP() + " / " + enemy.getMaxHP() + "]");
} }
} }
@@ -1,21 +1,15 @@
package org.project.entity; package org.project.entity;
public interface Entity { public interface Entity
{
void attack(Entity target); void attack(Entity target);
void defend(); void defend();
void heal(int health);
void fillMana(int mana);
void takeDamage(int damage); void takeDamage(int damage);
boolean isAlive();
int getHP();
int getMaxHP(); int getMaxHP();
void setHP(int hp);
int getMP();
int getMaxMP(); int getMaxMP();
void setMP(int mp);
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
} }
@@ -0,0 +1,30 @@
package org.project.entity.enemies;
public class Dragon extends Enemy
{
public Dragon()
{
super("Dragon", 200, 100);
}
@Override
public void attack(Entity target)
{
int damage = 40;
System.out.println(name + " breathes fire for " + damage + " damage ignoring defense!");
if (target instanceof Player)
{
Player p = (Player) target;
p.setHP(p.getHP() - damage);
if (p.getHP() < 0)
p.setHP(0);
System.out.println(target.getName() + " takes " + damage + " damage!");
}
else
{
target.takeDamage(damage);
}
}
}
@@ -1,34 +1,75 @@
package org.project.entity.enemies; package org.project.entity.enemies;
import org.project.item.weapons.Weapon; import org.project.entity.Entity;
// TODO: UPDATE IMPLEMENTATION public abstract class Enemy implements Entity
public abstract class Enemy { {
Weapon weapon; protected String name;
private int hp;
private int mp;
public Enemy(int hp, int mp, Weapon weapon) { protected int hp;
this.hp = hp; protected int maxHP;
this.mp = mp; protected int mp;
protected int maxMP;
protected boolean defending;
this.weapon = weapon; public Enemy(String name, int maxHP, int maxMP)
{
this.name = name;
this.maxHP = maxHP;
this.hp = maxHP;
this.maxMP = maxMP;
this.mp = maxMP;
this.defending = false;
} }
@Override @Override
public void takeDamage(int damage) { public boolean isAlive() {return hp > 0;}
@Override
public int getHP() {return hp;}
@Override
public int getMaxHP() {return maxHP;}
@Override
public void setHP(int hp) {this.hp = Math.min(hp, maxHP);}
@Override
public int getMP() {return mp;}
@Override
public int getMaxMP() {return maxMP;}
@Override
public void setMP(int mp) {this.mp = Math.min(mp, maxMP);}
@Override
public void defend()
{
defending = true;
System.out.println(name + " is defending and will reduce damage next turn.");
}
@Override
public void takeDamage(int damage)
{
if (defending)
{
damage /= 2;
System.out.println(name + " defended and reduced damage to " + damage);
defending = false;
}
hp -= damage; hp -= damage;
if (hp < 0) hp = 0;
} }
public int getHp() { @Override
return hp; public void attack(Entity target)
{
int damage = 8;
System.out.println(name + " attacks for " + damage + " damage!");
target.takeDamage(damage);
} }
public int getMp() { public String getName() {return name;}
return mp;
}
public Weapon getWeapon() {
return weapon;
}
} }
@@ -0,0 +1,30 @@
package org.project.entity.enemies;
import java.util.Random;
public class Goblin extends Enemy
{
private static final Random random = new Random();
public Goblin()
{
super("Goblin", 50, 20);
}
@Override
public void attack(Entity target)
{
// Goblin has 25% chance for critical hit (1.5x damage)
int baseDamage = 10;
double critChance = 0.25;
int damage = baseDamage;
if (random.nextDouble() < critChance)
{
damage = (int) (baseDamage * 1.5);
System.out.println(name + " lands a critical hit!");
}
System.out.println(name + " attacks for " + damage + " damage!");
target.takeDamage(damage);
}
}
@@ -1,6 +1,14 @@
package org.project.entity.enemies; public class Skeleton extends Enemy
{
public Skeleton()
{
super("Skeleton", 60, 15);
}
// TODO: UPDATE IMPLEMENTATION @Override
public class Skeleton { public void attack(Entity target)
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR {
System.out.println(name + " shoots a bone arrow!");
super.attack(target);
}
} }
@@ -0,0 +1,24 @@
package org.project.entity.enemies;
public class Vampire extends Enemy
{
public Vampire()
{
super("Vampire", 60, 30);
}
@Override
public void attack(Entity target)
{
int damage = 12;
System.out.println(name + " attacks for " + damage + " damage and absorbs health!");
target.takeDamage(damage);
int healAmount = damage / 2;
hp += healAmount;
if (hp > maxHP) hp = maxHP;
System.out.println(name + " heals for " + healAmount + " HP.");
}
}
@@ -1,6 +1,13 @@
package org.project.entity.players; public class Knight extends Player
{
public Knight(String name)
{
super(name, 150, 50, new Sword(), new HeavyArmor());
}
// TODO: UPDATE IMPLEMENTATION @Override
public class Knight { public void defend()
// TODO: DESIGN KNIGHT'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR {
System.out.println(name + " raises shield! Defense is highly increased.");
}
} }
@@ -1,89 +1,104 @@
package org.project.entity.players; package org.project.entity.players;
import org.project.entity.Entity; import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
// TODO: UPDATE IMPLEMENTATION public abstract class Player implements Entity
public abstract class Player { {
protected String name; protected String name;
Weapon weapon; protected int level;
Armor armor; protected int xp;
private int hp; protected int xpToNextLevel;
private int maxHP;
private int mp;
private int maxMP;
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) { protected int hp;
protected int maxHP;
protected int mp;
protected int maxMP;
protected boolean defending;
public Player(String name, int maxHP, int maxMP)
{
this.name = name; this.name = name;
this.hp = hp; this.level = 1;
this.mp = mp; this.xp = 0;
this.xpToNextLevel = 100;
this.weapon = weapon; this.maxHP = maxHP;
this.armor = armor; this.hp = maxHP;
this.maxMP = maxMP;
this.mp = maxMP;
this.defending = false;
} }
@Override public abstract void specialAbility(Entity target);
public void attack(Entity target) {
target.takeDamage(weapon.getDamage());
}
@Override public boolean checkLevelUp()
public void defend() { {
// TODO if (xp >= xpToNextLevel)
} {
level++;
xp -= xpToNextLevel;
@Override xpToNextLevel *= 1.5;
public void takeDamage(int damage) { maxHP += 10;
hp -= damage - armor.getDefense(); maxMP += 5;
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP; hp = maxHP;
}
}
@Override
public void fillMana(int mana) {
mp += mana;
if (mp > maxMP) {
mp = maxMP; mp = maxMP;
System.out.println("\u001B[32m[LEVEL UP] Congratulations! You reached Level " + level + ".\u001B[0m");
return true;
} }
return false;
} }
public void addXP(int amount) {xp += amount;}
public String getName() { @Override
return name; public boolean isAlive() {return hp > 0;}
}
public int getHp() { @Override
return hp; public int getHP() {return hp;}
@Override
public int getMaxHP() {return maxHP;}
@Override
public void setHP(int hp) {this.hp = Math.min(hp, maxHP);}
@Override
public int getMP() {return mp;}
@Override
public int getMaxMP() {return maxMP;}
@Override
public void setMP(int mp) {this.mp = Math.min(mp, maxMP);}
@Override
public void defend()
{
defending = true;
System.out.println(name + " is defending and will reduce damage next turn.");
} }
@Override @Override
public int getMaxHP() { public void takeDamage(int damage)
return maxHP; {
} if (defending)
{
public int getMp() { damage /= 2;
return mp; System.out.println(name + " defended and reduced damage to " + damage);
defending = false;
}
hp -= damage;
if (hp < 0) hp = 0;
} }
@Override @Override
public int getMaxMP() { public void attack(Entity target)
return maxMP; {
int damage = 10 + level * 2;
System.out.println(name + " attacks for " + damage + " damage!");
target.takeDamage(damage);
} }
public Weapon getWeapon() { public String getName() {return name;}
return weapon; }
}
public Armor getArmor() {
return armor;
}
}
@@ -2,10 +2,9 @@ package org.project.item;
import org.project.entity.Entity; import org.project.entity.Entity;
public interface Item { public interface Item
{
void use(Entity target); void use(Entity target);
String getName();
/* String getDescription();
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
} }
@@ -1,42 +1,68 @@
package org.project.item.armors; package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION public abstract class Armor
public abstract class Armor { {
private int defense; private int defense;
private int maxDefense; private int maxDefense;
private int durability; private int durability;
private int maxDurability; private int maxDurability;
private boolean isBroke; private boolean isBroke;
public Armor(int defense, int durability) { public Armor(int defense, int durability)
{
this.defense = defense; this.defense = defense;
this.maxDefense = defense;
this.durability = durability; this.durability = durability;
this.maxDurability = durability;
this.isBroke = false;
} }
public void checkBreak() { public void takeHit(int damageToDurability)
if (durability <= 0) { {
isBroke = true; if (!isBroke)
defense = 0; {
durability -= damageToDurability;
if (durability < 0) durability = 0;
checkBreak();
} }
} }
// TODO: (BONUS) UPDATE THE REPAIR METHOD public void checkBreak()
public void repair() { {
isBroke = false; if (durability <= 0)
defense = maxDefense; {
durability = maxDurability; isBroke = true;
defense = 0;
}
else
{
isBroke = false;
defense = maxDefense;
}
} }
public int getDefense() { public void repair()
return defense; {
if (isBroke)
{
isBroke = false;
defense = maxDefense;
durability = maxDurability;
System.out.println("Armor repaired successfully!");
}
else
{
System.out.println("Armor is still intact. No repair needed.");
}
} }
public int getDurability() { public int getDefense() {return defense;}
return durability;
}
public boolean isBroke() { public int getDurability() {return durability;}
return isBroke;
} public boolean isBroke() {return isBroke;}
public int getMaxDefense() {return maxDefense;}
public int getMaxDurability() {return maxDurability;}
} }
@@ -1,6 +1,27 @@
package org.project.item.armors; package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION public class KnightArmor extends Armor
public class KnightArmor { {
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
public KnightArmor()
{
super(40, 100);
}
@Override
public void checkBreak()
{
super.checkBreak();
if (isBroke())
{
System.out.println("Knight's armor is shattered!");
}
}
@Override
public void repair()
{
super.repair();
System.out.println("Knight's armor has been reforged by the royal blacksmith!");
}
} }
@@ -1,8 +1,29 @@
package org.project.item.consumables; package org.project.item.consumables;
// TODO: UPDATE IMPLEMENTATION import org.project.entity.Entity;
public abstract class Consumable {
/* public abstract class Consumable
TODO: ADD OTHER REQUIRED AND BONUS METHODS {
*/ private String name;
} private int amount;
public Consumable(String name, int amount)
{
this.name = name;
this.amount = amount;
}
public String getName() {return name;}
public int getAmount() {return amount;}
public void setAmount(int amount) {this.amount = amount;}
public abstract void use(Entity target);
@Override
public String toString()
{
return name + " (Effect amount: " + amount + ")";
}
}
@@ -2,15 +2,18 @@ package org.project.item.consumables;
import org.project.entity.Entity; import org.project.entity.Entity;
// TODO: UPDATE IMPLEMENTATION public class Flask extends Consumable
public class Flask { {
/* public Flask()
THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN. {
*/ super("Flask", 0);
}
// TODO: UPDATE USE METHOD
@Override @Override
public void use(Entity target) { public void use(Entity target)
target.heal(target.getMaxHP() / 10); {
int healAmount = target.getMaxHP() / 10;
target.heal(healAmount);
System.out.println(target.getName() + " used " + getName() + " and recovered " + healAmount + " HP.");
} }
} }
@@ -4,23 +4,42 @@ import org.project.entity.Entity;
import java.util.ArrayList; import java.util.ArrayList;
// TODO: UPDATE IMPLEMENTATION public class Sword extends Weapon
public class Sword { {
/*
THIS IS AN EXAMPLE OF A WEAPON DESIGN.
*/
int abilityCharge; private int abilityCharge;
public Sword() { public Sword()
// TODO: DESIGN SWORD'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR {
super(25, 10, 1.2, 0.15, 100);
this.abilityCharge = 0;
} }
// TODO: (BONUS) UPDATE THE UNIQUE ABILITY @Override
public void uniqueAbility(ArrayList<Entity> targets) { public String getName()
{
return "Basic Sword";
}
@Override
public String getDescription()
{
return "A sharp melee weapon with balanced damage and good critical chance.";
}
@Override
public void uniqueAbility(Entity... targets)
{
abilityCharge += 2; abilityCharge += 2;
for (Entity target : targets) {
target.takeDamage(getDamage()); System.out.println("Sword's unique ability activated! Hitting " + targets.length + " targets.");
for (Entity target : targets)
{
if (target != null && target.isAlive())
{
target.takeDamage(getDamage() + 10);
}
} }
} }
} }
@@ -1,35 +1,78 @@
package org.project.item.weapons; package org.project.item.weapons;
import org.project.entity.Entity; import org.project.entity.Entity;
import org.project.item.Item;
// TODO: UPDATE IMPLEMENTATION public abstract class Weapon implements Item
public abstract class Weapon { {
private int damage; private final int damage;
private int manaCost; private final int manaCost;
private final double attackSpeed;
private final double critChance;
private final int durability;
private int currentDurability;
/* public Weapon(int damage, int manaCost, double attackSpeed, double critChance, int durability)
TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES {
*/
public Weapon(int damage, int manaCost) {
this.damage = damage; this.damage = damage;
this.manaCost = manaCost; this.manaCost = manaCost;
this.attackSpeed = attackSpeed;
this.critChance = critChance;
this.durability = durability;
this.currentDurability = durability;
} }
@Override @Override
public void use(Entity target) { public void use(Entity target)
target.takeDamage(damage); {
if (currentDurability <= 0)
{
System.out.println(getName() + " is broken and cannot be used.");
return;
}
if (target == null)
{
System.out.println("No target to attack.");
return;
}
int finalDamage = damage;
if (Math.random() < critChance)
{
finalDamage *= 2;
System.out.println("Critical hit!");
}
target.takeDamage(finalDamage);
currentDurability--;
System.out.println(getName() + " used on " + (target.getClass().getSimpleName()) + ", damage: " + finalDamage + ", durability left: " + currentDurability);
if (currentDurability == 0)
System.out.println(getName() + " is now broken!");
} }
public int getDamage() { public void repair()
return damage; {
currentDurability = durability;
System.out.println(getName() + " repaired to full durability!");
} }
public int getManaCost() { public int getDamage() {return damage;}
return manaCost;
}
/* public int getManaCost() {return manaCost;}
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/ public double getAttackSpeed() {return attackSpeed;}
public double getCritChance() {return critChance;}
public int getDurability() {return durability;}
public int getCurrentDurability() {return currentDurability;}
public abstract String getName();
public abstract String getDescription();
public void uniqueAbility(Entity... targets) {}
} }
@@ -4,25 +4,52 @@ import org.project.entity.enemies.Enemy;
import java.util.ArrayList; import java.util.ArrayList;
public class Location { public class Location
{
private String name; private String name;
private ArrayList<Location> locations;
private ArrayList<Enemy> enemies; private ArrayList<Enemy> enemies;
public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies) { public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies)
{
this.locations = locations; this.locations = locations;
this.enemies = enemies; this.enemies = enemies;
} }
public String getName() { public String getName() {return name;}
return name;
public ArrayList<Location> getLocations() {return locations;}
public ArrayList<Enemy> getEnemies() {return enemies;}
public void setName(String name) {this.name = name;}
public void addAdjacentLocation(Location location)
{
if (this.locations == null)
{
this.locations = new ArrayList<>();
}
this.locations.add(location);
} }
public ArrayList<Location> getLocations() { public void addEnemy(Enemy enemy)
return locations; {
if (this.enemies == null)
{
this.enemies = new ArrayList<>();
}
this.enemies.add(enemy);
} }
public ArrayList<Enemy> getEnemies() { public boolean hasLivingEnemies()
return enemies; {
if (this.enemies == null) {return false;}
for (Enemy enemy : enemies)
{
if (enemy.isAlive()) {return true;}
}
return false;
} }
} }
+188
View File
@@ -0,0 +1,188 @@
# ⚔️ Java Knight RPG
## 🎮 Introduction
Java Knight is a text-based RPG game developed in Java using Object-Oriented Programming principles.
The player explores different locations, fights enemies, collects keys, gains experience, and becomes stronger throughout the adventure.
Each enemy has unique abilities, and the final goal is to defeat the Dragon Boss and complete the quest.
---
# 🛠️ Compile & Run
## ✅ Compile
Open the terminal in the project folder and run:
```bash
javac *.java
```
## ▶️ Run
After compiling, start the game using:
```bash
java Main
```
---
# 🧩 Classes & OOP Design
## 🧱 Entity
The base class of all living characters in the game.
It contains common attributes such as:
- Name
- Health
- Damage
- Defense
This class demonstrates:
- Inheritance
- Encapsulation
---
## 🛡️ Player
Represents the main playable character.
The player can:
- Fight enemies
- Gain XP
- Level up
- Collect keys
- Move between locations
Concepts used:
- Encapsulation
- Method overriding
- State management
---
## ⚔️ Knight
A specialized version of the Player class with stronger combat abilities and better starting stats.
Concepts used:
- Inheritance
- Polymorphism
---
## 👾 Enemy
Base class for all enemy types in the game.
Defines common enemy behavior such as:
- Attacking
- Taking damage
- Health management
Concepts used:
- Abstraction
- Inheritance
---
## 💀 Skeleton
A simple enemy with balanced combat stats.
---
## 👹 Goblin
A fast enemy with a chance to deal critical damage.
---
## 🧛 Vampire
An enemy capable of stealing health from the player during combat.
---
## 🐉 Dragon
The final boss of the game with powerful attacks that can ignore defense.
---
## 📍 Location
Handles the world map and movement system.
Each location contains:
- Enemies
- Connected locations
- Exploration logic
Concepts used:
- Object relationships
- Composition
---
## 🎒 Item
Represents collectible and usable objects inside the game.
Items can help the player by:
- Restoring health
- Increasing power
- Supporting progression
Concepts used:
- Encapsulation
- Object interaction
---
# 🧠 OOP Principles Used
- ✅ Inheritance
- ✅ Encapsulation
- ✅ Polymorphism
- ✅ Abstraction
The project is fully designed using Object-Oriented Programming to make the code modular, reusable, and easier to maintain.
---
# 🎯 How to Play
## 🎮 Controls
The game is menu-based.
Players select actions by entering numbers in the terminal.
Example actions:
- Attack enemy
- View stats
- Move to another location
- Continue exploration
---
## 📊 Player Stats
### ❤️ Health
Determines how much damage the player can survive.
### ⚔️ Damage
Controls attack power against enemies.
### 🛡️ Defense
Reduces incoming damage.
### ✨ XP
Earned after defeating enemies and used for leveling up.
### 🔑 Keys
Required to unlock progression and reach the final boss.
---
## 🌍 Gameplay Flow
1. Start the game
2. Explore locations
3. Fight enemies
4. Gain XP and level up
5. Collect keys
6. Reach the Dragon Castle
7. Defeat the Dragon Boss
---
# 👩‍💻 Credits
Developed with Java and Object-Oriented Programming concepts.
Made by Romina