diff --git a/pom.xml b/pom.xml index 3979246..da0c8b2 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,13 @@ maven-jar-plugin 3.0.2 + + + + de.wolc.gui.Gui + + + maven-install-plugin diff --git a/src/main/java/de/wolc/gui/Game.java b/src/main/java/de/wolc/gui/Game.java index ce500bc..8c06879 100644 --- a/src/main/java/de/wolc/gui/Game.java +++ b/src/main/java/de/wolc/gui/Game.java @@ -1,8 +1,13 @@ package de.wolc.gui; +import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Random; import de.wolc.MultiUse; +import de.wolc.gui.PapierObjekt; +import de.wolc.spiel.Farbe; import de.wolc.spiel.Spieler; import de.wolc.spiel.locher.Lochprozess; import de.wolc.spiel.papier.A4; @@ -11,45 +16,117 @@ import de.wolc.spiel.papier.Konfetti; import de.wolc.spiel.papier.Papier; import de.wolc.spiel.papier.PapierStapel; -//TODO: '*' entfernen und nur die benutzen objekte importieren +import de.wolc.gui.LocherPapier; + import javafx.stage.Stage; import javafx.scene.Scene; -import javafx.scene.image.*; -import javafx.scene.layout.*; -import javafx.geometry.*; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.BackgroundImage; +import javafx.scene.layout.BackgroundRepeat; +import javafx.scene.layout.BackgroundPosition; +import javafx.scene.layout.BackgroundSize; +import javafx.scene.layout.Background; +import javafx.scene.layout.VBox; +import javafx.scene.layout.HBox; +import javafx.geometry.Pos; +import javafx.geometry.Insets; import javafx.scene.control.Label; -import javafx.scene.paint.*; +import javafx.scene.control.ToggleButton; +import javafx.scene.control.ToggleGroup; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.paint.Color; import javafx.animation.AnimationTimer; import javafx.event.EventHandler; -import javafx.scene.input.*; -import javafx.scene.shape.*; +import javafx.scene.paint.ImagePattern; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; +import javafx.scene.shape.Rectangle; +import javafx.scene.shape.Shape; public class Game{ private final String windowTitle = "World of Locher Craft"; private final String backgroundImageLocation = "de/wolc/gui/images/Test_Bild.jpg"; private Spieler spieler; - private Class currentPapierFormat; private Rectangle locher_new; + private AnchorPane gameArea; + private Stage stage; + private AnimationTimer timer; + + private static final Random RANDOM = new Random(); //Game Variables - private int remainingTimeAvailable = 30; - private boolean hasLoched = false; + private double remainingTimeAvailable = 30d; //Variables for Countdown timer - private long lastNanoTimeTimer = 0; - private String leadingZero; + private long firstNanoTimeTimer = 0; + private double timeToNextPapier = 0; + + //Papierstapel erstellen + private PapierStapel stapel_A4; + private PapierStapel stapel_A5; + private PapierStapel stapel_A6; + + //Diverse Nodes + private Label score, remainingTime, formatLabel, papierLabel, locherCooldown; + private ToggleButton formatA4Button, formatA5Button, formatA6Button; + private ToggleGroup formatGroup; + private HashMap scoreLabels = new HashMap<>(); + private Alert speichernFehler, ladeFehler; + + private ArrayList locherPapier= new ArrayList(); public Game () { - this.spieler = new Spieler(); - this.lastNanoTimeTimer = System.currentTimeMillis(); - this.currentPapierFormat = A4.class; + //TODO: ToggleButtons müssen angepasst werden an das letzte SaveGame falls vorhanden + try { + this.spieler = (Spieler) Gui.DB.laden("spieler"); + } catch (Exception e) { + ladeFehler = new Alert(AlertType.INFORMATION); + ladeFehler.setTitle("Kein Speicherstand gefunden!"); + ladeFehler.setHeaderText("Es wurde kein Speicherstand gefunden oder es konnte kein Speicherstand geladen werden."); + ladeFehler.setContentText(e.toString()); + ladeFehler.setResult(ButtonType.OK); + ladeFehler.showAndWait(); + e.printStackTrace(); + + this.spieler = null; + } + if (this.spieler == null) { + this.spieler = new Spieler(); + } + this.firstNanoTimeTimer = 0; + } + + private void updateLabels() { + // Score einteilen nach Farbe + HashMap hash = new HashMap<>(); + for(Konfetti konfetti : this.spieler.getKonfetti()) { + Farbe farbe = konfetti.getFarbe(); + Integer zahl = hash.getOrDefault(farbe, 0) + 1; + hash.put(farbe, zahl); + } + for(Farbe farbe : Farbe.values()) { + Label label = this.scoreLabels.get(farbe); + Integer zahl = hash.getOrDefault(farbe, 0); + label.setText(" " + farbe.getAnzeigeName() + ": " + zahl); + } + this.score.setText("Score: " + this.spieler.getKonfetti().size()); + // Sonstige Stats + this.formatLabel.setText("Format: " + this.spieler.getLocher().getFormat().getSimpleName()); + this.papierLabel.setText("Stapel: " + this.spieler.getLocher().getStapel().groesse()); + this.locherCooldown.setText("Cooldown: " + Math.round(spieler.getLocher().getCooldown() * 10) / 10 + "s"); + remainingTime.setText("Zeit: " + Math.round(this.remainingTimeAvailable * 10d) / 10d + "s"); } public Scene GameMainStage(Stage stage){ + this.stage = stage; + //Main Orientation Node and initale settings BorderPane mainPane = new BorderPane(); - //mainPane.setStyle("-fx-background-repeat: repeat"); //Setting and creating the new Scene Scene gameScene = new Scene(mainPane); @@ -67,51 +144,80 @@ public Scene GameMainStage(Stage stage){ mainPane.setBackground(new Background(backgroundImageGame)); //Papierstapel creation - PapierStapel stapel_A4 = new PapierStapel<>(A4.class); - PapierStapel stapel_A5 = new PapierStapel<>(A5.class); - PapierStapel stapel_A6 = new PapierStapel<>(A6.class); - this.spieler.getLocher().setFormat(this.currentPapierFormat); + stapel_A4 = new PapierStapel<>(A4.class); + stapel_A5 = new PapierStapel<>(A5.class); + stapel_A6 = new PapierStapel<>(A6.class); + this.spieler.getLocher().setFormat(A4.class); this.spieler.getLocher().einlegen(stapel_A4); //Creating the Component-nodes //Creating the VBox for the right Output VBox rightVBox = new VBox(); - //Creating Label for outputing score - Label score = new Label(); - score.setTextFill(Color.RED); - score.setText("Score: " + spieler.getKonfetti().size()); + // Labels erstellen + score = new Label(); + papierLabel = new Label(); + formatLabel = new Label(); + remainingTime = new Label(); + locherCooldown = new Label(); + locherCooldown.setTextFill(Color.WHITE); + papierLabel.setTextFill(Color.WHITE); + score.setTextFill(Color.WHITE); + remainingTime.setTextFill(Color.WHITE); + formatLabel.setTextFill(Color.WHITE); + rightVBox.getChildren().addAll(remainingTime, score); + for(Farbe farbe : Farbe.values()) { + Label label = new Label(); + label.setTextFill(farbe.getGuiFarbe()); + this.scoreLabels.put(farbe, label); + rightVBox.getChildren().add(label); + } + rightVBox.getChildren().addAll(locherCooldown, formatLabel, papierLabel); + this.updateLabels(); + + //Adding the Format ToggleButtons + ToggleGroup + HBox formatBox = new HBox(); + formatGroup = new ToggleGroup(); + formatBox.setPadding(new Insets(20, 5 , 20 ,5)); + + formatA4Button = new ToggleButton("A4"); + formatA4Button.setSelected(true); + formatA4Button.setToggleGroup(formatGroup); + formatA4Button.setOnMousePressed((MouseEvent e) -> { + papierWechsel(stapel_A4, A4.class); + }); + + formatA5Button = new ToggleButton("A5"); + formatA5Button.setSelected(false); + formatA5Button.setToggleGroup(formatGroup); + formatA5Button.setOnMousePressed((MouseEvent e) -> { + papierWechsel(stapel_A5, A5.class); + }); + + formatA6Button = new ToggleButton("A6"); + formatA6Button.setSelected(false); + formatA6Button.setToggleGroup(formatGroup); + formatA6Button.setOnMousePressed((MouseEvent e) -> { + papierWechsel(stapel_A6, A6.class); + }); + + formatBox.getChildren().addAll(formatA4Button, formatA5Button, formatA6Button); + mainPane.setLeft(formatBox); + BorderPane.setAlignment(formatBox, Pos.CENTER_LEFT); - //Creating Label for remaining Time - Label remainingTime = new Label(); - remainingTime.setTextFill(Color.RED); - remainingTime.setText("Zeit: " + remainingTimeAvailable + "s"); //Adding remainingTime and score to VBox - rightVBox.getChildren().addAll(score, remainingTime); //Adding VBox to mainPane mainPane.setRight(rightVBox); BorderPane.setAlignment(rightVBox, Pos.CENTER); //Spawn the paper - AnchorPane gameArea = new AnchorPane(); + gameArea = new AnchorPane(); //Setting height of paperPane gameArea.setMinWidth(((double)windowSize[0] * 0.8)); gameArea.setMinHeight(((double)windowSize[1] * 0.8)); - //PAPER - Image paperImage = new Image("de/wolc/gui/images/paper_master.png"); - Rectangle paper_new = new Rectangle(); - paper_new.setHeight(paperImage.getHeight()); - paper_new.setWidth(paperImage.getWidth()); - paper_new.setFill(new ImagePattern(paperImage)); - - //Setting the default Anchor points for the paper - AnchorPane.setBottomAnchor(paper_new, 100.0); - AnchorPane.setLeftAnchor(paper_new, 100.0); - - //LOCHER String skin = spieler.getLocher().getSkin(); @@ -125,156 +231,188 @@ public Scene GameMainStage(Stage stage){ AnchorPane.setBottomAnchor(locher_new, stage.getWidth() * 0.20); AnchorPane.setLeftAnchor(locher_new, stage.getHeight() * 0.65); - - //Paper_new Mouse Events - paper_new.setOnMouseDragged(new EventHandler() { - @Override - public void handle(MouseEvent e){ - //Change the location if the cursor has moved - paper_new.setTranslateX(paper_new.getTranslateX() + (e.getX() - 175)); - paper_new.setTranslateY(paper_new.getTranslateY() + (e.getY() - 110)); - - - if(checkForCollision(paper_new, locher_new)){ - paper_new.setFill(Color.BLACK); - //TODO: Hier muss noch weiteres gemacht werden - - //PapierStapel -> ablegen() aufnehmen() - //Papier auf den Papierstapel legen und ein neues Objekt Papier erzeugen und anzeigen lassen - if(currentPapierFormat == A4.class){ - A4 a4 = new A4(); - stapel_A4.ablegen(a4); - - //Wieder an Ursprungspunkt zurücksetzen - - - - e.consume(); - } - else if(currentPapierFormat == A5.class){ - A5 a5 = new A5(); - stapel_A5.ablegen(a5); - } - else if(currentPapierFormat == A6.class){ - A6 a6 = new A6(); - stapel_A6.ablegen(a6); - } - - - } - else{ - paper_new.setFill(new ImagePattern(paperImage)); - } - } - }); - - //Locher_new Mouse Events locher_new.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent e) { - if (spieler.getLocher().getCooldown() == 0) { + //Abgleichen des gedrückten Buttons und des Cooldowns + if (e.getButton() == MouseButton.PRIMARY && spieler.getLocher().getCooldown() == 0) { Lochprozess prozess = spieler.getLocher().lochen(); ArrayList spielerKonfetti = spieler.getKonfetti(); spielerKonfetti.addAll(prozess.getKonfetti()); } + //Abgleichen des gedrückten Buttons + if ( e.getButton() == MouseButton.SECONDARY) { + PapierStapel stapel = spieler.getLocher().getStapel(); + Papier removedPapier = stapel.entnehmen(); + + //entfernen des Eingelgeten Bilds wenn kein Papier mehr im Locher + if (removedPapier != null) { + new PapierObjekt(Game.this, removedPapier); + for (int i = 0; i <= locherPapier.size(); i++) { + LocherPapier todeltetPapier = locherPapier.get(i); + if (todeltetPapier.getPapier() == removedPapier){ + ArrayList todeletRectangle = todeltetPapier.getPapierListe(); + locherPapier.remove(i); + for (int a = 0; a <= todeletRectangle.size(); a++) { + Rectangle deletLocherPapier = todeletRectangle.get(a); + gameArea.getChildren().remove(deletLocherPapier); + } + break; + + } + + } + + } + } } }); - /*locher_new.setOnMouseDragged(new EventHandler() { - @Override - public void handle(MouseEvent e){ - checkForCollision(paper_new, locher_new, paperImage); - } - });*/ + //creating a new Animation Timer for refreshing the GUI - new AnimationTimer(){ + this.timer = new AnimationTimer(){ public void handle(long currentNanoTime){ + if (firstNanoTimeTimer == 0) { + firstNanoTimeTimer = currentNanoTime; + } //Getting new and last TimeStamp in Miliseconds and calculating - long elapsedNanoSeconds = (System.currentTimeMillis() - lastNanoTimeTimer); - double elapsedSeconds = ((elapsedNanoSeconds / 1000d)); + long elapsedNanoSeconds = currentNanoTime - firstNanoTimeTimer; + double elapsedSeconds = ((elapsedNanoSeconds / 1000000000d)); + firstNanoTimeTimer = currentNanoTime; //Triggering Cooldown and giving him the elapsedSeconds spieler.tick(elapsedSeconds); - if(hasLoched) { - //Setting the new Score - score.setText("Score: " + spieler.getKonfetti().size()); - hasLoched = false; + timeToNextPapier -= elapsedSeconds; + remainingTimeAvailable -= elapsedSeconds; + + if (timeToNextPapier <= 0) { + spawnPapier(); + timeToNextPapier = 0.5d + (2d - 0.5d) * RANDOM.nextDouble(); } - if(elapsedSeconds >= 1){ - - //Check for end of Time - if(remainingTimeAvailable == 0){ - //TODO: End Game and Display Score Screen - } - - //Changing the Time - remainingTimeAvailable = remainingTimeAvailable - 1; - //Setting a leading Zero if reamingTimeAvailable is one digit - if (remainingTimeAvailable < 10) { - leadingZero = "0"; - } - else { - leadingZero = ""; - } - remainingTime.setText("Zeit: " + leadingZero + + remainingTimeAvailable + "s"); - - lastNanoTimeTimer = System.currentTimeMillis(); + //Check for end of Time + if(remainingTimeAvailable <= 0) { + Game.this.spielEnde(); } - /** else{ - //Notice if Timeing is not correct - remainingTime.setText("Zeit Asyncron!"); - lastNanoTimeTimer = System.currentTimeMillis(); - FIXME: Es wird immer else Ausgegeben + + Game.this.updateLabels(); + + PapierStapel stapel = spieler.getLocher().getStapel(); + if (stapel.groesse() == 0) { + } - */ - - } - }.start(); + }; + //Add Nodes to the AnchorPane - gameArea.getChildren().addAll(locher_new, paper_new); + gameArea.getChildren().add(locher_new); //Add the elements to the Main Pane mainPane.setCenter(gameArea); //Set Window Titel stage.setTitle(windowTitle); + + this.timer.start(); + return gameScene; } + public void spielEnde() { + this.timer.stop(); + try { + Gui.DB.speichern("spieler", this.spieler); + } catch (IOException e) { + speichernFehler = new Alert(AlertType.WARNING); + speichernFehler.setTitle("Fehler beim Speichern deines Spielstands!"); + speichernFehler.setHeaderText("Beim Speichern deines Spielstands ist ein Fehler aufgetreten."); + speichernFehler.setContentText(e.toString()); + speichernFehler.setResult(ButtonType.OK); + speichernFehler.showAndWait(); + e.printStackTrace(); + } + ItemShopMenu menu = new ItemShopMenu(); + stage.setScene(menu.ItemShopStage(this.stage)); + } + + public void spawnPapier() { + int format = RANDOM.nextInt(3); + Papier papier; + if(format == 0) { papier = new A4(); } + else if(format == 1) { papier = new A5(); } + else { papier = new A6(); } + papier.setFarbe(Farbe.zufallsfarbe()); + new PapierObjekt(Game.this, papier); + } + /** * Prüft, ob sich die beiden übergebenen Shapes überschneiden, wenn ja, dann wird die Anzeige angepasst * @return true=collision vorhanden, false= keine collision vorhanden */ - private boolean checkForCollision(Shape paper, Shape locher){ - boolean collisionDetection = false; - - Shape ueberschneidung = Shape.intersect(paper, locher); - if(ueberschneidung.getBoundsInLocal().getWidth() != -1){ - collisionDetection = true; - } + private boolean checkForCollision(Shape shape1, Shape shape2){ + Shape ueberschneidung = Shape.intersect(shape1, shape2); + return !ueberschneidung.getBoundsInLocal().isEmpty(); + } - if(collisionDetection){ - return true; - } - else{ - return false; - } + public AnchorPane getArea() { + return this.gameArea; } public boolean checkForLocherCollision(Shape papier) { return checkForCollision(papier, locher_new); } + public Spieler getCurrentSpieler(){ + return this.spieler; + } + + @SuppressWarnings("unchecked") public void papierAufLocherGezogen(PapierObjekt objekt) { - // penis - if (this.currentPapierFormat == objekt.getPapier().getClass()) { - this.spieler.getLocher().getStapel().ablegen(objekt.getPapier()); + // penis 🍆 + Class papierTyp = objekt.getPapier().getClass(); + if (this.spieler.getLocher().getFormat() == papierTyp) { + PapierStapel stapel = this.spieler.getLocher().getStapel(); + boolean abgelegt; + if(papierTyp == A4.class){ + PapierStapel stapel_A4 = (PapierStapel)stapel; + abgelegt = stapel_A4.ablegen((A4)objekt.getPapier()); + } + else if(papierTyp == A5.class){ + PapierStapel stapel_A5 = (PapierStapel)stapel; + abgelegt = stapel_A5.ablegen((A5)objekt.getPapier()); + } + else if(papierTyp == A6.class){ + PapierStapel stapel_A6 = (PapierStapel)stapel; + abgelegt = stapel_A6.ablegen((A6)objekt.getPapier()); + } else { + abgelegt = false; + } + if (abgelegt) { + locherPapier.add(new LocherPapier(Game.this, spieler.getLocher().getStapel().groesse(), locher_new, objekt.getPapier())); + objekt.zerstoeren(); + } + } + } + + /** + * Wechselt das Papier anhand des ausgewählten neuen Formats + * @param papierStapel - der neue Papierstapel des Formats + * @param neuesPapierformat - das neue Format mit .class + */ + private void papierWechsel(PapierStapel papierStapel, Class neuesPapierformat){ + // Alten Stapel rausnehmen + PapierStapel alterStapel = this.spieler.getLocher().entnehmen(); + if (alterStapel != null) { + while(alterStapel.groesse() > 0) { + alterStapel.entnehmen(); + } } + // Neue Auswahl setzen + this.spieler.getLocher().setFormat(neuesPapierformat); + this.spieler.getLocher().einlegen(papierStapel); } } \ No newline at end of file diff --git a/src/main/java/de/wolc/gui/Gui.java b/src/main/java/de/wolc/gui/Gui.java index cb31fde..7bb1cee 100644 --- a/src/main/java/de/wolc/gui/Gui.java +++ b/src/main/java/de/wolc/gui/Gui.java @@ -17,6 +17,8 @@ * die "main(String[] args)" Methode in "Gui" und wählt "Debug". */ public class Gui { + public static final Datenbank DB = new Datenbank(); + /** * Main Methode */ diff --git a/src/main/java/de/wolc/gui/ItemShopMenu.java b/src/main/java/de/wolc/gui/ItemShopMenu.java new file mode 100755 index 0000000..409bd4a --- /dev/null +++ b/src/main/java/de/wolc/gui/ItemShopMenu.java @@ -0,0 +1,199 @@ +package de.wolc.gui; + +import javafx.stage.Stage; +import javafx.scene.Scene; +import javafx.scene.Node; +import javafx.scene.layout.*; +import javafx.scene.control.Label; +import javafx.scene.input.MouseEvent; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.image.Image; +import javafx.scene.shape.Rectangle; +import javafx.scene.paint.ImagePattern; +import javafx.geometry.*; + +import java.util.HashMap; + +import de.wolc.MultiUse; +import de.wolc.spiel.Farbe; +import de.wolc.spiel.Spieler; +import de.wolc.spiel.papier.Konfetti; +import javafx.event.*; + +public class ItemShopMenu { + private static final String TITLE = "World of Locher Craft - 💲 Pay2Win 💲"; + private static final String[] SKINS = { + "locher_base", + "locher_baumblaetter", + "locher_beach", + "locher_blue", + "locher_coallblue", + "locher_copper", + "locher_deutschland", + "locher_gold", + "locher_green", + "locher_grey", + "locher_hflagge", + "locher_kleeblatt", + "locher_lightpurple", + "locher_lila", + "locher_love", + "locher_matrix", + "locher_microsoft", + "locher_mylittlepony", + "locher_pirate", + "locher_spooky", + "locher_storm", + "locher_tank", + "locher_unicorn" + }; + + private Spieler spieler; + private Stage stage; + + private HashMap scoreLabels = new HashMap<>(); + private Label scoreLabel; + + public Scene ItemShopStage(Stage stage) { + this.stage = stage; + try { + this.spieler = (Spieler) Gui.DB.laden("spieler"); + } catch (Exception e) { + this.spieler = new Spieler(); + // TODO: Fehlermeldung ausgeben dass der Spieler nicht geladen werden konnte + e.printStackTrace(); + } + + // BorderPane + BorderPane settingsPane = new BorderPane(); + settingsPane.setMinHeight(100); + + // GridPane + GridPane settingsGridPane = new GridPane(); + settingsGridPane.setHgap(1); + settingsGridPane.setVgap(1); + settingsGridPane.setMinHeight(100); + + // Buttons + + // =============================================== + // SKIN SHOP + // =============================================== + + // Get Scene size and create a new Instance + settingsPane.setTop(this.buttons()); + settingsPane.setLeft(this.scorescreen()); + settingsPane.setCenter(settingsGridPane); + settingsPane.setBottom(this.skinshop()); + + MultiUse mu = new MultiUse(); + int[] windowSize = mu.GetScreenSize(); + Scene sceneMainWindow = new Scene(settingsPane, windowSize[0] / 2d, windowSize[1] / 2d); + + // Updating the Title + stage.setTitle(TITLE); + + this.scoreLabelsAktualisieren(); + + return sceneMainWindow; + } + + private Node buttons() { + GridPane grid = new GridPane(); + grid.setVgap(1); + Button backButton = new Button("◀ Zur\u00fcck ◀"); + backButton.addEventHandler(ActionEvent.ACTION, (ActionEvent actionEvent) -> { + this.zurueck(); + }); + Button continueButton = new Button("▶ Weiterspielen ▶"); + continueButton.addEventHandler(ActionEvent.ACTION, (ActionEvent actionEvent) -> { + this.weiterspielen(); + }); + grid.add(backButton, 0, 0); + grid.add(continueButton, 1, 0); + return grid; + } + + private Node scorescreen() { + GridPane grid = new GridPane(); + grid.setHgap(1); + ScrollPane scroll = new ScrollPane(); + scroll.setContent(grid); + scroll.setPrefWidth(100d); + Farbe[] farben = Farbe.values(); + this.scoreLabel = new Label(); + for(int i = 0; i < farben.length; i++) { + Farbe farbe = farben[i]; + Label label = new Label(); + label.setTextFill(farbe.getGuiFarbe()); + this.scoreLabels.put(farbe, label); + grid.add(label, 0, i + 1); + } + grid.add(this.scoreLabel, 0, 0); + return scroll; + } + + private Node skinshop() { + GridPane grid = new GridPane(); + grid.setVgap(1); + grid.setAlignment(Pos.CENTER); + ScrollPane scroll = new ScrollPane(); + scroll.setContent(grid); + scroll.setPrefHeight(100d); + for(int i = 0; i< SKINS.length; i++) { + String skin = SKINS[i]; + Image locher_skin = new Image("de/wolc/gui/images/" + skin + ".png"); + Rectangle locher_new = new Rectangle(); + locher_new.setOnMouseClicked((MouseEvent e) -> { + this.spieler.getLocher().setSkin(skin); + System.out.println("Neuer Skin gekauft: " + skin); + }); + locher_new.setHeight(80d); + locher_new.setWidth(locher_skin.getWidth() / (locher_skin.getHeight() / 80d)); + locher_new.setFill(new ImagePattern(locher_skin)); + grid.add(locher_new, i, 0); + } + return scroll; + } + + private void scoreLabelsAktualisieren() { + // Score einteilen nach Farbe + HashMap hash = new HashMap<>(); + for(Konfetti konfetti : this.spieler.getKonfetti()) { + Farbe farbe = konfetti.getFarbe(); + Integer zahl = hash.getOrDefault(farbe, 0) + 1; + hash.put(farbe, zahl); + } + for(Farbe farbe : Farbe.values()) { + Label label = this.scoreLabels.get(farbe); + Integer zahl = hash.getOrDefault(farbe, 0); + label.setText(" " + farbe.getAnzeigeName() + ": " + zahl); + } + this.scoreLabel.setText("🎉 Score: " + this.spieler.getKonfetti().size() + " 🎊"); + } + + private void speichern() { + try { + Gui.DB.speichern("spieler", this.spieler); + } catch (Exception e) { + this.spieler = new Spieler(); + // TODO: Fehlermeldung ausgeben dass der Spieler nicht gespeichert werden konnte + e.printStackTrace(); + } + } + + private void weiterspielen() { + this.speichern(); + Game g = new Game(); + stage.setScene(g.GameMainStage(stage)); + stage.setFullScreen(true); + } + + private void zurueck() { + this.speichern(); + MainMenu mm = new MainMenu(); + this.stage.setScene(mm.MainMenuStage(stage)); + this.stage.centerOnScreen(); + } +} \ No newline at end of file diff --git a/src/main/java/de/wolc/gui/LocherPapier.java b/src/main/java/de/wolc/gui/LocherPapier.java new file mode 100644 index 0000000..f9df597 --- /dev/null +++ b/src/main/java/de/wolc/gui/LocherPapier.java @@ -0,0 +1,113 @@ +package de.wolc.gui; + +import java.util.ArrayList; + +import de.wolc.spiel.Spieler; +import de.wolc.spiel.papier.A4; +import de.wolc.spiel.papier.A5; +import de.wolc.spiel.papier.A6; +import de.wolc.spiel.papier.Papier; + +import javafx.scene.image.Image; +import javafx.scene.paint.ImagePattern; +import javafx.scene.shape.Rectangle; +import javafx.geometry.Bounds; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.paint.Color; +import javafx.scene.effect.Light; +import javafx.scene.effect.Lighting; + +public class LocherPapier{ + + private static final Image paperImageA4 = new Image("de/wolc/gui/images/paper_cutout.png"); + private static final Image paperImageA5 = new Image("de/wolc/gui/images/paper_cutout_a5.png"); + private static final Image paperImageA6 = new Image("de/wolc/gui/images/paper_cutout_a6.png"); + + //Klassenvariablen + private Rectangle locherPapier; + private final Game game; + private Spieler spieler; + private ArrayList locherPapiere = new ArrayList(); + private Class aktuellesFormat; + private Alert spielerAlert; + private Papier papier; + private Color currentColor; + + public LocherPapier(Game game, int stapelGroesse, Rectangle locher, Papier papier){ + //Zuweisung der Klassenvariabeln + this.game = game; + this.papier = papier; + this.currentColor = papier.getFarbe().getGuiFarbe(); + this.spieler = game.getCurrentSpieler(); + this.aktuellesFormat = this.spieler.getLocher().getFormat(); + + //Hole die position des lochers + Bounds locherPosition = locher.localToScene(locher.getBoundsInLocal()); + + //Effekt für die Farbe des Papieres setzen + Lighting lighting = new Lighting(); + lighting.setDiffuseConstant(1.0); + lighting.setSpecularConstant(0.0); + lighting.setSpecularExponent(0.0); + lighting.setSurfaceScale(0.0); + lighting.setLight(new Light.Distant(45, 45, currentColor)); + + //Neues papier erzeugen + this.locherPapier = new Rectangle(); + this.locherPapier.toFront(); + this.locherPapier.setEffect(lighting); + + //A4 Papier + if(this.aktuellesFormat == A4.class){ + //Neues A4 Blatt erzeugen + this.locherPapier.setFill(new ImagePattern(paperImageA4)); + this.locherPapier.setWidth(paperImageA4.getWidth()); + this.locherPapier.setHeight(paperImageA4.getHeight()); + this.locherPapier.setTranslateX(locherPosition.getMinX() - 199 - (stapelGroesse * 0.15)); + this.locherPapier.setTranslateY(locherPosition.getMinY() + 249 - (stapelGroesse * 0.15)); + } + //A5 Papier + else if(this.aktuellesFormat == A5.class){ + //Neues A5 Blatt erzeugen + this.locherPapier.setFill(new ImagePattern(paperImageA5)); + this.locherPapier.setWidth(paperImageA5.getWidth()); + this.locherPapier.setHeight(paperImageA5.getHeight()); + this.locherPapier.setTranslateX(locherPosition.getMinX() - 100 - (stapelGroesse * 0.15)); + this.locherPapier.setTranslateY(locherPosition.getMinY() + 290 - (stapelGroesse * 0.15)); + } + //A6 Papier + else if(this.aktuellesFormat == A6.class){ + //Neues A6 Blatt erzeugen + this.locherPapier.setFill(new ImagePattern(paperImageA6)); + this.locherPapier.setWidth(paperImageA6.getWidth()); + this.locherPapier.setHeight(paperImageA6.getHeight()); + this.locherPapier.setTranslateX(locherPosition.getMinX() - 23.5 - (stapelGroesse * 0.15)); + this.locherPapier.setTranslateY(locherPosition.getMinY() + 309.5 - (stapelGroesse * 0.15)); + } + else{ + this.spielerAlert = new Alert(AlertType.WARNING); + this.spielerAlert.setTitle("Fehler beim zuweisen des Papieres in den Locher!"); + this.spielerAlert.setHeaderText("Das Papier, dass du gerade in den Locher stecken wolltest kann nicht hinzugefügt werden."); + this.spielerAlert.setResult(ButtonType.OK); + this.spielerAlert.showAndWait(); + } + + //Das eben erzeugte Blatt dem 'game' hinzufügen + this.game.getArea().getChildren().add(this.locherPapier); + this.locherPapiere.add(this.locherPapier); + } + + /** + * Gibt das Array mit den Papieren zurück + * @return Die ArrayList + */ + public ArrayList getPapierListe(){ + return this.locherPapiere; + } + + public Papier getPapier () { + return this.papier; + } +} \ No newline at end of file diff --git a/src/main/java/de/wolc/gui/MainMenu.java b/src/main/java/de/wolc/gui/MainMenu.java index 98e225d..b4ba978 100644 --- a/src/main/java/de/wolc/gui/MainMenu.java +++ b/src/main/java/de/wolc/gui/MainMenu.java @@ -4,11 +4,18 @@ import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.image.Image; -import javafx.scene.layout.*; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.BackgroundImage; +import javafx.scene.layout.BackgroundRepeat; +import javafx.scene.layout.BackgroundPosition; +import javafx.scene.layout.BackgroundSize; +import javafx.scene.layout.Background; +import javafx.scene.layout.VBox; import javafx.scene.control.Button; import javafx.geometry.Insets; -import javafx.geometry.*; -import javafx.event.*; +import javafx.geometry.Pos; +import javafx.event.EventHandler; +import javafx.event.ActionEvent; public class MainMenu{ @@ -45,7 +52,7 @@ public Scene MainMenuStage(final Stage stage){ //Buttons //Button1 - final Button button_playgame = new Button("Play_Game()"); + final Button button_playgame = new Button("▶ Spiel starten ▶"); button_playgame.setMinWidth(buttonBox.getPrefWidth()); button_playgame.setMinHeight(buttonBox.getPrefHeight()); @@ -62,7 +69,7 @@ public void handle(ActionEvent actionEvent){ }); //Button2 - final Button button_settings = new Button("Settings()"); + final Button button_settings = new Button("⚙ Einstellungen ⚙"); button_settings.setMinWidth(buttonBox.getPrefWidth()); button_settings.setMinHeight(buttonBox.getPrefHeight()); @@ -77,7 +84,7 @@ public void handle(ActionEvent actionEvent){ }); //Button3 - Button button_exit = new Button("Exit()"); + Button button_exit = new Button("☠ Beenden ☠"); button_exit.setMinWidth(buttonBox.getPrefWidth()); button_exit.setMinHeight(buttonBox.getPrefHeight()); diff --git a/src/main/java/de/wolc/gui/PapierObjekt.java b/src/main/java/de/wolc/gui/PapierObjekt.java index e00c723..b1d4f2f 100644 --- a/src/main/java/de/wolc/gui/PapierObjekt.java +++ b/src/main/java/de/wolc/gui/PapierObjekt.java @@ -1,29 +1,50 @@ package de.wolc.gui; -import de.wolc.MultiUse; -import de.wolc.spiel.Spieler; -import de.wolc.spiel.locher.Lochprozess; -import de.wolc.spiel.papier.A4; -import de.wolc.spiel.papier.A5; -import de.wolc.spiel.papier.A6; -import de.wolc.spiel.papier.Konfetti; +import java.util.Random; + import de.wolc.spiel.papier.Papier; -import de.wolc.spiel.papier.PapierStapel; -//TODO: '*' entfernen und nur die benutzen objekte importieren -import javafx.stage.Stage; -import javafx.scene.Scene; -import javafx.scene.image.*; -import javafx.scene.layout.*; -import javafx.geometry.*; -import javafx.scene.control.Label; -import javafx.scene.paint.*; -import javafx.animation.AnimationTimer; -import javafx.event.EventHandler; -import javafx.scene.input.*; -import javafx.scene.shape.*; + +import javafx.scene.image.Image; +import javafx.scene.paint.ImagePattern; +import javafx.scene.shape.Rectangle; +import javafx.scene.input.MouseEvent; +import javafx.scene.effect.Blend; +import javafx.scene.effect.BlendMode; +import javafx.scene.effect.ColorInput; +import javafx.scene.effect.ColorAdjust; +import javafx.scene.paint.Color; +import javafx.scene.effect.Light; +import javafx.scene.effect.Lighting; public class PapierObjekt { private static final Image IMAGE = new Image("de/wolc/gui/images/paper_master.png"); + private static final Random RANDOM = new Random(); + + public double zufallsBreite() { + double halfWidth = this.game.getArea().getWidth() / 2d; + if (RANDOM.nextBoolean()) { + // links + return zufall(0, halfWidth / 2); + } else { + // rechts + return zufall(halfWidth + halfWidth / 2, halfWidth + halfWidth); + } + } + + public double zufallsHoehe() { + double halfHeight = this.game.getArea().getHeight() / 2d; + if (RANDOM.nextBoolean()) { + // oben + return zufall(0, halfHeight / 2); + } else { + // unten + return zufall(halfHeight + halfHeight / 2, halfHeight + halfHeight); + } + } + + public double zufall(double min, double max) { + return min + (max - min) * RANDOM.nextDouble(); + } private final Papier papier; private final Game game; @@ -32,24 +53,43 @@ public class PapierObjekt { public PapierObjekt(Game game, Papier papier) { this.papier = papier; this.game = game; + Color farbe = papier.getFarbe().getGuiFarbe(); + + Lighting lighting = new Lighting(); + lighting.setDiffuseConstant(1.0); + lighting.setSpecularConstant(0.0); + lighting.setSpecularExponent(0.0); + lighting.setSurfaceScale(0.0); + lighting.setLight(new Light.Distant(45, 45, farbe)); + this.drawnPapier = new Rectangle(); + this.drawnPapier.setScaleX(papier.getGroesse()); + this.drawnPapier.setScaleY(papier.getGroesse()); + this.drawnPapier.setScaleZ(papier.getGroesse()); this.drawnPapier.setFill(new ImagePattern(IMAGE)); this.drawnPapier.setWidth(IMAGE.getWidth()); this.drawnPapier.setHeight(IMAGE.getHeight()); - this.drawnPapier.setOnMouseDragged(new EventHandler() { - @Override - public void handle(MouseEvent e){ - //Change the location if the cursor has moved - drawnPapier.setTranslateX(drawnPapier.getTranslateX() + (e.getX() - 175)); - drawnPapier.setTranslateY(drawnPapier.getTranslateY() + (e.getY() - 110)); - if (game.checkForLocherCollision(drawnPapier)) { - //game.papierAufLocherGezogen(); - } + this.drawnPapier.setTranslateX(this.zufallsBreite()); + this.drawnPapier.setTranslateY(this.zufallsHoehe()); + this.drawnPapier.setEffect(lighting); + this.drawnPapier.setOnMouseDragged((MouseEvent e) -> { + //Change the location if the cursor has moved + this.drawnPapier.toFront(); + this.drawnPapier.setTranslateX(this.drawnPapier.getTranslateX() + (e.getX() - (this.drawnPapier.getWidth() * 0.35))); + this.drawnPapier.setTranslateY(this.drawnPapier.getTranslateY() + (e.getY() - (this.drawnPapier.getHeight() * 0.35))); + if (this.game.checkForLocherCollision(this.drawnPapier)){ + this.game.papierAufLocherGezogen(this); + e.consume(); } }); + this.game.getArea().getChildren().add(this.drawnPapier); } public Papier getPapier() { return this.papier; } + + public void zerstoeren() { + this.game.getArea().getChildren().remove(this.drawnPapier); + } } \ No newline at end of file diff --git a/src/main/java/de/wolc/gui/images/locher_paper.psd b/src/main/java/de/wolc/gui/images/locher_paper.psd new file mode 100644 index 0000000..131f540 Binary files /dev/null and b/src/main/java/de/wolc/gui/images/locher_paper.psd differ diff --git a/src/main/java/de/wolc/gui/images/paper_cutout.png b/src/main/java/de/wolc/gui/images/paper_cutout.png new file mode 100644 index 0000000..1e5a38c Binary files /dev/null and b/src/main/java/de/wolc/gui/images/paper_cutout.png differ diff --git a/src/main/java/de/wolc/gui/images/paper_cutout_a5.png b/src/main/java/de/wolc/gui/images/paper_cutout_a5.png new file mode 100644 index 0000000..4be6651 Binary files /dev/null and b/src/main/java/de/wolc/gui/images/paper_cutout_a5.png differ diff --git a/src/main/java/de/wolc/gui/images/paper_cutout_a6.png b/src/main/java/de/wolc/gui/images/paper_cutout_a6.png new file mode 100644 index 0000000..d0cb929 Binary files /dev/null and b/src/main/java/de/wolc/gui/images/paper_cutout_a6.png differ diff --git a/src/main/java/de/wolc/spiel/Farbe.java b/src/main/java/de/wolc/spiel/Farbe.java index f7a6e36..04059d1 100644 --- a/src/main/java/de/wolc/spiel/Farbe.java +++ b/src/main/java/de/wolc/spiel/Farbe.java @@ -1,21 +1,38 @@ package de.wolc.spiel; import java.util.Random; +import javafx.scene.paint.Color; /** * Repräsentiert eine Farbe. */ public enum Farbe { - WEISS, - ROT, - GRUEN, - BLAU, - PINK, - ORANGE; + WEISS("Weiß", Color.WHITE), + ROT("Rot", Color.RED), + GRUEN("Grün", Color.GREEN), + BLAU("Blau", Color.BLUE), + PINK("Pink", Color.PINK), + ORANGE("Orange", Color.ORANGE); + + private Farbe(String anzeigeName, Color guiFarbe) { + this.anzeigeName = anzeigeName; + this.guiFarbe = guiFarbe; + } private static final Farbe[] ALLE_FARBEN = values(); private static final Random ZUFALL = new Random(); + private String anzeigeName; + private Color guiFarbe; + + public String getAnzeigeName() { + return this.anzeigeName; + } + + public Color getGuiFarbe() { + return this.guiFarbe; + } + /** * Gibt eine zufällige Farbe zurück. * @return Die Farbe. diff --git a/src/main/java/de/wolc/spiel/locher/SimLocher.java b/src/main/java/de/wolc/spiel/locher/SimLocher.java index 05401e1..d4e5c08 100644 --- a/src/main/java/de/wolc/spiel/locher/SimLocher.java +++ b/src/main/java/de/wolc/spiel/locher/SimLocher.java @@ -101,11 +101,17 @@ public Class getFormat() { } /** - * Setzt das aktuelle Format auf das der Locher eingestellt ist. + * Setzt das aktuelle Format auf das der Locher eingestellt ist. Das Format kann nicht geändert werden wenn bereits + * ein Papier Stapel eingelegt ist. * @param format A4.class, A5.class, A6.class + * @return Wurde das Format umgestellt? true wenn ja, sonst false. */ - public void setFormat(Class format) { + public boolean setFormat(Class format) { + if (this.stapel != null) { + return false; + } this.format = format; + return true; } /** diff --git a/src/main/java/de/wolc/spiel/papier/A4.java b/src/main/java/de/wolc/spiel/papier/A4.java index fdbfa08..74cb948 100644 --- a/src/main/java/de/wolc/spiel/papier/A4.java +++ b/src/main/java/de/wolc/spiel/papier/A4.java @@ -7,10 +7,11 @@ public class A4 extends Papier implements Serializable /** MUSS um 1 erhöht werden, wenn sich die Eigenschaften der Klasse ändern. */ private static final long serialVersionUID = 1L; - private static final int maximaleAnzahlLochen = 20; + private static final int MAX_LOECHER = 20; + private static final double GROESSE = 1d; //Konstruktor public A4(){ - super(maximaleAnzahlLochen); + super(MAX_LOECHER, GROESSE); } } diff --git a/src/main/java/de/wolc/spiel/papier/A5.java b/src/main/java/de/wolc/spiel/papier/A5.java index 9c7c17a..dbe9c59 100644 --- a/src/main/java/de/wolc/spiel/papier/A5.java +++ b/src/main/java/de/wolc/spiel/papier/A5.java @@ -7,10 +7,11 @@ public class A5 extends Papier implements Serializable /** MUSS um 1 erhöht werden, wenn sich die Eigenschaften der Klasse ändern. */ private static final long serialVersionUID = 1L; - private static int maximaleAnzahlLochen = 15; + private static int MAX_LOECHER = 15; + private static final double GROESSE = 0.8d; //Konstruktor public A5(){ - super(maximaleAnzahlLochen); + super(MAX_LOECHER, GROESSE); } } diff --git a/src/main/java/de/wolc/spiel/papier/A6.java b/src/main/java/de/wolc/spiel/papier/A6.java index 311169c..bdb0ba9 100644 --- a/src/main/java/de/wolc/spiel/papier/A6.java +++ b/src/main/java/de/wolc/spiel/papier/A6.java @@ -7,10 +7,11 @@ public class A6 extends Papier implements Serializable /** MUSS um 1 erhöht werden, wenn sich die Eigenschaften der Klasse ändern. */ private static final long serialVersionUID = 1L; - private static int maximaleAnzahlLochen = 10; + private static int MAX_LOECHER = 10; + private static final double GROESSE = 0.6d; //Konstruktor public A6(){ - super(maximaleAnzahlLochen); + super(MAX_LOECHER, GROESSE); } } diff --git a/src/main/java/de/wolc/spiel/papier/Papier.java b/src/main/java/de/wolc/spiel/papier/Papier.java index 669c8b0..3b1a24e 100644 --- a/src/main/java/de/wolc/spiel/papier/Papier.java +++ b/src/main/java/de/wolc/spiel/papier/Papier.java @@ -13,12 +13,22 @@ public abstract class Papier implements Serializable private int maximaleAnzahlLochen; private Farbe farbe; private int lochAnzahl; + private double groesse; - protected Papier(int maximaleAnzahlLochen) { + protected Papier(int maximaleAnzahlLochen, double groesse) { this.farbe = Farbe.WEISS; + this.groesse = groesse; this.maximaleAnzahlLochen = maximaleAnzahlLochen; } + /** + * Wie Groß ist dieses Papierformat? + * @return Die Größe des Papiers im GUI als Multikator. + */ + public double getGroesse() { + return groesse; + } + public Farbe getFarbe() { return this.farbe; } @@ -54,7 +64,7 @@ public int getLochAnzahl() { */ public void gelocht(Lochprozess prozess) { // Füge neue soviele Löcher wie möglich hinzu, und der Locher Stanzer hat. - int loecher = Math.max(this.moeglicheLoecher(), prozess.getLocher().getStanzer()); + int loecher = Math.min(this.moeglicheLoecher(), prozess.getLocher().getStanzer()); this.lochAnzahl += loecher; // Für jedes erstellte Loch soll ein Konfetti erstellt werden. for(int i = 0; i < loecher; i++) { diff --git a/src/main/java/de/wolc/spiel/papier/PapierStapel.java b/src/main/java/de/wolc/spiel/papier/PapierStapel.java index 95c65b5..f5d6e78 100644 --- a/src/main/java/de/wolc/spiel/papier/PapierStapel.java +++ b/src/main/java/de/wolc/spiel/papier/PapierStapel.java @@ -47,12 +47,14 @@ public boolean ablegen(TPapier papier) { } /** - * Entnimmt das Papier aus dem Stapel wenn es darauf liegt. - * @param papier Das Papier, welches vom Stapel entnommen werden soll. - * @return true wenn das Papier entnommen wurde, sonst false. + * Entnimmt das oberste Papier aus dem Stapel wenn es darauf liegt. + * @return Das Papier, welches vom Stapel entnommen wurde, sonst null. */ - public boolean entnehmen(TPapier papier) { - return papiere.remove(papier); + public TPapier entnehmen() { + if (groesse() == 0) { + return null; + } + return papiere.remove(groesse() - 1); } /**