Sobottasgithub e2f5e70d70 Init
2025-11-09 15:17:21 +01:00

352 lines
12 KiB
Java

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class MainFX extends Application {
private TextArea logArea;
private Label heroLabel;
private Label monsterLabel;
private Button attackButton, specialButton, healButton, newGameButton;
private ToggleButton autoToggle;
private ProgressBar heroHpBar;
private ProgressBar monsterHpBar;
private Held hero;
private Monster monster;
private volatile boolean autoFightRunning = false;
private Thread autoThread;
private int healPotionCount = 3;
// entry point
public static void main(String[] args) {
System.out.println("Starte JavaFX...");
launch(args);
}
@Override
public void start(Stage primaryStage) {
try {
primaryStage.setTitle("RPG - JavaFX GUI");
VBox leftPane = new VBox(10);
leftPane.setPadding(new Insets(12));
leftPane.setPrefWidth(300);
Label chooseLabel = new Label("Held erstellen");
ChoiceBox<String> typeChoice = new ChoiceBox<>();
typeChoice.getItems().addAll("Krieger", "Schurke", "Elf", "Zauberer");
typeChoice.setValue("Krieger");
// Waffenauswahl (für alle außer Schurke)
Label weaponLabel = new Label("Waffe wählen:");
ChoiceBox<String> weaponChoice = new ChoiceBox<>();
weaponChoice.getItems().addAll("Schwert", "Axt", "Dolch", "Sichel");
weaponChoice.setValue("Schwert");
Label materialLabel = new Label("Material:");
ChoiceBox<String> materialChoice = new ChoiceBox<>();
materialChoice.getItems().addAll("Eisen", "Holz", "Knochen", "Stahl");
materialChoice.setValue("Eisen");
TextField nameField = new TextField();
nameField.setPromptText("Name des Helden");
newGameButton = new Button("Neues Spiel");
newGameButton.setMaxWidth(Double.MAX_VALUE);
attackButton = new Button("Angreifen");
specialButton = new Button("Spezialangriff");
healButton = new Button("Heiltrank benutzen");
autoToggle = new ToggleButton("Automatisch kämpfen");
for (ButtonBase b : new ButtonBase[] {attackButton, specialButton, healButton, autoToggle}) {
b.setMaxWidth(Double.MAX_VALUE);
b.setDisable(true);
}
leftPane
.getChildren()
.addAll(
chooseLabel,
typeChoice,
weaponLabel,
weaponChoice,
materialLabel,
materialChoice,
nameField,
newGameButton);
// Typ-Wahl: Wenn Schurke gewählt ist, Waffenauswahl deaktivieren, Spezial nur für Schurke/Elf
typeChoice.setOnAction(
ev -> {
String t = typeChoice.getValue();
boolean isRogue = "Schurke".equals(t);
weaponChoice.setDisable(isRogue);
materialChoice.setDisable(isRogue);
specialButton.setDisable(!("Schurke".equals(t) || "Elf".equals(t)));
});
VBox rightPane = new VBox(10);
rightPane.setPadding(new Insets(12));
rightPane.setAlignment(Pos.TOP_LEFT);
heroLabel = new Label("Held: ---");
heroHpBar = new ProgressBar(0);
heroHpBar.setPrefWidth(600);
monsterLabel = new Label("Monster: ---");
monsterHpBar = new ProgressBar(0);
monsterHpBar.setPrefWidth(600);
logArea = new TextArea();
logArea.setEditable(false);
logArea.setWrapText(true);
logArea.setPrefSize(600, 340);
// Action buttons über der Anzeige (log)
HBox actionBox = new HBox(8);
actionBox.setAlignment(Pos.CENTER_LEFT);
actionBox.getChildren().addAll(attackButton, specialButton, healButton, autoToggle);
rightPane
.getChildren()
.addAll(
heroLabel,
heroHpBar,
monsterLabel,
monsterHpBar,
actionBox,
new Label("Spiel-Log:"),
logArea);
Label infoLabel =
new Label("Tipps: Spezialangriff verursacht mehr Schaden. Heiltränke = begrenzt.");
BorderPane root = new BorderPane();
root.setLeft(leftPane);
root.setCenter(rightPane);
root.setBottom(infoLabel);
BorderPane.setAlignment(infoLabel, Pos.CENTER);
BorderPane.setMargin(infoLabel, new Insets(8));
Scene scene = new Scene(root, 960, 550);
primaryStage.setScene(scene);
primaryStage.show();
// --- Event Handler ---
newGameButton.setOnAction(
e -> {
String type = typeChoice.getValue();
String name = nameField.getText().trim();
if (name.isEmpty()) name = type;
String weapon = weaponChoice.getValue();
String material = materialChoice.getValue();
createNewGame(type, name, weapon, material);
});
attackButton.setOnAction(e -> runOneRound(false));
specialButton.setOnAction(e -> runOneRound(true));
healButton.setOnAction(e -> useHealPotion());
autoToggle.setOnAction(
e -> {
if (autoToggle.isSelected()) startAutoFight();
else stopAutoFight();
});
primaryStage.setOnCloseRequest(
e -> {
stopAutoFight();
Platform.exit();
System.exit(0);
});
appendLog("Willkommen zum RPG (GUI). Erstelle zuerst einen Helden.");
} catch (Exception e) {
e.printStackTrace();
}
}
// ---- Ab hier: deine Spiellogik-Methoden ----
private void createNewGame(String typ, String name, String weaponType, String material) {
try {
Waffe weapon = new Waffe(weaponType, material);
if (typ.equals("Krieger")) {
hero = new Krieger(name, 30, 6, 1.2);
} else if (typ.equals("Schurke")) {
// Waffen in Schurken anders genutzt
Waffe dolch = new Waffe("Dolch", "stahl");
Waffe axt = new Waffe("Axt", "stahl");
hero = new Schurke(name, 24, 5, dolch, axt);
} else if (typ.equals("Zauberer")) {
hero = new Zauberer(name, 22, 5);
} else {
hero = new Elf(name, 22, 5);
}
hero.setWaffe(weapon);
monster = generateMonster();
healPotionCount = 3;
appendLog(
String.format(
"Neues Spiel gestartet: %s (%s) vs %s HP:%d DMG:%d",
hero.getName(),
hero.getTyp(),
monster.getName(),
monster.getHp(),
monster.getDamage()));
updateStatusLabels();
for (ButtonBase b : new ButtonBase[] {attackButton, specialButton, healButton, autoToggle}) {
b.setDisable(false);
}
// Spezial nur für Schurke und Elf
specialButton.setDisable(!("Schurke".equals(typ) || "Elf".equals(typ)));
} catch (Exception ex) {
appendLog("Fehler beim Erstellen des Helden: " + ex.getMessage());
ex.printStackTrace();
}
}
private Monster generateMonster() {
String[] names = {"Goblin", "Zombie", "Ork", "Skelett", "Troll", "Drache"};
String name = names[(int) (Math.random() * names.length)];
int baseHp = 18 + (int) (Math.random() * 10);
int baseDmg = 3 + (int) (Math.random() * 5);
Monster m = new Monster(baseHp, baseDmg, name);
return m;
}
private void runOneRound(boolean special) {
if (hero == null || monster == null) return;
if (hero.getHp() <= 0 || monster.getHp() <= 0) return;
if (special) {
// Spezialfähigkeiten nur für Elf (SpeedBoost) und Schurke (Doppelangriff)
if (hero instanceof Elf) {
((Elf) hero).speedBoostAktivieren();
appendLog(hero.getName() + " aktiviert SpeedBoost!");
hero.angreifen(monster);
} else if (hero instanceof Schurke) {
// Spezieller Schurke-Angriff: wechselt zur Axt, führt Angriff aus, dann normaler Angriff
String msg = ((Schurke) hero).specialAngriff(monster);
appendLog(msg);
if (monster.getHp() > 0) {
// zusätzlich ein normaler Folgeangriff
hero.angreifen(monster);
appendLog(hero.getName() + " greift nach dem Spezialangriff erneut an!");
}
} else {
appendLog("Spezialfähigkeit nicht verfügbar für " + hero.getTyp());
hero.angreifen(monster);
}
} else {
hero.angreifen(monster);
appendLog(hero.getName() + " greift an!");
}
updateStatusLabels();
if (monster.getHp() <= 0) {
appendLog("Monster " + monster.getName() + " besiegt!");
disableActions();
return;
}
int mdmg = monster.getDamage();
hero.setHp(hero.getHp() - mdmg);
appendLog(monster.getName() + " kontert für " + mdmg + " Schaden!");
updateStatusLabels();
if (hero.getHp() <= 0) {
appendLog(hero.getName() + " ist gefallen. Spiel Ende.");
disableActions();
}
}
private void disableActions() {
for (ButtonBase b : new ButtonBase[] {attackButton, specialButton, healButton, autoToggle}) {
b.setDisable(true);
}
autoToggle.setSelected(false);
stopAutoFight();
}
private void useHealPotion() {
if (healPotionCount <= 0) {
appendLog("Keine Heiltränke mehr!");
return;
}
hero.setHp(hero.getHp() + 10);
healPotionCount--;
appendLog(hero.getName() + " trinkt einen Heiltrank (+10 HP). Verbleibend: " + healPotionCount);
updateStatusLabels();
}
private void updateStatusLabels() {
if (hero != null) {
heroLabel.setText(
String.format(
"Held: %s (%s) DMG: %d Heiltränke: %d",
hero.getName(), hero.getTyp(), hero.getDamage(), healPotionCount));
double hpFraction = hero.getMaxHp() > 0 ? (double) hero.getHp() / hero.getMaxHp() : 0;
heroHpBar.setProgress(Math.max(0.0, Math.min(1.0, hpFraction)));
heroHpBar.setTooltip(new Tooltip(hero.getHp() + " / " + hero.getMaxHp()));
} else heroLabel.setText("Held: ---");
if (monster != null) {
monsterLabel.setText(
String.format(
"Monster: %s HP: %d DMG: %d",
monster.getName(), monster.getHp(), monster.getDamage()));
double mhpFraction =
monster.getMaxHp() > 0 ? (double) monster.getHp() / monster.getMaxHp() : 0;
monsterHpBar.setProgress(Math.max(0.0, Math.min(1.0, mhpFraction)));
monsterHpBar.setTooltip(new Tooltip(monster.getHp() + " / " + monster.getMaxHp()));
} else monsterLabel.setText("Monster: ---");
}
private void appendLog(String text) {
Platform.runLater(() -> logArea.appendText(text + "\n"));
}
private void startAutoFight() {
if (autoFightRunning) return;
autoFightRunning = true;
appendLog("Auto-Kampf gestartet.");
autoThread =
new Thread(
() -> {
while (autoFightRunning && hero.getHp() > 0 && monster.getHp() > 0) {
Platform.runLater(() -> runOneRound(false));
try {
Thread.sleep(800);
} catch (InterruptedException ignored) {
}
}
Platform.runLater(
() -> {
autoToggle.setSelected(false);
appendLog("Auto-Kampf beendet.");
});
autoFightRunning = false;
});
autoThread.setDaemon(true);
autoThread.start();
}
private void stopAutoFight() {
autoFightRunning = false;
if (autoThread != null) autoThread.interrupt();
}
}