add GameLoop.java
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
package org.project;
|
||||
|
||||
import org.project.combat.*;
|
||||
import org.project.entity.enemies.*;
|
||||
import org.project.entity.players.*;
|
||||
import org.project.location.Location;
|
||||
import org.project.managers.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GameLoop {
|
||||
|
||||
private final Scanner scanner = new Scanner(System.in);
|
||||
|
||||
private final ActionDecisionManager actionManager = new ActionDecisionManager();
|
||||
private final StatusEffectManager statusManager = new StatusEffectManager();
|
||||
private final SpecialAbilityManager abilityManager = new SpecialAbilityManager();
|
||||
private final ManaCostManager manaManager = new ManaCostManager();
|
||||
|
||||
private final TotalAttackCalculator attackCalculator =
|
||||
new TotalAttackCalculator(statusManager, abilityManager, manaManager);
|
||||
|
||||
private Player player;
|
||||
private Enemy currentEnemy;
|
||||
|
||||
private boolean gameRunning = true;
|
||||
|
||||
private boolean hasGoblinKey;
|
||||
private boolean hasSkeletonKey;
|
||||
private boolean hasVampireKey;
|
||||
|
||||
private Location currentLocation;
|
||||
private final List<Location> locations = new ArrayList<>();
|
||||
|
||||
|
||||
public GameLoop() {
|
||||
initializeLocations();
|
||||
}
|
||||
|
||||
private void initializeLocations() {
|
||||
|
||||
Location valhalla = new Location("Valhalla");
|
||||
Location elysium = new Location("Elysium");
|
||||
Location niflheim = new Location("Niflheim");
|
||||
Location castle = new Location("Castle");
|
||||
|
||||
valhalla.connect(elysium);
|
||||
valhalla.connect(niflheim);
|
||||
elysium.connect(niflheim);
|
||||
niflheim.connect(castle);
|
||||
|
||||
locations.add(valhalla);
|
||||
locations.add(elysium);
|
||||
locations.add(niflheim);
|
||||
locations.add(castle);
|
||||
|
||||
currentLocation = valhalla;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
||||
System.out.println("====== JAVA KNIGHT ======");
|
||||
|
||||
chooseClass();
|
||||
spawnEnemy();
|
||||
|
||||
while (gameRunning) {
|
||||
showMenu();
|
||||
}
|
||||
|
||||
System.out.println("Game Ended.");
|
||||
}
|
||||
|
||||
private void chooseClass() {
|
||||
|
||||
System.out.println("""
|
||||
Choose class:
|
||||
1. Knight (HP:150 MP:80 DMG:12)
|
||||
2. Wizard (HP:80 MP:200 DMG:10)
|
||||
3. Assassin (HP:90 MP:120 DMG:15)
|
||||
""");
|
||||
|
||||
int choice = scanner.nextInt();
|
||||
|
||||
switch (choice) {
|
||||
case 2 -> player = new Wizard("Merlin");
|
||||
case 3 -> player = new Assassin("Shadow");
|
||||
default -> player = new Knight("Sir Duncan");
|
||||
}
|
||||
}
|
||||
|
||||
private void showMenu() {
|
||||
|
||||
System.out.println("====" + Colors.YELLOW + " GAME MENU " + Colors.RESET + "====");
|
||||
System.out.println("Location: " + currentLocation.getName());
|
||||
|
||||
if (currentEnemy != null)
|
||||
System.out.println("Enemy: " + currentEnemy);
|
||||
|
||||
System.out.println("""
|
||||
\n1. Fight
|
||||
2. Inventory
|
||||
3. Move
|
||||
0. Exit
|
||||
""");
|
||||
|
||||
if (hasAllKeys())
|
||||
System.out.println("4. Fight Dragon");
|
||||
|
||||
int choice = scanner.nextInt();
|
||||
|
||||
switch (choice) {
|
||||
case 1 -> startCombat();
|
||||
case 2 -> new InventoryManager().displayInventory(player);
|
||||
case 3 -> move();
|
||||
case 4 -> {
|
||||
if (hasAllKeys())
|
||||
fightDragon();
|
||||
}
|
||||
case 0 -> gameRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void move() {
|
||||
|
||||
List<Location> connected = currentLocation.getConnectedLocations();
|
||||
|
||||
if (connected.isEmpty()) {
|
||||
System.out.println("No paths from here.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Choose destination:");
|
||||
|
||||
for (int i = 0; i < connected.size(); i++)
|
||||
System.out.println((i + 1) + ". " + connected.get(i).getName());
|
||||
|
||||
int choice = scanner.nextInt();
|
||||
|
||||
if (choice < 1 || choice > connected.size())
|
||||
return;
|
||||
|
||||
currentLocation = connected.get(choice - 1);
|
||||
|
||||
spawnEnemy();
|
||||
}
|
||||
|
||||
private void spawnEnemy() {
|
||||
|
||||
Enemy[] enemies = {
|
||||
new Goblin(),
|
||||
new Skeleton(),
|
||||
new Vampire()
|
||||
};
|
||||
|
||||
currentEnemy = enemies[(int) (Math.random() * enemies.length)];
|
||||
}
|
||||
|
||||
private void startCombat() {
|
||||
|
||||
if (currentEnemy == null) {
|
||||
System.out.println("No enemy here.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println(Colors.RED_BRIGHT + "⚔ COMBAT STARTED! ⚔" + Colors.RESET);
|
||||
|
||||
|
||||
while (player.isLive() && currentEnemy.isLive()) {
|
||||
|
||||
statusManager.tick(player);
|
||||
statusManager.tick(currentEnemy);
|
||||
|
||||
abilityManager.tick(currentEnemy, player);
|
||||
abilityManager.tick(player, currentEnemy);
|
||||
|
||||
if (!player.isLive() || !currentEnemy.isLive())
|
||||
break;
|
||||
|
||||
playerTurn();
|
||||
currentEnemy.resetTurnState();
|
||||
|
||||
if (currentEnemy.isLive())
|
||||
enemyTurn();
|
||||
player.resetTurnState();
|
||||
}
|
||||
|
||||
if (player.isLive())
|
||||
victory();
|
||||
else
|
||||
gameRunning = false;
|
||||
}
|
||||
|
||||
|
||||
private void playerTurn() {
|
||||
System.out.println("====" + Colors.YELLOW + " YOUR TURN " + Colors.RESET + "====");
|
||||
System.out.println(player.getName() + "-> HP: " + player.getHp() + " | MP: " + player.getMp() + " | level: " + player.getLevel() + " | XP: " + player.getXp());
|
||||
System.out.println(currentEnemy.getName() + "-> HP: " + currentEnemy.getHp() + " | MP: " + currentEnemy.getMp());
|
||||
System.out.println("\n");
|
||||
var action = actionManager.userChooseAction();
|
||||
|
||||
AttackResult result = attackCalculator.calculate(player, currentEnemy, action);
|
||||
|
||||
int totalDamage = result.getDamageToTarget();
|
||||
int healAmount = result.getHealSelf();
|
||||
boolean isDefend = result.isDefended();
|
||||
|
||||
if (totalDamage > 0) {
|
||||
System.out.println(currentEnemy.getName() + " got " + totalDamage + " damage");
|
||||
currentEnemy.takeDamage(totalDamage);
|
||||
}
|
||||
|
||||
if (healAmount > 0) {
|
||||
player.heal(healAmount);
|
||||
if (player.getHp() < player.getMaxHP())
|
||||
System.out.println(player.getName() + "healed " + healAmount + " HP");
|
||||
}
|
||||
|
||||
if (isDefend) {
|
||||
player.defend();
|
||||
System.out.println(player.getName() + " will defend (50% damage)");
|
||||
}
|
||||
System.out.println("\n");
|
||||
}
|
||||
|
||||
private void enemyTurn() {
|
||||
System.out.println("====" + Colors.YELLOW + " ENEMY TURN " + Colors.RESET + "====\n");
|
||||
var action = actionManager.botChooseAction();
|
||||
|
||||
System.out.println("enemy random choose action: " + Colors.RED + action + Colors.RESET);
|
||||
|
||||
AttackResult result = attackCalculator.calculate(currentEnemy, player, action);
|
||||
|
||||
int totalDamage = result.getDamageToTarget();
|
||||
int healAmount = result.getHealSelf();
|
||||
boolean isDefend = result.isDefended();
|
||||
|
||||
|
||||
if (totalDamage > 0) {
|
||||
System.out.println(player.getName() + " got " + totalDamage + " damage");
|
||||
player.takeDamage(totalDamage);
|
||||
}
|
||||
|
||||
if (healAmount > 0) {
|
||||
currentEnemy.heal(healAmount);
|
||||
if (currentEnemy.getHp() < currentEnemy.getMaxHP())
|
||||
System.out.println(currentEnemy.getName() + " healed " + healAmount + " HP");
|
||||
|
||||
}
|
||||
|
||||
if (isDefend) {
|
||||
currentEnemy.defend();
|
||||
System.out.println(currentEnemy.getName() + " will defend (50% damage)");
|
||||
}
|
||||
|
||||
|
||||
System.out.println("\n");
|
||||
|
||||
}
|
||||
|
||||
private void victory() {
|
||||
|
||||
System.out.println(Colors.GREEN + "Victory!" + Colors.RESET);
|
||||
|
||||
currentEnemy.rewardXp(player);
|
||||
|
||||
checkKeyDrop();
|
||||
|
||||
player.restore();
|
||||
|
||||
currentEnemy = null;
|
||||
}
|
||||
|
||||
private void checkKeyDrop() {
|
||||
|
||||
if (Math.random() * 100 > 20)
|
||||
return;
|
||||
|
||||
if (currentEnemy instanceof Goblin && !hasGoblinKey) {
|
||||
hasGoblinKey = true;
|
||||
System.out.println("Goblin Key obtained!");
|
||||
}
|
||||
|
||||
else if (currentEnemy instanceof Skeleton && ! hasSkeletonKey) {
|
||||
hasSkeletonKey = true;
|
||||
System.out.println("Skeleton Key obtained!");
|
||||
}
|
||||
|
||||
else if (currentEnemy instanceof Vampire && !hasVampireKey) {
|
||||
hasVampireKey = true;
|
||||
System.out.println("Vampire Key obtained!");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasAllKeys() {
|
||||
return hasGoblinKey && hasSkeletonKey && hasVampireKey;
|
||||
}
|
||||
|
||||
private void fightDragon() {
|
||||
|
||||
currentEnemy = new Dragon();
|
||||
|
||||
System.out.println("The Dragon Appears!");
|
||||
|
||||
startCombat();
|
||||
|
||||
if (player.isLive())
|
||||
System.out.println("YOU SAVED JAVANEST!");
|
||||
else
|
||||
System.out.println("The Dragon has defeated you...");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user