diff --git a/.idea/misc.xml b/.idea/misc.xml index 97dd9e8..64c32f6 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -13,7 +13,7 @@ - + \ No newline at end of file diff --git a/.idea/resourceBundles.xml b/.idea/resourceBundles.xml index 362dcdf..731ea6a 100644 --- a/.idea/resourceBundles.xml +++ b/.idea/resourceBundles.xml @@ -1,8 +1,26 @@ + + + + + + + + + + + + + + + + + + + - @@ -11,5 +29,21 @@ localization + + + + + + + + + + + + + + + localization + \ No newline at end of file diff --git a/app/pom.xml b/app/pom.xml index f8a54cf..c3f2ea5 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -19,7 +19,11 @@ spotless-maven-plugin 2.46.1 - + + com.google.code.gson + gson + 2.10.1 + org.toop pism_framework diff --git a/app/src/main/java/org/toop/app/App.java b/app/src/main/java/org/toop/app/App.java index d0116cb..b54fa79 100644 --- a/app/src/main/java/org/toop/app/App.java +++ b/app/src/main/java/org/toop/app/App.java @@ -1,23 +1,30 @@ package org.toop.app; -import org.toop.app.canvas.GameCanvas; import org.toop.app.layer.Layer; import org.toop.app.layer.layers.MainLayer; import org.toop.app.layer.layers.QuitLayer; import org.toop.framework.asset.ResourceManager; import org.toop.framework.asset.resources.CssAsset; +import org.toop.framework.asset.resources.SettingsAsset; +import org.toop.framework.audio.events.AudioEvents; +import org.toop.framework.eventbus.EventFlow; +import org.toop.local.AppContext; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.stage.Stage; +import org.toop.local.AppSettings; + +import java.util.Stack; public final class App extends Application { private static Stage stage; private static StackPane root; - - private static int width; - private static int height; + private static Stack stack; + private static int height; + private static int width; + private static SettingsAsset settingsAsset; private static boolean isQuitting; @@ -27,12 +34,19 @@ public final class App extends Application { @Override public void start(Stage stage) throws Exception { - final StackPane root = new StackPane(); + + App.stage = stage; + final StackPane root = new StackPane(); + App.root = root; + App.stack = new Stack<>(); + + AppSettings settings = new AppSettings(); + settings.applySettings(); final Scene scene = new Scene(root); - scene.getStylesheets().add(ResourceManager.get(CssAsset.class, "app.css").getUrl()); + scene.getStylesheets().add(ResourceManager.get("app.css").getUrl()); - stage.setTitle("pism"); + stage.setTitle(AppContext.getString("appTitle")); stage.setWidth(1080); stage.setHeight(720); @@ -51,14 +65,16 @@ public final class App extends Application { App.stage = stage; App.root = root; + App.stack = new Stack<>(); - App.width = (int)stage.getWidth(); - App.height = (int)stage.getHeight(); + App.width = (int) stage.getWidth(); + App.height = (int) stage.getHeight(); App.isQuitting = false; + new EventFlow().addPostEvent(new AudioEvents.StartBackgroundMusic()).asyncPostEvent(); activate(new MainLayer()); - } + } public static void activate(Layer layer) { popAll(); @@ -66,16 +82,15 @@ public final class App extends Application { } public static void push(Layer layer) { - root.getChildren().addLast(layer.getLayer()); + root.getChildren().addLast(layer.getLayer()); + stack.push(layer); } public static void pop() { root.getChildren().removeLast(); - isQuitting = false; - } + stack.pop(); - public static void pushCanvas(GameCanvas canvas) { - root.getChildren().addLast(canvas.getCanvas()); + isQuitting = false; } public static void popAll() { @@ -84,6 +99,8 @@ public final class App extends Application { for (int i = 0; i < childrenCount; i++) { root.getChildren().removeLast(); } + + stack.removeAllElements(); } public static void quitPopup() { @@ -95,6 +112,28 @@ public final class App extends Application { stage.close(); } - public static int getWidth() { return width; } - public static int getHeight() { return height; } + public static void reloadAll() { + stage.setTitle(AppContext.getString("appTitle")); + + for (final Layer layer : stack) { + layer.reload(); + } + } + + public static void setFullscreen(boolean fullscreen) { + stage.setFullScreen(fullscreen); + + width = (int) stage.getWidth(); + height = (int) stage.getHeight(); + + reloadAll(); + } + + public static int getWidth() { + return width; + } + + public static int getHeight() { + return height; + } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/GameInformation.java b/app/src/main/java/org/toop/app/GameInformation.java new file mode 100644 index 0000000..8f307a3 --- /dev/null +++ b/app/src/main/java/org/toop/app/GameInformation.java @@ -0,0 +1,5 @@ +package org.toop.app; + +public record GameInformation(String[] playerName, boolean[] isPlayerHuman, int[] computerDifficulty, + boolean isConnectionLocal, String serverIP, String serverPort) { +} diff --git a/app/src/main/java/org/toop/app/canvas/GameCanvas.java b/app/src/main/java/org/toop/app/canvas/GameCanvas.java index 0255504..5d4b56d 100644 --- a/app/src/main/java/org/toop/app/canvas/GameCanvas.java +++ b/app/src/main/java/org/toop/app/canvas/GameCanvas.java @@ -3,31 +3,49 @@ package org.toop.app.canvas; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.input.MouseButton; +import javafx.scene.paint.Color; + +import java.util.function.Consumer; public abstract class GameCanvas { - protected record Cell(float x, float y, float width, float height) {} - - protected final int width; - protected final int height; + protected record Cell(float x, float y, float width, float height) { + } protected final Canvas canvas; protected final GraphicsContext graphics; + protected final Color color; + + protected int width; + protected int height; + protected final int rows; protected final int columns; protected final int gapSize; + protected final boolean edges; protected final Cell[] cells; - protected GameCanvas(int width, int height, int rows, int columns, int gapSize) { - final Canvas canvas = new Canvas(width, height); - final GraphicsContext graphics = canvas.getGraphicsContext2D(); + protected GameCanvas(Color color, int width, int height, int rows, int columns, int gapSize, boolean edges, Consumer onCellClicked) { + canvas = new Canvas(width, height); + graphics = canvas.getGraphicsContext2D(); - final Cell[] cells = new Cell[rows * columns]; + this.color = color; - final float cellWidth = ((float)width - (rows - 1) * gapSize) / rows; - final float cellHeight = ((float)height - (columns - 1) * gapSize) / columns; + this.width = width; + this.height = height; + + this.rows = rows; + this.columns = columns; + + this.gapSize = gapSize; + this.edges = edges; + + cells = new Cell[rows * columns]; + + final float cellWidth = ((float) width - (rows - 1) * gapSize) / rows; + final float cellHeight = ((float) height - (columns - 1) * gapSize) / columns; for (int y = 0; y < columns; y++) { final float startY = y * cellHeight + y * gapSize; @@ -39,39 +57,67 @@ public abstract class GameCanvas { } canvas.setOnMouseClicked(event -> { - final MouseButton button = event.getButton(); - - if (button != MouseButton.PRIMARY && button != MouseButton.SECONDARY) { + if (event.getButton() != MouseButton.PRIMARY) { return; } - final int column = (int)((event.getX() / width) * rows); - final int row = (int)((event.getY() / height) * columns); + final int column = (int) ((event.getX() / width) * rows); + final int row = (int) ((event.getY() / height) * columns); event.consume(); - onCellClicked(row * rows + column, button == MouseButton.PRIMARY); + onCellClicked.accept(row * rows + column); }); + render(); + } + + public void clear() { + graphics.clearRect(0, 0, width, height); + } + + public void render() { + graphics.setFill(color); + + for (int x = 1; x < rows; x++) { + graphics.fillRect(cells[x].x() - gapSize, 0, gapSize, height); + } + + for (int y = 1; y < columns; y++) { + graphics.fillRect(0, cells[y * rows].y() - gapSize, width, gapSize); + } + + if (edges) { + graphics.fillRect(-gapSize, 0, gapSize, height); + graphics.fillRect(0, -gapSize, width, gapSize); + + graphics.fillRect(width - gapSize, 0, gapSize, height); + graphics.fillRect(0, height - gapSize, width, gapSize); + } + } + + public void draw(Color color, int cell) { + final float x = cells[cell].x() + gapSize; + final float y = cells[cell].y() + gapSize; + + final float width = cells[cell].width() - gapSize * 2; + final float height = cells[cell].height() - gapSize * 2; + + graphics.setFill(color); + graphics.fillRect(x, y, width, height); + } + + public void resize(int width, int height) { + canvas.setWidth(width); + canvas.setHeight(height); + this.width = width; this.height = height; - this.canvas = canvas; - this.graphics = graphics; - - this.rows = rows; - this.columns = columns; - - this.gapSize = gapSize; - - this.cells = cells; + clear(); + render(); } - protected void clearCell(int cell) { - assert cell >= 0 && cell < cells.length; - graphics.clearRect(cells[cell].x(), cells[cell].y(), cells[cell].width(), cells[cell].height()); + public Canvas getCanvas() { + return canvas; } - - protected abstract void onCellClicked(int cell, boolean primary); - - public Canvas getCanvas() { return canvas; } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/canvas/TicTacToeCanvas.java b/app/src/main/java/org/toop/app/canvas/TicTacToeCanvas.java index 66b520f..0f7cbb9 100644 --- a/app/src/main/java/org/toop/app/canvas/TicTacToeCanvas.java +++ b/app/src/main/java/org/toop/app/canvas/TicTacToeCanvas.java @@ -1,30 +1,16 @@ package org.toop.app.canvas; import javafx.scene.paint.Color; -import org.toop.app.App; -import org.toop.game.Game; -import org.toop.game.tictactoe.TicTacToe; + +import java.util.function.Consumer; public class TicTacToeCanvas extends GameCanvas { - private final TicTacToe game; - - public TicTacToeCanvas() { - super(App.getHeight(), App.getHeight(), 3, 3, 10); - game = new TicTacToe(); - - graphics.setFill(Color.CYAN); - - for (int x = 1; x < rows; x++) { - graphics.fillRect(cells[x].x() - gapSize, 0, gapSize, height); - } - - for (int y = 1; y < columns; y++) { - graphics.fillRect(0, cells[y * rows].y() - gapSize, width, gapSize); - } + public TicTacToeCanvas(Color color, int width, int height, Consumer onCellClicked) { + super(color, width, height, 3, 3, 10, false, onCellClicked); } - public void placeX(int cell) { - graphics.setStroke(Color.ORANGERED); + public void drawX(Color color, int cell) { + graphics.setStroke(color); graphics.setLineWidth(gapSize); final float x = cells[cell].x() + gapSize; @@ -37,8 +23,8 @@ public class TicTacToeCanvas extends GameCanvas { graphics.strokeLine(x + width, y, x, y + height); } - public void placeO(int cell) { - graphics.setStroke(Color.DEEPSKYBLUE); + public void drawO(Color color, int cell) { + graphics.setStroke(color); graphics.setLineWidth(gapSize); final float x = cells[cell].x() + gapSize; @@ -49,33 +35,4 @@ public class TicTacToeCanvas extends GameCanvas { graphics.strokeOval(x, y, width, height); } - - @Override - protected void onCellClicked(int cell, boolean primary) { - for (final Game.Move move : game.getLegalMoves()) { - if (move.position() == cell) { - if (move.value() == 'X') { - placeX(cell); - } else { - placeO(cell); - } - - final Game.State state = game.play(move); - - if (state == Game.State.WIN) { - for (int i = 0; i < game.board.length; i++) { - if (game.board[i] != move.value()) { - clearCell(i); - } - } - - graphics.setFill(Color.GREEN); - graphics.fillRect(cells[4].x(), cells[4].y(), cells[4].width(), cells[4].height()); - } else if (state == Game.State.DRAW) { - graphics.setFill(Color.DARKORANGE); - graphics.fillRect(cells[4].x(), cells[4].y(), cells[4].width(), cells[4].height()); - } - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/events/AppEvents.java b/app/src/main/java/org/toop/app/events/AppEvents.java index e326ff0..aa07457 100644 --- a/app/src/main/java/org/toop/app/events/AppEvents.java +++ b/app/src/main/java/org/toop/app/events/AppEvents.java @@ -4,9 +4,5 @@ import org.toop.framework.eventbus.events.EventWithoutSnowflake; import org.toop.framework.eventbus.events.EventsBase; public class AppEvents extends EventsBase { - public record OnNodeHover() implements EventWithoutSnowflake {} - public record OnNodeClick() implements EventWithoutSnowflake {} - - public record OnLanguageChange(String language) implements EventWithoutSnowflake {} } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/Container.java b/app/src/main/java/org/toop/app/layer/Container.java index 7d53475..3b67be3 100644 --- a/app/src/main/java/org/toop/app/layer/Container.java +++ b/app/src/main/java/org/toop/app/layer/Container.java @@ -1,13 +1,14 @@ package org.toop.app.layer; import org.toop.app.events.AppEvents; -import org.toop.framework.eventbus.GlobalEventBus; +import org.toop.framework.audio.events.AudioEvents; +import org.toop.framework.eventbus.EventFlow; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; +import javafx.geometry.Orientation; import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; +import javafx.scene.control.*; import javafx.scene.layout.Region; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; @@ -18,53 +19,51 @@ public abstract class Container { public abstract Region getContainer(); public abstract void addNode(Node node); + public abstract void addContainer(Container container, boolean fill); - public void addText(String cssClass, String x, boolean wrap) { + public Text addText(String cssClass, String x, boolean wrap) { final Text element = new Text(x); element.getStyleClass().add(cssClass); if (wrap) { addNode(new TextFlow(element)); - } else { addNode(element); } + } else { + addNode(element); + } + + return element; } - public void addText(String x, boolean wrap) { - addText("text", x, wrap); + public Text addText(String x, boolean wrap) { + return addText("text", x, wrap); } - public void addButton(String cssClass, String x, Runnable runnable) { + public Label addButton(String cssClass, String x, Runnable runnable) { final Label element = new Label(x); element.getStyleClass().add(cssClass); - element.setOnMouseEntered(_ -> { - GlobalEventBus.post(new AppEvents.OnNodeHover()); - }); - element.setOnMouseClicked(_ -> { - GlobalEventBus.post(new AppEvents.OnNodeClick()); + new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent(); runnable.run(); }); addNode(element); + return element; } - public void addButton(String x, Runnable runnable) { - addButton("button", x, runnable); + public Label addButton(String x, Runnable runnable) { + return addButton("button", x, runnable); } - public void addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer consumer) { - final Label element = new Label(toggled? x2 : x1); + public Label addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer consumer) { + final Label element = new Label(toggled ? x2 : x1); element.getStyleClass().add(cssClass); final BooleanProperty checked = new SimpleBooleanProperty(toggled); - element.setOnMouseEntered(_ -> { - GlobalEventBus.post(new AppEvents.OnNodeHover()); - }); - element.setOnMouseClicked(_ -> { - GlobalEventBus.post(new AppEvents.OnNodeClick()); + new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent(); checked.set(!checked.get()); if (checked.get()) { @@ -77,18 +76,46 @@ public abstract class Container { }); addNode(element); + return element; } - public void addToggle(String x1, String x2, boolean toggled, Consumer consumer) { - addToggle("toggle", x1, x2, toggled, consumer); + public Label addToggle(String x1, String x2, boolean toggled, Consumer consumer) { + return addToggle("toggle", x1, x2, toggled, consumer); } - public void addInput(String cssClass, String input, Consumer consumer) { + public Slider addSlider(String cssClass, int max, int initial, Consumer consumer) { + final Slider element = new Slider(0, max, initial); + element.getStyleClass().add(cssClass); + + element.setMinorTickCount(0); + element.setMajorTickUnit(1); + element.setBlockIncrement(1); + + element.setSnapToTicks(true); + element.setShowTickLabels(true); + + element.setOnMouseClicked(_ -> { + new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent(); + }); + + element.valueProperty().addListener((_, _, newValue) -> { + consumer.accept(newValue.intValue()); + }); + + addNode(element); + return element; + } + + public Slider addSlider(int max, int initial, Consumer consumer) { + return addSlider("slider", max, initial, consumer); + } + + public TextField addInput(String cssClass, String input, Consumer consumer) { final TextField element = new TextField(input); element.getStyleClass().add(cssClass); - element.setOnMouseEntered(_ -> { - GlobalEventBus.post(new AppEvents.OnNodeHover()); + element.setOnMouseClicked(_ -> { + new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent(); }); element.textProperty().addListener((_, _, newValue) -> { @@ -96,9 +123,43 @@ public abstract class Container { }); addNode(element); + return element; } - public void addInput(String input, Consumer consumer) { - addInput("input", input, consumer); + public TextField addInput(String input, Consumer consumer) { + return addInput("input", input, consumer); + } + + public ChoiceBox addChoiceBox(String cssClass, Consumer consumer) { + final ChoiceBox element = new ChoiceBox<>(); + element.getStyleClass().add(cssClass); + + element.setOnMouseClicked(_ -> { + new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent(); + }); + + element.valueProperty().addListener((_, _, newValue) -> { + consumer.accept(newValue); + }); + + addNode(element); + return element; + } + + public ChoiceBox addChoiceBox(Consumer consumer) { + return addChoiceBox("choicebox", consumer); + } + + public Separator addSeparator(String cssClass, boolean horizontal) { + final Separator element = new Separator(horizontal ? Orientation.HORIZONTAL : Orientation.VERTICAL); + element.getStyleClass().add(cssClass); + element.setMinSize(50, 50); + + addNode(element); + return element; + } + + public Separator addSeparator(boolean horizontal) { + return addSeparator("separator", horizontal); } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/Layer.java b/app/src/main/java/org/toop/app/layer/Layer.java index a33ea92..ac12b10 100644 --- a/app/src/main/java/org/toop/app/layer/Layer.java +++ b/app/src/main/java/org/toop/app/layer/Layer.java @@ -13,22 +13,17 @@ public abstract class Layer { protected StackPane layer; protected Region background; - protected Layer(String cssFile, String backgroundCssClass) { + protected Layer(String cssFile) { layer = new StackPane(); - layer.setPickOnBounds(false); - layer.getStylesheets().add(ResourceManager.get(CssAsset.class, cssFile).getUrl()); + layer.getStylesheets().add(ResourceManager.get(cssFile).getUrl()); background = new Region(); + background.getStyleClass().add("background"); background.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE); - background.getStyleClass().add(backgroundCssClass); layer.getChildren().addLast(background); } - protected Layer(String cssFile) { - this(cssFile, "background"); - } - protected void addContainer(Container container, Pos position, int xOffset, int yOffset, int widthPercent, int heightPercent) { StackPane.setAlignment(container.getContainer(), position); @@ -37,11 +32,15 @@ public abstract class Layer { if (widthPercent > 0) { container.getContainer().setMaxWidth(widthPercent * widthUnit); - } else { container.getContainer().setMaxWidth(Region.USE_PREF_SIZE); } + } else { + container.getContainer().setMaxWidth(Region.USE_PREF_SIZE); + } if (heightPercent > 0) { container.getContainer().setMaxHeight(heightPercent * heightUnit); - } else { container.getContainer().setMaxHeight(Region.USE_PREF_SIZE); } + } else { + container.getContainer().setMaxHeight(Region.USE_PREF_SIZE); + } container.getContainer().setTranslateX(xOffset * widthUnit); container.getContainer().setTranslateY(yOffset * heightUnit); @@ -49,20 +48,12 @@ public abstract class Layer { layer.getChildren().addLast(container.getContainer()); } - protected void addCanvas(GameCanvas canvas, Pos position, int xOffset, int yOffset, int widthPercent, int heightPercent) { + protected void addGameCanvas(GameCanvas canvas, Pos position, int xOffset, int yOffset) { StackPane.setAlignment(canvas.getCanvas(), position); final double widthUnit = App.getWidth() / 100.0; final double heightUnit = App.getHeight() / 100.0; - if (widthPercent > 0) { - canvas.getCanvas().setWidth(widthPercent * widthUnit); - } else { canvas.getCanvas().setWidth(Region.USE_PREF_SIZE); } - - if (heightPercent > 0) { - canvas.getCanvas().setHeight(heightPercent * heightUnit); - } else { canvas.getCanvas().setHeight(Region.USE_PREF_SIZE); } - canvas.getCanvas().setTranslateX(xOffset * widthUnit); canvas.getCanvas().setTranslateY(yOffset * heightUnit); @@ -85,8 +76,9 @@ public abstract class Layer { } } - public StackPane getLayer() { return layer; } - public Region getBackground() { return background; } + public StackPane getLayer() { + return layer; + } public abstract void reload(); } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/containers/HorizontalContainer.java b/app/src/main/java/org/toop/app/layer/containers/HorizontalContainer.java index 79b8fa0..11ca3f7 100644 --- a/app/src/main/java/org/toop/app/layer/containers/HorizontalContainer.java +++ b/app/src/main/java/org/toop/app/layer/containers/HorizontalContainer.java @@ -21,7 +21,9 @@ public final class HorizontalContainer extends Container { } @Override - public Region getContainer() { return container; } + public Region getContainer() { + return container; + } @Override public void addNode(Node node) { @@ -51,7 +53,7 @@ public final class HorizontalContainer extends Container { for (final Node child : children) { if (child instanceof Region) { - ((Region)child).setPrefWidth(widthPerChild); + ((Region) child).setPrefWidth(widthPerChild); } } } diff --git a/app/src/main/java/org/toop/app/layer/containers/VerticalContainer.java b/app/src/main/java/org/toop/app/layer/containers/VerticalContainer.java index ce9024f..6e8d803 100644 --- a/app/src/main/java/org/toop/app/layer/containers/VerticalContainer.java +++ b/app/src/main/java/org/toop/app/layer/containers/VerticalContainer.java @@ -21,7 +21,9 @@ public final class VerticalContainer extends Container { } @Override - public Region getContainer() { return container; } + public Region getContainer() { + return container; + } @Override public void addNode(Node node) { @@ -51,7 +53,7 @@ public final class VerticalContainer extends Container { for (final Node child : children) { if (child instanceof Region) { - ((Region)child).setPrefHeight(heightPerChild); + ((Region) child).setPrefHeight(heightPerChild); } } } diff --git a/app/src/main/java/org/toop/app/layer/layers/CreditsLayer.java b/app/src/main/java/org/toop/app/layer/layers/CreditsLayer.java new file mode 100644 index 0000000..b6f3852 --- /dev/null +++ b/app/src/main/java/org/toop/app/layer/layers/CreditsLayer.java @@ -0,0 +1,73 @@ +package org.toop.app.layer.layers; + +import org.toop.app.App; +import org.toop.app.layer.Container; +import org.toop.app.layer.Layer; +import org.toop.app.layer.containers.HorizontalContainer; +import org.toop.app.layer.containers.VerticalContainer; +import org.toop.local.AppContext; + +import javafx.animation.PauseTransition; +import javafx.animation.TranslateTransition; +import javafx.geometry.Pos; +import javafx.util.Duration; + +public final class CreditsLayer extends Layer { + private final int lineHeight = 100; + + CreditsLayer() { + super("credits.css"); + reload(); + } + + @Override + public void reload() { + popAll(); + + final String[] credits = { + AppContext.getString("scrumMaster") + ": Stef", + AppContext.getString("productOwner") + ": Omar", + AppContext.getString("mergeCommander") + ": Bas", + AppContext.getString("localization") + ": Ticho", + AppContext.getString("ai") + ": Michiel", + AppContext.getString("developers") + ": Michiel, Bas, Stef, Omar, Ticho", + AppContext.getString("moralSupport") + ": Wesley", + AppContext.getString("opengl") + ": Omar" + }; + + final Container creditsContainer = new HorizontalContainer(0); + + final Container animatedContainer = new VerticalContainer("animated_credits_container", lineHeight); + creditsContainer.addContainer(animatedContainer, true); + + for (final String credit : credits) { + animatedContainer.addText("credit-text", credit, false); + } + + final Container controlContainer = new VerticalContainer(5); + controlContainer.addButton(AppContext.getString("back"), () -> { + App.activate(new MainLayer()); + }); + + addContainer(creditsContainer, Pos.CENTER, 0, 0, 50, 100); + addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); + + playCredits(animatedContainer, App.getHeight()); + } + + private void playCredits(Container container, double sceneLength) { + container.getContainer().setTranslateY(-sceneLength); + + final TranslateTransition scrollCredits = new TranslateTransition(Duration.seconds(20), container.getContainer()); + scrollCredits.setFromY(-sceneLength - lineHeight); + scrollCredits.setToY(sceneLength + lineHeight); + + scrollCredits.setOnFinished(_ -> { + final PauseTransition pauseCredits = new PauseTransition(Duration.seconds(3)); + pauseCredits.setOnFinished(_ -> playCredits(container, sceneLength)); + pauseCredits.play(); + }); + + scrollCredits.play(); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/layers/MainLayer.java b/app/src/main/java/org/toop/app/layer/layers/MainLayer.java index d156407..41781dd 100644 --- a/app/src/main/java/org/toop/app/layer/layers/MainLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/MainLayer.java @@ -1,10 +1,12 @@ package org.toop.app.layer.layers; import org.toop.app.App; -import org.toop.app.GameType; import org.toop.app.layer.Container; import org.toop.app.layer.Layer; import org.toop.app.layer.containers.VerticalContainer; +import org.toop.game.othello.Othello; +import org.toop.game.tictactoe.TicTacToe; +import org.toop.local.AppContext; import javafx.geometry.Pos; @@ -19,15 +21,30 @@ public final class MainLayer extends Layer { popAll(); final Container gamesContainer = new VerticalContainer(5); - gamesContainer.addButton("Tic Tac Toe", () -> { App.activate(new MultiplayerLayer(GameType.TICTACTOE)); }); - gamesContainer.addButton("Othello", () -> { App.activate(new MultiplayerLayer(GameType.OTHELLO)); }); + + gamesContainer.addButton(AppContext.getString("tictactoe"), () -> { + App.activate(new MultiplayerLayer()); + }); + + gamesContainer.addButton(AppContext.getString("othello"), () -> { + App.activate(new MultiplayerLayer()); + }); final Container controlContainer = new VerticalContainer(5); - controlContainer.addButton("Credits", () -> {}); - controlContainer.addButton("Options", () -> {}); - controlContainer.addButton("Quit", () -> { App.quitPopup(); }); - addContainer(gamesContainer, Pos.TOP_LEFT, 2, 2, 25, 0); - addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 25, 0); + controlContainer.addButton(AppContext.getString("credits"), () -> { + App.activate(new CreditsLayer()); + }); + + controlContainer.addButton(AppContext.getString("options"), () -> { + App.activate(new OptionsLayer()); + }); + + controlContainer.addButton(AppContext.getString("quit"), () -> { + App.quitPopup(); + }); + + addContainer(gamesContainer, Pos.TOP_LEFT, 2, 2, 20, 0); + addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 20, 0); } } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java b/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java index 10a6210..715c6f3 100644 --- a/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/MultiplayerLayer.java @@ -1,22 +1,31 @@ package org.toop.app.layer.layers; import org.toop.app.App; -import org.toop.app.GameType; -import org.toop.app.canvas.TicTacToeCanvas; +import org.toop.app.GameInformation; import org.toop.app.layer.Container; import org.toop.app.layer.Layer; import org.toop.app.layer.containers.HorizontalContainer; import org.toop.app.layer.containers.VerticalContainer; +import org.toop.app.layer.layers.game.TicTacToeLayer; +import org.toop.local.AppContext; import javafx.geometry.Pos; -public class MultiplayerLayer extends Layer { - boolean isConnectionLocal = true; +public final class MultiplayerLayer extends Layer { + private boolean isConnectionLocal = true; - boolean isPlayer1Human = true; - boolean isPlayer2Human = true; + private boolean isPlayer1Human = true; + private String player1Name = ""; + private int computer1Difficulty = 0; - protected MultiplayerLayer(GameType type) { + private boolean isPlayer2Human = true; + private String player2Name = ""; + private int computer2Difficulty = 0; + + private String serverIP = ""; + private String serverPort = ""; + + public MultiplayerLayer() { super("multiplayer.css"); reload(); } @@ -26,64 +35,87 @@ public class MultiplayerLayer extends Layer { popAll(); final Container mainContainer = new VerticalContainer(5); - mainContainer.addToggle("Local", "Server", !isConnectionLocal, (server) -> { + + mainContainer.addToggle(AppContext.getString("local"), AppContext.getString("server"), !isConnectionLocal, (server) -> { isConnectionLocal = !server; reload(); }); final Container playersContainer = new HorizontalContainer(50); + mainContainer.addContainer(playersContainer, true); final Container player1Container = new VerticalContainer("player_container", 5); + playersContainer.addContainer(player1Container, true); playersContainer.addText("VS", false); final Container player2Container = new VerticalContainer("player_container", 5); + playersContainer.addContainer(player2Container, true); - if (isConnectionLocal) { - mainContainer.addButton("Start", () -> {}); - } else { - mainContainer.addButton("Connnect", () -> { App.activate(new GameLayer()); }); - } + mainContainer.addButton(isConnectionLocal? AppContext.getString("start") : AppContext.getString("connect"), () -> { + App.activate(new TicTacToeLayer(new GameInformation( + new String[] { player1Name, player2Name }, + new boolean[] { isPlayer1Human, isPlayer2Human }, + new int[] { computer1Difficulty, computer2Difficulty }, + isConnectionLocal, serverIP, serverPort))); + }); - player1Container.addToggle("Human", "Computer", !isPlayer1Human, (computer) -> { + player1Container.addToggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer1Human, (computer) -> { isPlayer1Human = !computer; reload(); }); if (isPlayer1Human) { - player1Container.addText("player is human", true); - player1Container.addText("input player name here: ...", true); + player1Container.addText(AppContext.getString("playerName"), true); + player1Container.addInput(player1Name, (name) -> { + player1Name = name; + }); } else { - player1Container.addText("playing against ai", true); - player1Container.addToggle("Easy", "Hard", false, (hard) -> {}); + player1Container.addText(AppContext.getString("computerDifficulty"), true); + player1Container.addSlider(5, computer1Difficulty, (difficulty) -> { + computer1Difficulty = difficulty; + }); } if (isConnectionLocal) { - player2Container.addToggle("Human", "Computer", !isPlayer2Human, (computer) -> { + player2Container.addToggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer2Human, (computer) -> { isPlayer2Human = !computer; reload(); }); if (isPlayer2Human) { - player2Container.addText("player is human", true); - player2Container.addText("input player name here: ...", true); + player2Container.addText(AppContext.getString("playerName"), true); + player2Container.addInput(player2Name, (name) -> { + player2Name = name; + }); } else { - player2Container.addText("playing against ai", true); - player2Container.addToggle("Easy", "Hard", false, (hard) -> {}); + player2Container.addText(AppContext.getString("computerDifficulty"), true); + player2Container.addSlider(5, computer2Difficulty, (difficulty) -> { + computer2Difficulty = difficulty; + }); } } else { - player2Container.addText("Server IP", true); - player2Container.addInput("", (input) -> {}); + player2Container.addText(AppContext.getString("serverIP"), true); + player2Container.addInput(serverIP, (ip) -> { + serverIP = ip; + }); - player2Container.addText("Server Port", true); - player2Container.addInput("", (input) -> {}); + player2Container.addSeparator(true); + + player2Container.addText(AppContext.getString("serverPort"), true); + player2Container.addInput(serverPort, (port) -> { + serverPort = port; + }); } final Container controlContainer = new VerticalContainer(5); - controlContainer.addButton("Back", () -> { App.activate(new MainLayer()); }); + + controlContainer.addButton(AppContext.getString("back"), () -> { + App.activate(new MainLayer()); + }); addContainer(mainContainer, Pos.CENTER, 0, 0, 75, 75); addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); diff --git a/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java b/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java new file mode 100644 index 0000000..aa8d479 --- /dev/null +++ b/app/src/main/java/org/toop/app/layer/layers/OptionsLayer.java @@ -0,0 +1,105 @@ +package org.toop.app.layer.layers; + +import org.toop.app.App; +import org.toop.app.layer.Container; +import org.toop.app.layer.Layer; +import org.toop.app.layer.containers.VerticalContainer; +import org.toop.framework.asset.resources.SettingsAsset; +import org.toop.framework.audio.events.AudioEvents; +import org.toop.framework.eventbus.EventFlow; +import org.toop.local.AppContext; + +import javafx.geometry.Pos; +import javafx.scene.control.ChoiceBox; +import org.toop.local.AppSettings; + +import java.util.Locale; + +public final class OptionsLayer extends Layer { + AppSettings appSettings = new AppSettings(); + SettingsAsset settings = appSettings.getPath(); + + private int currentVolume = settings.getVolume(); + private boolean isWindowed = !(settings.getFullscreen()); + + OptionsLayer() { + super("options.css"); + reload(); + } + + @Override + public void reload() { + popAll(); + + final Container optionsContainer = new VerticalContainer(5); + optionsContainer.addText(AppContext.getString("language"), false); + addLanguageBox(optionsContainer); + optionsContainer.addSeparator(true); + + optionsContainer.addText(AppContext.getString("volume"), false); + addVolumeSlider(optionsContainer); + optionsContainer.addSeparator(true); + + addFullscreenToggle(optionsContainer); + + final Container mainContainer = new VerticalContainer(50); + mainContainer.addText(AppContext.getString("options"), false); + mainContainer.addContainer(optionsContainer, true); + + final Container controlContainer = new VerticalContainer(5); + controlContainer.addButton(AppContext.getString("back"), () -> { + App.activate(new MainLayer()); + }); + + addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 60); + addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); + } + + private void addLanguageBox(Container container) { + assert AppContext.getLocalization() != null; + + final ChoiceBox languageBox = container.addChoiceBox((locale) -> { + if (locale == AppContext.getLocale()) { + return; + } + + AppContext.setLocale(locale); + settings.setLocale(locale.toString()); + App.reloadAll(); + }); + + for (final Locale localeFile : AppContext.getLocalization().getAvailableLocales()) { + languageBox.getItems().add(localeFile); + } + + languageBox.setConverter(new javafx.util.StringConverter<>() { + @Override + public String toString(Locale locale) { + return AppContext.getString(locale.getDisplayName().toLowerCase()); + } + + @Override + public Locale fromString(String string) { + return null; + } + }); + + languageBox.setValue(AppContext.getLocale()); + } + + private void addVolumeSlider(Container container) { + container.addSlider(100, currentVolume, (volume) -> { + currentVolume = volume; + settings.setVolume(volume); + new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(volume.doubleValue())).asyncPostEvent(); + }); + } + + private void addFullscreenToggle(Container container) { + container.addToggle(AppContext.getString("windowed"), AppContext.getString("fullscreen"), !isWindowed, (fullscreen) -> { + isWindowed = !fullscreen; + App.setFullscreen(fullscreen); + settings.setFullscreen(fullscreen); + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/layer/layers/QuitLayer.java b/app/src/main/java/org/toop/app/layer/layers/QuitLayer.java index 1dc5af5..13fc367 100644 --- a/app/src/main/java/org/toop/app/layer/layers/QuitLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/QuitLayer.java @@ -5,12 +5,13 @@ import org.toop.app.layer.Container; import org.toop.app.layer.Layer; import org.toop.app.layer.containers.HorizontalContainer; import org.toop.app.layer.containers.VerticalContainer; +import org.toop.local.AppContext; import javafx.geometry.Pos; public final class QuitLayer extends Layer { public QuitLayer() { - super("quit.css", "quit_background"); + super("quit.css"); reload(); } @@ -19,13 +20,19 @@ public final class QuitLayer extends Layer { popAll(); final Container mainContainer = new VerticalContainer(30); - mainContainer.addText("Are you sure?", false); + mainContainer.addText(AppContext.getString("quitSure"), false); final Container controlContainer = new HorizontalContainer(30); + mainContainer.addContainer(controlContainer, false); - controlContainer.addButton("Yes", () -> { App.quit(); }); - controlContainer.addButton("No", () -> { App.pop(); }); + controlContainer.addButton(AppContext.getString("yes"), () -> { + App.quit(); + }); + + controlContainer.addButton(AppContext.getString("no"), () -> { + App.pop(); + }); addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 30); } diff --git a/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java b/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java new file mode 100644 index 0000000..aadc783 --- /dev/null +++ b/app/src/main/java/org/toop/app/layer/layers/game/TicTacToeLayer.java @@ -0,0 +1,146 @@ +package org.toop.app.layer.layers.game; + +import javafx.geometry.Pos; +import javafx.scene.paint.Color; +import org.toop.app.App; +import org.toop.app.GameInformation; +import org.toop.app.canvas.TicTacToeCanvas; +import org.toop.app.layer.Container; +import org.toop.app.layer.Layer; +import org.toop.app.layer.containers.VerticalContainer; +import org.toop.app.layer.layers.MainLayer; +import org.toop.game.Game; +import org.toop.game.tictactoe.TicTacToe; +import org.toop.game.tictactoe.TicTacToeAI; +import org.toop.local.AppContext; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public final class TicTacToeLayer extends Layer { + private TicTacToeCanvas canvas; + + private TicTacToe ticTacToe; + private TicTacToeAI ticTacToeAI; + + private GameInformation information; + + private final BlockingQueue playerMoveQueue = new LinkedBlockingQueue<>(); + + public TicTacToeLayer(GameInformation information) { + super("game.css"); + + canvas = new TicTacToeCanvas(Color.WHITE, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> { + try { + if (information.isConnectionLocal()) { + if (ticTacToe.getCurrentTurn() == 0) { + playerMoveQueue.put(new Game.Move(cell, 'X')); + } else { + playerMoveQueue.put(new Game.Move(cell, 'O')); + } + } else { + if (ticTacToe.getCurrentTurn() == 0) { + // Todo: identify if we are x or o and put in queue + } + } + } catch (InterruptedException e) { + return; + } + }); + + ticTacToe = new TicTacToe(); + ticTacToeAI = new TicTacToeAI(); + + this.information = information; + + if (information.isConnectionLocal()) { + new Thread(this::localGameThread).start(); + } else { + new Thread(this::serverGameThread).start(); + } + + reload(); + } + + @Override + public void reload() { + popAll(); + + canvas.resize((App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75); + + for (int i = 0; i < ticTacToe.board.length; i++) { + final char value = ticTacToe.board[i]; + + if (value == 'X') { + canvas.drawX(Color.RED, i); + } else if (value == 'O') { + canvas.drawO(Color.BLUE, i); + } + } + + final Container controlContainer = new VerticalContainer(5); + + if (information.isPlayerHuman()[0] || information.isConnectionLocal() && information.isPlayerHuman()[1]) { + controlContainer.addButton(AppContext.getString("hint"), () -> { + }); + } + + controlContainer.addButton(AppContext.getString("back"), () -> { + App.activate(new MainLayer()); + }); + + addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0); + addGameCanvas(canvas, Pos.CENTER, 0, 0); + } + + private int compurterDifficultyToDepth(int maxDifficulty, int difficulty) { + return (int) (((float) maxDifficulty / difficulty) * 9); + } + + private void localGameThread() { + boolean running = true; + + while (running) { + final int currentPlayer = ticTacToe.getCurrentTurn(); + + Game.Move move = null; + + if (information.isPlayerHuman()[currentPlayer]) { + try { + move = playerMoveQueue.take(); + } catch (InterruptedException exception) { + return; + } + } else { + move = ticTacToeAI.findBestMove(ticTacToe, compurterDifficultyToDepth(5, information.computerDifficulty()[currentPlayer])); + } + + assert move != null; + final Game.State state = ticTacToe.play(move); + + if (move.value() == 'X') { + canvas.drawX(Color.RED, move.position()); + } else if (move.value() == 'O') { + canvas.drawO(Color.BLUE, move.position()); + } + + if (state != Game.State.NORMAL) { + if (state == Game.State.WIN) { + // Win logic + } else if (state == Game.State.DRAW) { + // Draw logic + } + + running = false; + } + } + } + + private void serverGameThread() { + boolean running = true; + + while (running) { + final int currentPlayer = ticTacToe.getCurrentTurn(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/menu/CreditsMenu.java b/app/src/main/java/org/toop/app/menu/CreditsMenu.java deleted file mode 100644 index 3817d69..0000000 --- a/app/src/main/java/org/toop/app/menu/CreditsMenu.java +++ /dev/null @@ -1,100 +0,0 @@ -// package org.toop.app.menu; -// -// import javafx.animation.Interpolator; -// import javafx.animation.PauseTransition; -// import javafx.animation.TranslateTransition; -// import javafx.application.Platform; -// import javafx.geometry.Pos; -// import javafx.scene.control.Button; -// import javafx.scene.layout.Region; -// import javafx.scene.layout.StackPane; -// import javafx.scene.layout.VBox; -// import javafx.util.Duration; -// import org.toop.app.App; -// import org.toop.framework.asset.ResourceManager; -// import org.toop.framework.asset.resources.LocalizationAsset; -// import org.toop.framework.eventbus.EventFlow; -// import org.toop.local.AppContext; -// import org.toop.local.LocalizationEvents; -// -// import java.util.Locale; -// -// public final class CreditsMenu extends Menu { ; -// private Locale currentLocale = AppContext.getLocale(); -// private LocalizationAsset loc = ResourceManager.get("localization_en_us.properties"); -// -// String[] credits = { -// "Scrum Master: Stef", -// "Product Owner: Omar", -// "Merge Commander: Bas", -// "Localization: Ticho", -// "AI: Michiel", -// "Developers: Michiel, Bas, Stef, Omar, Ticho", -// "Moral Support: Wesley (voor 1 week)", -// "OpenGL: Omar" -// }; -// -// double scrollDuration = 20.0; -// double lineHeight = 40.0; -// -// public CreditsMenu() { -// VBox creditsBox = new VBox(lineHeight / 2); -// for (int i = credits.length - 1; i >= 0; i--) { -// creditsBox.getChildren().add(createText(credits[i])); -// creditsBox.setAlignment(Pos.CENTER); -// } -// -// Button exit = new Button("<"); -// exit.setStyle( -// "-fx-background-color: transparent;" + -// "-fx-text-fill: white;" + -// "-fx-font-size: 72px;" + -// "-fx-padding: 10 20 10 20;" -// ); -// exit.setOnAction(e -> App.pop()); -// -// final Region background = createBackground(); -// StackPane.setAlignment(exit, Pos.TOP_LEFT); -// pane = new StackPane(background, creditsBox, exit); -// -// Platform.runLater(() -> playCredits(creditsBox, 800)); -// -// try { -// new EventFlow() -// .listen(this::handleChangeLanguage); -// -// }catch (Exception e){ -// System.out.println("Something went wrong while trying to change the language."); -// throw e; -// } -// } -// -// public void playCredits(VBox creditsBox, double sceneLength) { -// double height = (credits.length * lineHeight); -// double startY = -sceneLength; -// double endY = height; -// -// creditsBox.setTranslateY(startY); -// -// TranslateTransition scrollCredits = new TranslateTransition(); -// scrollCredits.setNode(creditsBox); -// scrollCredits.setFromY(startY); -// scrollCredits.setToY(endY / 2 - 200); -// scrollCredits.setDuration(Duration.seconds(scrollDuration)); -// scrollCredits.setInterpolator(Interpolator.LINEAR); -// -// scrollCredits.setOnFinished(e -> { -// PauseTransition pauseCredits = new PauseTransition(Duration.seconds(5)); -// pauseCredits.setOnFinished(a -> playCredits(creditsBox, sceneLength)); -// pauseCredits.play(); -// }); -// -// scrollCredits.play(); -// } -// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) { -// Platform.runLater(() -> { -// currentLocale = AppContext.getLocale(); -// //credits.setText(loc.getString("credits",currentLocale)); -// }); -// } -// } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/menu/GameSelectMenu.java b/app/src/main/java/org/toop/app/menu/GameSelectMenu.java deleted file mode 100644 index 89d9a89..0000000 --- a/app/src/main/java/org/toop/app/menu/GameSelectMenu.java +++ /dev/null @@ -1,66 +0,0 @@ -// package org.toop.app.menu; -// -// import javafx.application.Platform; -// import javafx.scene.control.ComboBox; -// import javafx.scene.control.TextField; -// import javafx.scene.layout.HBox; -// import javafx.scene.layout.Region; -// import javafx.scene.layout.StackPane; -// import javafx.scene.layout.VBox; -// import org.toop.app.GameType; -// import org.toop.framework.asset.ResourceManager; -// import org.toop.framework.asset.resources.LocalizationAsset; -// import org.toop.framework.eventbus.EventFlow; -// import org.toop.local.AppContext; -// -// import java.util.Locale; -// -// public class GameSelectMenu extends Menu { -// private Locale currentLocale = AppContext.getLocale(); -// private final LocalizationAsset loc = ResourceManager.get("localization"); -// -// final ComboBox selectedMode, selectedGame; -// final TextField serverIpField; -// -// public GameSelectMenu(GameType type) { -// final Region background = createBackground(); -// -// selectedGame = new ComboBox<>(); -// selectedGame.getItems().add(GameType.toName(GameType.TICTACTOE)); -// selectedGame.getItems().add(GameType.toName(GameType.REVERSI)); -// selectedGame.setValue(GameType.toName(type)); -// -// selectedMode = new ComboBox<>(); -// selectedMode.getItems().add("Local"); -// selectedMode.getItems().add("Online"); -// selectedMode.setValue("Local"); -// -// final HBox selectedContainer = new HBox(10, selectedGame, selectedMode); -// -// serverIpField = new TextField(); -// serverIpField.setPromptText(loc.getString("gameSelectMenuEnterIP",currentLocale)); -// -// VBox box = new VBox(selectedContainer, serverIpField); -// pane = new StackPane(background, box); -// try { -// new EventFlow() -// .listen(this::handleChangeLanguage); -// -// }catch (Exception e){ -// System.out.println("Something went wrong while trying to change the language."); -// throw e; -// } -// -// } -// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) { -// Platform.runLater(() -> { -// currentLocale = AppContext.getLocale(); -// serverIpField.setPromptText(loc.getString("gameSelectMenuEnterIP",currentLocale)); -// selectedGame.getItems().set(0, loc.getString("mainMenuSelectTicTacToe",currentLocale)); -// selectedGame.getItems().set(1, loc.getString("mainMenuSelectReversi",currentLocale)); -// selectedMode.getItems().set(0, loc.getString("gameSelectMenuLocal",currentLocale)); -// selectedMode.getItems().set(1, loc.getString("gameSelectMenuOnline",currentLocale)); -// }); -// -// } -// } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/menu/MainMenu.java b/app/src/main/java/org/toop/app/menu/MainMenu.java deleted file mode 100644 index 9696b5d..0000000 --- a/app/src/main/java/org/toop/app/menu/MainMenu.java +++ /dev/null @@ -1,69 +0,0 @@ -// package org.toop.app.menu; -// -// import javafx.application.Platform; -// import org.toop.app.App; -// import org.toop.app.GameType; -// -// import javafx.geometry.Pos; -// import javafx.scene.control.Button; -// import javafx.scene.layout.*; -// import org.toop.framework.asset.ResourceManager; -// import org.toop.framework.asset.resources.LocalizationAsset; -// import org.toop.framework.eventbus.EventFlow; -// import org.toop.game.tictactoe.TicTacToe; -// import org.toop.local.AppContext; -// import org.toop.local.LocalizationEvents; -// -// import java.util.Locale; -// -// public final class MainMenu extends Menu { -// private Locale currentLocale = AppContext.getLocale(); -// private final LocalizationAsset loc = ResourceManager.get("localization"); -// private final Button tictactoe,reversi,credits,options,quit; -// public MainMenu() { -// final Region background = createBackground(); -// -// tictactoe = createButton( -// loc.getString("mainMenuSelectTicTacToe",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.TICTACTOE)); }); -// reversi = createButton( -// loc.getString("mainMenuSelectReversi",currentLocale), () -> { App.activate(new GameSelectMenu(GameType.REVERSI)); }); -// -// final VBox gamesBox = new VBox(10, tictactoe, reversi); -// gamesBox.setAlignment(Pos.TOP_LEFT); -// gamesBox.setPickOnBounds(false); -// gamesBox.setTranslateY(50); -// gamesBox.setTranslateX(25); -// -// credits = createButton(loc.getString("mainMenuSelectCredits",currentLocale), () -> { App.push(new CreditsMenu()); }); -// options = createButton(loc.getString("mainMenuSelectOptions",currentLocale), () -> { App.push(new OptionsMenu()); }); -// quit = createButton(loc.getString("mainMenuSelectQuit",currentLocale), () -> { App.quitPopup(); }); -// -// final VBox controlBox = new VBox(10, credits, options, quit); -// controlBox.setAlignment(Pos.BOTTOM_LEFT); -// controlBox.setPickOnBounds(false); -// controlBox.setTranslateY(-50); -// controlBox.setTranslateX(25); -// -// pane = new StackPane(background, gamesBox, controlBox); -// try { -// new EventFlow() -// .listen(this::handleChangeLanguage); -// -// }catch (Exception e){ -// System.out.println("Something went wrong while trying to change the language."); -// throw e; -// } -// -// } -// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) { -// Platform.runLater(() -> { -// currentLocale = AppContext.getLocale(); -// tictactoe.setText(loc.getString("mainMenuSelectTicTacToe",currentLocale)); -// reversi.setText(loc.getString("mainMenuSelectReversi",currentLocale)); -// credits.setText(loc.getString("mainMenuSelectCredits",currentLocale)); -// options.setText(loc.getString("mainMenuSelectOptions",currentLocale)); -// quit.setText(loc.getString("mainMenuSelectQuit",currentLocale)); -// }); -// -// } -// } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/menu/Menu.java b/app/src/main/java/org/toop/app/menu/Menu.java deleted file mode 100644 index 6863d8e..0000000 --- a/app/src/main/java/org/toop/app/menu/Menu.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.toop.app.menu; - -import javafx.scene.control.Button; -import javafx.scene.layout.Pane; -import javafx.scene.layout.Region; -import javafx.scene.text.Text; -import org.toop.framework.audio.events.AudioEvents; -import org.toop.framework.eventbus.EventFlow; - -public abstract class Menu { - protected Pane pane; - public Pane getPane() { return pane; } - - public Region createBackground(String css) { - final Region background = new Region(); - background.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE); - background.getStyleClass().add(css); - - return background; - } - - public Region createBackground() { - return createBackground("background"); - } - - public Text createText(String css, String x) { - final Text text = new Text(x); - text.getStyleClass().add(css); - - return text; - } - - public Text createText(String x) { - return createText("text", x); - } - - public Button createButton(String css, String x, Runnable runnable) { - final Button button = new Button(x); - button.setOnAction(_ -> { - new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); - runnable.run(); - }); - button.getStyleClass().add(css); - - return button; - } - - public Button createButton(String x, Runnable runnable) { - return createButton("button", x, runnable); - } -} \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/menu/OptionsMenu.java b/app/src/main/java/org/toop/app/menu/OptionsMenu.java deleted file mode 100644 index c738d32..0000000 --- a/app/src/main/java/org/toop/app/menu/OptionsMenu.java +++ /dev/null @@ -1,174 +0,0 @@ -// package org.toop.app.menu; -// -// import javafx.geometry.Pos; -// import javafx.scene.control.*; -// import javafx.scene.control.Button; -// import javafx.scene.control.Label; -// import javafx.scene.layout.Region; -// import javafx.scene.layout.StackPane; -// import javafx.scene.layout.VBox; -// import org.toop.app.App; -// import org.toop.framework.asset.ResourceManager; -// import org.toop.framework.asset.resources.LocalizationAsset; -// import org.toop.framework.audio.events.AudioEvents; -// import org.toop.framework.eventbus.EventFlow; -// import org.toop.local.AppContext; -// -// import java.awt.*; -// import java.util.Locale; -// -// public final class OptionsMenu extends Menu { -// private Locale currentLocale = AppContext.getLocale(); -// private LocalizationAsset loc = ResourceManager.get("localization"); -// private GraphicsDevice currentScreenDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0]; -// -// public OptionsMenu() { -// final Label selectLanguageLabel = new Label( -// loc.getString("optionsMenuLabelSelectLanguage", currentLocale) -// ); -// -// final Button exitOptionsButton = createButton("Exit Options", () -> { App.pop(); } ); -// -// final VBox optionsBox = new VBox(10, -// selectLanguageLabel, -// languageSelectorCreation(), -// screenDeviceSelectorCreation(), -// displayModeSelectorCreation(), -// selectFullscreenCreation(), -// volumeSelectorCreation(), -// exitOptionsButton); -// -// optionsBox.setAlignment(Pos.CENTER); -// optionsBox.setPickOnBounds(false); -// optionsBox.setTranslateY(50); -// optionsBox.setTranslateX(25); -// -// pane = new StackPane(optionsBox); -// -// } -// -// private ChoiceBox languageSelectorCreation() { -// final ChoiceBox selectLanguage = new ChoiceBox<>(); -// selectLanguage.setValue(currentLocale); -// -// for (Locale locFile : loc.getAvailableLocales()) { -// selectLanguage.getItems().add(locFile); -// } -// -// selectLanguage.setConverter(new javafx.util.StringConverter<>() { -// @Override -// public String toString(Locale locale) { -// return locale.getDisplayName(); -// } -// -// @Override -// public Locale fromString(String string) { -// return null; -// } -// }); -// -// selectLanguage.setOnShowing(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// }); -// -// selectLanguage.setOnAction(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// Locale selectedLocale = selectLanguage.getSelectionModel().getSelectedItem(); -// if (selectedLocale != null) { -// AppContext.setLocale(selectedLocale); -// App.pop(); -// App.push(new OptionsMenu()); -// } -// }); -// -// return selectLanguage; -// } -// -// private ChoiceBox screenDeviceSelectorCreation() { -// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); -// GraphicsDevice[] devices = ge.getScreenDevices(); -// final ChoiceBox selectScreen = new ChoiceBox<>(); -// for (GraphicsDevice screen : devices) { -// selectScreen.getItems().add(screen); -// } -// -// selectScreen.setOnShowing(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// }); -// -// selectScreen.setOnAction(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// int selectedIndex = selectScreen.getSelectionModel().getSelectedIndex(); -// Object selectedItem = selectScreen.getSelectionModel().getSelectedItem(); -// -// System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem); -// System.out.println(" ChoiceBox.getValue(): " + selectScreen.getValue()); -// }); -// return selectScreen; -// } -// -// private ChoiceBox displayModeSelectorCreation() { -// final ChoiceBox selectWindowSize = new ChoiceBox<>(); -// for (DisplayMode displayMode : currentScreenDevice.getDisplayModes()) { -// selectWindowSize.getItems().add(displayMode); -// } -// selectWindowSize.setOnShowing(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// }); -// selectWindowSize.setOnAction(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// int selectedIndex = selectWindowSize.getSelectionModel().getSelectedIndex(); -// Object selectedItem = selectWindowSize.getSelectionModel().getSelectedItem(); -// -// System.out.println("Selection made: [" + selectedIndex + "] " + selectedItem); -// System.out.println(" ChoiceBox.getValue(): " + selectWindowSize.getValue()); -// }); -// return selectWindowSize; -// } -// -// private CheckBox selectFullscreenCreation() { -// final CheckBox setFullscreen = new CheckBox("Fullscreen"); -// setFullscreen.setSelected(App.isFullscreen()); -// setFullscreen.setOnAction(event -> { -// new EventFlow().addPostEvent(new AudioEvents.clickButton()).asyncPostEvent(); -// boolean isSelected = setFullscreen.isSelected(); -// App.setFullscreen(isSelected); -// }); -// return setFullscreen; -// } -// -// private Slider volumeSelectorCreation() { -// Slider volumeSlider = new Slider(0, 100, 50); -// new EventFlow() -// .addPostEvent(AudioEvents.GetCurrentVolume.class) -// .onResponse(AudioEvents.GetCurrentVolumeReponse.class, event -> { -// volumeSlider.setValue(event.currentVolume() * 100); -// }, true).asyncPostEvent(); -// volumeSlider.setShowTickLabels(true); -// volumeSlider.setShowTickMarks(true); -// volumeSlider.setMajorTickUnit(25); -// volumeSlider.setMinorTickCount(4); -// volumeSlider.setBlockIncrement(5); -// volumeSlider.setMaxWidth(225); -// -// Label valueLabel = new Label(String.valueOf((int) volumeSlider.getValue())); -// -// final long[] lastPlayed = {0}; -// final long cooldown = 50; -// volumeSlider.valueProperty().addListener((obs, oldVal, newVal) -> { -// long now = System.currentTimeMillis(); -// -// if (now - lastPlayed[0] >= cooldown) { -// lastPlayed[0] = now; -// // new EventFlow().addPostEvent(new AudioEvents.clickButton()) -// // .asyncPostEvent(); // TODO: creates double sound bug, WHYYY???? -// } -// valueLabel.setText(String.valueOf(newVal.intValue())); -// new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(newVal.doubleValue()/100.0)) -// .asyncPostEvent(); -// }); -// -// return volumeSlider; -// } -// -// } \ No newline at end of file diff --git a/app/src/main/java/org/toop/app/menu/game/GameMenu.java b/app/src/main/java/org/toop/app/menu/game/GameMenu.java deleted file mode 100644 index 13ab5e1..0000000 --- a/app/src/main/java/org/toop/app/menu/game/GameMenu.java +++ /dev/null @@ -1,127 +0,0 @@ -// package org.toop.app.menu.game; -// -// import javafx.application.Platform; -// import javafx.geometry.Pos; -// import javafx.scene.canvas.Canvas; -// import javafx.scene.canvas.GraphicsContext; -// import javafx.scene.control.Button; -// import javafx.scene.layout.HBox; -// import javafx.scene.layout.Region; -// import javafx.scene.layout.StackPane; -// import javafx.scene.layout.VBox; -// import javafx.scene.text.Text; -// import org.toop.app.App; -// import org.toop.app.menu.MainMenu; -// import org.toop.app.menu.Menu; -// import org.toop.framework.asset.ResourceManager; -// import org.toop.framework.asset.resources.LocalizationAsset; -// import org.toop.framework.eventbus.EventFlow; -// import org.toop.local.AppContext; -// -// import java.util.Locale; -// -// public abstract class GameMenu extends Menu { -// protected final class Cell { -// public float x; -// public float y; -// -// public float width; -// public float height; -// -// public Cell(float x, float y, float width, float height) { -// this.x = x; -// this.y = y; -// -// this.width = width; -// this.height = height; -// } -// -// public boolean check(float x, float y) { -// return x >= this.x && y >= this.y && x <= this.x + width && y <= this.y + height; -// } -// } -// -// protected final int size; -// -// protected final Canvas canvas; -// protected final GraphicsContext graphics; -// -// protected final int rows; -// protected final int columns; -// -// protected final int gapSize; -// -// protected final Cell[] cells; -// -// private Locale currentLocale = AppContext.getLocale(); -// private final LocalizationAsset loc = ResourceManager.get("localization"); -// private final Button hint,back; -// protected GameMenu(int rows, int columns, int gapSize) { -// -// final int size = Math.min(App.getWidth(), App.getHeight()) / 5 * 4; -// -// final Canvas canvas = new Canvas(size, size); -// -// final GraphicsContext graphics = canvas.getGraphicsContext2D(); -// -// this.size = size; -// -// this.canvas = canvas; -// this.graphics = graphics; -// -// this.rows = rows; -// this.columns = columns; -// -// this.gapSize = gapSize; -// -// cells = new Cell[rows * columns]; -// -// final float cellWidth = ((float)size - (rows - 1) * gapSize) / rows; -// final float cellHeight = ((float)size - (columns - 1) * gapSize) / rows; -// -// for (int y = 0; y < columns; y++) { -// final float startY = y * cellHeight + y * gapSize; -// -// for (int x = 0; x < rows; x++) { -// final float startX = x * cellWidth + x * gapSize; -// cells[y * rows + x] = new Cell(startX, startY, cellWidth, cellHeight); -// } -// } -// -// final Region background = createBackground(); -// -// final Text player1 = createText("player_1", "Player 1"); -// final Text player2 = createText("player_2", "Player 2"); -// -// final HBox playersContainer = new HBox(100, player1, player2); -// playersContainer.setAlignment(Pos.TOP_CENTER); -// playersContainer.setPickOnBounds(false); -// playersContainer.setTranslateY(50); -// -// hint = createButton(loc.getString("gameMenuHint",currentLocale), () -> {}); -// back = createButton(loc.getString("gameMenuBack",currentLocale), () -> { App.activate(new MainMenu()); }); -// -// final VBox controlContainer = new VBox(hint, back); -// StackPane.setAlignment(controlContainer, Pos.BOTTOM_LEFT); -// controlContainer.setPickOnBounds(false); -// -// pane = new StackPane(background, canvas, playersContainer, controlContainer); -// try { -// new EventFlow() -// .listen(this::handleChangeLanguage); -// -// }catch (Exception e){ -// System.out.println("Something went wrong while trying to change the language."); -// throw e; -// } -// -// } -// private void handleChangeLanguage(LocalizationEvents.LanguageHasChanged event) { -// Platform.runLater(() -> { -// currentLocale = AppContext.getLocale(); -// hint.setText(loc.getString("gameMenuHint",currentLocale)); -// back.setText(loc.getString("gameMenuBack",currentLocale)); -// }); -// -// } -// } \ No newline at end of file diff --git a/app/src/main/java/org/toop/local/AppContext.java b/app/src/main/java/org/toop/local/AppContext.java index 277940e..10009b0 100644 --- a/app/src/main/java/org/toop/local/AppContext.java +++ b/app/src/main/java/org/toop/local/AppContext.java @@ -1,24 +1,28 @@ package org.toop.local; -import org.toop.app.events.AppEvents; -import org.toop.framework.eventbus.EventFlow; +import org.toop.framework.asset.ResourceManager; +import org.toop.framework.asset.resources.LocalizationAsset; import java.util.Locale; public class AppContext { - private static Locale currentLocale = Locale.getDefault(); + private static final LocalizationAsset localization = ResourceManager.get("localization"); + private static Locale locale = Locale.forLanguageTag("en"); - public static void setLocale(Locale locale) { - currentLocale = locale; - new EventFlow().addPostEvent(new AppEvents.OnLanguageChange(locale.getLanguage())).asyncPostEvent(); - } + public static LocalizationAsset getLocalization() { + return localization; + } - public static void setCurrentLocale(Locale locale) { - currentLocale = locale; - new EventFlow().addPostEvent(new AppEvents.OnLanguageChange(locale.getLanguage())).asyncPostEvent(); - } + public static void setLocale(Locale locale) { + AppContext.locale = locale; + } - public static Locale getLocale() { - return currentLocale; - } + public static Locale getLocale() { + return locale; + } + + public static String getString(String key) { + assert localization != null; + return localization.getString(key, locale); + } } diff --git a/app/src/main/java/org/toop/local/AppSettings.java b/app/src/main/java/org/toop/local/AppSettings.java new file mode 100644 index 0000000..5bc8fe5 --- /dev/null +++ b/app/src/main/java/org/toop/local/AppSettings.java @@ -0,0 +1,50 @@ +package org.toop.local; + +import org.toop.app.App; +import org.toop.framework.asset.resources.SettingsAsset; +import org.toop.framework.audio.events.AudioEvents; +import org.toop.framework.eventbus.EventFlow; +import org.toop.framework.settings.Settings; + +import java.io.File; +import java.util.Locale; + +public class AppSettings { + + private SettingsAsset settingsAsset; + + public void applySettings() { + SettingsAsset settings = getPath(); + if (!settings.isLoaded()) { + settings.load(); + } + Settings settingsData = settings.getContent(); + + AppContext.setLocale(Locale.of(settingsData.locale)); + App.setFullscreen(settingsData.fullScreen); + new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(settingsData.volume)).asyncPostEvent(); + + } + + public SettingsAsset getPath() { + if (this.settingsAsset == null) { + String os = System.getProperty("os.name").toLowerCase(); + String basePath; + + if (os.contains("win")) { + basePath = System.getenv("APPDATA"); + if (basePath == null) { + basePath = System.getProperty("user.home"); + } + } else if (os.contains("mac")) { + basePath = System.getProperty("user.home") + "/Library/Application Support"; + } else { + basePath = System.getProperty("user.home") + "/.config"; + } + + File settingsFile = new File(basePath + File.separator + "ISY1" + File.separator + "settings.json"); + this.settingsAsset = new SettingsAsset(settingsFile); + } + return this.settingsAsset; + } +} diff --git a/app/src/main/resources/assets/audio/music/gladius.mp3 b/app/src/main/resources/assets/audio/music/gladius.mp3 new file mode 100644 index 0000000..a6717be Binary files /dev/null and b/app/src/main/resources/assets/audio/music/gladius.mp3 differ diff --git a/app/src/main/resources/assets/image/lowpoly.png b/app/src/main/resources/assets/image/lowpoly.png deleted file mode 100644 index 6565080..0000000 Binary files a/app/src/main/resources/assets/image/lowpoly.png and /dev/null differ diff --git a/app/src/main/resources/assets/localization/localization_ar.properties b/app/src/main/resources/assets/localization/localization_ar.properties new file mode 100644 index 0000000..205b9e5 --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_ar.properties @@ -0,0 +1,47 @@ +ai=\u0627\u0644\u0630\u0643\u0627\u0621 \u0627\u0644\u0635\u0646\u0627\u0639\u064a +appTitle=\u0645\u062e\u062a\u0627\u0631 \u0623\u0644\u0639\u0627\u0628 ISY +back=\u0631\u062c\u0648\u0639 +computer=\u0627\u0644\u062d\u0627\u0633\u0648\u0628 +computerDifficulty=\u0635\u0639\u0648\u0628\u0629 \u0627\u0644\u062d\u0627\u0633\u0648\u0628 +connect=\u0627\u062a\u0635\u0644 +credits=\u0627\u0644\u0634\u0643\u0631 \u0648\u0627\u0644\u062a\u0642\u062f\u064a\u0631 +developers=\u0627\u0644\u0645\u0637\u0648\u0631\u0648\u0646 +fullscreen=\u0643\u0627\u0645\u0644 \u0627\u0644\u0634\u0627\u0634\u0629 +hint=\u062a\u0644\u0645\u064a\u062d +human=\u0627\u0644\u0625\u0646\u0633\u0627\u0646 +language=\u0627\u0644\u0644\u063a\u0629 +local=\u0645\u062d\u0644\u064a +localization=\u062a\u0648\u0645\u064a\u0645 \u0627\u0644\u0644\u063a\u0629 +mergeCommander=\u0642\u0627\u0626\u062f \u0627\u0644\u062f\u0645\u062c +moralSupport=\u062f\u0639\u0645 \u0645\u0639\u0646\u0648\u064a +no=\u0644\u0627 +opengl=OpenGL +options=\u0627\u0644\u062e\u064a\u0627\u0631\u0627\u062a +othello=\u0623\u0648\u062a\u064a\u0644\u0648 +playerName=\u0627\u0633\u0645 \u0627\u0644\u0644\u0627\u0639\u0628 +productOwner=\u0645\u0627\u0644\u0643 \u0627\u0644\u0645\u0646\u062a\u062c +quit=\u062e\u0631\u0648\u062c +quitSure=\u0647\u0644 \u0623\u0646\u062a \u0645\u062a\u0623\u0643\u062f\u061f +scrumMaster=\u0645\u062f\u064a\u0631 \u0627\u0644\u0633\u0643\u0631\u0645 +server=\u062e\u0627\u062f\u0645 +serverIP=IP \u0627\u0644\u062e\u0627\u062f\u0645 +serverPort=\u0645\u0646\u0641\u0630 \u0627\u0644\u062e\u0627\u062f\u0645 +start=\u0627\u0628\u062f\u0623 +tictactoe=\u062a\u064a\u0643 \u062a\u0627\u0643 \u062a\u0648 +volume=\u0627\u0644\u0635\u0648\u062a +windowed=\u0646\u0627\u0641\u0630\u064a +yes=\u0646\u0639\u0645 + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 +chinese=\u4e2d\u6587 (\u0627\u0644\u0635\u064a\u0646\u064a\u0629) +dutch=Nederlands (\u0627\u0644\u0647\u0648\u0644\u0646\u062f\u064a\u0629) +english=English (\u0627\u0644\u0625\u0646\u062c\u0644\u064a\u0632\u064a\u0629) +french=Fran\u00e7ais (\u0627\u0644\u0641\u0631\u0646\u0633\u064a\u0629) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u0627\u0644\u062c\u0648\u0631\u062c\u064a\u0629) +german=Deutsch (\u0627\u0644\u0623\u0644\u0645\u0627\u0646\u064a\u0629) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u0627\u0644\u0647\u0646\u062f\u064a\u0629) +italian=Italiano (\u0627\u0644\u0625\u064a\u0637\u0627\u0644\u064a\u0629) +japanese=\u65e5\u672c\u8a9e (\u0627\u0644\u064a\u0627\u0628\u0627\u0646\u064a\u0629) +korean=\ud55c\uad6d\uc5b4 (\u0627\u0644\u0643\u0648\u0631\u064a\u0629) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u0627\u0644\u0631\u0648\u0633\u064a\u0629) +spanish=Espa\u00f1ol (\u0627\u0644\u0625\u0633\u0628\u0627\u0646\u064a\u0629) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_de.properties b/app/src/main/resources/assets/localization/localization_de.properties index e38762e..e59e01a 100644 --- a/app/src/main/resources/assets/localization/localization_de.properties +++ b/app/src/main/resources/assets/localization/localization_de.properties @@ -1,40 +1,47 @@ -# Window title -windowTitle=ISY Spiele-Auswahl +ai=K\u00fcnstliche Intelligenz +appTitle=ISY Spieleauswahl +back=Zur\u00fcck +computer=Computer +computerDifficulty=Computerschwierigkeit +connect=Verbinden +credits=Credits +developers=Entwickler +fullscreen=Vollbild +hint=Hinweis +human=Mensch +language=Sprache +local=Lokal +localization=Lokalisierung +mergeCommander=Merge-Kommandant +moralSupport=Mentale Unterst\u00fctzung +no=Nein +opengl=OpenGL +options=Optionen +othello=Othello +playerName=Spielername +productOwner=Produktverantwortlicher +quit=Beenden +quitSure=Bist du dir sicher? +scrumMaster=Scrum Master +server=Server +serverIP=Server-IP +serverPort=Server-Port +start=Start +tictactoe=Tic Tac Toe +volume=Lautst\u00e4rke +windowed=Fenstermodus +yes=Ja -# Main Menu buttons -mainMenuSelectTicTacToe=Tic Tac Toe -mainMenuSelectReversi=Reversi -mainMenuSelectSudoku=Sudoku -mainMenuSelectBattleship=Flottenman\u00F6ver -mainMenuSelectOther=Andere -mainMenuSelectCredits=Credits -mainMenuSelectOptions=Optionen -mainMenuSelectQuit=Beenden - -# Quit Menu text and buttons -quitMenuTextSure=Bist du sicher? -quitMenuButtonYes=Ja -quitMenuButtonNo=Nein - -# Language menu -languageChangeText=Sprache w\u00E4hlen. -languageEnglish=Englisch -languageDutch=Niederl\u00E4ndisch -languageGerman=Deutsch -languageFrench=Franz\u00F6sisch -languageItalian=Italienisch -languageSpanish=Spanisch -languageChinese=Chinesisch - -# Game select menu -gameSelectMenuLocal=Lokal -gameSelectMenuOnline=Online -gameSelectMenuEnterIP=Gib hier deine IP-Adresse ein: - -# Game Menu -gameMenuHint=Tipp -gameMenuBack=Zur\u00FCck - - -# Options menu -optionsMenuLabelSelectLanguage=Sprache: \ No newline at end of file +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabisch) +chinese=\u4e2d\u6587 (Chinesisch) +dutch=Nederlands (Niederl\u00e4ndisch) +english=English (Englisch) +french=Fran\u00e7ais (Franz\u00f6sisch) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgisch) +german=Deutsch +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi) +italian=Italiano (Italienisch) +japanese=\u65e5\u672c\u8a9e (Japanisch) +korean=\ud55c\uad6d\uc5b4 (Koreanisch) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russisch) +spanish=Espa\u00f1ol (Spanisch) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_en.properties b/app/src/main/resources/assets/localization/localization_en.properties new file mode 100644 index 0000000..1221b03 --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_en.properties @@ -0,0 +1,47 @@ +ai=Artificial Intelligence +appTitle=ISY Games Selector +back=Back +computer=Computer +computerDifficulty=Computer Difficulty +connect=Connect +credits=Credits +developers=Developers +fullscreen=Fullscreen +hint=Hint +human=Human +language=Language +local=Local +localization=Localization +mergeCommander=Merge Commander +moralSupport=Moral Support +no=No +opengl=OpenGL +options=Options +othello=Othello +playerName=Player Name +productOwner=Product Owner +quit=Quit +quitSure=Are you sure? +scrumMaster=Scrum Master +server=Server +serverIP=Server IP +serverPort=Server Port +start=Start +tictactoe=Tic Tac Toe +volume=Volume +windowed=Windowed +yes=Yes + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic) +chinese=\u4e2d\u6587 (Chinese) +dutch=Nederlands (Dutch) +english=English +french=Fran\u00e7ais (French) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgian) +german=Deutsch (German) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi) +italian=Italiano (Italian) +japanese=\u65e5\u672c\u8a9e (Japanese) +korean=\ud55c\uad6d\uc5b4 (Korean) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russian) +spanish=Espa\u00f1ol (Spanish) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_en_US.properties b/app/src/main/resources/assets/localization/localization_en_US.properties deleted file mode 100644 index 2d5da19..0000000 --- a/app/src/main/resources/assets/localization/localization_en_US.properties +++ /dev/null @@ -1,39 +0,0 @@ -# Window title -windowTitle=ISY Games Selector - -# Main Menu buttons -mainMenuSelectTicTacToe=Tic Tac Toe -mainMenuSelectReversi=Reversi -mainMenuSelectSudoku=Sudoku -mainMenuSelectBattleship=Battleship -mainMenuSelectOther=Other -mainMenuSelectCredits=Credits -mainMenuSelectOptions=Options -mainMenuSelectQuit=Quit - -# Quit Menu text and buttons -quitMenuTextSure=Are you sure? -quitMenuButtonYes=Yes -quitMenuButtonNo=No - -# Language menu -languageChangeText=Choose a language. -languageEnglish=English -languageDutch=Dutch -languageGerman=German -languageFrench=French -languageItalian=Italian -languageSpanish=Spanish -languageChinese=Chinese - -# Game select menu -gameSelectMenuLocal=Local -gameSelectMenuOnline=Online -gameSelectMenuEnterIP=Enter your IP address here: - -# Game Menu -gameMenuHint=Hint -gameMenuBack=Back - -# Options menu -optionsMenuLabelSelectLanguage=Language: \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_es.properties b/app/src/main/resources/assets/localization/localization_es.properties index c6c0648..34b9848 100644 --- a/app/src/main/resources/assets/localization/localization_es.properties +++ b/app/src/main/resources/assets/localization/localization_es.properties @@ -1,40 +1,47 @@ -# Window title -windowTitle=Selector de juegos ISY +ai=Inteligencia Artificial +appTitle=Selector de Juegos ISY +back=Atr\u00e1s +computer=Ordenador +computerDifficulty=Dificultad del Ordenador +connect=Conectar +credits=Cr\u00e9ditos +developers=Desarrolladores +fullscreen=Pantalla completa +hint=Pista +human=Humano +language=Idioma +local=Local +localization=Localizaci\u00f3n +mergeCommander=Comandante de Merge +moralSupport=Apoyo moral +no=No +opengl=OpenGL +options=Opciones +othello=Othello +playerName=Nombre del Jugador +productOwner=Propietario del Producto +quit=Salir +quitSure=\u00BFAst\u00e1s seguro? +scrumMaster=Scrum Master +server=Servidor +serverIP=Servidor-IP +serverPort=Servidor-puerto +start=Iniciar +tictactoe=Tres en Raya +volume=Volumen +windowed=Ventana +yes=S\u00ed -# Main Menu buttons -mainMenuSelectTicTacToe=Tres en raya -mainMenuSelectReversi=Reversi -mainMenuSelectSudoku=Sudoku -mainMenuSelectBattleship=Batalla naval -mainMenuSelectOther=Otros -mainMenuSelectCredits=Cr\u00E9ditos -mainMenuSelectOptions=Opciones -mainMenuSelectQuit=Salir - -# Quit Menu text and buttons -quitMenuTextSure=\u00BFEst\u00E1s seguro? -quitMenuButtonYes=S\u00ED -quitMenuButtonNo=No - -# Language menu -languageChangeText=Elige un idioma. -languageEnglish=Ingl\u00E9s -languageDutch=Neerland\u00E9s -languageGerman=Alem\u00E1n -languageFrench=Franc\u00E9s -languageItalian=Italiano -languageSpanish=Espa\u00F1ol -languageChinese=Chino - -# Game select menu -gameSelectMenuLocal=Local -gameSelectMenuOnline=En l\u00EDnea -gameSelectMenuEnterIP=Introduce aqu\u00ED tu direcci\u00F3n IP: - -# Game Menu -gameMenuHint=Pista -gameMenuBack=Atr\u00E1s - - -# Options menu -optionsMenuLabelSelectLanguage=Idioma: \ No newline at end of file +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Ar\u00e1bigo) +chinese=\u4e2d\u6587 (Chino) +dutch=Nederlands (Neerland\u00e9s) +english=English (Ingl\u00e9s) +french=Fran\u00e7ais (Franc\u00e9s) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgiano) +german=Deutsch (Alem\u00e1n) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi) +italian=Italiano (Italiano) +japanese=\u65e5\u672c\u8a9e (Japon\u00e9s) +korean=\ud55c\uad6d\uc5b4 (Coreano) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Ruso) +spanish=Espa\u00f1ol \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_fr.properties b/app/src/main/resources/assets/localization/localization_fr.properties index 6b71c6e..1102a68 100644 --- a/app/src/main/resources/assets/localization/localization_fr.properties +++ b/app/src/main/resources/assets/localization/localization_fr.properties @@ -1,40 +1,47 @@ -# Window title -windowTitle=S\u00E9lecteur de jeux ISY +ai=Intelligence Artificielle +appTitle=S\u00e9lecteur de Jeux ISY +back=Retour +computer=Ordinateur +computerDifficulty=Difficult\u00e9 de l'Ordinateur +connect=Connecter +credits=Cr\u00e9dits +developers=D\u00e9veloppeurs +fullscreen=Plein \u00e9cran +hint=Indice +human=Humain +language=Langue +local=Local +localization=Localisation +mergeCommander=Commandant de Merge +moralSupport=Soutien moral +no=Non +opengl=OpenGL +options=Options +othello=Othello +playerName=Nom du joueur +productOwner=Responsable du produit +quit=Quitter +quitSure=Es-tu s\u00fbr ? +scrumMaster=Scrum Master +server=Serveur +serverIP=Serveur-IP +serverPort=Serveur-Port +start=D\u00e9marrer +tictactoe=Morpion +volume=Volume +windowed=Fen\u00eatre +yes=Oui -# Main Menu buttons -mainMenuSelectTicTacToe=Morpion -mainMenuSelectReversi=Reversi -mainMenuSelectSudoku=Sudoku -mainMenuSelectBattleship=Bataille navale -mainMenuSelectOther=Autres -mainMenuSelectCredits=Cr\u00E9dits -mainMenuSelectOptions=Options -mainMenuSelectQuit=Quitter - -# Quit Menu text and buttons -quitMenuTextSure=\u00CAtes-vous s\u00FBr? -quitMenuButtonYes=Oui -quitMenuButtonNo=Non - -# Language menu -languageChangeText=Choisissez une langue. -languageEnglish=Anglais -languageDutch=N\u00E9erlandais -languageGerman=Allemand -languageFrench=Fran\u00E7ais -languageItalian=Italien -languageSpanish=Espagnol -languageChinese=Chinois - -# Game select menu -gameSelectMenuLocal=Local -gameSelectMenuOnline=En ligne -gameSelectMenuEnterIP=Entrez votre adresse IP ici : - -# Game Menu -gameMenuHint=Indice -gameMenuBack=Retour - - -# Options menu -optionsMenuLabelSelectLanguage=Langue: \ No newline at end of file +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabe) +chinese=\u4e2d\u6587 (Chinois) +dutch=Nederlands (N\u00e9erlandais) +english=English (Anglais) +french=Fran\u00e7ais +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (G\u00e9orgien) +german=Deutsch (Allemand) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi) +italian=Italiano (Italien) +japanese=\u65e5\u672c\u8a9e (Japonais) +korean=\ud55c\uad6d\uc5b4 (Cor\u00e9en) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russe) +spanish=Espa\u00f1ol (Espagnol) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_hi.properties b/app/src/main/resources/assets/localization/localization_hi.properties new file mode 100644 index 0000000..119b5f2 --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_hi.properties @@ -0,0 +1,47 @@ +ai=\u092a\u094d\u0930\u0924\u093f\u092a\u094d\u0930\u0923\u093e\u0924\u094d\u092e\u093e\u0928 \u092a\u094d\u0930\u092c\u094d\u0939\u093e\u0935\u0924\u094d\u0924\u093e +appTitle=ISY \u0917\u0947\u092e \u0938\u0947\u0932\u0947\u0915\u094d\u091f\u0930 +back=\u092a\u093f\u091a\u093e\u0932 +computer=\u0915\u092e\u092a\u094d\u092f\u0942\u091f\u0930 +computerDifficulty=\u0915\u092e\u092a\u094d\u092f\u0942\u091f\u0930 \u092a\u094d\u0930\u092f\u093e\u0938 +connect=\u091c\u0942\u0921\u094d\u0921 \u0915\u0930\u0947\u0902 +credits=\u0916\u094d\u092f\u093e\u0924\u0947 +developers=\u0935\u093f\u0915\u0938\u093f\u0915\u0930 +fullscreen=\u092a\u0942\u0930\u094d\u0923 \u0938\u0915\u0940\u0928\u093e +hint=\u0938\u0902\u0917\u094d\u0917 +human=\u092e\u093e\u0928\u0935 +language=\u092d\u093e\u0937\u093e +local=\u0938\u094d\u0925\u093e\u0928\u093f\u092f +localization=\u0938\u094d\u0925\u093e\u0928\u093f\u092f\u0915\u0930\u0923 +mergeCommander=\u092e\u0930\u094d\u091c \u0915\u092e\u0902\u0921\u0930 +moralSupport=\u0928\u094d\u092e\u093e\u0928\u093f\u0915 \u0938\u092e\u0930\u094d\u0925\u0928 +no=\u0928\u0939\u0940\u0902 +opengl=OpenGL +options=\u0935\u093f\u0915\u0932\u094d\u092a +othello=\u0913\u0925\u0940\u0932\u094b +playerName=\u0915\u0941\u0930\u093e\u0930\u0940 \u0928\u093e\u092e +productOwner=\u0906\u092f\u0947\u0915\u093e \u092e\u093e\u0932\u093f\u0915 +quit=\u0938\u094e\u091c\u094d +quitSure=\u0915\u094d\u092f\u093e \u0915\u094d\u092f\u093e \u091f\u0940\u091f \u0939\u0948\u0902? +scrumMaster=\u0938\u094d\u0915\u094d\u0930\u0941\u092e \u092e\u093e\u0938\u094d\u091f\u0930 +server=\u0938\u0930\u094d\u0935\u0930 +serverIP=\u0938\u0930\u094d\u0935\u0930 IP +serverPort=\u0938\u0930\u094d\u0935\u0930 \u092a\u094b\u0930\u094d\u091f +start=\u092b\u093f\u0930\u0942 +tictactoe=\u091f\u093f\u0915 \u091f\u0948\u0915 \u091f\u094b +volume=\u0935\u0949\u0932\u094d\u092f\u0947\u092e +windowed=\u0915\u094d\u0930\u094d\u0939 \u092e\u0947\u0902 +yes=\u0939\u093e\u0907 + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0905\u0930\u092c\u0940) +chinese=\u4e2d\u6587 (\u091a\u0940\u0928\u0940) +dutch=Nederlands (\u0921\u091a) +english=English (\u0905\u0902\u0917\u094d\u0930\u0947\u091c\u0940) +french=Fran\u00e7ais (\u092b\u094d\u0930\u0947\u0902\u091a) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u091c\u094d\u091c\u094b\u0930\u094d\u091c\u093f\u092f\u0928) +german=Deutsch (\u091c\u0930\u094d\u092e\u0928) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 +italian=Italiano (\u0907\u091f\u093e\u0932\u093f\u092f\u0928) +japanese=\u65e5\u672c\u8a9e (\u091c\u093e\u092a\u093e\u0928\u0940) +korean=\ud55c\uad6d\uc5b4 (\u0915\u094b\u0930\u093f\u092f\u0928) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u0930\u0942\u0938\u0940) +spanish=Espa\u00f1ol (\u0938\u094d\u092a\u0947\u0928\u093f\u0936) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_it.properties b/app/src/main/resources/assets/localization/localization_it.properties index c608a87..a23cfde 100644 --- a/app/src/main/resources/assets/localization/localization_it.properties +++ b/app/src/main/resources/assets/localization/localization_it.properties @@ -1,41 +1,47 @@ -# Window title -windowTitle=Selettore giochi ISY +ai=Intelligenza Artificiale +appTitle=Selettore di Giochi ISY +back=Indietro +computer=Computer +computerDifficulty=Difficolt\u00e0 del computer +connect=Connetti +credits=Crediti +developers=Sviluppatori +fullscreen=Schermo intero +hint=Suggerimento +human=Umano +language=Lingua +local=Locale +localization=Localizzazione +mergeCommander=Comandante di Merge +moralSupport=Supporto morale +no=No +opengl=OpenGL +options=Opzioni +othello=Othello +playerName=Nome del giocatore +productOwner=Proprietario del prodotto +quit=Uscire +quitSure=Sei sicuro? +scrumMaster=Scrum Master +server=Server +serverIP=Server-IP +serverPort=Porta del server +start=Inizia +tictactoe=Tic Tac Toe +volume=Volume +windowed=Finestra +yes=S\u00ec -# Main Menu buttons -mainMenuSelectTicTacToe=Tris -mainMenuSelectReversi=Reversi -mainMenuSelectSudoku=Sudoku -mainMenuSelectBattleship=Battaglia navale -mainMenuSelectOther=Altro -mainMenuSelectCredits=Crediti -mainMenuSelectOptions=Opzioni -mainMenuSelectQuit=Esci - -# Quit Menu text and buttons -quitMenuTextSure=Sei sicuro? -quitMenuButtonYes=S\u00EC -quitMenuButtonNo=No - -# Language menu -languageChangeText=Scegli una lingua. -languageEnglish=Inglese -languageDutch=Olandese -languageGerman=Tedesco -languageFrench=Francese -languageItalian=Italiano -languageSpanish=Spagnolo -languageChinese=Cinese - -# Game select menu -gameSelectMenuLocal=Locale -gameSelectMenuOnline=Online -gameSelectMenuEnterIP=Inserisci qui il tuo indirizzo IP: - -# Game Menu -gameMenuHint=Suggerimento -gameMenuBack=Indietro - - - -# Options menu -optionsMenuLabelSelectLanguage=Lingua: \ No newline at end of file +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabo) +chinese=\u4e2d\u6587 (Cinese) +dutch=Nederlands (Olandese) +english=English (Inglese) +french=Fran\u00e7ais (Francese) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgiano) +german=Deutsch (Tedesco) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi) +italian=Italiano +japanese=\u65e5\u672c\u8a9e (Giapponese) +korean=\ud55c\uad6d\uc5b4 (Coreano) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russo) +spanish=Espa\u00f1ol (Spagnolo) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_ja.properties b/app/src/main/resources/assets/localization/localization_ja.properties new file mode 100644 index 0000000..cbd4826 --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_ja.properties @@ -0,0 +1,47 @@ +ai=\u4eba\u5de5\u77e5\u80fd +appTitle=ISY \u30b2\u30fc\u30e0\u30bb\u30ec\u30af\u30bf\u30fc +back=\u623b\u308b +computer=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc +computerDifficulty=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u30fc\u96e3\u6613\u5ea6 +connect=\u63a5\u7d9a +credits=\u30af\u30ec\u30b8\u30c3\u30c8 +developers=\u958b\u767a\u8005 +fullscreen=\u5168\u753b\u9762 +hint=\u30d2\u30f3\u30c8 +human=\u4eba\u9593 +language=\u8a00\u8a9e +local=\u5730\u57df +localization=\u30ed\u30fc\u30ab\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3 +mergeCommander=\u30de\u30fc\u30b8\u30b3\u30de\u30f3\u30c0\u30fc +moralSupport=\u6c17\u529b\u652f\u63f4 +no=\u3044\u3044\u3048 +opengl=OpenGL +options=\u30aa\u30d7\u30b7\u30e7\u30f3 +othello=\u30aa\u30bb\u30ed +playerName=\u30d7\u30ec\u30a4\u30e4\u30fc\u540d +productOwner=\u30d7\u30ed\u30c0\u30af\u30c8\u30aa\u30fc\u30ca\u30fc +quit=\u7d42\u4e86 +quitSure=\u672c\u5f53\u306b\u7d42\u4e86\u3057\u307e\u3059\u304b\uff1f +scrumMaster=\u30b9\u30af\u30e9\u30e0\u30de\u30b9\u30bf\u30fc +server=\u30b5\u30fc\u30d0\u30fc +serverIP=\u30b5\u30fc\u30d0\u30fc IP +serverPort=\u30b5\u30fc\u30d0\u30fc \u30dd\u30fc\u30c8 +start=\u59cb\u307e\u308a +tictactoe=\u30bf\u30a4\u30af\u30bf\u30c3\u30c8\u30c8\u30a6 +volume=\u30dc\u30ea\u30e5\u30fc\u30e0 +windowed=\u30a6\u30a3\u30f3\u30c9\u30a6 +yes=\u306f\u3044 + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u30a2\u30e9\u30d3\u30a2\u8a9e) +chinese=\u4e2d\u6587 (\u4e2d\u6587) +dutch=Nederlands (\u30aa\u30e9\u30f3\u30c0\u8a9e) +english=English (\u82f1\u8a9e) +french=Fran\u00e7ais (\u30d5\u30e9\u30f3\u30b9\u8a9e) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u30b0\u30eb\u30b8\u30a2\u8a9e) +german=Deutsch (\u30c9\u30a4\u30c4\u8a9e) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u30d2\u30f3\u30c7\u30a3\u8a9e) +italian=Italiano (\u30a4\u30bf\u30ea\u30a2\u8a9e) +japanese=\u65e5\u672c\u8a9e +korean=\ud55c\uad6d\uc5b4 (\u97d3\u56fd\u8a9e) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u30ed\u30b7\u30a2\u8a9e) +spanish=Espa\u00f1ol (\u30b9\u30da\u30a4\u30f3\u8a9e) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_ka.properties b/app/src/main/resources/assets/localization/localization_ka.properties new file mode 100644 index 0000000..58087d0 --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_ka.properties @@ -0,0 +1,47 @@ +ai=\u10e1\u10d0\u10e0\u10d7\u10d5\u10d4\u10d9\u10d8 \u10d8\u10e0\u10d5\u10d5\u10e0\u10d8\u10d2\u10d4\u10d1\u10d0 +appTitle=ISY \u10d2\u10d4\u10db\u10d3\u10d8 \u10e1\u10d4\u10da\u10d4\u10ea\u10d9\u10d4\u10da\u10d0 +back=\u10db\u10d0\u10d2\u10d0\u10dc\u10d0 +computer=\u10e2\u10d0\u10db\u10d7\u10d8\u10d2\u10d3\u10d0\u10e0\u10d8 +computerDifficulty=\u10e8\u10d0\u10d5\u10d0\u10e0\u10d8 \u10e2\u10d0\u10db\u10d7\u10d8\u10d2\u10d3\u10d0\u10e0\u10d8 +connect=\u10d7\u10d0\u10db\u10d0\u10d4\u10e0\u10d7\u10d8 +credits=\u10d9\u10d0\u10e0\u10d4\u10d3\u10d0\u10e0\u10d8 +developers=\u10db\u10d0\u10e0\u10e3\u10d1\u10d7\u10d0\u10ea\u10d4\u10da\u10d8 +fullscreen=\u10e1\u10d0\u10e5\u10d8 \u10d8\u10e0\u10e2\u10d8\u10d5\u10d0\u10e0\u10d8 +hint=\u10db\u10d8\u10e0\u10d7\u10d4\u10da\u10d8 +human=\u10db\u10d4\u10db\u10d0\u10dc\u10d8 +language=\u10dc\u10d0\u10db\u10d0 +local=\u10db\u10d4\u10e0\u10d7\u10d4\u10da\u10d0\u10e0\u10d8 +localization=\u10d0\u10e1\u10d5\u10e0\u10d0\u10e2\u10d4\u10da\u10d0\u10e0\u10d8 +mergeCommander=\u10db\u10d4\u10e0\u10d7\u10d4\u10da\u10d8 \u10d9\u10d0\u10dc\u10d3\u10d0\u10e0\u10d8 +moralSupport=\u10db\u10d0\u10e0\u10d4\u10dc\u10d8 \u10d3\u10d0\u10db\u10d4\u10d4\u10da\u10d4\u10da\u10d0 +no=\u10dc\u10d4 +opengl=OpenGL +options=\u10e3\u10e0\u10d5\u10d4\u10da\u10d8 +othello=\u10d0\u10e2\u10e5\u10d4\u10da\u10d8 +playerName=\u10dc\u10d0\u10e0\u10d4 \u10db\u10d0\u10e5\u10d3\u10d0\u10e0\u10d8 +productOwner=\u10db\u10d0\u10e0\u10e3\u10d1\u10d7\u10d0\u10e0\u10d8 \u10db\u10d0\u10dc\u10e2\u10d0\u10e0\u10d8 +quit=\u10db\u10d0\u10e0\u10d7\u10d4\u10da\u10d8 +quitSure=\u10ec\u10d7\u10d0 \u10db\u10d0\u10e0 \u10db\u10d0\u10e0\u10d7\u10d4\u10da\u10d8? +scrumMaster=\u10e1\u10e0\u10d9\u10d3 \u10db\u10d0\u10e1\u10d7\u10d0\u10e0\u10d8 +server=\u10e1\u10d0\u10e0\u10d7\u10d4\u10e0\u10d8 +serverIP=\u10e1\u10d0\u10e0\u10d7\u10d4\u10e0\u10d8 IP +serverPort=\u10e1\u10d0\u10e0\u10d7\u10d4\u10e0\u10d8 \u10e2\u10dd\u10e0\u10d7\u10d0 +start=\u10e0\u10d0\u10d3\u10d4\u10e1 +tictactoe=\u10e2\u10d8\u10d9\u10d8 \u10e2\u10d8\u10e9\u10d8 \u10e2\u10d8 +volume=\u10d7\u10d0\u10e7\u10d8 +windowed=\u10e1\u10d0\u10db\u10d7\u10d8 +yes=\u10d3\u10d0 + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u10d0\u10e0\u10d0\u10d1\u10d8\u10d1\u10d3\u10d3\u10d4\u10da\u10d8) +chinese=\u4e2d\u6587 (\u10d9\u10d8\u10e2\u10d8\u10e1\u10d8) +dutch=Nederlands (\u10db\u10d4\u10d3\u10d0\u10da\u10d0\u10dc\u10d3\u10d8) +english=English (\u10d2\u10d0\u10e0\u10d7\u10d8\u10e1\u10d8) +french=Fran\u00e7ais (\u10e4\u10e0\u10d0\u10dc\u10d9\u10e3\u10e1\u10d8) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 +german=Deutsch (\u10db\u10d4\u10db\u10d4\u10e6\u10d8) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u10f0\u10d4\u10dc\u10d3\u10d8) +italian=Italiano (\u10d7\u10d4\u10ea\u10d0\u10da\u10d8) +japanese=\u65e5\u672c\u8a9e (\u10d9\u10d0\u10e7\u10d0\u10dc\u10d8) +korean=\ud55c\uad6d\uc5b4 (\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u10e0\u10e3\u10e1\u10e1\u10d8\u10d5\u10d4\u10d1\u10d8) +spanish=Espa\u00f1ol (\u10e1\u10da\u10d0\u10dc\u10d8) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_ko.properties b/app/src/main/resources/assets/localization/localization_ko.properties new file mode 100644 index 0000000..1f90d2f --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_ko.properties @@ -0,0 +1,47 @@ +ai=\uc778\uacf5 \uc9c0\ub2a5 +appTitle=ISY \uac8c\uc784 \uc120\ud0dd\uae30 +back=\ub4a4\ub85c +computer=\uce74\ud14c\uae4c +computerDifficulty=\uce74\ud14c\uae4c \ub2e8\uacc4 +connect=\uc5f0\uacb0 +credits=\uac10\uc0ac +developers=\uac1c\ubc1c\uc790 +fullscreen=\uc804\uccb4 \ud654\uba74 +hint=\ud78c\ud2b8 +human=\uc778\uac04 +language=\uc5b8\uc5b4 +local=\ub85c\uceec +localization=\uc5b8\uc5b4\ud654 +mergeCommander=\uba54\uc9c0 \ucea0\ub9ac\ub354 +moralSupport=\uc815\uc2e0\uc801 \uc9c0\uc6d0 +no=\uc544\ub2c8\uc624 +opengl=OpenGL +options=\uc635\uc158 +othello=\uc624\ud14c\ub85c +playerName=\ud50c\ub808\uc774\uc5b4 \uc774\ub984 +productOwner=\uc81c\ud488 \uad00\ub9ac\uc790 +quit=\uc885\ub8cc +quitSure=\uc815\ub9d0 \uc885\ub8cc\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c? +scrumMaster=\uc2a4\ud06c\ub7fc \ub9c8\uc2a4\ud130 +server=\uc11c\ubc84 +serverIP=\uc11c\ubc84 IP +serverPort=\uc11c\ubc84 \ud3ec\ud2b8 +start=\uc2dc\uc791 +tictactoe=\ud2f0\ud06c\ud0d0\ud1a0 +volume=\ubcf4\ub7ec\uc6b4 +windowed=\ucc3d \ubaa8\ub4dc +yes=\ub124 + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0639\u0631\u0628\u064a\u0629) +chinese=\u4e2d\u6587 (\u4e2d\u6587) +dutch=Nederlands (\ub3c4\ucc99) +english=English (\uc601\uad6d\uc5b4) +french=Fran\u00e7ais (\ud504\ub791\uc81c\uc2a4\ucf54) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\uac8c\uc774\uc874) +german=Deutsch (\ub3c4\ucf54) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\ud567\ub9ac) +italian=Italiano (\uc774\ud0c0\ub9ac\uc5b4\ub098) +japanese=\u65e5\u672c\u8a9e (\uc65c\uc790\ub9ac\uc5b4) +korean=\ud55c\uad6d\uc5b4 +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\ub85c\uc6b0\uc2a4\uc544\uc774\ucf58) +spanish=Espa\u00f1ol (\uc2a4\ud398\ub974\uc2a4\uc544\uc774\ucf58) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_nl.properties b/app/src/main/resources/assets/localization/localization_nl.properties index 2f3cf82..57ceeae 100644 --- a/app/src/main/resources/assets/localization/localization_nl.properties +++ b/app/src/main/resources/assets/localization/localization_nl.properties @@ -1,40 +1,47 @@ -# Window title -windowTitle=ISY Spellen Kiezer +ai=Kunstmatige Intelligentie +appTitle=ISY Spel Kiezer +back=Terug +computer=Computer +computerDifficulty=Computermoeilijkheid +connect=Verbinden +credits=Credits +developers=Ontwikkelaars +fullscreen=Volledig scherm +hint=Hint +human=Mens +language=Taal +local=Lokaal +localization=Lokalisatie +mergeCommander=Merge-commandant +moralSupport=Moraalsteun +no=Nee +opengl=OpenGL +options=Opties +othello=Othello +playerName=Spelernaam +productOwner=Producteigenaar +quit=Afsluiten +quitSure=Weet je het zeker? +scrumMaster=Scrum Master +server=Server +serverIP=Server-IP +serverPort=Serverpoort +start=Start +tictactoe=Boter Kaas en Eieren +volume=Volume +windowed=Venstermodus +yes=Ja -# Main Menu buttons -mainMenuSelectTicTacToe=Boter Kaas En Eieren -mainMenuSelectReversi=Reversi -mainMenuSelectSudoku=Sudoku -mainMenuSelectBattleship=Zeeslag -mainMenuSelectOther=Anders -mainMenuSelectCredits=Credits -mainMenuSelectOptions=Opties -mainMenuSelectQuit=Afsluiten - -# Quit Menu text and buttons -quitMenuTextSure=Weet je het zeker? -quitMenuButtonYes=Ja -quitMenuButtonNo=Nee - -# Language menu -languageChangeText=Kies een taal. -languageEnglish=Engels -languageDutch=Nederlands -languageGerman=Duits -languageFrench=Frans -languageItalian=Italiaans -languageSpanish=Spaans -languageChinese=Chinees - -# Game select menu -gameSelectMenuLocal=Lokaal -gameSelectMenuOnline=Online -gameSelectMenuEnterIP=Voer hier je IP-adres in: - -# Game Menu -gameMenuHint=Hint -gameMenuBack=Terug - - -# Options menu -optionsMenuLabelSelectLanguage=Taal: \ No newline at end of file +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabisch) +chinese=\u4e2d\u6587 (Chinees) +dutch=Nederlands +english=English (Engels) +french=Fran\u00e7ais (Frans) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (Georgisch) +german=Deutsch (Duits) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (Hindi) +italian=Italiano (Italiaans) +japanese=\u65e5\u672c\u8a9e (Japans) +korean=\ud55c\uad6d\uc5b4 (Koreaans) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russisch) +spanish=Espa\u00f1ol (Spaans) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_ru.properties b/app/src/main/resources/assets/localization/localization_ru.properties new file mode 100644 index 0000000..12d1094 --- /dev/null +++ b/app/src/main/resources/assets/localization/localization_ru.properties @@ -0,0 +1,47 @@ +ai=\u0418\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442 +appTitle=ISY \u0412\u044b\u0431\u043e\u0440 \u0438\u0433\u0440 +back=\u041d\u0430\u0437\u0430\u0434 +computer=\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 +computerDifficulty=\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430 +connect=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f +credits=\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438 +developers=\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 +fullscreen=\u041f\u043e\u043b\u043d\u043e\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c +hint=\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430 +human=\u0427\u0435\u043b\u043e\u0432\u0435\u043a +language=\u042f\u0437\u044b\u043a +local=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 +localization=\u041b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f +mergeCommander=\u041a\u043e\u043c\u0430\u043d\u0434\u0435\u0440 \u0441\u043b\u0438\u044f\u043d\u0438\u044f +moralSupport=\u041c\u043e\u0440\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 +no=\u041d\u0435\u0442 +opengl=OpenGL +options=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +othello=\u041e\u0442\u0435\u043b\u043b\u043e +playerName=\u0418\u043c\u044f \u0438\u0433\u0440\u043e\u043a\u0430 +productOwner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 +quit=\u0412\u044b\u0445\u043e\u0434 +quitSure=\u0423\u0432\u0435\u0440\u0435\u043d\u044b \u043b\u0438? +scrumMaster=\u041c\u0430\u0441\u0442\u0435\u0440 Scrum +server=\u0421\u0435\u0440\u0432\u0435\u0440 +serverIP=\u0418\u043f\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +serverPort=\u041f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +start=\u0421\u0442\u0430\u0440\u0442 +tictactoe=\u041a\u0440\u0435\u0441\u0442\u0438\u043a\u0438 +volume=\u0413\u0440\u0430\u043c\u043c\u043e\u0444\u043e\u043d +windowed=\u041e\u043a\u043d\u043e +yes=\u0414\u0430 + +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0410\u0440\u0430\u0431\u0441\u043a\u0438\u0439) +chinese=\u4e2d\u6587 (\u041a\u0438\u0442\u0430\u0439\u0441\u043a\u0438\u0439) +dutch=Nederlands (\u041d\u0438\u0434\u0435\u0440\u043b\u0430\u043d\u0434\u0441\u043a\u0438\u0439) +english=English (\u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439) +french=Fran\u00e7ais (\u0424\u0440\u0430\u043d\u0446\u0443\u0437\u0441\u043a\u0438\u0439) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u0413\u0440\u0443\u0437\u0438\u043d\u0441\u043a\u0438\u0439) +german=Deutsch (\u041d\u0435\u043c\u0435\u0446\u043a\u0438\u0439) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u0425\u0438\u043d\u0434\u0438) +italian=Italiano (\u0418\u0442\u0430\u043b\u044c\u044f\u043d\u0441\u043a\u0438\u0439) +japanese=\u65e5\u672c\u8a9e (\u042f\u043f\u043e\u043d\u0441\u043a\u0438\u0439) +korean=\ud55c\uad6d\uc5b4 (\u041a\u043e\u0440\u0435\u0439\u0441\u043a\u0438\u0439) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 +spanish=Espa\u00f1ol (\u0418\u0441\u043f\u0430\u043d\u0441\u043a\u0438\u0439) \ No newline at end of file diff --git a/app/src/main/resources/assets/localization/localization_zh.properties b/app/src/main/resources/assets/localization/localization_zh.properties index 2e82178..ebff3eb 100644 --- a/app/src/main/resources/assets/localization/localization_zh.properties +++ b/app/src/main/resources/assets/localization/localization_zh.properties @@ -1,52 +1,47 @@ -# suppress inspection "LossyEncoding" for whole file -# Window title -windowTitle=ISY \u6E38\u620F\u9009\u62E9\u5668 -# ????? +ai=\u4eba\u5de5\u667a\u80fd +appTitle=ISY \u6e38\u620f\u9009\u62e9\u5668 +back=\u8fd4\u56de +computer=\u8ba1\u7b97\u673a +computerDifficulty=\u8ba1\u7b97\u673a\u96be\u5ea6 +connect=\u8fde\u63a5 +credits=\u6b23\u8d4f +developers=\u5f00\u53d1\u8005 +fullscreen=\u5168\u5c4f +hint=\u63d0\u793a +human=\u4eba +language=\u8bed\u8a00 +local=\u672c\u5730 +localization=\u6d88\u606f\u5c55\u793a / \u672c\u5730\u5316 +mergeCommander=Merge \u63a7\u4e3b +moralSupport=\u795e\u7cbe\u652f\u6301 +no=\u5426 +opengl=OpenGL +options=\u9009\u9879 +othello=Othello +playerName=\u73a9\u5bb6\u540d\u79f0 +productOwner=\u54c1\u76d8\u4ea7\u54c1\u4eba +quit=\u9000\u51fa +quitSure=\u4f60\u786e\u5b9a\u5417? +scrumMaster=Scrum \u4f1a\u5458 +server=\u670d\u52a1\u5668 +serverIP=\u670d\u52a1\u5668 IP +serverPort=\u670d\u52a1\u5668 \u7aef\u53e3 +start=\u5f00\u59cb +tictactoe=Tic Tac Toe +volume=\u97f3\u91cf +windowed=\u7a97\u53e3\u6a21\u5f0f +yes=\u662f -# Main Menu buttons -mainMenuSelectTicTacToe=\u4E95\u5B57\u68CB -# ??? -mainMenuSelectReversi=\u9ED1\u767D\u68CB -# ??? -mainMenuSelectSudoku=\u6570\u72EC -# ?? -mainMenuSelectBattleship=\u6D77\u6218\u68CB -# ??? -mainMenuSelectOther=\u5176\u4ED6 -# ?? -mainMenuSelectCredits=\u5236\u4F5C\u4EBA\u5458 -# ???? -mainMenuSelectOptions=\u9009\u9879 -# ?? -mainMenuSelectQuit=\u9000\u51FA -# ?? - -# Quit Menu text and buttons -quitMenuTextSure=\u4F60\u786E\u5B9A\u5417\uFF1F -# ????? -quitMenuButtonYes=\u662F -# ? -quitMenuButtonNo=\u5426 -# ? -# Language menu -languageChangeText=\u9009\u62E9\u4E00\u79CD\u8BED\u8A00\u3002 -languageEnglish=\u82F1\u8BED -languageDutch=\u8377\u5170\u8BED -languageGerman=\u5FB7\u8BED -languageFrench=\u6CD5\u8BED -languageItalian=\u610F\u5927\u5229\u8BED -languageSpanish=\u897F\u73ED\u7259\u8BED -languageChinese=\u4E2D\u6587 - -# Game select menu -gameSelectMenuLocal=\u672C\u5730 -gameSelectMenuOnline=\u5728\u7EBF -gameSelectMenuEnterIP=\u5728\u6B64\u8F93\u5165\u4F60\u7684IP\u5730\u5740\uFF1A - -# Game Menu -gameMenuHint=\u63D0\u793A -gameMenuBack=\u8FD4\u56DE - - -# Options menu -optionsMenuLabelSelectLanguage=\u8BED\u8A00: \ No newline at end of file +arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u963f\u62c9\u4f2f\u8bed) +chinese=\u4e2d\u6587 +dutch=Nederlands (\u8377\u5170\u8bed) +english=English (\u82f1\u8bed) +french=Fran\u00e7ais (\u6cd5\u8bed) +georgian=\u10e5\u10d0\u10e0\u10d4\u10e1\u10d8 (\u683c\u9c81\u5409\u4e9a\u8bed) +german=Deutsch (\u5fb7\u8bed) +hindi=\u0939\u093f\u0928\u094d\u0926\u0940 (\u5370\u5ea6\u8bed) +italian=Italiano (\u610f\u5927\u5229\u8bed) +japanese=\u65e5\u672c\u8a9e (\u65e5\u8bed) +korean=\ud55c\uad6d\uc5b4 (\u97e9\u8bed) +russian=\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (\u4fc4\u8bed) +spanish=Espa\u00f1ol (\u897f\u73ed\u7259\u8bed) \ No newline at end of file diff --git a/app/src/main/resources/assets/style/app.css b/app/src/main/resources/assets/style/app.css index 6bafc5b..2ca80d3 100644 --- a/app/src/main/resources/assets/style/app.css +++ b/app/src/main/resources/assets/style/app.css @@ -2,19 +2,17 @@ -fx-background-color: linear-gradient(to bottom right, #21a7b2, #8f32b9); } -.vertical_container, .horizontal_container { +.stack_container, .vertical_container, .horizontal_container { -fx-padding: 10; - -fx-alignment: center; - -fx-text-alignment: center; -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; -fx-background-insets: 0, 2; -fx-background-radius: 5; } -.text, .button, .toggle, .input { - -fx-padding: 10; +.text, .button, .toggle { + -fx-padding: 5 10 5 10; -fx-fill: white; -fx-text-fill: white; @@ -24,6 +22,7 @@ -fx-font-size: 20px; -fx-background-color: transparent; + -fx-border-color: transparent; } @@ -36,10 +35,76 @@ -fx-effect: dropshadow(gaussian, #007fff, 10, 0.5, 0, 0); } +.input { + -fx-padding: 10; + + -fx-fill: white; + -fx-text-fill: white; + + -fx-font-family: "Segoe UI", sans-serif; + -fx-font-weight: bold; + -fx-font-size: 20px; + + -fx-background-color: transparent; + + -fx-border-color: #7f7f7f; +} + .input:focused { + -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; + -fx-background-insets: 0, 2; + -fx-background-radius: 8; + -fx-border-color: transparent; +} + +.slider { + -fx-padding: 10; + + -fx-background-color: transparent; +} + +.slider .track { + -fx-background-color: linear-gradient(to right, #00ff00, #ff0000); + -fx-background-radius: 2; +} + +.slider .thumb { + -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; +} + +.choicebox { + -fx-alignment: center; -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; -fx-background-insets: 0, 2; -fx-background-radius: 8; + + -fx-border-color: transparent; +} + +.choicebox .label { + -fx-text-fill: white; + -fx-alignment: center; + -fx-padding: 5 10 5 10; +} + +.choicebox .arrow { + -fx-background-color: transparent; +} + +.choicebox .context-menu { + -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; + -fx-background-insets: 0, 2; + -fx-background-radius: 5; +} + +.choicebox .menu-item:hover { + -fx-cursor: hand; + + -fx-background-color: #ffffff11; +} + +.separator { + -fx-background-color: linear-gradient(to bottom right, orange, indigo), #1d1d1d; } \ No newline at end of file diff --git a/app/src/main/resources/assets/style/credits.css b/app/src/main/resources/assets/style/credits.css index be920fe..9786d12 100644 --- a/app/src/main/resources/assets/style/credits.css +++ b/app/src/main/resources/assets/style/credits.css @@ -6,13 +6,7 @@ -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.7), 4, 0, 2, 2); } -.button.exit-button { - -fx-background-color: #3498db; - -fx-text-fill: white; - -fx-font-size: 72px; - -fx-padding: 10 20 10 20; - -fx-background-radius: 5; -} -.button.exit-button:hover { - -fx-background-color: #2980b9; -} +.animated_credits_container { + -fx-padding: 10; + -fx-alignment: center; +} \ No newline at end of file diff --git a/app/src/main/resources/assets/style/options.css b/app/src/main/resources/assets/style/options.css new file mode 100644 index 0000000..e69de29 diff --git a/app/src/main/resources/assets/style/quit.css b/app/src/main/resources/assets/style/quit.css index b49bf21..bc0615c 100644 --- a/app/src/main/resources/assets/style/quit.css +++ b/app/src/main/resources/assets/style/quit.css @@ -1,3 +1,3 @@ -.quit_background { +.background { -fx-background-color: #0000007f; } \ No newline at end of file diff --git a/framework/pom.xml b/framework/pom.xml index b32b25c..33b077a 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -116,8 +116,14 @@ reflections 0.10.2 + + com.google.code.gson + gson + 2.10.1 + compile + - + diff --git a/framework/src/main/java/org/toop/framework/asset/ResourceManager.java b/framework/src/main/java/org/toop/framework/asset/ResourceManager.java index 8324b25..68072ef 100644 --- a/framework/src/main/java/org/toop/framework/asset/ResourceManager.java +++ b/framework/src/main/java/org/toop/framework/asset/ResourceManager.java @@ -84,22 +84,12 @@ public class ResourceManager { @SuppressWarnings("unchecked") public static T get(String name) { ResourceMeta asset = (ResourceMeta) assets.get(name); - if (asset == null) return null; + if (asset == null) { + throw new TypeNotPresentException(name, new RuntimeException(String.format("Type %s not present", name))); // TODO: Create own exception, BAM + } return asset.getResource(); } - /** - * Retrieve the resource of a given name, cast to the expected type. - * - * @param name the asset name - * @param the expected resource type - * @return the resource, or null if not found - */ - @SuppressWarnings("unchecked") - public static T get(Class type, String name) { - return type.cast(assets.get(name).getResource()); - } - /** * Retrieve all assets of a specific resource type. * @@ -134,26 +124,6 @@ public class ResourceManager { return null; } - /** - * Retrieve an asset by its name. - * - * @param name the asset name - * @return the asset, or null if not found - */ - public static ResourceMeta getByName(String name) { - return assets.get(name); - } - - /** - * Attempt to find an asset by name, returning an {@link Optional}. - * - * @param name the asset name - * @return an Optional containing the asset if found - */ - public static Optional> findByName(String name) { - return Optional.ofNullable(assets.get(name)); - } - /** * Add a new asset to the manager. * diff --git a/framework/src/main/java/org/toop/framework/asset/resources/JsonAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/JsonAsset.java new file mode 100644 index 0000000..5f9e1ba --- /dev/null +++ b/framework/src/main/java/org/toop/framework/asset/resources/JsonAsset.java @@ -0,0 +1,75 @@ +package org.toop.framework.asset.resources; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.toop.framework.asset.types.FileExtension; +import org.toop.framework.asset.types.LoadableResource; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +@FileExtension({"json"}) +public class JsonAsset extends BaseResource implements LoadableResource { + + private T content; + private Class type; + private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + public JsonAsset(File file, Class type) { + super(file); + this.type = type; + } + + @Override + public void load() { + File file = getFile(); + if (!file.exists()) { + try { + // make a new file with the declared constructor (example: settings) if it doesn't exist + content = type.getDeclaredConstructor().newInstance(); + save(); + } catch (Exception e) { + throw new RuntimeException("Could not make default JSON settings for" + file, e); + } + } else { + // else open the file, try reading it using gson, and set it to loaded + try (FileReader reader = new FileReader(file)) { + content = gson.fromJson(reader, type); + this.isLoaded = true; + } catch(Exception e) { + throw new RuntimeException("Failed to load JSON asset" + getFile(), e); + } + } + } + + @Override + public void unload() { + this.content = null; + this.isLoaded = false; + } + + public T getContent() { + if (!isLoaded()) { + load(); + } + return content; + } + + public void save() { + File file = getFile(); + File parent = file.getParentFile(); + if (parent != null && !parent.exists()) { + parent.mkdirs(); + } + try (FileWriter writer = new FileWriter(file)) { + gson.toJson(content, writer); + } catch (IOException e) { + throw new RuntimeException("Failed to save JSON asset" + getFile(), e); + } + } + + @Override + public boolean isLoaded() { + return this.isLoaded; + } +} diff --git a/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java b/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java new file mode 100644 index 0000000..f1a7fc8 --- /dev/null +++ b/framework/src/main/java/org/toop/framework/asset/resources/SettingsAsset.java @@ -0,0 +1,41 @@ +package org.toop.framework.asset.resources; + + +import org.toop.framework.settings.Settings; + +import java.io.File; +import java.util.Locale; + +public class SettingsAsset extends JsonAsset { + + public SettingsAsset(File file) { + super(file, Settings.class); + } + + public int getVolume() { + return getContent().volume; + } + + public Locale getLocale() { + return Locale.forLanguageTag(getContent().locale); + } + + public boolean getFullscreen() { + return getContent().fullScreen; + } + + public void setVolume(int volume) { + getContent().volume = volume; + save(); + } + + public void setLocale(String locale) { + getContent().locale = locale; + save(); + } + + public void setFullscreen(boolean fullscreen) { + getContent().fullScreen = fullscreen; + save(); + } +} \ No newline at end of file diff --git a/framework/src/main/java/org/toop/framework/audio/SoundManager.java b/framework/src/main/java/org/toop/framework/audio/SoundManager.java index f7fad76..6614236 100644 --- a/framework/src/main/java/org/toop/framework/audio/SoundManager.java +++ b/framework/src/main/java/org/toop/framework/audio/SoundManager.java @@ -41,7 +41,7 @@ public class SoundManager { .listen(this::handleMusicStart) .listen(this::handleVolumeChange) .listen(this::handleGetCurrentVolume) - .listen(AudioEvents.clickButton.class, _ -> { + .listen(AudioEvents.ClickButton.class, _ -> { try { playSound("medium-button-click.wav", false); } catch (UnsupportedAudioFileException | LineUnavailableException | IOException e) { @@ -69,15 +69,16 @@ public class SoundManager { } private void handleVolumeChange(AudioEvents.ChangeVolume event) { - if (event.newVolume() > 1.0) this.volume = 1.0; - else this.volume = Math.max(event.newVolume(), 0.0); + double newVolume = event.newVolume() / 100; + if (newVolume > 1.0) this.volume = 1.0; + else this.volume = Math.max(newVolume, 0.0); for (MediaPlayer mediaPlayer : this.activeMusic) { mediaPlayer.setVolume(this.volume); } } private void handleGetCurrentVolume(AudioEvents.GetCurrentVolume event) { - new EventFlow().addPostEvent(new AudioEvents.GetCurrentVolumeReponse(volume, event.snowflakeId())) + new EventFlow().addPostEvent(new AudioEvents.GetCurrentVolumeReponse(volume * 100, event.snowflakeId())) .asyncPostEvent(); } diff --git a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java index 5aceb8c..28f3d7a 100644 --- a/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java +++ b/framework/src/main/java/org/toop/framework/audio/events/AudioEvents.java @@ -37,5 +37,5 @@ public class AudioEvents extends EventsBase { return snowflakeId; } } - public record clickButton() implements EventWithoutSnowflake {} + public record ClickButton() implements EventWithoutSnowflake {} } diff --git a/framework/src/main/java/org/toop/framework/settings/Settings.java b/framework/src/main/java/org/toop/framework/settings/Settings.java new file mode 100644 index 0000000..c8ec7f2 --- /dev/null +++ b/framework/src/main/java/org/toop/framework/settings/Settings.java @@ -0,0 +1,9 @@ +package org.toop.framework.settings; + +import java.util.Locale; + +public class Settings { + public boolean fullScreen = false; + public String locale = "en"; + public int volume = 15; +} diff --git a/game/src/main/java/org/toop/game/othello/Othello.java b/game/src/main/java/org/toop/game/othello/Othello.java new file mode 100644 index 0000000..3012eac --- /dev/null +++ b/game/src/main/java/org/toop/game/othello/Othello.java @@ -0,0 +1,19 @@ +package org.toop.game.othello; + +import org.toop.game.TurnBasedGame; + +public final class Othello extends TurnBasedGame { + Othello() { + super(8, 8, 2); + } + + @Override + public Move[] getLegalMoves() { + return new Move[0]; + } + + @Override + public State play(Move move) { + return null; + } +} \ No newline at end of file diff --git a/game/src/main/java/org/toop/game/othello/OthelloAI.java b/game/src/main/java/org/toop/game/othello/OthelloAI.java new file mode 100644 index 0000000..8957387 --- /dev/null +++ b/game/src/main/java/org/toop/game/othello/OthelloAI.java @@ -0,0 +1,11 @@ +package org.toop.game.othello; + +import org.toop.game.AI; +import org.toop.game.Game; + +public final class OthelloAI extends AI { + @Override + public Game.Move findBestMove(Othello game, int depth) { + return null; + } +}