388 lines
13 KiB
Java
388 lines
13 KiB
Java
package org.project;
|
|
|
|
import org.project.entity.Entity;
|
|
import org.project.entity.enemies.*;
|
|
import org.project.entity.players.Assassin;
|
|
import org.project.entity.players.Knight;
|
|
import org.project.entity.players.Player;
|
|
import org.project.entity.players.Wizard;
|
|
import org.project.item.weapons.Dagger;
|
|
import org.project.item.weapons.Sword;
|
|
import org.project.location.Location;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.Scanner;
|
|
|
|
import static org.project.entity.enemies.Enemy.GREEN;
|
|
import static org.project.entity.players.Player.*;
|
|
|
|
public class Game {
|
|
|
|
private Player player;
|
|
private Scanner scanner;
|
|
private Location currentLocation;
|
|
private List<Location> allLocations;
|
|
private Enemy currentEnemy;
|
|
private Random random = new Random();
|
|
|
|
private boolean hasGoblinKey = false;
|
|
private boolean hasSkeletonKey = false;
|
|
private boolean hasVampireKey = false;
|
|
|
|
private List<Enemy> allEnemiesInGame = new ArrayList<>();
|
|
|
|
protected static final String GREEN_LIGHT = "\033[92m";
|
|
protected static final String PURPLE = "\033[35m";
|
|
|
|
public Game()
|
|
{
|
|
this.scanner = new Scanner(System.in);
|
|
this.allLocations = setupWorld();
|
|
}
|
|
|
|
public void start()
|
|
{
|
|
System.out.println("\n🏰 Welcome to Java Knight!");
|
|
this.player = createPlayer();
|
|
selectStartingLocation();
|
|
spawnRandomEnemy();
|
|
gameLoop();
|
|
}
|
|
|
|
public Player createPlayer()
|
|
{
|
|
System.out.println("Enter your name: ");
|
|
String name = scanner.nextLine();
|
|
|
|
System.out.println("1. ⚔️ Knight (High Damage, Balanced HP)");
|
|
System.out.println("2. 🧙 Wizard (High HP, Magic Power)");
|
|
System.out.println("3. 🗡️ Assassin (High Mana, Critical Hits)");
|
|
int choice = getIntInput("Choose your character: ");
|
|
|
|
Player newPlayer = null;
|
|
switch (choice)
|
|
{
|
|
case 1:
|
|
System.out.println("You chose the Knight!");
|
|
newPlayer = new Knight(name);
|
|
break;
|
|
case 2:
|
|
System.out.println("You chose the Wizard!");
|
|
newPlayer = new Wizard(name);
|
|
break;
|
|
case 3:
|
|
System.out.println("You chose the Assassin!");
|
|
newPlayer = new Assassin(name);
|
|
break;
|
|
default:
|
|
System.out.println("Invalid choice. Defaulting to Knight.");
|
|
newPlayer = new Knight(name);
|
|
break;
|
|
}
|
|
return newPlayer;
|
|
}
|
|
|
|
public void selectStartingLocation()
|
|
{
|
|
System.out.println("🗺️ Choose your starting location:");
|
|
for (int i = 0; i < allLocations.size(); i++)
|
|
{
|
|
System.out.println((i+1) + ". " + allLocations.get(i).getName());
|
|
}
|
|
int choice = getIntInput("Enter your choice: ");
|
|
if (choice > 0 && choice <= allLocations.size())
|
|
{
|
|
this.currentLocation = allLocations.get(choice - 1);
|
|
System.out.println("🚶 You have arrived at: " + currentLocation.getName());
|
|
}
|
|
else
|
|
{
|
|
System.out.println("Invalid choice. Defaulting to Forest.");
|
|
this.currentLocation = allLocations.get(0);
|
|
}
|
|
}
|
|
|
|
private List<Location> setupWorld()
|
|
{
|
|
List<Location> locations = new ArrayList<>();
|
|
|
|
ArrayList<Enemy> forestEnemies = new ArrayList<>();
|
|
forestEnemies.add(new Goblin(new Dagger()));
|
|
forestEnemies.add(new Goblin(new Dagger()));
|
|
forestEnemies.add(new Goblin(new Dagger()));
|
|
forestEnemies.add(new Goblin(new Dagger()));
|
|
forestEnemies.add(new Skeleton(new Sword()));
|
|
forestEnemies.add(new Vampire(new Dagger()));
|
|
forestEnemies.add(new Skeleton(new Sword()));
|
|
forestEnemies.add(new Vampire(new Dagger()));
|
|
forestEnemies.add(new Skeleton(new Sword()));
|
|
Location forest = new Location("Dark Forest", new ArrayList<>(), forestEnemies);
|
|
allEnemiesInGame.addAll(forestEnemies);
|
|
|
|
ArrayList<Enemy> caveEnemies = new ArrayList<>();
|
|
caveEnemies.add(new Skeleton(new Sword()));
|
|
caveEnemies.add(new Skeleton(new Sword()));
|
|
caveEnemies.add(new Skeleton(new Sword()));
|
|
caveEnemies.add(new Skeleton(new Sword()));
|
|
caveEnemies.add(new Goblin(new Dagger()));
|
|
caveEnemies.add(new Vampire(new Dagger()));
|
|
caveEnemies.add(new Goblin(new Dagger()));
|
|
caveEnemies.add(new Vampire(new Dagger()));
|
|
caveEnemies.add(new Vampire(new Dagger()));
|
|
Location cave = new Location("Spooky Cave", new ArrayList<>(), caveEnemies);
|
|
allEnemiesInGame.addAll(caveEnemies);
|
|
|
|
ArrayList<Enemy> swampEnemies = new ArrayList<>();
|
|
swampEnemies.add(new Vampire(new Dagger()));
|
|
swampEnemies.add(new Vampire(new Dagger()));
|
|
swampEnemies.add(new Vampire(new Dagger()));
|
|
swampEnemies.add(new Vampire(new Dagger()));
|
|
swampEnemies.add(new Goblin(new Dagger()));
|
|
swampEnemies.add(new Skeleton(new Sword()));
|
|
swampEnemies.add(new Goblin(new Dagger()));
|
|
swampEnemies.add(new Goblin(new Dagger()));
|
|
swampEnemies.add(new Skeleton(new Sword()));
|
|
Location swamp = new Location("Swamp", new ArrayList<>(), swampEnemies);
|
|
allEnemiesInGame.addAll(swampEnemies);
|
|
|
|
locations.add(forest);
|
|
locations.add(cave);
|
|
locations.add(swamp);
|
|
|
|
return locations;
|
|
}
|
|
|
|
public void spawnRandomEnemy()
|
|
{
|
|
ArrayList<Enemy> enemies = currentLocation.getEnemies();
|
|
if (enemies == null || enemies.isEmpty()) {
|
|
System.out.println("🌲 The area is quiet... no enemies nearby. Move to another location.");
|
|
this.currentEnemy = null;
|
|
return;
|
|
}
|
|
|
|
int index = random.nextInt(enemies.size());
|
|
this.currentEnemy = enemies.get(index);
|
|
this.currentEnemy = enemies.remove(index);
|
|
allEnemiesInGame.remove(this.currentEnemy);
|
|
|
|
System.out.println("⚠️ A wild " + currentEnemy.getClass().getSimpleName() + " appears in " + currentLocation.getName() + "!");
|
|
}
|
|
|
|
public void gameLoop()
|
|
{
|
|
while (player.isAlive())
|
|
{
|
|
System.out.println("\n========================================");
|
|
System.out.println("📍 Location: " + currentLocation.getName());
|
|
System.out.println("❤️ Player HP: " + player.getHp() + "/" + player.getMaxHP());
|
|
System.out.println("💎 Player MP: " + player.getMp() + "/" + player.getMaxMP());
|
|
|
|
if (currentEnemy != null && currentEnemy.isAlive())
|
|
{
|
|
System.out.println("Enemy: " + currentEnemy.getClass().getSimpleName() + " (HP: " + currentEnemy.getHp() + ")");
|
|
}
|
|
|
|
System.out.println("---- Actions ----");
|
|
System.out.println("1. 🥷 Fight enemy");
|
|
System.out.println("2. 🚶 Move to another location");
|
|
System.out.println("3. 🔒 Go to Dragon Castle");
|
|
System.out.println("4. 🏳️ Quit game");
|
|
|
|
int choice = getIntInput("Enter your choice: ");
|
|
|
|
switch (choice)
|
|
{
|
|
case 1: //fight
|
|
if (currentEnemy == null)
|
|
{
|
|
spawnRandomEnemy();
|
|
}
|
|
|
|
if (currentEnemy != null)
|
|
{
|
|
System.out.println("⚔️ Battle Started: " + player.getName() + " vs " + currentEnemy.getClass().getSimpleName());
|
|
fight(currentEnemy);
|
|
postCombat(currentEnemy);
|
|
|
|
spawnRandomEnemy();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("⚠️ No enemy found in this location.");
|
|
}
|
|
break;
|
|
|
|
case 2: //move
|
|
moveLocation();
|
|
spawnRandomEnemy();
|
|
break;
|
|
|
|
case 3:
|
|
if (hasGoblinKey && hasSkeletonKey && hasVampireKey)
|
|
{
|
|
System.out.println(PURPLE+"🐉 Entering Dragon's lair..."+RESET);
|
|
startDragonFight();
|
|
}
|
|
else
|
|
{
|
|
System.out.println("🔒 Locked! Collect all 3 keys.");
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
System.out.println("Byyyeee!");
|
|
return;
|
|
|
|
default:
|
|
System.out.println("Invalid."); break;
|
|
}
|
|
}
|
|
System.out.println(RED+"==== 💀 Game Over! ===="+RESET);
|
|
}
|
|
|
|
private void fight(Enemy enemy)
|
|
{
|
|
while (player.isAlive() && enemy.isAlive())
|
|
{
|
|
handlePlayerTurn(enemy);
|
|
if (enemy.isStunned())
|
|
{
|
|
System.out.println("Enemy is stunned and skips its turn!");
|
|
enemy.unstun();
|
|
}
|
|
else
|
|
{
|
|
enemy.attack(player);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void handlePlayerTurn(Entity target)
|
|
{
|
|
System.out.println(BLUE+"\n--- Your Turn ---"+RESET);
|
|
System.out.println("1. Light Attack | 2. Heavy Attack (-20 Mana) | 3. Defend (-15 Mana) | 4. Heal (-30 Mana) | 5. Special (-50 Mana)");
|
|
int action = getIntInput("Choose action: ");
|
|
|
|
switch (action)
|
|
{
|
|
case 1: player.lightAttack(target); break;
|
|
case 2: player.heavyAttack(target); break;
|
|
case 3: player.defend(); break;
|
|
case 4: player.heal(20); break;
|
|
case 5: player.specialAbility(target); break;
|
|
default: System.out.println("Invalid!"); break;
|
|
}
|
|
}
|
|
|
|
public void postCombat(Enemy enemy)
|
|
{
|
|
if (player.isAlive())
|
|
{
|
|
int xp = enemy.getXpReward();
|
|
player.addXp(xp);
|
|
checkKeyDrop(enemy);
|
|
player.setHp(player.getMaxHP());
|
|
player.fillMana(player.getMaxMP() - player.getMp());
|
|
System.out.println("💖 HP and MP fully restored!");
|
|
}
|
|
}
|
|
|
|
public void checkKeyDrop(Enemy enemy)
|
|
{
|
|
if (enemy instanceof Goblin && hasGoblinKey) return;
|
|
if (enemy instanceof Skeleton && hasSkeletonKey) return;
|
|
if (enemy instanceof Vampire && hasVampireKey) return;
|
|
|
|
String enemyType = enemy.getClass().getSimpleName();
|
|
|
|
boolean isLastOne = true;
|
|
|
|
for (Enemy e : allEnemiesInGame)
|
|
{
|
|
if (e.getClass().getSimpleName().equals(enemyType))
|
|
{
|
|
isLastOne = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
double dropChance;
|
|
if (isLastOne)
|
|
{
|
|
dropChance = 1.0;
|
|
System.out.println("✨ This is the last " + enemyType + " in the world!");
|
|
}
|
|
else
|
|
{
|
|
dropChance = 0.2; //20% chance
|
|
}
|
|
|
|
if (Math.random() < dropChance)
|
|
{
|
|
if (enemy instanceof Goblin)
|
|
{
|
|
hasGoblinKey = true;
|
|
System.out.println(GREEN + "🔑 You found the Goblin Key!" + RESET);
|
|
}
|
|
else if (enemy instanceof Skeleton)
|
|
{
|
|
hasSkeletonKey = true;
|
|
System.out.println(GREEN + "🔑 You found the Skeleton Key!" + RESET);
|
|
}
|
|
else if (enemy instanceof Vampire)
|
|
{
|
|
hasVampireKey = true;
|
|
System.out.println(GREEN + "🔑 You found the Vampire Key!" + RESET);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void moveLocation()
|
|
{
|
|
System.out.println("🗺️ Available destinations:");
|
|
for (int i = 0; i < allLocations.size(); i++)
|
|
{
|
|
System.out.println((i + 1) + ". " + allLocations.get(i).getName());
|
|
}
|
|
|
|
int choice = getIntInput("Choose destination: ");
|
|
if (choice > 0 && choice <= allLocations.size())
|
|
{
|
|
currentLocation = allLocations.get(choice - 1);
|
|
System.out.println("🚶 You traveled to " + currentLocation.getName());
|
|
}
|
|
}
|
|
|
|
private void startDragonFight() {
|
|
System.out.println("🐉 THE DRAGON APPEARS! PREPARE FOR BATTLE!");
|
|
Dragon dragon = new Dragon(null);
|
|
|
|
fight(dragon);
|
|
|
|
if (player.isAlive())
|
|
{
|
|
System.out.println(GREEN_LIGHT + "\n== 🏆 VICTORY! You have defeated the Dragon and broken the curse! ==" + RESET);
|
|
System.out.println("🎉 You are the Hero of the Realm!");
|
|
}
|
|
else
|
|
{
|
|
System.out.println(RED + "\n==== 💀 You have been slain by the Dragon! ====" + RESET);
|
|
}
|
|
}
|
|
|
|
private int getIntInput(String prompt) {
|
|
System.out.print(prompt);
|
|
while (!scanner.hasNextInt()) {
|
|
System.out.println("⚠️ Please enter a valid number!");
|
|
scanner.next();
|
|
System.out.print(prompt);
|
|
}
|
|
return scanner.nextInt();
|
|
}
|
|
|
|
|
|
}
|