package nl.minkema.leendert; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; import javafx.scene.control.Tooltip; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.layout.StackPane; import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.scene.text.Text; import javafx.scene.text.TextBoundsType; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Random; /** * @author J0QUE * @version 1.0 */ public class Menu extends Group { public static Image[] images; public static String[] names; private static Random random = new Random(System.currentTimeMillis()); private int hoeveel = -1; private ArrayList chosen = new ArrayList<>(); /** * De constructor voor het menu * * @throws URISyntaxException als de achtergrondmuziek niet gevonden kan worden. * @throws MalformedURLException gebeurt hopelijk niet... */ public Menu() throws URISyntaxException, MalformedURLException { ArrayList nodes = new ArrayList<>(); //achtergrondafbeelding Image bg = new Image("/images/background.png"); ImageView view = new ImageView(bg); //zet de x en y naar de linker bovenhoek view.setX(0); view.setY(0); //dit is om te zorgen dat de afbeelding past view.setFitHeight(850); view.setPreserveRatio(false); view.setFitWidth(1250); nodes.add(view); //De achtergrondmuziek String loc = this.getClass().getResource("/music/menu.mp4").toString(); Media music = new Media(loc); MediaPlayer menuplayer = new MediaPlayer(music); menuplayer.setCycleCount(Integer.MAX_VALUE); menuplayer.setVolume(0.6f); //Dit deel is om te garanderen dat de muziek start, hoewel het soms toch niet werkt, iets met codecs enzo menuplayer.setAutoPlay(true); menuplayer.play(); menuplayer.play(); //De breedte van de afbeelding int imagewidth = 100; //Een array met speler afbeeldingen images = new Image[]{ new Image("/svg/p1.svg", imagewidth, 0, true, false), new Image("/svg/p2.svg", imagewidth, 0, true, false), new Image("/svg/p3.svg", imagewidth, 0, true, false), new Image("/svg/p4.svg", imagewidth, 0, true, false), new Image("/svg/p5.svg", imagewidth, 0, true, false)}; //De namen van de karakters names = new String[]{"Paulus", "Pinkeltje", "Petunia", "Kwebbel", "Stuart"}; int x = 0, y = 0; //Voor elke afbeelding wordt dit uitgevoerd for (int i1 = 0; i1 < images.length; i1++) { //We maken van de afbeelding een ImageView, zodat het zichtbaar gemaakt kan worden Image i = images[i1]; ImageView iv = new ImageView(i); iv.setX(750 + x); iv.setY(400 + y); //En geven het een tooltip met de naam van de Kabouter Tooltip.install(iv, new Tooltip(names[i1])); x += i.getRequestedWidth(); //Als we te ver gaan op de x as, gaan we door op een volgende regel if (x > 200) { y += 150; x = -70; } final int ch = i1; //Wat er gebeurt als je op een kabouter klikt iv.setOnMouseClicked(e -> { //Eerst controleren of het karakter al is gekozen. if (chosen.contains(ch)) { new Alert(Alert.AlertType.ERROR, "Sorry, dit karakter is al door iemand anders gekozen...").show(); return; } //Als er nog geen hoeveelheid is gekozen kan dat ook best een probleempje opleveren. if (hoeveel < 0) { Alert alert = new Alert(Alert.AlertType.ERROR, "Je moet eerst kiezen hoe veel spelers je wilt!\nDruk links op de juiste hoeveelheid kaboutertjes!", ButtonType.OK); alert.show(); } else { //Maar verder kunnen we gewoon de karakters vinden Image image = new Image(i.impl_getUrl(), 0, 50, true, false); //Toevoegen aan de lijst van spelers Game.players.add(new Player(image, ch)); //De hoeveelheid benodigde spelers met één verlagen hoeveel--; //En controleren of iedereen er een gekozen heeft if (hoeveel == 0) { //Zo ja: we stoppen het muziekje en starten het spel! menuplayer.stop(); Main.scene.setRoot(new Game()); } else { //Maar anders laten we mensen nog kiezen. String een = "Er moet nog 1 persoon kiezen!"; String meer = String.format("Er moeten nog %d mensen kiezen!", hoeveel); Alert alert = new Alert(Alert.AlertType.NONE, hoeveel > 1 ? meer : een, ButtonType.OK); alert.show(); chosen.add(ch); } } }); //Maar we moeten wel het karakter zichtbaar maken. nodes.add(iv); } int x2 = 30, y2 = 50; //Dit zijn de knoppen voor de hoeveelheid spelers for (int i = 0; i < 4; i++) { if (i == 0) continue; int number = 1 + i; int locy = y2 + 155 * i + 10; for (int e = 0; e < number; e++) { ImageView view1 = new ImageView(new Image("/svg/p1.svg", 75, 0, true, false)); view1.setX(x2 + 85 * e + 10 * e); view1.setY(locy); nodes.add(view1); } Rectangle clickable = new Rectangle(x2 - 10, locy + 125, 95 + i * 95, 152); clickable.setFill(Color.TRANSPARENT); clickable.setStroke(Color.BLACK); clickable.setArcHeight(50); clickable.setArcWidth(50); final int s = i + 1; clickable.setOnMouseClicked(e -> { hoeveel = s; new Alert(Alert.AlertType.INFORMATION, "Alle " + hoeveel + " spelers kunnen nu een karakter kiezen. \nAls iemand de verkeerde kiest kan je opnieuw \nop de knop drukken om opnieuw te beginnen.").show(); }); Tooltip tip = new Tooltip("Hier kan je op klikken"); Tooltip.install(clickable, tip); nodes.add(clickable); } getChildren().addAll(nodes); } /** * Maakt een knop op een plek, met een willekeurige kleur. * @param string de tekst van de knop * @param x de x coördinaat van de knop * @param y de y coördinaat van de knop * @param onClick een {@link EventHandler} die wordt uitgevoerd als de knop is ingedrukt * @return een stackpane met daarin een knop */ public static StackPane createButton(String string, double x, double y, EventHandler onClick) { Text text = createText(string); Rectangle rectangle = rectangulate(text); StackPane pane = new StackPane(rectangle, text); pane.setOnMouseClicked(onClick); pane.setLayoutX(x); pane.setLayoutY(y); return pane; } /** * Maakt een text object * @param string de tekst van het object * @return een object met de tekst */ private static Text createText(String string) { Text text = new Text(string); text.setBoundsType(TextBoundsType.VISUAL); text.setStyle( "-fx-font-family: \"Arial\";" + //"-fx-font-style: normal;" + "-fx-font-size: 24px;" ); return text; } /** * Maakt een rechthoek precies passend om de tekst heen. * @param text een {@link Text} object * @return een rechthoek met daar in de tekst */ private static Rectangle rectangulate(Text text) { Rectangle rectangle = new Rectangle(); rectangle.setFill(getRandomColor()); final double PADDING = 25; rectangle.setWidth(getWidth(text) + PADDING); rectangle.setHeight(getHeight(text) + PADDING); rectangle.setArcHeight(20); rectangle.setArcWidth(20); return rectangle; } /** * methode die de breedte van een {@link Text} object opvraagt * @param text het object * @return de breedte van het object */ private static double getWidth(Text text) { new Scene(new Group(text)); text.applyCss(); return text.getLayoutBounds().getWidth(); } /** * methode die de hoogte van een {@link Text} object opvraagt * @param text het object * @return de hoogte van het object */ private static double getHeight(Text text) { new Scene(new Group(text)); text.applyCss(); return text.getLayoutBounds().getHeight(); } /** * maakt een willekeurige kleur * @return een willekeurige kleur. */ public static Color getRandomColor() { return Color.hsb(random.nextInt(360), 0.8, 0.8); } }