From aae98b8bfca1578c14d6dde3a2f3180c7c580131 Mon Sep 17 00:00:00 2001 From: sowgro Date: Tue, 23 Jul 2024 00:24:44 -0400 Subject: Improve difficulty ordering and add songEnd and support multiple file types. --- pom.xml | 2 +- src/main/java/net/sowgro/npehero/Driver.java | 16 +- .../net/sowgro/npehero/devmenu/DiffEditor.java | 163 -------- .../java/net/sowgro/npehero/devmenu/DiffList.java | 132 ------ .../net/sowgro/npehero/devmenu/ErrorDisplay.java | 85 ---- .../net/sowgro/npehero/devmenu/LevelEditor.java | 189 --------- .../java/net/sowgro/npehero/devmenu/LevelList.java | 135 ------- .../net/sowgro/npehero/devmenu/NotesEditor.java | 132 ------ .../net/sowgro/npehero/devmenu/NotesEditor2.java | 399 ------------------ .../java/net/sowgro/npehero/editor/DiffEditor.java | 165 ++++++++ .../java/net/sowgro/npehero/editor/DiffList.java | 162 ++++++++ .../net/sowgro/npehero/editor/ErrorDisplay.java | 85 ++++ .../net/sowgro/npehero/editor/LevelEditor.java | 195 +++++++++ .../java/net/sowgro/npehero/editor/LevelList.java | 135 +++++++ .../net/sowgro/npehero/editor/NotesEditor.java | 132 ++++++ .../net/sowgro/npehero/editor/NotesEditor2.java | 444 +++++++++++++++++++++ .../net/sowgro/npehero/gameplay/SongPlayer.java | 25 +- .../java/net/sowgro/npehero/gui/LevelSurround.java | 5 + src/main/java/net/sowgro/npehero/gui/MainMenu.java | 2 +- src/main/java/net/sowgro/npehero/main/Control.java | 2 + .../java/net/sowgro/npehero/main/Difficulties.java | 6 + .../java/net/sowgro/npehero/main/Difficulty.java | 26 +- src/main/java/net/sowgro/npehero/main/Level.java | 28 +- 23 files changed, 1391 insertions(+), 1274 deletions(-) delete mode 100755 src/main/java/net/sowgro/npehero/devmenu/DiffEditor.java delete mode 100755 src/main/java/net/sowgro/npehero/devmenu/DiffList.java delete mode 100644 src/main/java/net/sowgro/npehero/devmenu/ErrorDisplay.java delete mode 100755 src/main/java/net/sowgro/npehero/devmenu/LevelEditor.java delete mode 100755 src/main/java/net/sowgro/npehero/devmenu/LevelList.java delete mode 100755 src/main/java/net/sowgro/npehero/devmenu/NotesEditor.java delete mode 100644 src/main/java/net/sowgro/npehero/devmenu/NotesEditor2.java create mode 100755 src/main/java/net/sowgro/npehero/editor/DiffEditor.java create mode 100755 src/main/java/net/sowgro/npehero/editor/DiffList.java create mode 100644 src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java create mode 100755 src/main/java/net/sowgro/npehero/editor/LevelEditor.java create mode 100755 src/main/java/net/sowgro/npehero/editor/LevelList.java create mode 100755 src/main/java/net/sowgro/npehero/editor/NotesEditor.java create mode 100644 src/main/java/net/sowgro/npehero/editor/NotesEditor2.java diff --git a/pom.xml b/pom.xml index 3b63ed6..3637f51 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ org.openjfx javafx-media - 18.0.1 + 22.0.2 com.fasterxml.jackson.core diff --git a/src/main/java/net/sowgro/npehero/Driver.java b/src/main/java/net/sowgro/npehero/Driver.java index 6544ebe..4c737f7 100755 --- a/src/main/java/net/sowgro/npehero/Driver.java +++ b/src/main/java/net/sowgro/npehero/Driver.java @@ -20,7 +20,7 @@ import java.net.URL; public class Driver extends Application { - public static final Image MENU_BACKGROUND = new Image(Driver.class.getResource("mountains.png").toExternalForm());; + public static final Image MENU_BACKGROUND = new Image(Driver.class.getResource("mountains.png").toExternalForm()); public static Stage primaryStage; public static ScrollPane primaryPane = new ScrollPane(); @@ -32,8 +32,7 @@ public class Driver extends Application /* * starts javafx */ - public static void main(String[] args) - { + public static void main(String[] args) { launch(args); } @@ -42,8 +41,7 @@ public class Driver extends Application * (automatically called by javafx on start) */ @Override - public void start(Stage newPrimaryStage) - { + public void start(Stage newPrimaryStage) { Settings.read(); Levels.readData(); Control.readFromFile(); @@ -87,8 +85,7 @@ public class Driver extends Application * Replaces/adds a new pane to the primaryPane * @param pane the new pane */ - private static void setMenu(Pane pane) - { + private static void setMenu(Pane pane) { primaryPane.setContent(pane); pane.prefWidthProperty().bind(primaryPane.widthProperty()); //makes pane fill the window pane.prefHeightProperty().bind(primaryPane.heightProperty()); @@ -98,7 +95,7 @@ public class Driver extends Application /** * @return the current pane in primaryPane */ - public static Page getMenu(){ + public static Page getMenu() { return currentPage; } @@ -148,8 +145,7 @@ public class Driver extends Application st.setOnFinished(_ -> backgroundImage.setImage(image)); } - public static void setMenuBackground() - { + public static void setMenuBackground() { setBackground(MENU_BACKGROUND); } diff --git a/src/main/java/net/sowgro/npehero/devmenu/DiffEditor.java b/src/main/java/net/sowgro/npehero/devmenu/DiffEditor.java deleted file mode 100755 index 11ee274..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/DiffEditor.java +++ /dev/null @@ -1,163 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import javafx.beans.binding.DoubleBinding; -import javafx.geometry.Pos; -import javafx.scene.control.Label; -import javafx.scene.control.ScrollPane; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.scene.paint.Color; -import net.sowgro.npehero.Driver; -import net.sowgro.npehero.gameplay.Block; -import net.sowgro.npehero.gui.LevelSurround; -import javafx.scene.control.Button; -import javafx.scene.control.TextField; -import javafx.scene.layout.VBox; -import javafx.scene.text.Text; -import net.sowgro.npehero.main.*; - -public class DiffEditor extends Page -{ - Difficulty diff; - ScrollPane scroll; - - HBox content = new HBox(); - - public Page prev; - - public DiffEditor(Difficulty diff, Page prev) { - this.diff = diff; - this.prev = prev; - - Text folderNameLabel = new Text("Folder name"); - TextField folderName = new TextField(diff.thisDir.getName()); - folderName.setDisable(true); - - Text titleLabel = new Text("Title"); - TextField title = new TextField(diff.title); - - Text priorityLabel = new Text("Order (lower first)"); - TextField priority = new TextField(diff.priority+""); - - Button editNotes = new Button("Edit notes"); - editNotes.setOnAction(_ -> { - if (diff.level.song == null) { - Driver.setMenu(new ErrorDisplay("You must import a song file before editing the notes!", this)); - } - else { - Driver.setMenu(new NotesEditor2(diff, this)); - } - }); - - Button oldEditNotes = new Button("Edit notes (legacy)"); - oldEditNotes.setOnAction(_ -> Driver.setMenu(new ErrorDisplay( - "Warning: \nThe legacy editor will overwrite all existing notes!", - this, - new NotesEditor(diff, this)) - )); - - Button editScores = new Button("Clear leaderboard"); - editScores.setOnAction(_ -> diff.leaderboard.entries.clear()); - - Button playLevel = new Button("Play level"); - playLevel.setOnAction(_ -> { - if (diff.isValid && diff.level.isValid) { - Driver.setMenu(new LevelSurround(diff.level, diff, this)); - } - else { - Driver.setMenu(new ErrorDisplay("This Level is not valid!\nCheck that all required fields\nare populated.", this)); - } - }); - - Button save = new Button("Save"); - save.setOnAction(_ -> { //assigns text fields to values - diff.title = title.getText(); -// diff.bpm = Double.parseDouble(bpm.getText()); -// diff.numBeats = Integer.parseInt(numBeats.getText()); - diff.priority = Integer.parseInt(priority.getText()); - diff.write(); - }); - - HBox scrollContent = new HBox(); - ScrollPane scroll = new ScrollPane(scrollContent); - scroll.setFitToWidth(true); - this.scroll = scroll; - scroll.getStyleClass().remove("scroll-pane"); - scroll.getStyleClass().add("box"); -// scroll.setPrefHeight(400); - scroll.prefWidthProperty().bind(scroll.heightProperty().multiply(0.66)); - - Pane[] lanes = new Pane[5]; - for (int i = 0; i < lanes.length; i++) { - lanes[i] = new Pane(); - } - - scrollContent.getChildren().addAll(lanes); - scrollContent.setSpacing(5); - scrollContent.setAlignment(Pos.CENTER); - - diff.notes.list.forEach(n -> lanes[n.lane].getChildren().add(drawNote(n))); - - VBox notePreview = new VBox(); - - ValidIndicator validNotes = new ValidIndicator(); - if (diff.notes.list.isEmpty()) { - validNotes.setInvalid("This difficulty does not contain any notes!"); - } - HBox notesLabel = new HBox(new Label("Notes"), validNotes); - Pane scrollHolder = new Pane(scroll); - scroll.prefHeightProperty().bind(scrollHolder.heightProperty()); - scrollHolder.setPrefHeight(400); - notePreview.getChildren().addAll(notesLabel, scrollHolder, editNotes, oldEditNotes); - notePreview.setSpacing(10); - - VBox left = new VBox(); - left.getChildren().addAll(folderNameLabel,folderName,titleLabel,title,priorityLabel,priority,editScores,playLevel,save); - left.setSpacing(10); - - HBox main = new HBox(); - main.getChildren().addAll(left, notePreview); - main.setSpacing(30); - - Button exit = new Button(); - exit.setText("Back"); - exit.setOnAction(e -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, exit); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - } - - @Override - public Pane getContent() { - return content; - } - - // Duplicates of NotesEditor2 methods, should be made generic and combined - private Block drawNote(Note n) { - Color color = diff.level.colors[n.lane]; - Block b = new Block(color,20, 20, 5, false, n); - b.heightProperty().bind(scroll.widthProperty().divide(8)); - b.widthProperty().bind(scroll.widthProperty().divide(8)); - b.arcHeightProperty().bind(scroll.widthProperty().divide(25)); - b.arcWidthProperty().bind(scroll.widthProperty().divide(25)); - b.strokeWidthProperty().bind(scroll.widthProperty().divide(120)); - b.layoutYProperty().bind(secondToScreenPos(n.time.add(0))); - return b; - } - - private DoubleBinding secondToScreenPos(double second) { - return scroll.heightProperty().multiply(second * 0.9); - } - - private DoubleBinding secondToScreenPos(DoubleBinding second) { - return scroll.heightProperty().multiply(second).multiply(0.9); - } -} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/devmenu/DiffList.java b/src/main/java/net/sowgro/npehero/devmenu/DiffList.java deleted file mode 100755 index 63c09bb..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/DiffList.java +++ /dev/null @@ -1,132 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import javafx.beans.property.ReadOnlyStringWrapper; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.control.*; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.scene.layout.VBox; -import net.sowgro.npehero.Driver; -import net.sowgro.npehero.main.Difficulty; -import net.sowgro.npehero.main.Level; -import net.sowgro.npehero.main.Page; -import net.sowgro.npehero.main.Sound; - -public class DiffList extends Page -{ - private HBox content = new HBox(); - - public DiffList(Level level, Page prev) - { - //sets up table view: requires special getters, setters and constructors to work - TableView diffs = new TableView<>(); - - TableColumn titleCol = new TableColumn<>("Name"); - TableColumn validCol = new TableColumn<>("Valid?"); - - diffs.getColumns().add(titleCol); - diffs.getColumns().add(validCol); - - titleCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title)); - validCol.setCellValueFactory(data -> { - if (data.getValue().isValid) { - return new ReadOnlyStringWrapper("Yes"); - } - else { - return new ReadOnlyStringWrapper("No"); - } - }); - - diffs.setItems(level.difficulties.list); - - diffs.setRowFactory( _ -> { - TableRow row = new TableRow<>(); - row.setOnMouseClicked(event -> { - if (event.getClickCount() == 2 && (! row.isEmpty()) ) { - Difficulty rowData = row.getItem(); - Driver.setMenu(new DiffEditor(rowData, this)); - } - }); - return row ; - }); - - diffs.setPrefWidth(400); - diffs.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.67)); - - Button edit = new Button("Edit"); - edit.setOnAction(e -> Driver.setMenu(new DiffEditor(diffs.getSelectionModel().getSelectedItem(), this))); - edit.setDisable(true); - edit.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull()); - - Button remove = new Button("Delete"); - remove.setOnAction(e -> level.difficulties.remove(diffs.getSelectionModel().getSelectedItem())); - remove.setDisable(true); - remove.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull()); - - Button refresh = new Button("Refresh"); - refresh.setOnAction(e -> { - level.readData(); - diffs.setItems(level.difficulties.list); - }); - - ToggleButton create = new ToggleButton("Create"); - - VBox buttons = new VBox(); - buttons.getChildren().addAll(create, edit, remove, refresh); - buttons.setSpacing(10); - - TextField newLevelEntry = new TextField(); - Button newLevelButton = new Button("add"); - - HBox newLevel = new HBox(newLevelEntry,newLevelButton); - Label newLevelLabel = new Label("Name of new difficulty"); - VBox newLevelBox = new VBox(newLevelLabel, newLevel); - newLevelBox.setSpacing(10); - newLevelBox.getStyleClass().add("box"); - newLevelBox.setPadding(new Insets(10)); - - Pane sidebar = new Pane(); - - HBox main = new HBox(); - main.getChildren().addAll(diffs,buttons, sidebar); - main.setSpacing(10); - - Button exit = new Button(); - exit.setText("Back"); - exit.setOnAction(e -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - create.setOnAction(_ -> { - if (create.isSelected()) { - sidebar.getChildren().add(newLevelBox); - } - else { - sidebar.getChildren().remove(newLevelBox); - } - }); - - newLevelButton.setOnAction(_ -> { - level.difficulties.add(newLevelEntry.getText()); - newLevelEntry.clear(); - refresh.fire(); - sidebar.getChildren().clear(); - create.setSelected(false); - }); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, exit); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - } - - @Override - public Pane getContent() { - return content; - } -} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/devmenu/ErrorDisplay.java b/src/main/java/net/sowgro/npehero/devmenu/ErrorDisplay.java deleted file mode 100644 index dc4b40c..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/ErrorDisplay.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.scene.layout.VBox; -import net.sowgro.npehero.Driver; -import net.sowgro.npehero.main.Page; -import net.sowgro.npehero.main.Sound; - -public class ErrorDisplay extends Page { - - private HBox content = new HBox(); - - /** - * Error display with a message and Back button - * @param message The message to display - * @param prev The destination of the close button - */ - public ErrorDisplay(String message, Page prev) { - Label main = new Label(message); - main.getStyleClass().add("box"); - - Button exit = new Button(); - exit.setText("Back"); - exit.setOnAction(e -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, exit); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - } - - /** - * Error display with a message and Cancel and Proceed buttons - * @param message The message to display - * @param prev The destination of the Cancel button - * @param next The destination of the Proceed button - */ - public ErrorDisplay(String message, Page prev, Page next) { - Label main = new Label(message); - main.getStyleClass().add("box"); - main.setPadding(new Insets(10)); - - Button exit = new Button(); - exit.setText("Cancel"); - exit.setOnAction(_ -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - Button nextButton = new Button(); - nextButton.setText("Proceed"); - nextButton.setOnAction(_ -> { - Sound.playSfx(Sound.FORWARD); - Driver.setMenu(next); - }); - - HBox bottom = new HBox(exit, nextButton); - bottom.setAlignment(Pos.CENTER); - bottom.setSpacing(10); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, bottom); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - } - - @Override - public Pane getContent() { - return content; - } -} diff --git a/src/main/java/net/sowgro/npehero/devmenu/LevelEditor.java b/src/main/java/net/sowgro/npehero/devmenu/LevelEditor.java deleted file mode 100755 index 003f929..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/LevelEditor.java +++ /dev/null @@ -1,189 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import java.io.File; - -import javafx.beans.property.ReadOnlyStringWrapper; -import javafx.geometry.Pos; -import javafx.scene.control.*; -import javafx.scene.layout.*; -import javafx.scene.text.Text; -import javafx.stage.FileChooser; -import javafx.stage.FileChooser.ExtensionFilter; -import net.sowgro.npehero.Driver; -import net.sowgro.npehero.main.*; - -public class LevelEditor extends Page -{ - private HBox content = new HBox(); - - private File selectedSong = null; - private File selectedPreview = null; - private File selectedBackground = null; - - public LevelEditor(Level level, Page prev) - { - Text folderNameLabel = new Text("Folder name"); - TextField folderName = new TextField(); - if (level.dir != null) { - folderName.setText(level.dir.getName()); - folderName.setDisable(true); - } - - Text titleLabel = new Text("Title"); - TextField title = new TextField(level.title); - - Text artistLabel = new Text("Artist"); - TextField artist = new TextField(level.artist); - - Text descLabel = new Text("Description"); - TextField desc = new TextField(level.desc); - - Text colorsLabel = new Text("Colors"); - - ColorPicker[] colorsPickers = new ColorPicker[] { - new ColorPicker(level.colors[0]), - new ColorPicker(level.colors[1]), - new ColorPicker(level.colors[2]), - new ColorPicker(level.colors[3]), - new ColorPicker(level.colors[4]) - }; - - for (ColorPicker cp : colorsPickers) { - cp.getStyleClass().add("button"); - } - - HBox colorPickerBox = new HBox(); - colorPickerBox.getChildren().addAll(colorsPickers); - - ValidIndicator songValid = new ValidIndicator(); - if (level.song == null) { - songValid.setInvalid("Missing file song.wav!"); - } - HBox filesLabel = new HBox(new Text("Files"), songValid); - - FileChooser backgroundChooser = new FileChooser(); - backgroundChooser.getExtensionFilters().add(new ExtensionFilter("PNG", "*.png")); - Button backgroundButton = new Button("Background Image"); - backgroundButton.setOnAction(e -> {selectedBackground = backgroundChooser.showOpenDialog(Driver.primaryStage);}); - - FileChooser previewChooser = new FileChooser(); - previewChooser.getExtensionFilters().add(new ExtensionFilter("PNG", "*.png")); - Button previewButton = new Button("Preview Image"); - previewButton.setOnAction(e -> {selectedPreview = previewChooser.showOpenDialog(Driver.primaryStage);}); - - FileChooser songChooser = new FileChooser(); - songChooser.getExtensionFilters().add(new ExtensionFilter("WAV", "*.wav")); - Button songButton = new Button("Song file"); - songButton.setOnAction(e -> selectedSong = songChooser.showOpenDialog(Driver.primaryStage)); - - - ValidIndicator diffsInvalid = new ValidIndicator(); - if (level.difficulties.validList.isEmpty()) { - diffsInvalid.setInvalid("This level contains no valid difficulties!"); - } - HBox diffLabel = new HBox(new Text("Difficulties"), diffsInvalid); - diffLabel.setSpacing(5); - - - TableView diffList = new TableView<>(); - - TableColumn diffCol = new TableColumn<>("Difficulty"); - TableColumn validCol = new TableColumn<>("Valid?"); - - diffList.getColumns().add(diffCol); - diffList.getColumns().add(validCol); - - diffCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title)); - validCol.setCellValueFactory(data -> { - if (data.getValue().isValid) { - return new ReadOnlyStringWrapper("Yes"); - } - else { - return new ReadOnlyStringWrapper("No"); - } - }); - - diffList.setItems(level.difficulties.list); - - diffList.setRowFactory( _ -> { - TableRow row = new TableRow<>(); - row.setOnMouseClicked(event -> { - if (event.getClickCount() == 2 && (! row.isEmpty()) ) { - Difficulty rowData = row.getItem(); - Driver.setMenu(new DiffEditor(rowData, this)); - } - }); - return row ; - }); - - Button newDiffs = new Button("Edit difficulties"); - newDiffs.setOnAction(_ -> Driver.setMenu(new DiffList(level, this))); - - diffList.setSelectionModel(null); - - Button save = new Button("Save"); - save.setOnAction(e -> { //assigns fields to values - level.title = title.getText(); - level.artist = artist.getText(); - level.desc = desc.getText(); - level.colors[0] = colorsPickers[0].getValue(); - level.colors[1] = colorsPickers[1].getValue(); - level.colors[2] = colorsPickers[2].getValue(); - level.colors[3] = colorsPickers[3].getValue(); - level.colors[4] = colorsPickers[4].getValue(); - if (selectedBackground != null && selectedBackground.exists()) - { - level.addFile(selectedBackground,"background.png"); - } - if (selectedPreview != null && selectedPreview.exists()) - { - level.addFile(selectedPreview,"preview.png"); - } - if (selectedSong != null) - { - level.addFile(selectedSong,"song.wav"); - } - level.writeMetadata(); - }); - - VBox left = new VBox(filesLabel, songButton, previewButton, backgroundButton, colorsLabel, colorPickerBox); - left.setSpacing(10); - left.setPrefWidth(300); - - VBox center = new VBox(folderNameLabel,folderName,titleLabel,title,artistLabel,artist,descLabel,desc); - center.setSpacing(10); - center.setPrefWidth(300); - - VBox right = new VBox(diffLabel,diffList,newDiffs); - right.setSpacing(10); - center.setPrefWidth(300); - - HBox mainBox = new HBox(); - mainBox.getChildren().addAll(left, center, right); - mainBox.setSpacing(30); - - Button exit = new Button(); - exit.setText("Back"); - exit.setOnAction(e -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - HBox bottom = new HBox(save, exit); - bottom.setAlignment(Pos.CENTER); - bottom.setSpacing(10); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(mainBox, bottom); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - } - - @Override - public Pane getContent() { - return content; - } -} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/devmenu/LevelList.java b/src/main/java/net/sowgro/npehero/devmenu/LevelList.java deleted file mode 100755 index 7d899bd..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/LevelList.java +++ /dev/null @@ -1,135 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import javafx.beans.property.ReadOnlyStringWrapper; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.control.*; -import javafx.scene.layout.Pane; -import net.sowgro.npehero.Driver; -import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; -import net.sowgro.npehero.gui.MainMenu; -import net.sowgro.npehero.main.Level; -import net.sowgro.npehero.main.Levels; -import net.sowgro.npehero.main.Page; -import net.sowgro.npehero.main.Sound; - -public class LevelList extends Page -{ - private HBox content = new HBox(); - - public LevelList() - { - //sets up table view: requires special getters, setters and constructors to work - TableView levels = new TableView<>(); - - TableColumn titleCol = new TableColumn<>("Title"); - TableColumn artistCol = new TableColumn<>("Artist"); - TableColumn validCol = new TableColumn<>("Valid?"); - - levels.getColumns().add(titleCol); - levels.getColumns().add(artistCol); - levels.getColumns().add(validCol); - - titleCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title)); - artistCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().artist)); - validCol.setCellValueFactory(data -> { - if (data.getValue().isValid) { - return new ReadOnlyStringWrapper("Yes"); - } - else { - return new ReadOnlyStringWrapper("No"); - } - }); - - levels.setItems(Levels.list); - - levels.setRowFactory( _ -> { - TableRow row = new TableRow<>(); - row.setOnMouseClicked(event -> { - if (event.getClickCount() == 2 && (! row.isEmpty()) ) { - Level rowData = row.getItem(); - Driver.setMenu(new LevelEditor(rowData, this)); - } - }); - return row ; - }); - levels.setPrefWidth(600); - levels.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.75)); - - Button edit = new Button("Edit"); - edit.setOnAction(e -> Driver.setMenu(new LevelEditor(levels.getSelectionModel().getSelectedItem(), this))); - edit.setDisable(true); - edit.disableProperty().bind(levels.getSelectionModel().selectedItemProperty().isNull()); - - Button remove = new Button("Delete"); - remove.setOnAction(e -> Levels.remove(levels.getSelectionModel().getSelectedItem())); - remove.setDisable(true); - remove.disableProperty().bind(levels.getSelectionModel().selectedItemProperty().isNull()); - - Button refresh = new Button("Refresh"); - refresh.setOnAction(e -> { - Levels.readData(); - levels.setItems(Levels.list); - }); - - ToggleButton create = new ToggleButton("Create"); - - VBox buttons = new VBox(); - buttons.getChildren().addAll(create, edit, remove, refresh); - buttons.setSpacing(10); - - TextField newLevelEntry = new TextField(); - Button newLevelButton = new Button("add"); - - HBox newLevel = new HBox(newLevelEntry,newLevelButton); - Label newLevelLabel = new Label("Name of new level"); - VBox newLevelBox = new VBox(newLevelLabel, newLevel); - newLevelBox.setSpacing(10); - newLevelBox.getStyleClass().add("box"); - newLevelBox.setPadding(new Insets(10)); - - Pane sidebar = new Pane(); - - HBox main = new HBox(); - main.getChildren().addAll(levels,buttons,sidebar); - main.setSpacing(10); - - Button exit = new Button(); - exit.setText("Back"); - exit.setOnAction(e -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(new MainMenu()); - }); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, exit); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - - create.setOnAction(_ -> { - if (create.isSelected()) { - sidebar.getChildren().add(newLevelBox); - } - else { - sidebar.getChildren().remove(newLevelBox); - } - }); - - newLevelButton.setOnAction(_ -> { - Levels.add(newLevelEntry.getText()); - newLevelEntry.clear(); - refresh.fire(); - sidebar.getChildren().clear(); - create.setSelected(false); - }); - } - - @Override - public Pane getContent() { - return content; - } -} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/devmenu/NotesEditor.java b/src/main/java/net/sowgro/npehero/devmenu/NotesEditor.java deleted file mode 100755 index 3754847..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/NotesEditor.java +++ /dev/null @@ -1,132 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import java.io.FileNotFoundException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; - -import javafx.geometry.Pos; -import javafx.scene.input.KeyEvent; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.scene.media.Media; -import net.sowgro.npehero.gameplay.Timer; -import net.sowgro.npehero.Driver; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.layout.VBox; -import javafx.scene.text.Text; -import net.sowgro.npehero.main.Control; -import net.sowgro.npehero.main.Difficulty; -import net.sowgro.npehero.main.Page; -import net.sowgro.npehero.main.Sound; - -public class NotesEditor extends Page -{ - Text help; - String t1 = "Press Start to begin recording. Use the same keys. Note: existing notes will be overwritten."; - String t2 = "Now recording. Press Stop or " + Control.LEGACY_STOP.getKey().toString() + " to finish"; - Difficulty diff; - Timer timer; - PrintWriter writer; - - private HBox content = new HBox(); - - public NotesEditor(Difficulty diff, Page prev) - { - this.diff = diff; - - help = new Text(t1); - Text cur = new Text("-----"); - - Button start = new Button("Start"); - start.setOnAction(e -> start()); - start.setFocusTraversable(false); - - Button stop = new Button("Stop"); - stop.setOnAction(e -> stop()); - stop.setFocusTraversable(false); - - VBox main = new VBox(); - main.getChildren().addAll(help,cur,start,stop); - - Button exit = new Button(); - exit.setText("Back"); - exit.setOnAction(e -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, exit); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - - try { - writer = new PrintWriter(diff.notes.getFile(), "UTF-8"); - } catch (FileNotFoundException | UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - - Scene scene = Driver.primaryStage.getScene(); - scene.addEventFilter(KeyEvent.KEY_PRESSED, e -> { - if (e.getCode() == Control.LANE0.getKey()) { - writer.println("d"+timer); - cur.setText("d"+timer); - } - if (e.getCode() == Control.LANE1.getKey()) { - writer.println("f"+timer); - cur.setText("f"+timer); - } - if (e.getCode() == Control.LANE2.getKey()) { - writer.println("s"+timer); - cur.setText("s"+timer); - } - if (e.getCode() == Control.LANE3.getKey()) { - writer.println("j"+timer); - cur.setText("j"+timer); - } - if (e.getCode() == Control.LANE4.getKey()) { - writer.println("k"+timer); - cur.setText("k"+timer); - } - if (e.getCode() == Control.LEGACY_STOP.getKey()) - { - stop(); - } - e.consume(); - }); - - Driver.primaryStage.setOnCloseRequest(e -> stop()); - } - - @Override - public Pane getContent() { - return content; - } - - private void start() - { - Sound.playSong(new Media(diff.level.song.toString())); - timer = new Timer(diff.bpm); - help.setText(t2); - } - - private void stop() - { - try - { - Sound.stopSong(); - diff.numBeats = (int)Double.parseDouble(timer.toString()); - timer = null; - writer.close(); - help.setText(t1); - } - catch (Exception e) - { - //System.err.println("tried to stop but already stopped"); - } - } -} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/devmenu/NotesEditor2.java b/src/main/java/net/sowgro/npehero/devmenu/NotesEditor2.java deleted file mode 100644 index 22c3f5e..0000000 --- a/src/main/java/net/sowgro/npehero/devmenu/NotesEditor2.java +++ /dev/null @@ -1,399 +0,0 @@ -package net.sowgro.npehero.devmenu; - -import javafx.beans.binding.DoubleBinding; -import javafx.beans.property.ListProperty; -import javafx.beans.property.SimpleListProperty; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.control.*; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.scene.layout.StackPane; -import javafx.scene.layout.VBox; -import javafx.scene.media.Media; -import javafx.scene.media.MediaPlayer; -import javafx.scene.paint.Color; -import javafx.scene.shape.Line; -import javafx.scene.shape.Polygon; -import javafx.util.Duration; -import net.sowgro.npehero.Driver; -import net.sowgro.npehero.gameplay.Block; -import net.sowgro.npehero.gameplay.Target; -import net.sowgro.npehero.main.*; -import net.sowgro.npehero.main.Control; - -import java.util.concurrent.atomic.AtomicInteger; - -public class NotesEditor2 extends Page { - Difficulty diff; - ScrollPane scroll = new ScrollPane(); - Pane[] lanes; - MediaPlayer m; - Polygon playhead; - ListProperty activeNotes = new SimpleListProperty<>(FXCollections.observableArrayList()); - ListProperty noteList; - DiffEditor prev; - - private HBox content = new HBox(); - - public NotesEditor2(Difficulty diff, DiffEditor prev) { - this.diff = diff; - noteList = diff.notes.deepCopyList(); - m = new MediaPlayer(new Media(diff.level.song.toURI().toString())); - this.prev = prev; - - // Buttons - VBox actionBox = new VBox(); - actionBox.setSpacing(10); - - Label noteLabel = new Label("Notes"); - ToggleButton addNote = new ToggleButton("Add"); - Button delNote = new Button("Delete"); - ToggleButton moveNote = new ToggleButton("Move"); - actionBox.getChildren().addAll(noteLabel, addNote, delNote, moveNote); - - Label selectionLabel = new Label("Selection"); - Button selectAll = new Button("Select All"); - Button clearSelect = new Button("Clear"); - actionBox.getChildren().addAll(selectionLabel, selectAll, clearSelect); - - Label playbackLabel = new Label("Playback"); - ToggleButton play = new ToggleButton("Play"); - Button reset = new Button("Reset"); - ToggleButton scrollLock = new ToggleButton("Scroll Lock"); - actionBox.getChildren().addAll(playbackLabel, play, reset, scrollLock); - - delNote.disableProperty().bind(activeNotes.emptyProperty()); - moveNote.disableProperty().bind(activeNotes.emptyProperty()); - clearSelect.disableProperty().bind(activeNotes.emptyProperty()); - - ToggleGroup tg = new ToggleGroup(); - addNote.setToggleGroup(tg); - moveNote.setToggleGroup(tg); - - // Lanes - this.lanes = new Pane[5]; - for (int i = 0; i < lanes.length; i++) { - lanes[i] = new Pane(); - } - Block sizer = drawBlock(new Note(0, 0)); - for (Pane lane : lanes) { - lane.prefWidthProperty().bind(sizer.widthProperty()); - } - Pane rulerLane = new Pane(); - rulerLane.setManaged(false); - Pane playheadLane = new Pane(); - playheadLane.setOnMouseClicked(e -> { - m.seek(new Duration(screenPosToSecond(e.getY()) * 1000)); - }); - - this.playhead = new Polygon(); - playhead.getPoints().addAll( - 0.0, -10.0, - 20.0, -10.0, - 30.0, 0.0, - 20.0, 10.0, - 0.0, 10.0 - ); - playhead.setFill(Color.WHITE); - playheadLane.getChildren().add(playhead); - - HBox scrollContent = new HBox(); - scrollContent.setAlignment(Pos.CENTER); - scrollContent.setSpacing(10); - scrollContent.getChildren().addAll(playheadLane, rulerLane); - scrollContent.getChildren().addAll(lanes); - - Line playheadLine = new Line(); - playheadLine.setStartX(0); - playheadLine.endXProperty().bind(scroll.widthProperty().subtract(80)); - playheadLine.setStartY(0); - playheadLine.setEndY(0); - playheadLine.setStroke(Color.WHITE); - playheadLine.layoutYProperty().bind(playhead.layoutYProperty()); - - Pane contentOverlay = new Pane(playheadLine); - contentOverlay.setPickOnBounds(false); - - StackPane stackPane = new StackPane(); - stackPane.getChildren().addAll(scrollContent, contentOverlay); - - scroll.setContent(stackPane); -// scroll.prefWidthProperty().bind(super.prefWidthProperty().multiply(0.35)); - scroll.setMinWidth(400); -// scroll.prefHeightProperty().bind(super.prefHeightProperty().multiply(0.75)); - scroll.getStyleClass().remove("scroll-pane"); - scroll.getStyleClass().add("box"); - scroll.setPadding(new Insets(5)); - - Pane helpBox = new Pane(); - - HBox main = new HBox(); - main.getChildren().addAll(scroll, actionBox, helpBox); - main.setSpacing(10); - - Button exit = new Button(); - exit.setText("Cancel"); - exit.setOnAction(_ -> { - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(prev); - }); - - Button save = new Button(); - save.setText("Done"); - save.setOnAction(_ -> { - diff.notes.list = noteList; - diff.notes.writeFile(); - Sound.playSfx(Sound.BACKWARD); - Driver.setMenu(new DiffEditor(diff, prev.prev)); - }); - - HBox buttons = new HBox(save, exit); - buttons.setSpacing(10); - buttons.setAlignment(Pos.CENTER); - - // Draw notes - noteList.forEach(n -> lanes[n.lane].getChildren().add(drawBlock(n))); - noteList.addListener((ListChangeListener) _ -> { - // TODO - for (Pane lane : lanes) { - lane.getChildren().clear(); - } - noteList.forEach(n -> lanes[n.lane].getChildren().add(drawBlock(n))); - }); - - // Draw and update ruler - AtomicInteger lastRuler = new AtomicInteger(-1); - scrollContent.heightProperty().addListener(_ -> { - int ruler1 = (int) screenPosToSecond(scrollContent.getHeight()); - for (int i = lastRuler.get() + 1; i <= ruler1; i++) { - Label l = new Label(toMinAndSec(i)+" -"); - l.layoutYProperty().bind(secondToScreenPos(i)); - l.setTextFill(Color.WHITE); - rulerLane.getChildren().add(l); - } - lastRuler.set(ruler1); - }); - - VBox centerBox = new VBox(); - centerBox.getChildren().addAll(main, exit); - centerBox.setSpacing(10); - centerBox.setAlignment(Pos.CENTER); - - content.getChildren().add(centerBox); - content.setAlignment(Pos.CENTER); - - // write notes on key press - content.addEventFilter(KeyEvent.KEY_PRESSED, e -> { - KeyCode k = e.getCode(); - if (k == Control.LANE0.getKey()) { WriteNote(0); } - if (k == Control.LANE1.getKey()) { WriteNote(1); } - if (k == Control.LANE2.getKey()) { WriteNote(2); } - if (k == Control.LANE3.getKey()) { WriteNote(3); } - if (k == Control.LANE4.getKey()) { WriteNote(4); } - if (k == Control.NOTE_DOWN.getKey()) { MoveNoteDown(); } - if (k == Control.NOTE_UP.getKey()) { MoveNoteUp(); } - if (k == Control.DELETE_NOTE.getKey()) { delNote.fire(); } - if (k == Control.CLEAR_SELECTION.getKey()) { clearSelect.fire(); } - if (k == Control.SCROLL_LOCK.getKey()) { scrollLock.fire(); } - if (k == Control.PLAY_PAUSE.getKey()) { play.fire(); } - if (k == Control.SELECT_ALL.getKey()) { selectAll.fire(); } - e.consume(); - }); - - m.currentTimeProperty().addListener(_ -> { - // TODO - playhead.layoutYProperty().bind(secondToScreenPos(m.getCurrentTime().toSeconds())); - }); - - play.setOnAction(_ -> { - if (play.isSelected()) { - m.play(); - } - else { - m.pause(); - } - - }); - - scrollLock.setOnAction(_ -> { - if (scrollLock.isSelected()) { - // vvalue takes in a value between 0 and 1 NOT a pixel value - scroll.vvalueProperty().bind(playhead.layoutYProperty().subtract(scroll.heightProperty().divide(2)).divide(scrollContent.heightProperty().subtract(scroll.heightProperty()))); - } - else { - scroll.vvalueProperty().unbind(); - } - - - }); - - reset.setOnAction(_ -> { - m.seek(new Duration(0)); - }); - - delNote.setOnAction(_ -> { - activeNotes.forEach(e -> { - noteList.remove(e.note); - }); - activeNotes.clear(); - }); - - clearSelect.setOnAction(_ -> { - activeNotes.forEach(e -> e.setFill(e.color)); - activeNotes.clear(); - }); - - selectAll.setOnAction(_ -> { - activeNotes.clear(); - for (Pane lane : lanes) { - lane.getChildren().forEach(e -> activeNotes.add((Block) e)); - } - activeNotes.forEach(e -> e.setFill(Color.WHITE)); - }); - - Pane addHelp = addHelp(); - Pane moveHelp = moveHelp(); - addNote.setOnAction(_ -> { - if (addNote.isSelected()) { - helpBox.getChildren().clear(); - helpBox.getChildren().add(addHelp); - } - else { - helpBox.getChildren().clear(); - } - }); - - moveNote.setOnAction(_ -> { - if (moveNote.isSelected()) { - helpBox.getChildren().clear(); - helpBox.getChildren().add(moveHelp); - } - else { - helpBox.getChildren().clear(); - } - }); - - moveNote.disabledProperty().addListener(_ -> { - if (moveNote.isDisabled() && moveNote.isSelected()) { - moveNote.setSelected(false); - helpBox.getChildren().clear(); - } - }); - } - - @Override - public Pane getContent() { - return content; - } - - @Override - public void onView() { - Sound.stopSong(); - } - - @Override - public void onLeave() { - m.stop(); - Sound.playSong(Sound.MENU_SONG); - } - - private Block drawBlock(Note n) { - Color color = diff.level.colors[n.lane]; - Block b = new Block(color,20, 20, 5, false, n); - b.heightProperty().bind(scroll.widthProperty().divide(8)); - b.widthProperty().bind(scroll.widthProperty().divide(8)); - b.arcHeightProperty().bind(scroll.widthProperty().divide(25)); - b.arcWidthProperty().bind(scroll.widthProperty().divide(25)); - b.strokeWidthProperty().bind(scroll.widthProperty().divide(120)); - b.layoutYProperty().bind(secondToScreenPos(n.time.add(0))); - b.setOnMouseClicked(_ -> { - if (activeNotes.contains(b)) { - activeNotes.remove(b); - b.setFill(b.color); - } - else { - activeNotes.add(b); - b.setFill(Color.WHITE); - } - }); - return b; - } - - private String toMinAndSec(int t) { - int min = t / 60; - int sec = t % 60; - - String min2 = min + ""; - if (min2.length() == 1) { - min2 = "0" + min2; - } - String sec2 = sec + ""; - if (sec2.length() == 1) { - sec2 = "0" + sec2; - } - return min2 + ":" + sec2; - } - - private double screenPosToSecond(double screenYPos) { - return screenYPos / (scroll.getHeight() * 0.9); - } - - private DoubleBinding secondToScreenPos(DoubleBinding second) { - return scroll.heightProperty().multiply(second).multiply(0.9); - } - - private DoubleBinding secondToScreenPos(double second) { - return scroll.heightProperty().multiply(second).multiply(0.9); - } - - private void WriteNote(int col) { - Note tmp = new Note(screenPosToSecond(playhead.getLayoutY()), col); - noteList.add(tmp); - } - - private void MoveNoteUp() { - activeNotes.forEach(n -> n.note.time.setValue(n.note.time.get() + 0.01)); - } - - private void MoveNoteDown() { - activeNotes.forEach(n -> n.note.time.setValue(n.note.time.get() - 0.01)); - } - - private Pane addHelp() { - Label l1 = new Label("Use the following keys"); - HBox hb = new HBox( - new Target(diff.level.colors[0], 40, 40, 10, Control.LANE0.targetString()), - new Target(diff.level.colors[1], 40, 40, 10, Control.LANE1.targetString()), - new Target(diff.level.colors[2], 40, 40, 10, Control.LANE2.targetString()), - new Target(diff.level.colors[3], 40, 40, 10, Control.LANE3.targetString()), - new Target(diff.level.colors[4], 40, 40, 10, Control.LANE4.targetString()) - ); - hb.setSpacing(10); - hb.setAlignment(Pos.CENTER_LEFT); - Label l2 = new Label("to write a new note at \nthe play head's position."); - - VBox ret = new VBox(l1, hb, l2); - ret.setPadding(new Insets(10)); - ret.getStyleClass().add("box"); - return ret; - } - - private Pane moveHelp() { - Label l1 = new Label("Use the"); - HBox hb = new HBox(new Target(Color.BLACK, 40, 40, 10, Control.NOTE_UP.targetString()), new Label("and"), new Target(Color.BLACK, 40, 40, 10, Control.NOTE_DOWN.targetString()), new Label("keys")); - hb.setSpacing(10); - hb.setAlignment(Pos.CENTER_LEFT); - Label l2 = new Label("to move the selected \nnote(s) up and down."); - - VBox ret = new VBox(l1, hb, l2); - ret.setPadding(new Insets(10)); - ret.getStyleClass().add("box"); - ret.setLayoutY(120); - return ret; - } -} diff --git a/src/main/java/net/sowgro/npehero/editor/DiffEditor.java b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java new file mode 100755 index 0000000..f98ff46 --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java @@ -0,0 +1,165 @@ +package net.sowgro.npehero.editor; + +import javafx.beans.binding.DoubleBinding; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; +import net.sowgro.npehero.Driver; +import net.sowgro.npehero.gameplay.Block; +import net.sowgro.npehero.gui.LevelSurround; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import net.sowgro.npehero.main.*; + +public class DiffEditor extends Page +{ + Difficulty diff; + ScrollPane scroll; + + HBox content = new HBox(); + + public Page prev; + + public DiffEditor(Difficulty diff, Page prev) { + this.diff = diff; + this.prev = prev; + + Text folderNameLabel = new Text("Folder name"); + TextField folderName = new TextField(diff.thisDir.getName()); + folderName.setDisable(true); + + Text titleLabel = new Text("Title"); + TextField title = new TextField(diff.title); + + Button editNotes = new Button("Edit notes"); + editNotes.setOnAction(_ -> { + if (diff.level.song == null) { + Driver.setMenu(new ErrorDisplay("You must import a song file before editing the notes!", this)); + } + if (diff.bpm != 0.0) { + Driver.setMenu(new ErrorDisplay( + "Note:\nThe new notes editor does not support bpm and beat based songs. If you continue the beats will be converted to seconds.", + this, + new NotesEditor2(diff, this) + )); + } + Driver.setMenu(new NotesEditor2(diff, this)); + }); + + Button oldEditNotes = new Button("Edit notes (legacy)"); + oldEditNotes.setOnAction(_ -> Driver.setMenu(new ErrorDisplay( + "Warning: \nThe legacy editor will overwrite all existing notes!", + this, + new NotesEditor(diff, this)) + )); + + Label scoresLable = new Label("Scores"); + Button editScores = new Button("Clear leaderboard"); + editScores.setOnAction(_ -> diff.leaderboard.entries.clear()); + + Button playLevel = new Button("Play level"); + playLevel.setOnAction(_ -> { + if (diff.isValid && diff.level.isValid) { + Driver.setMenu(new LevelSurround(diff.level, diff, this)); + } + else { + Driver.setMenu(new ErrorDisplay("This Level is not valid!\nCheck that all required fields\nare populated.", this)); + } + }); + + Button save = new Button("Save"); + save.setOnAction(_ -> { //assigns text fields to values + diff.title = title.getText(); +// diff.bpm = Double.parseDouble(bpm.getText()); +// diff.numBeats = Integer.parseInt(numBeats.getText()); + diff.write(); + }); + + HBox scrollContent = new HBox(); + scroll = new ScrollPane(scrollContent); + scroll.setFitToWidth(true); + scroll.getStyleClass().remove("scroll-pane"); + scroll.getStyleClass().add("box"); +// scroll.setPrefHeight(400); + scroll.prefWidthProperty().bind(scroll.heightProperty().multiply(0.66)); + + Pane[] lanes = new Pane[5]; + for (int i = 0; i < lanes.length; i++) { + lanes[i] = new Pane(); + } + + scrollContent.getChildren().addAll(lanes); + scrollContent.setSpacing(5); + scrollContent.setAlignment(Pos.CENTER); + + diff.notes.list.forEach(n -> lanes[n.lane].getChildren().add(drawNote(n))); + + VBox notePreview = new VBox(); + + ValidIndicator validNotes = new ValidIndicator(); + if (diff.notes.list.isEmpty()) { + validNotes.setInvalid("This difficulty does not contain any notes!"); + } + HBox notesLabel = new HBox(new Label("Notes"), validNotes); + Pane scrollHolder = new Pane(scroll); + scroll.prefHeightProperty().bind(scrollHolder.heightProperty()); + scrollHolder.setPrefHeight(400); + notePreview.getChildren().addAll(notesLabel, scrollHolder, editNotes, oldEditNotes); + notePreview.setSpacing(10); + + VBox left = new VBox(); + left.getChildren().addAll(folderNameLabel,folderName,titleLabel,title,scoresLable,editScores,playLevel); + left.setSpacing(10); + + HBox main = new HBox(); + main.getChildren().addAll(left, notePreview); + main.setSpacing(30); + + Button exit = new Button(); + exit.setText("Back"); + exit.setOnAction(e -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + HBox bottom = new HBox(exit,save); + bottom.setSpacing(10); + bottom.setAlignment(Pos.CENTER); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, bottom); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + } + + @Override + public Pane getContent() { + return content; + } + + // Duplicates of NotesEditor2 methods, should be made generic and combined + private Block drawNote(Note n) { + Color color = diff.level.colors[n.lane]; + Block b = new Block(color,20, 20, 5, false, n); + b.heightProperty().bind(scroll.widthProperty().divide(8)); + b.widthProperty().bind(scroll.widthProperty().divide(8)); + b.arcHeightProperty().bind(scroll.widthProperty().divide(25)); + b.arcWidthProperty().bind(scroll.widthProperty().divide(25)); + b.strokeWidthProperty().bind(scroll.widthProperty().divide(120)); + b.layoutYProperty().bind(secondToScreenPos(n.time.add(0))); + return b; + } + + private DoubleBinding secondToScreenPos(double second) { + return scroll.heightProperty().multiply(second * 0.9); + } + + private DoubleBinding secondToScreenPos(DoubleBinding second) { + return scroll.heightProperty().multiply(second).multiply(0.9); + } +} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/editor/DiffList.java b/src/main/java/net/sowgro/npehero/editor/DiffList.java new file mode 100755 index 0000000..13e4795 --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/DiffList.java @@ -0,0 +1,162 @@ +package net.sowgro.npehero.editor; + +import javafx.beans.property.ReadOnlyStringWrapper; +import javafx.collections.ObservableList; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; +import net.sowgro.npehero.Driver; +import net.sowgro.npehero.main.Difficulty; +import net.sowgro.npehero.main.Level; +import net.sowgro.npehero.main.Page; +import net.sowgro.npehero.main.Sound; + +import java.util.Collections; + +public class DiffList extends Page +{ + private HBox content = new HBox(); + + public DiffList(Level level, Page prev) + { + //sets up table view: requires special getters, setters and constructors to work + TableView diffs = new TableView<>(); + + TableColumn titleCol = new TableColumn<>("Name"); + TableColumn validCol = new TableColumn<>("Valid?"); + + diffs.getColumns().add(titleCol); + diffs.getColumns().add(validCol); + + titleCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title)); + validCol.setCellValueFactory(data -> { + if (data.getValue().isValid) { + return new ReadOnlyStringWrapper("Yes"); + } + else { + return new ReadOnlyStringWrapper("No"); + } + }); + + diffs.setItems(level.difficulties.list); + + diffs.setRowFactory( _ -> { + TableRow row = new TableRow<>(); + row.setOnMouseClicked(event -> { + if (event.getClickCount() == 2 && (! row.isEmpty()) ) { + Difficulty rowData = row.getItem(); + Driver.setMenu(new DiffEditor(rowData, this)); + } + }); + return row ; + }); + + diffs.setPrefWidth(400); + diffs.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.67)); + + Button edit = new Button("Edit"); + edit.setOnAction(e -> Driver.setMenu(new DiffEditor(diffs.getSelectionModel().getSelectedItem(), this))); + edit.setDisable(true); + edit.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull()); + + Button remove = new Button("Delete"); + remove.setOnAction(e -> level.difficulties.remove(diffs.getSelectionModel().getSelectedItem())); + remove.setDisable(true); + remove.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull()); + + Button refresh = new Button("Refresh"); + refresh.setOnAction(e -> { +// level.readData(); +// diffs.setItems(level.difficulties.list.sorted()); + diffs.refresh(); + }); + + ToggleButton create = new ToggleButton("Create"); + + Button moveUp = new Button("Move Up"); + moveUp.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull()); + moveUp.setOnAction(_ -> { + Difficulty diff = diffs.getSelectionModel().selectedItemProperty().get(); + ObservableList diffList = level.difficulties.list; + int oldIndex = diffList.indexOf(diff); + if (oldIndex <= 0) { + return; + } + Collections.swap(diffList, oldIndex, oldIndex-1); + level.difficulties.saveOrder(); + }); + + Button moveDown = new Button("Move Down"); + moveDown.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull()); + moveDown.setOnAction(_ -> { + Difficulty diff = diffs.getSelectionModel().selectedItemProperty().get(); + ObservableList diffList = level.difficulties.list; + int oldIndex = diffList.indexOf(diff); + if (oldIndex >= diffList.size()-1) { + return; + } + Collections.swap(diffList, oldIndex, oldIndex+1); + level.difficulties.saveOrder(); + }); + + VBox buttons = new VBox(); + buttons.getChildren().addAll(create, edit, remove, moveUp, moveDown, refresh); + buttons.setSpacing(10); + + TextField newLevelEntry = new TextField(); + Button newLevelButton = new Button("add"); + + HBox newLevel = new HBox(newLevelEntry,newLevelButton); + Label newLevelLabel = new Label("Name of new difficulty"); + VBox newLevelBox = new VBox(newLevelLabel, newLevel); + newLevelBox.setSpacing(10); + newLevelBox.getStyleClass().add("box"); + newLevelBox.setPadding(new Insets(10)); + + Pane sidebar = new Pane(); + + HBox main = new HBox(); + main.getChildren().addAll(diffs,buttons, sidebar); + main.setSpacing(10); + + Button exit = new Button(); + exit.setText("Back"); + exit.setOnAction(e -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + create.setOnAction(_ -> { + if (create.isSelected()) { + sidebar.getChildren().add(newLevelBox); + } + else { + sidebar.getChildren().remove(newLevelBox); + } + }); + + newLevelButton.setOnAction(_ -> { + level.difficulties.add(newLevelEntry.getText()); + newLevelEntry.clear(); + refresh.fire(); + sidebar.getChildren().clear(); + create.setSelected(false); + }); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, exit); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + } + + @Override + public Pane getContent() { + return content; + } +} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java b/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java new file mode 100644 index 0000000..b3ec751 --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java @@ -0,0 +1,85 @@ +package net.sowgro.npehero.editor; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; +import net.sowgro.npehero.Driver; +import net.sowgro.npehero.main.Page; +import net.sowgro.npehero.main.Sound; + +public class ErrorDisplay extends Page { + + private HBox content = new HBox(); + + /** + * Error display with a message and Back button + * @param message The message to display + * @param prev The destination of the close button + */ + public ErrorDisplay(String message, Page prev) { + Label main = new Label(message); + main.getStyleClass().add("box"); + + Button exit = new Button(); + exit.setText("Back"); + exit.setOnAction(e -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, exit); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + } + + /** + * Error display with a message and Cancel and Proceed buttons + * @param message The message to display + * @param prev The destination of the Cancel button + * @param next The destination of the Proceed button + */ + public ErrorDisplay(String message, Page prev, Page next) { + Label main = new Label(message); + main.getStyleClass().add("box"); + main.setPadding(new Insets(10)); + + Button exit = new Button(); + exit.setText("Cancel"); + exit.setOnAction(_ -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + Button nextButton = new Button(); + nextButton.setText("Proceed"); + nextButton.setOnAction(_ -> { + Sound.playSfx(Sound.FORWARD); + Driver.setMenu(next); + }); + + HBox bottom = new HBox(exit, nextButton); + bottom.setAlignment(Pos.CENTER); + bottom.setSpacing(10); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, bottom); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + } + + @Override + public Pane getContent() { + return content; + } +} diff --git a/src/main/java/net/sowgro/npehero/editor/LevelEditor.java b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java new file mode 100755 index 0000000..56a2924 --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java @@ -0,0 +1,195 @@ +package net.sowgro.npehero.editor; + +import java.io.File; + +import javafx.beans.property.ReadOnlyStringWrapper; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.layout.*; +import javafx.scene.text.Text; +import javafx.stage.FileChooser; +import javafx.stage.FileChooser.ExtensionFilter; +import net.sowgro.npehero.Driver; +import net.sowgro.npehero.main.*; + +public class LevelEditor extends Page +{ + private HBox content = new HBox(); + + private File selectedSong = null; + private File selectedPreview = null; + private File selectedBackground = null; + + public LevelEditor(Level level, Page prev) + { + Text folderNameLabel = new Text("Folder name"); + TextField folderName = new TextField(); + if (level.dir != null) { + folderName.setText(level.dir.getName()); + folderName.setDisable(true); + } + + Text titleLabel = new Text("Title"); + TextField title = new TextField(level.title); + + Text artistLabel = new Text("Artist"); + TextField artist = new TextField(level.artist); + + Text descLabel = new Text("Description"); + TextField desc = new TextField(level.desc); + + Text colorsLabel = new Text("Colors"); + + ColorPicker[] colorsPickers = new ColorPicker[] { + new ColorPicker(level.colors[0]), + new ColorPicker(level.colors[1]), + new ColorPicker(level.colors[2]), + new ColorPicker(level.colors[3]), + new ColorPicker(level.colors[4]) + }; + + for (ColorPicker cp : colorsPickers) { + cp.getStyleClass().add("button"); + } + + HBox colorPickerBox = new HBox(); + colorPickerBox.getChildren().addAll(colorsPickers); + + ValidIndicator songValid = new ValidIndicator(); + if (level.song == null) { + songValid.setInvalid("Missing song file!"); + } + HBox filesLabel = new HBox(new Text("Files"), songValid); + + FileChooser backgroundChooser = new FileChooser(); + backgroundChooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")); + Button backgroundButton = new Button("Background Image"); + backgroundButton.setOnAction(_ -> selectedBackground = backgroundChooser.showOpenDialog(Driver.primaryStage)); + + FileChooser previewChooser = new FileChooser(); + previewChooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")); + Button previewButton = new Button("Preview Image"); + previewButton.setOnAction(_ -> selectedPreview = previewChooser.showOpenDialog(Driver.primaryStage)); + + FileChooser songChooser = new FileChooser(); + songChooser.getExtensionFilters().add(new ExtensionFilter("Audio Files", "*.wav", "*.mp3", "*.aac")); + Button songButton = new Button("Song file"); + songButton.setOnAction(_ -> selectedSong = songChooser.showOpenDialog(Driver.primaryStage)); + + + ValidIndicator diffsInvalid = new ValidIndicator(); + if (level.difficulties.validList.isEmpty()) { + diffsInvalid.setInvalid("This level contains no valid difficulties!"); + } + HBox diffLabel = new HBox(new Text("Difficulties"), diffsInvalid); + diffLabel.setSpacing(5); + + + TableView diffList = new TableView<>(); + + TableColumn diffCol = new TableColumn<>("Difficulty"); + TableColumn validCol = new TableColumn<>("Valid?"); + + diffList.getColumns().add(diffCol); + diffList.getColumns().add(validCol); + + diffCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title)); + validCol.setCellValueFactory(data -> { + if (data.getValue().isValid) { + return new ReadOnlyStringWrapper("Yes"); + } + else { + return new ReadOnlyStringWrapper("No"); + } + }); + + diffList.setItems(level.difficulties.list); + + diffList.setRowFactory( _ -> { + TableRow row = new TableRow<>(); + row.setOnMouseClicked(event -> { + if (event.getClickCount() == 2 && (! row.isEmpty()) ) { + Difficulty rowData = row.getItem(); + Driver.setMenu(new DiffEditor(rowData, this)); + } + }); + return row ; + }); + + Button newDiffs = new Button("Edit difficulties"); + newDiffs.setOnAction(_ -> Driver.setMenu(new DiffList(level, this))); + + diffList.setSelectionModel(null); + + Button save = new Button("Save"); + save.setOnAction(e -> { //assigns fields to values + level.title = title.getText(); + level.artist = artist.getText(); + level.desc = desc.getText(); + level.colors[0] = colorsPickers[0].getValue(); + level.colors[1] = colorsPickers[1].getValue(); + level.colors[2] = colorsPickers[2].getValue(); + level.colors[3] = colorsPickers[3].getValue(); + level.colors[4] = colorsPickers[4].getValue(); + if (selectedBackground != null && selectedBackground.exists()) { + level.addFile(selectedBackground,"background." + getFileExtension(selectedBackground)); + } + if (selectedPreview != null && selectedPreview.exists()) { + level.addFile(selectedPreview,"preview." + getFileExtension(selectedPreview)); + } + if (selectedSong != null) { + level.addFile(selectedSong,"song." + getFileExtension(selectedSong)); + } + level.writeMetadata(); + }); + + VBox left = new VBox(filesLabel, songButton, previewButton, backgroundButton, colorsLabel, colorPickerBox); + left.setSpacing(10); + left.setPrefWidth(300); + + VBox center = new VBox(folderNameLabel,folderName,titleLabel,title,artistLabel,artist,descLabel,desc); + center.setSpacing(10); + center.setPrefWidth(300); + + VBox right = new VBox(diffLabel,diffList,newDiffs); + right.setSpacing(10); + center.setPrefWidth(300); + + HBox mainBox = new HBox(); + mainBox.getChildren().addAll(left, center, right); + mainBox.setSpacing(30); + + Button exit = new Button(); + exit.setText("Back"); + exit.setOnAction(e -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + HBox bottom = new HBox(save, exit); + bottom.setAlignment(Pos.CENTER); + bottom.setSpacing(10); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(mainBox, bottom); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + } + + @Override + public Pane getContent() { + return content; + } + + /** + * Get the extension of a file. + * @param file The file to return the extension of + * @return The extension of the file in the format "*.ext" + */ + public String getFileExtension(File file) { + return file.getName().substring(file.getName().lastIndexOf('.') + 1); + } +} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/editor/LevelList.java b/src/main/java/net/sowgro/npehero/editor/LevelList.java new file mode 100755 index 0000000..b479f49 --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/LevelList.java @@ -0,0 +1,135 @@ +package net.sowgro.npehero.editor; + +import javafx.beans.property.ReadOnlyStringWrapper; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.layout.Pane; +import net.sowgro.npehero.Driver; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import net.sowgro.npehero.gui.MainMenu; +import net.sowgro.npehero.main.Level; +import net.sowgro.npehero.main.Levels; +import net.sowgro.npehero.main.Page; +import net.sowgro.npehero.main.Sound; + +public class LevelList extends Page +{ + private HBox content = new HBox(); + + public LevelList() + { + //sets up table view: requires special getters, setters and constructors to work + TableView levels = new TableView<>(); + + TableColumn titleCol = new TableColumn<>("Title"); + TableColumn artistCol = new TableColumn<>("Artist"); + TableColumn validCol = new TableColumn<>("Valid?"); + + levels.getColumns().add(titleCol); + levels.getColumns().add(artistCol); + levels.getColumns().add(validCol); + + titleCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title)); + artistCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().artist)); + validCol.setCellValueFactory(data -> { + if (data.getValue().isValid) { + return new ReadOnlyStringWrapper("Yes"); + } + else { + return new ReadOnlyStringWrapper("No"); + } + }); + + levels.setItems(Levels.list); + + levels.setRowFactory( _ -> { + TableRow row = new TableRow<>(); + row.setOnMouseClicked(event -> { + if (event.getClickCount() == 2 && (! row.isEmpty()) ) { + Level rowData = row.getItem(); + Driver.setMenu(new LevelEditor(rowData, this)); + } + }); + return row ; + }); + levels.setPrefWidth(600); + levels.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.75)); + + Button edit = new Button("Edit"); + edit.setOnAction(e -> Driver.setMenu(new LevelEditor(levels.getSelectionModel().getSelectedItem(), this))); + edit.setDisable(true); + edit.disableProperty().bind(levels.getSelectionModel().selectedItemProperty().isNull()); + + Button remove = new Button("Delete"); + remove.setOnAction(e -> Levels.remove(levels.getSelectionModel().getSelectedItem())); + remove.setDisable(true); + remove.disableProperty().bind(levels.getSelectionModel().selectedItemProperty().isNull()); + + Button refresh = new Button("Refresh"); + refresh.setOnAction(e -> { + Levels.readData(); + levels.setItems(Levels.list); + }); + + ToggleButton create = new ToggleButton("Create"); + + VBox buttons = new VBox(); + buttons.getChildren().addAll(create, edit, remove, refresh); + buttons.setSpacing(10); + + TextField newLevelEntry = new TextField(); + Button newLevelButton = new Button("add"); + + HBox newLevel = new HBox(newLevelEntry,newLevelButton); + Label newLevelLabel = new Label("Name of new level"); + VBox newLevelBox = new VBox(newLevelLabel, newLevel); + newLevelBox.setSpacing(10); + newLevelBox.getStyleClass().add("box"); + newLevelBox.setPadding(new Insets(10)); + + Pane sidebar = new Pane(); + + HBox main = new HBox(); + main.getChildren().addAll(levels,buttons,sidebar); + main.setSpacing(10); + + Button exit = new Button(); + exit.setText("Back"); + exit.setOnAction(e -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(new MainMenu()); + }); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, exit); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + + create.setOnAction(_ -> { + if (create.isSelected()) { + sidebar.getChildren().add(newLevelBox); + } + else { + sidebar.getChildren().remove(newLevelBox); + } + }); + + newLevelButton.setOnAction(_ -> { + Levels.add(newLevelEntry.getText()); + newLevelEntry.clear(); + refresh.fire(); + sidebar.getChildren().clear(); + create.setSelected(false); + }); + } + + @Override + public Pane getContent() { + return content; + } +} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor.java new file mode 100755 index 0000000..133330f --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor.java @@ -0,0 +1,132 @@ +package net.sowgro.npehero.editor; + +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; + +import javafx.geometry.Pos; +import javafx.scene.input.KeyEvent; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.media.Media; +import net.sowgro.npehero.gameplay.Timer; +import net.sowgro.npehero.Driver; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import net.sowgro.npehero.main.Control; +import net.sowgro.npehero.main.Difficulty; +import net.sowgro.npehero.main.Page; +import net.sowgro.npehero.main.Sound; + +public class NotesEditor extends Page +{ + Text help; + String t1 = "Press Start to begin recording. Use the same keys. Note: existing notes will be overwritten."; + String t2 = "Now recording. Press Stop or " + Control.LEGACY_STOP.getKey().toString() + " to finish"; + Difficulty diff; + Timer timer; + PrintWriter writer; + + private HBox content = new HBox(); + + public NotesEditor(Difficulty diff, Page prev) + { + this.diff = diff; + + help = new Text(t1); + Text cur = new Text("-----"); + + Button start = new Button("Start"); + start.setOnAction(e -> start()); + start.setFocusTraversable(false); + + Button stop = new Button("Stop"); + stop.setOnAction(e -> stop()); + stop.setFocusTraversable(false); + + VBox main = new VBox(); + main.getChildren().addAll(help,cur,start,stop); + + Button exit = new Button(); + exit.setText("Back"); + exit.setOnAction(e -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, exit); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + + try { + writer = new PrintWriter(diff.notes.getFile(), "UTF-8"); + } catch (FileNotFoundException | UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + + Scene scene = Driver.primaryStage.getScene(); + scene.addEventFilter(KeyEvent.KEY_PRESSED, e -> { + if (e.getCode() == Control.LANE0.getKey()) { + writer.println("d"+timer); + cur.setText("d"+timer); + } + if (e.getCode() == Control.LANE1.getKey()) { + writer.println("f"+timer); + cur.setText("f"+timer); + } + if (e.getCode() == Control.LANE2.getKey()) { + writer.println("s"+timer); + cur.setText("s"+timer); + } + if (e.getCode() == Control.LANE3.getKey()) { + writer.println("j"+timer); + cur.setText("j"+timer); + } + if (e.getCode() == Control.LANE4.getKey()) { + writer.println("k"+timer); + cur.setText("k"+timer); + } + if (e.getCode() == Control.LEGACY_STOP.getKey()) + { + stop(); + } + e.consume(); + }); + + Driver.primaryStage.setOnCloseRequest(e -> stop()); + } + + @Override + public Pane getContent() { + return content; + } + + private void start() + { + Sound.playSong(new Media(diff.level.song.toString())); + timer = new Timer(diff.bpm); + help.setText(t2); + } + + private void stop() + { + try + { + Sound.stopSong(); +// diff.numBeats = (int)Double.parseDouble(timer.toString()); + timer = null; + writer.close(); + help.setText(t1); + } + catch (Exception e) + { + //System.err.println("tried to stop but already stopped"); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java new file mode 100644 index 0000000..38ad234 --- /dev/null +++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java @@ -0,0 +1,444 @@ +package net.sowgro.npehero.editor; + +import javafx.beans.binding.DoubleBinding; +import javafx.beans.property.DoubleProperty; +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleDoubleProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.control.*; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.media.Media; +import javafx.scene.media.MediaPlayer; +import javafx.scene.paint.Color; +import javafx.scene.shape.Line; +import javafx.scene.shape.Polygon; +import javafx.util.Duration; +import net.sowgro.npehero.Driver; +import net.sowgro.npehero.gameplay.Block; +import net.sowgro.npehero.gameplay.Target; +import net.sowgro.npehero.main.*; +import net.sowgro.npehero.main.Control; + +import java.util.concurrent.atomic.AtomicInteger; + +public class NotesEditor2 extends Page { + Difficulty diff; + ScrollPane scroll = new ScrollPane(); + Pane[] lanes; + MediaPlayer m; + Polygon playhead; + ListProperty activeNotes = new SimpleListProperty<>(FXCollections.observableArrayList()); + ListProperty noteList; + DiffEditor prev; + DoubleProperty newEndTime = new SimpleDoubleProperty(0); + + private HBox content = new HBox(); + + public NotesEditor2(Difficulty diff, DiffEditor prev) { + this.diff = diff; + noteList = diff.notes.deepCopyList(); + m = new MediaPlayer(diff.level.song); + this.prev = prev; + + // Buttons + VBox actionBox = new VBox(); + actionBox.setSpacing(10); + + Label noteLabel = new Label("Notes"); + ToggleButton addNote = new ToggleButton("Add"); + Button delNote = new Button("Delete"); + ToggleButton moveNote = new ToggleButton("Move"); + actionBox.getChildren().addAll(noteLabel, addNote, delNote, moveNote); + + Label selectionLabel = new Label("Selection"); + Button selectAll = new Button("Select All"); + Button clearSelect = new Button("Clear"); + actionBox.getChildren().addAll(selectionLabel, selectAll, clearSelect); + + Label playbackLabel = new Label("Playback"); + ToggleButton play = new ToggleButton("Play"); + Button reset = new Button("Reset"); + ToggleButton scrollLock = new ToggleButton("Scroll Lock"); + Button setEnd = new Button("End Here"); + actionBox.getChildren().addAll(playbackLabel, play, reset, scrollLock, setEnd); + + delNote.disableProperty().bind(activeNotes.emptyProperty()); + moveNote.disableProperty().bind(activeNotes.emptyProperty()); + clearSelect.disableProperty().bind(activeNotes.emptyProperty()); + + ToggleGroup tg = new ToggleGroup(); + addNote.setToggleGroup(tg); + moveNote.setToggleGroup(tg); + + // Lanes + this.lanes = new Pane[5]; + for (int i = 0; i < lanes.length; i++) { + lanes[i] = new Pane(); + } + Block sizer = drawBlock(new Note(0, 0)); + for (Pane lane : lanes) { + lane.prefWidthProperty().bind(sizer.widthProperty()); + } + Pane rulerLane = new Pane(); +// rulerLane.setManaged(false); + + Pane playheadLane = new Pane(); + playheadLane.setOnMouseClicked(e -> { + m.seek(new Duration(screenPosToSecond(e.getY()) * 1000)); + }); + + this.playhead = new Polygon(); + playhead.getPoints().addAll( + 0.0, -10.0, + 20.0, -10.0, + 30.0, 0.0, + 20.0, 10.0, + 0.0, 10.0 + ); + playhead.setFill(Color.WHITE); + playheadLane.getChildren().add(playhead); +// playhead.setOnMouseDragged(e -> { +// scroll.get +// playhead.layoutYProperty().bind(secondToScreenPos()); +// }); + + HBox scrollContent = new HBox(); + scrollContent.setAlignment(Pos.CENTER); + scrollContent.setSpacing(10); + scrollContent.getChildren().addAll(playheadLane, rulerLane); + scrollContent.getChildren().addAll(lanes); + + Line playheadLine = new Line(); + playheadLine.setStartX(0); + playheadLine.endXProperty().bind(scroll.widthProperty().subtract(80)); + playheadLine.setStartY(0); + playheadLine.setEndY(0); + playheadLine.setStroke(Color.WHITE); + playheadLine.layoutYProperty().bind(playhead.layoutYProperty()); + + Line endLine = new Line(); + endLine.setStartX(0); + endLine.endXProperty().bind(scroll.widthProperty().subtract(80)); + endLine.setStartY(0); + endLine.setEndY(0); + endLine.setStroke(Color.RED); + + Pane contentOverlay = new Pane(playheadLine, endLine); + contentOverlay.setPickOnBounds(false); + + StackPane stackPane = new StackPane(); + stackPane.getChildren().addAll(scrollContent, contentOverlay); + + scroll.setContent(stackPane); +// scroll.prefWidthProperty().bind(super.prefWidthProperty().multiply(0.35)); +// scroll.setMinWidth(400); + scroll.prefHeightProperty().bind(content.heightProperty().multiply(0.75)); + scroll.prefWidthProperty().bind(scroll.prefHeightProperty().multiply(0.70)); + scroll.getStyleClass().remove("scroll-pane"); + scroll.getStyleClass().add("box"); + scroll.setPadding(new Insets(5)); + + Pane helpBox = new Pane(); + + HBox main = new HBox(); + main.getChildren().addAll(scroll, actionBox, helpBox); + main.setSpacing(10); + + Button exit = new Button(); + exit.setText("Cancel"); + exit.setOnAction(_ -> { + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(prev); + }); + + Button save = new Button(); + save.setText("Save"); + save.setOnAction(_ -> { + diff.notes.list = noteList; + diff.notes.writeFile(); + diff.endTime = newEndTime.get(); + Sound.playSfx(Sound.BACKWARD); + Driver.setMenu(new DiffEditor(diff, prev.prev)); + }); + + HBox buttons = new HBox(save, exit); + buttons.setSpacing(10); + buttons.setAlignment(Pos.CENTER); + + Runnable updateEndLine = () -> { + System.out.println("LISTENER CALLED"); + if (newEndTime.get() != 0) { + endLine.layoutYProperty().bind(secondToScreenPos(newEndTime.get())); + } + else { + endLine.layoutYProperty().bind(secondToScreenPos(m.getTotalDuration().toSeconds())); + } + }; + + newEndTime.addListener((_, _, _) -> updateEndLine.run()); + newEndTime.set(diff.endTime); + updateEndLine.run(); + + // Draw notes + noteList.forEach(n -> lanes[n.lane].getChildren().add(drawBlock(n))); + noteList.addListener((ListChangeListener) _ -> { + // TODO + for (Pane lane : lanes) { + lane.getChildren().clear(); + } + noteList.forEach(n -> lanes[n.lane].getChildren().add(drawBlock(n))); + }); + + // Draw and update ruler + AtomicInteger lastRuler = new AtomicInteger(-1); + scrollContent.heightProperty().addListener(_ -> { + int ruler1 = (int) screenPosToSecond(scrollContent.getHeight()); + for (int i = lastRuler.get() + 1; i <= ruler1; i++) { + Label l = new Label(toMinAndSec(i)+" -"); + l.layoutYProperty().bind(secondToScreenPos(i)); + l.setTextFill(Color.WHITE); + rulerLane.getChildren().add(l); + } + lastRuler.set(ruler1); + }); + + VBox centerBox = new VBox(); + centerBox.getChildren().addAll(main, buttons); + centerBox.setSpacing(10); + centerBox.setAlignment(Pos.CENTER); + + content.getChildren().add(centerBox); + content.setAlignment(Pos.CENTER); + + // write notes on key press + content.addEventFilter(KeyEvent.KEY_PRESSED, e -> { + KeyCode k = e.getCode(); + if (k == Control.LANE0.getKey()) { WriteNote(0); } + if (k == Control.LANE1.getKey()) { WriteNote(1); } + if (k == Control.LANE2.getKey()) { WriteNote(2); } + if (k == Control.LANE3.getKey()) { WriteNote(3); } + if (k == Control.LANE4.getKey()) { WriteNote(4); } + if (k == Control.NOTE_DOWN.getKey()) { MoveNoteDown(); } + if (k == Control.NOTE_UP.getKey()) { MoveNoteUp(); } + if (k == Control.DELETE_NOTE.getKey()) { delNote.fire(); } + if (k == Control.CLEAR_SELECTION.getKey()) { clearSelect.fire(); } + if (k == Control.SCROLL_LOCK.getKey()) { scrollLock.fire(); } + if (k == Control.PLAY_PAUSE.getKey()) { play.fire(); } + if (k == Control.SELECT_ALL.getKey()) { selectAll.fire(); } + e.consume(); + }); + + m.currentTimeProperty().addListener(_ -> { + // TODO + playhead.layoutYProperty().bind(secondToScreenPos(m.getCurrentTime().toSeconds())); + }); + + play.setOnAction(_ -> { + if (play.isSelected()) { + m.play(); + } + else { + m.pause(); + } + + }); + + scrollLock.setOnAction(_ -> { + if (scrollLock.isSelected()) { + // vvalue takes in a value between 0 and 1 NOT a pixel value + scroll.vvalueProperty().bind(playhead.layoutYProperty().subtract(scroll.heightProperty().divide(2)).divide(scrollContent.heightProperty().subtract(scroll.heightProperty()))); + } + else { + scroll.vvalueProperty().unbind(); + } + + + }); + + reset.setOnAction(_ -> { + m.seek(new Duration(0)); + }); + + delNote.setOnAction(_ -> { + activeNotes.forEach(e -> { + noteList.remove(e.note); + }); + activeNotes.clear(); + }); + + clearSelect.setOnAction(_ -> { + activeNotes.forEach(e -> e.setFill(e.color)); + activeNotes.clear(); + }); + + selectAll.setOnAction(_ -> { + activeNotes.clear(); + for (Pane lane : lanes) { + lane.getChildren().forEach(e -> activeNotes.add((Block) e)); + } + activeNotes.forEach(e -> e.setFill(Color.WHITE)); + }); + + Pane addHelp = addHelp(); + Pane moveHelp = moveHelp(); + addNote.setOnAction(_ -> { + if (addNote.isSelected()) { + helpBox.getChildren().clear(); + helpBox.getChildren().add(addHelp); + } + else { + helpBox.getChildren().clear(); + } + }); + + moveNote.setOnAction(_ -> { + if (moveNote.isSelected()) { + helpBox.getChildren().clear(); + helpBox.getChildren().add(moveHelp); + } + else { + helpBox.getChildren().clear(); + } + }); + + moveNote.disabledProperty().addListener(_ -> { + if (moveNote.isDisabled() && moveNote.isSelected()) { + moveNote.setSelected(false); + helpBox.getChildren().clear(); + } + }); + + setEnd.setOnAction(_ -> { + double tmp = screenPosToSecond(playhead.getLayoutY()); + if (Math.round(tmp*10)/10 == Math.round(m.getTotalDuration().toSeconds() * 10)/10) { + newEndTime.set(0); + } + else { + newEndTime.set(tmp); + } + }); + } + + @Override + public Pane getContent() { + return content; + } + + @Override + public void onView() { + Sound.stopSong(); + m.play(); + m.pause(); + m.seek(Duration.ZERO); + } + + @Override + public void onLeave() { + m.stop(); + Sound.playSong(Sound.MENU_SONG); + } + + private Block drawBlock(Note n) { + Color color = diff.level.colors[n.lane]; + Block b = new Block(color,20, 20, 5, false, n); + b.heightProperty().bind(scroll.widthProperty().divide(8)); + b.widthProperty().bind(scroll.widthProperty().divide(8)); + b.arcHeightProperty().bind(scroll.widthProperty().divide(25)); + b.arcWidthProperty().bind(scroll.widthProperty().divide(25)); + b.strokeWidthProperty().bind(scroll.widthProperty().divide(120)); + b.layoutYProperty().bind(secondToScreenPos(n.time.add(0))); + b.setOnMouseClicked(_ -> { + if (activeNotes.contains(b)) { + activeNotes.remove(b); + b.setFill(b.color); + } + else { + activeNotes.add(b); + b.setFill(Color.WHITE); + } + }); + return b; + } + + private String toMinAndSec(int t) { + int min = t / 60; + int sec = t % 60; + + String min2 = min + ""; + if (min2.length() == 1) { + min2 = "0" + min2; + } + String sec2 = sec + ""; + if (sec2.length() == 1) { + sec2 = "0" + sec2; + } + return min2 + ":" + sec2; + } + + private double screenPosToSecond(double screenYPos) { + return screenYPos / (scroll.getHeight() * 0.9); + } + + private DoubleBinding secondToScreenPos(DoubleBinding second) { + return scroll.heightProperty().multiply(second).multiply(0.9); + } + + private DoubleBinding secondToScreenPos(double second) { + return scroll.heightProperty().multiply(second).multiply(0.9); + } + + private void WriteNote(int col) { + Note tmp = new Note(screenPosToSecond(playhead.getLayoutY()), col); + noteList.add(tmp); + } + + private void MoveNoteUp() { + activeNotes.forEach(n -> n.note.time.setValue(n.note.time.get() - 0.01)); + } + + private void MoveNoteDown() { + activeNotes.forEach(n -> n.note.time.setValue(n.note.time.get() + 0.01)); + } + + private Pane addHelp() { + Label l1 = new Label("Use the following keys"); + HBox hb = new HBox( + new Target(diff.level.colors[0], 40, 40, 10, Control.LANE0.targetString()), + new Target(diff.level.colors[1], 40, 40, 10, Control.LANE1.targetString()), + new Target(diff.level.colors[2], 40, 40, 10, Control.LANE2.targetString()), + new Target(diff.level.colors[3], 40, 40, 10, Control.LANE3.targetString()), + new Target(diff.level.colors[4], 40, 40, 10, Control.LANE4.targetString()) + ); + hb.setSpacing(10); + hb.setAlignment(Pos.CENTER_LEFT); + Label l2 = new Label("to write a new note at \nthe play head's position."); + + VBox ret = new VBox(l1, hb, l2); + ret.setPadding(new Insets(10)); + ret.getStyleClass().add("box"); + return ret; + } + + private Pane moveHelp() { + Label l1 = new Label("Use the"); + HBox hb = new HBox(new Target(Color.BLACK, 40, 40, 10, Control.NOTE_UP.targetString()), new Label("and"), new Target(Color.BLACK, 40, 40, 10, Control.NOTE_DOWN.targetString()), new Label("keys")); + hb.setSpacing(10); + hb.setAlignment(Pos.CENTER_LEFT); + Label l2 = new Label("to move the selected \nnote(s) up and down."); + + VBox ret = new VBox(l1, hb, l2); + ret.setPadding(new Insets(10)); + ret.getStyleClass().add("box"); + ret.setLayoutY(120); + return ret; + } +} diff --git a/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java b/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java index b61d11c..2f95ee8 100755 --- a/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java +++ b/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java @@ -42,11 +42,11 @@ import javafx.util.*; public class SongPlayer extends Pane { private Double bpm; //initializes the bpm of the song, to be read in from a metadata file later - private int songLength; //initializes the length of the song in terms of the song's bpm, to be read in later + private double songLength; //initializes the length of the song in terms of the song's bpm, to be read in later private EventHandler eventHandler; - private File song; + private Media song; private boolean songIsPlaying = false; private boolean missMute = false; @@ -89,11 +89,11 @@ public class SongPlayer extends Pane { public void loadSong() throws FileNotFoundException { difficulty.notes.list.forEach(e -> { switch (e.lane) { - case 0 -> dSends.add(new NoteInfo(e.time.get() * (difficulty.bpm / 60))); - case 1 -> fSends.add(new NoteInfo(e.time.get() * (difficulty.bpm / 60))); - case 2 -> spaceSends.add(new NoteInfo(e.time.get() * (difficulty.bpm / 60))); - case 3 -> jSends.add(new NoteInfo(e.time.get() * (difficulty.bpm / 60))); - case 4 -> kSends.add(new NoteInfo(e.time.get() * (difficulty.bpm / 60))); + case 0 -> dSends.add(new NoteInfo(e.time.get() * (bpm / 60))); + case 1 -> fSends.add(new NoteInfo(e.time.get() * (bpm / 60))); + case 2 -> spaceSends.add(new NoteInfo(e.time.get() * (bpm / 60))); + case 3 -> jSends.add(new NoteInfo(e.time.get() * (bpm / 60))); + case 4 -> kSends.add(new NoteInfo(e.time.get() * (bpm / 60))); } }); } @@ -105,14 +105,19 @@ public class SongPlayer extends Pane { if (lvl.background != null) { Driver.setBackground(lvl.background); } - bpm = d.bpm; //Reads the song's bpm from a metadata file + bpm = 60.0; //Reads the song's bpm from a metadata file level = lvl; difficulty = d; pane = p; //System.out.println(d.bpm + " " + d.numBeats); - songLength = d.numBeats; + if (d.endTime != 0) { + songLength = d.endTime; + } + else { + songLength = d.level.song.getDuration().toSeconds(); + } timer = new Timer(bpm); //Sets the timer's bpm to that of the song scoreCounter = cntrl; //Uses the song's designated scoreCounter @@ -255,7 +260,7 @@ public class SongPlayer extends Pane { } if (!songIsPlaying && timer.time() > 0.0) { songIsPlaying = true; - Sound.playSong(new Media(song.toURI().toString())); + Sound.playSong(song); } } }; diff --git a/src/main/java/net/sowgro/npehero/gui/LevelSurround.java b/src/main/java/net/sowgro/npehero/gui/LevelSurround.java index 05614ff..ea1eb30 100755 --- a/src/main/java/net/sowgro/npehero/gui/LevelSurround.java +++ b/src/main/java/net/sowgro/npehero/gui/LevelSurround.java @@ -128,4 +128,9 @@ public class LevelSurround extends Page public Pane getContent() { return content; } + + @Override + public void onLeave() { + Sound.playSong(Sound.MENU_SONG); + } } \ No newline at end of file diff --git a/src/main/java/net/sowgro/npehero/gui/MainMenu.java b/src/main/java/net/sowgro/npehero/gui/MainMenu.java index f13deac..3b8c8db 100755 --- a/src/main/java/net/sowgro/npehero/gui/MainMenu.java +++ b/src/main/java/net/sowgro/npehero/gui/MainMenu.java @@ -10,7 +10,7 @@ import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.text.Text; import net.sowgro.npehero.Driver; -import net.sowgro.npehero.devmenu.LevelList; +import net.sowgro.npehero.editor.LevelList; import net.sowgro.npehero.main.Page; import net.sowgro.npehero.main.Sound; diff --git a/src/main/java/net/sowgro/npehero/main/Control.java b/src/main/java/net/sowgro/npehero/main/Control.java index 2a12f5a..d9e3942 100644 --- a/src/main/java/net/sowgro/npehero/main/Control.java +++ b/src/main/java/net/sowgro/npehero/main/Control.java @@ -64,6 +64,8 @@ public enum Control { case LEFT -> "←"; case RIGHT -> "→"; case SPACE -> "_"; + case EQUALS -> "+"; + case MINUS -> "-"; case null -> " "; default -> { String s = key.toString(); diff --git a/src/main/java/net/sowgro/npehero/main/Difficulties.java b/src/main/java/net/sowgro/npehero/main/Difficulties.java index 83137a7..f2ccd99 100644 --- a/src/main/java/net/sowgro/npehero/main/Difficulties.java +++ b/src/main/java/net/sowgro/npehero/main/Difficulties.java @@ -40,6 +40,7 @@ public class Difficulties { list.add(diff); } } + list.sort(Comparator.naturalOrder()); } /** @@ -71,6 +72,11 @@ public class Difficulties { Difficulty temp = new Difficulty(diffDir,level); temp.title = text; list.add(temp); + list.sort(Comparator.naturalOrder()); + } + + public void saveOrder() { + list.forEach(d -> d.order = list.indexOf(d)); } diff --git a/src/main/java/net/sowgro/npehero/main/Difficulty.java b/src/main/java/net/sowgro/npehero/main/Difficulty.java index 290461d..c80e650 100755 --- a/src/main/java/net/sowgro/npehero/main/Difficulty.java +++ b/src/main/java/net/sowgro/npehero/main/Difficulty.java @@ -1,5 +1,7 @@ package net.sowgro.npehero.main; +import javafx.scene.media.Media; + import java.io.File; import java.io.IOException; @@ -10,8 +12,8 @@ public class Difficulty implements Comparable public String title = "Unnamed"; public Double bpm = 0.0; - public int numBeats; - public int priority = 0; + public double endTime = 0; + public int order = 0; public Leaderboard leaderboard; public Notes notes; @@ -40,8 +42,14 @@ public class Difficulty implements Comparable title = metadataYaml.getString("title", title); bpm = metadataYaml.getDouble("bpm", bpm); - numBeats = metadataYaml.getInt("numBeats", numBeats); - priority = metadataYaml.getInt("priority", priority); + endTime = metadataYaml.getDouble("endTime", endTime); + if (endTime == 0) { + int tmp = metadataYaml.getInt("numBeats", 0); + if (tmp != 0) { + endTime = beatToSecond(tmp); + } + } + order = metadataYaml.getInt("priority", order); notes = new Notes(new File(thisDir, "notes.txt"), this); leaderboard = new Leaderboard(new File(thisDir, "leaderboard.json")); @@ -65,8 +73,8 @@ public class Difficulty implements Comparable */ public void write() { metadataYaml.set("title", title); - metadataYaml.set("numBeats", numBeats); - metadataYaml.set("priority", priority); + metadataYaml.set("endTime", endTime); + metadataYaml.set("priority", order); try { metadataYaml.write(); @@ -78,7 +86,11 @@ public class Difficulty implements Comparable @Override public int compareTo(Difficulty d) { - return priority - d.priority; + return order - d.order; + } + + private double beatToSecond(double beat) { + return beat/(bpm/60); } diff --git a/src/main/java/net/sowgro/npehero/main/Level.java b/src/main/java/net/sowgro/npehero/main/Level.java index dd96815..1b10f3d 100755 --- a/src/main/java/net/sowgro/npehero/main/Level.java +++ b/src/main/java/net/sowgro/npehero/main/Level.java @@ -3,6 +3,7 @@ package net.sowgro.npehero.main; import java.io.File; import javafx.scene.image.Image; +import javafx.scene.media.Media; import javafx.scene.paint.Color; import java.io.IOException; @@ -20,7 +21,7 @@ public class Level public Image preview; //optional public Image background; //optional - public File song; + public Media song; public Difficulties difficulties; @@ -43,16 +44,23 @@ public class Level public void readData() { - if (new File(dir, "song.wav").exists()) { - song = new File(dir,"song.wav"); + var fileList = dir.listFiles(); + if (fileList == null) { + return; } - if (new File(dir, "background.png").exists()) { - background = new Image(new File(dir,"background.png").toURI().toString()); - } - - if (new File(dir, "preview.png").exists()) { - preview = new Image(new File(dir,"preview.png").toURI().toString()); + // support any file extension (maybe a bad idea) + for (File file : fileList) { + String fileName = file.getName(); + if (fileName.contains("song")) { + song = new Media(file.toURI().toString()); + } + else if (fileName.contains("background")) { + background = new Image(file.toURI().toString()); + } + else if (fileName.contains("preview")) { + preview = new Image(file.toURI().toString()); + } } parseMetadata(); @@ -61,7 +69,7 @@ public class Level public void validate() { if (song == null) { - System.err.println(dir +" is missing song.wav"); + System.err.println(dir +" is missing song file"); } if (difficulties.validList.isEmpty()) { -- cgit v1.2.3