mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 19:04:49 +00:00
redesign. add: themes and text size
This commit is contained in:
@@ -2,7 +2,7 @@ package org.toop.app;
|
||||
|
||||
import org.toop.app.layer.Layer;
|
||||
import org.toop.app.layer.layers.MainLayer;
|
||||
import org.toop.app.layer.layers.QuitLayer;
|
||||
import org.toop.app.layer.layers.QuitPopup;
|
||||
import org.toop.framework.asset.ResourceManager;
|
||||
import org.toop.framework.asset.resources.CssAsset;
|
||||
import org.toop.framework.audio.events.AudioEvents;
|
||||
@@ -19,7 +19,9 @@ import java.util.Stack;
|
||||
|
||||
public final class App extends Application {
|
||||
private static Stage stage;
|
||||
private static Scene scene;
|
||||
private static StackPane root;
|
||||
|
||||
private static Stack<Layer> stack;
|
||||
private static int height;
|
||||
private static int width;
|
||||
@@ -32,17 +34,8 @@ public final class App extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
|
||||
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.<CssAsset>get("app.css").getUrl());
|
||||
|
||||
stage.setTitle(AppContext.getString("appTitle"));
|
||||
stage.setWidth(1080);
|
||||
@@ -62,7 +55,9 @@ public final class App extends Application {
|
||||
stage.show();
|
||||
|
||||
App.stage = stage;
|
||||
App.scene = scene;
|
||||
App.root = root;
|
||||
|
||||
App.stack = new Stack<>();
|
||||
|
||||
App.width = (int) stage.getWidth();
|
||||
@@ -70,6 +65,9 @@ public final class App extends Application {
|
||||
|
||||
App.isQuitting = false;
|
||||
|
||||
final AppSettings settings = new AppSettings();
|
||||
settings.applySettings();
|
||||
|
||||
new EventFlow().addPostEvent(new AudioEvents.StartBackgroundMusic()).asyncPostEvent();
|
||||
activate(new MainLayer());
|
||||
}
|
||||
@@ -102,7 +100,7 @@ public final class App extends Application {
|
||||
}
|
||||
|
||||
public static void quitPopup() {
|
||||
push(new QuitLayer());
|
||||
push(new QuitPopup());
|
||||
isQuitting = true;
|
||||
}
|
||||
|
||||
@@ -127,6 +125,19 @@ public final class App extends Application {
|
||||
reloadAll();
|
||||
}
|
||||
|
||||
public static void setStyle(String theme, String layoutSize) {
|
||||
final int stylesCount = scene.getStylesheets().size();
|
||||
|
||||
for (int i = 0; i < stylesCount; i++) {
|
||||
scene.getStylesheets().removeLast();
|
||||
}
|
||||
|
||||
scene.getStylesheets().add(ResourceManager.<CssAsset>get(theme + ".css").getUrl());
|
||||
scene.getStylesheets().add(ResourceManager.<CssAsset>get(layoutSize + ".css").getUrl());
|
||||
|
||||
reloadAll();
|
||||
}
|
||||
|
||||
public static int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@@ -1,163 +1,11 @@
|
||||
package org.toop.app.layer;
|
||||
|
||||
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.*;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.text.TextFlow;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class Container {
|
||||
public abstract Region getContainer();
|
||||
|
||||
public abstract void addNode(Node node);
|
||||
|
||||
public abstract void addNodes(Node... nodes);
|
||||
public abstract void addContainer(Container container, boolean fill);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public Text addText(String x, boolean wrap) {
|
||||
return addText("text", x, wrap);
|
||||
}
|
||||
|
||||
public Label addButton(String cssClass, String x, Runnable runnable) {
|
||||
final Label element = new Label(x);
|
||||
element.getStyleClass().add(cssClass);
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
runnable.run();
|
||||
});
|
||||
|
||||
addNode(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public Label addButton(String x, Runnable runnable) {
|
||||
return addButton("button", x, runnable);
|
||||
}
|
||||
|
||||
public Label addToggle(String cssClass, String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
|
||||
final Label element = new Label(toggled ? x2 : x1);
|
||||
element.getStyleClass().add(cssClass);
|
||||
|
||||
final BooleanProperty checked = new SimpleBooleanProperty(toggled);
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
checked.set(!checked.get());
|
||||
|
||||
if (checked.get()) {
|
||||
element.setText(x1);
|
||||
} else {
|
||||
element.setText(x2);
|
||||
}
|
||||
|
||||
consumer.accept(checked.get());
|
||||
});
|
||||
|
||||
addNode(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public Label addToggle(String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
|
||||
return addToggle("toggle", x1, x2, toggled, consumer);
|
||||
}
|
||||
|
||||
public Slider addSlider(String cssClass, int max, int initial, Consumer<Integer> 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<Integer> consumer) {
|
||||
return addSlider("slider", max, initial, consumer);
|
||||
}
|
||||
|
||||
public TextField addInput(String cssClass, String input, Consumer<String> consumer) {
|
||||
final TextField element = new TextField(input);
|
||||
element.getStyleClass().add(cssClass);
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
});
|
||||
|
||||
element.textProperty().addListener((_, _, newValue) -> {
|
||||
consumer.accept(newValue);
|
||||
});
|
||||
|
||||
addNode(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public TextField addInput(String input, Consumer<String> consumer) {
|
||||
return addInput("input", input, consumer);
|
||||
}
|
||||
|
||||
public <T> ChoiceBox<T> addChoiceBox(String cssClass, Consumer<T> consumer) {
|
||||
final ChoiceBox<T> 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 <T> ChoiceBox<T> addChoiceBox(Consumer<T> 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);
|
||||
|
||||
addNode(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
public Separator addSeparator(boolean horizontal) {
|
||||
return addSeparator("separator", horizontal);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package org.toop.app.layer;
|
||||
|
||||
import org.toop.app.App;
|
||||
import org.toop.app.canvas.GameCanvas;
|
||||
import org.toop.framework.asset.ResourceManager;
|
||||
import org.toop.framework.asset.resources.CssAsset;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.layout.Region;
|
||||
@@ -13,12 +11,11 @@ public abstract class Layer {
|
||||
protected StackPane layer;
|
||||
protected Region background;
|
||||
|
||||
protected Layer(String cssFile) {
|
||||
protected Layer(String... backgroundStyles) {
|
||||
layer = new StackPane();
|
||||
layer.getStylesheets().add(ResourceManager.<CssAsset>get(cssFile).getUrl());
|
||||
|
||||
background = new Region();
|
||||
background.getStyleClass().add("background");
|
||||
background.getStyleClass().addAll(backgroundStyles);
|
||||
background.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
|
||||
|
||||
layer.getChildren().addLast(background);
|
||||
|
||||
131
app/src/main/java/org/toop/app/layer/NodeBuilder.java
Normal file
131
app/src/main/java/org/toop/app/layer/NodeBuilder.java
Normal file
@@ -0,0 +1,131 @@
|
||||
package org.toop.app.layer;
|
||||
|
||||
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.*;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public final class NodeBuilder {
|
||||
public static void addCss(Node node, String... cssClasses) {
|
||||
node.getStyleClass().addAll(cssClasses);
|
||||
}
|
||||
|
||||
public static void setCss(Node node, String... cssClasses) {
|
||||
node.getStyleClass().removeAll();
|
||||
node.getStyleClass().addAll(cssClasses);
|
||||
}
|
||||
|
||||
public static Text header(String x) {
|
||||
final Text element = new Text(x);
|
||||
setCss(element, "text-primary", "text-header");
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Text text(String x) {
|
||||
final Text element = new Text(x);
|
||||
setCss(element, "text-secondary", "text-normal");
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Label button(String x, Runnable runnable) {
|
||||
final Label element = new Label(x);
|
||||
setCss(element, "button", "text-normal");
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
runnable.run();
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Label toggle(String x1, String x2, boolean toggled, Consumer<Boolean> consumer) {
|
||||
final Label element = new Label(toggled ? x2 : x1);
|
||||
setCss(element, "toggle", "text-normal");
|
||||
|
||||
final BooleanProperty checked = new SimpleBooleanProperty(toggled);
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
checked.set(!checked.get());
|
||||
|
||||
if (checked.get()) {
|
||||
element.setText(x1);
|
||||
} else {
|
||||
element.setText(x2);
|
||||
}
|
||||
|
||||
consumer.accept(checked.get());
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Slider slider(int max, int initial, Consumer<Integer> consumer) {
|
||||
final Slider element = new Slider(0, max, initial);
|
||||
setCss(element, "bg-slider-track");
|
||||
|
||||
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());
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static TextField input(String x, Consumer<String> consumer) {
|
||||
final TextField element = new TextField(x);
|
||||
setCss(element, "input", "text-normal");
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
});
|
||||
|
||||
element.textProperty().addListener((_, _, newValue) -> {
|
||||
consumer.accept(newValue);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static <T> ChoiceBox<T> choiceBox(Consumer<T> consumer) {
|
||||
final ChoiceBox<T> element = new ChoiceBox<>();
|
||||
setCss(element, "choice-box", "text-normal");
|
||||
|
||||
element.setOnMouseClicked(_ -> {
|
||||
new EventFlow().addPostEvent(new AudioEvents.ClickButton()).asyncPostEvent();
|
||||
});
|
||||
|
||||
element.valueProperty().addListener((_, _, newValue) -> {
|
||||
consumer.accept(newValue);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public static Separator separator() {
|
||||
final Separator element = new Separator(Orientation.HORIZONTAL);
|
||||
setCss(element, "separator");
|
||||
|
||||
return element;
|
||||
}
|
||||
}
|
||||
19
app/src/main/java/org/toop/app/layer/Popup.java
Normal file
19
app/src/main/java/org/toop/app/layer/Popup.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package org.toop.app.layer;
|
||||
|
||||
import org.toop.app.App;
|
||||
|
||||
public abstract class Popup extends Layer {
|
||||
protected Popup(boolean popOnBackground, String... backgroundStyles) {
|
||||
super(backgroundStyles);
|
||||
|
||||
if (popOnBackground) {
|
||||
background.setOnMouseClicked(_ -> {
|
||||
App.pop();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected Popup(boolean popOnBackground) {
|
||||
this(popOnBackground, "bg-popup");
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,13 @@ import javafx.scene.layout.Region;
|
||||
public final class HorizontalContainer extends Container {
|
||||
private final HBox container;
|
||||
|
||||
public HorizontalContainer(String cssClass, int spacing) {
|
||||
public HorizontalContainer(int spacing, String... cssClasses) {
|
||||
container = new HBox(spacing);
|
||||
container.getStyleClass().add(cssClass);
|
||||
container.getStyleClass().addAll(cssClasses);
|
||||
}
|
||||
|
||||
public HorizontalContainer(int spacing) {
|
||||
this("horizontal_container", spacing);
|
||||
this(spacing, "container");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,8 +26,8 @@ public final class HorizontalContainer extends Container {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode(Node node) {
|
||||
container.getChildren().addLast(node);
|
||||
public void addNodes(Node... nodes) {
|
||||
container.getChildren().addAll(nodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,13 +11,13 @@ import javafx.scene.layout.VBox;
|
||||
public final class VerticalContainer extends Container {
|
||||
private final VBox container;
|
||||
|
||||
public VerticalContainer(String cssClass, int spacing) {
|
||||
public VerticalContainer(int spacing, String... cssClasses) {
|
||||
container = new VBox(spacing);
|
||||
container.getStyleClass().add(cssClass);
|
||||
container.getStyleClass().addAll(cssClasses);
|
||||
}
|
||||
|
||||
public VerticalContainer(int spacing) {
|
||||
this("vertical_container", spacing);
|
||||
this(spacing, "container");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,8 +26,8 @@ public final class VerticalContainer extends Container {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode(Node node) {
|
||||
container.getChildren().addLast(node);
|
||||
public void addNodes(Node... nodes) {
|
||||
container.getChildren().addAll(nodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,7 +2,8 @@ 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.NodeBuilder;
|
||||
import org.toop.app.layer.Popup;
|
||||
import org.toop.app.layer.containers.HorizontalContainer;
|
||||
import org.toop.app.layer.containers.VerticalContainer;
|
||||
import org.toop.local.AppContext;
|
||||
@@ -10,13 +11,14 @@ import org.toop.local.AppContext;
|
||||
import javafx.animation.PauseTransition;
|
||||
import javafx.animation.TranslateTransition;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Duration;
|
||||
|
||||
public final class CreditsLayer extends Layer {
|
||||
public final class CreditsPopup extends Popup {
|
||||
private final int lineHeight = 100;
|
||||
|
||||
CreditsLayer() {
|
||||
super("credits.css");
|
||||
public CreditsPopup() {
|
||||
super(true, "bg-primary");
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -35,22 +37,19 @@ public final class CreditsLayer extends Layer {
|
||||
AppContext.getString("opengl") + ": Omar"
|
||||
};
|
||||
|
||||
final Container creditsContainer = new HorizontalContainer(0);
|
||||
final Text[] creditsHeaders = new Text[credits.length];
|
||||
|
||||
final Container animatedContainer = new VerticalContainer("animated_credits_container", lineHeight);
|
||||
creditsContainer.addContainer(animatedContainer, true);
|
||||
|
||||
for (final String credit : credits) {
|
||||
animatedContainer.addText("credit-text", credit, false);
|
||||
for (int i = 0; i < credits.length; i++) {
|
||||
creditsHeaders[i] = NodeBuilder.header(credits[i]);
|
||||
}
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
controlContainer.addButton(AppContext.getString("back"), () -> {
|
||||
App.activate(new MainLayer());
|
||||
});
|
||||
final Container creditsContainer = new HorizontalContainer(0);
|
||||
|
||||
final Container animatedContainer = new VerticalContainer(lineHeight);
|
||||
creditsContainer.addContainer(animatedContainer, true);
|
||||
|
||||
animatedContainer.addNodes(creditsHeaders);
|
||||
addContainer(creditsContainer, Pos.CENTER, 0, 0, 50, 100);
|
||||
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
|
||||
|
||||
playCredits(animatedContainer, App.getHeight());
|
||||
}
|
||||
@@ -3,16 +3,15 @@ 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.NodeBuilder;
|
||||
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;
|
||||
|
||||
public final class MainLayer extends Layer {
|
||||
public MainLayer() {
|
||||
super("main.css");
|
||||
super("bg-primary");
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -20,30 +19,32 @@ public final class MainLayer extends Layer {
|
||||
public void reload() {
|
||||
popAll();
|
||||
|
||||
final Container gamesContainer = new VerticalContainer(5);
|
||||
|
||||
gamesContainer.addButton(AppContext.getString("tictactoe"), () -> {
|
||||
final var tictactoeButton = NodeBuilder.button(AppContext.getString("tictactoe"), () -> {
|
||||
App.activate(new MultiplayerLayer());
|
||||
});
|
||||
|
||||
gamesContainer.addButton(AppContext.getString("othello"), () -> {
|
||||
final var othelloButton = NodeBuilder.button(AppContext.getString("othello"), () -> {
|
||||
App.activate(new MultiplayerLayer());
|
||||
});
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
|
||||
controlContainer.addButton(AppContext.getString("credits"), () -> {
|
||||
App.activate(new CreditsLayer());
|
||||
final var creditsButton = NodeBuilder.button(AppContext.getString("credits"), () -> {
|
||||
App.push(new CreditsPopup());
|
||||
});
|
||||
|
||||
controlContainer.addButton(AppContext.getString("options"), () -> {
|
||||
App.activate(new OptionsLayer());
|
||||
final var optionsButton = NodeBuilder.button(AppContext.getString("options"), () -> {
|
||||
App.push(new OptionsPopup());
|
||||
});
|
||||
|
||||
controlContainer.addButton(AppContext.getString("quit"), () -> {
|
||||
final var quitButton = NodeBuilder.button(AppContext.getString("quit"), () -> {
|
||||
App.quitPopup();
|
||||
});
|
||||
|
||||
final Container gamesContainer = new VerticalContainer(5);
|
||||
gamesContainer.addNodes(tictactoeButton, othelloButton);
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
controlContainer.addNodes(creditsButton, optionsButton, quitButton);
|
||||
|
||||
addContainer(gamesContainer, Pos.TOP_LEFT, 2, 2, 20, 0);
|
||||
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 20, 0);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package org.toop.app.layer.layers;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import org.toop.app.App;
|
||||
import org.toop.app.GameInformation;
|
||||
import org.toop.app.layer.Container;
|
||||
import org.toop.app.layer.Layer;
|
||||
import org.toop.app.layer.NodeBuilder;
|
||||
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;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public final class MultiplayerLayer extends Layer {
|
||||
private boolean isConnectionLocal = true;
|
||||
@@ -29,7 +29,7 @@ public final class MultiplayerLayer extends Layer {
|
||||
private String serverPort = "";
|
||||
|
||||
public MultiplayerLayer() {
|
||||
super("multiplayer.css");
|
||||
super("bg-primary");
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -37,89 +37,127 @@ public final class MultiplayerLayer extends Layer {
|
||||
public void reload() {
|
||||
popAll();
|
||||
|
||||
final Container mainContainer = new VerticalContainer(5);
|
||||
final Container player1Container = new VerticalContainer(20);
|
||||
final Container player2Container = new VerticalContainer(20);
|
||||
|
||||
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);
|
||||
|
||||
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, "127.0.0.1", "7789")));
|
||||
// serverIP, serverPort)));
|
||||
});
|
||||
|
||||
player1Container.addToggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer1Human, (computer) -> {
|
||||
final var isPlayer1HumanToggle = NodeBuilder.toggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer1Human, (computer) -> {
|
||||
isPlayer1Human = !computer;
|
||||
reload();
|
||||
});
|
||||
|
||||
player1Container.addNodes(isPlayer1HumanToggle);
|
||||
|
||||
if (isPlayer1Human) {
|
||||
player1Container.addText(AppContext.getString("playerName"), true);
|
||||
player1Container.addInput(player1Name, (name) -> {
|
||||
final var playerNameText = NodeBuilder.text(AppContext.getString("playerName"));
|
||||
final var playerNameInput = NodeBuilder.input(player1Name, (name) -> {
|
||||
player1Name = name;
|
||||
});
|
||||
|
||||
player1Container.addNodes(playerNameText, playerNameInput);
|
||||
} else {
|
||||
player1Name = "PismBot" + LocalDateTime.now().getSecond();
|
||||
player1Container.addText(AppContext.getString("computerDifficulty"), true);
|
||||
player1Container.addSlider(10, computer1Difficulty, (difficulty) ->
|
||||
player1Name = "Pism Bot #" + LocalDateTime.now().getSecond();
|
||||
|
||||
final var computerNameText = NodeBuilder.text(player1Name);
|
||||
final var computerNameSeparator = NodeBuilder.separator();
|
||||
|
||||
final var computerDifficultyText = NodeBuilder.text(AppContext.getString("computerDifficulty"));
|
||||
final var computerDifficultySlider = NodeBuilder.slider(10, computer1Difficulty, (difficulty) ->
|
||||
computer1Difficulty = difficulty);
|
||||
|
||||
player1Container.addNodes(computerNameText, computerNameSeparator,
|
||||
computerDifficultyText, computerDifficultySlider);
|
||||
}
|
||||
|
||||
if (isConnectionLocal) {
|
||||
player2Container.addToggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer2Human, (computer) -> {
|
||||
final var isPlayer2HumanToggle = NodeBuilder.toggle(AppContext.getString("human"), AppContext.getString("computer"), !isPlayer2Human, (computer) -> {
|
||||
isPlayer2Human = !computer;
|
||||
reload();
|
||||
});
|
||||
|
||||
player2Container.addNodes(isPlayer2HumanToggle);
|
||||
|
||||
if (isPlayer2Human) {
|
||||
player2Container.addText(AppContext.getString("playerName"), true);
|
||||
player2Container.addInput(player2Name, (name) -> {
|
||||
final var playerNameText = NodeBuilder.text(AppContext.getString("playerName"));
|
||||
final var playerNameInput = NodeBuilder.input(player2Name, (name) -> {
|
||||
player2Name = name;
|
||||
});
|
||||
|
||||
player2Container.addNodes(playerNameText, playerNameInput);
|
||||
} else {
|
||||
player2Container.addText(AppContext.getString("computerDifficulty"), true);
|
||||
player2Container.addSlider(10, computer2Difficulty, (difficulty) ->
|
||||
player2Name = "Pism Bot #" + LocalDateTime.now().getSecond();
|
||||
|
||||
final var computerNameText = NodeBuilder.text(player2Name);
|
||||
final var computerNameSeparator = NodeBuilder.separator();
|
||||
|
||||
final var computerDifficultyText = NodeBuilder.text(AppContext.getString("computerDifficulty"));
|
||||
final var computerDifficultySlider = NodeBuilder.slider(10, computer1Difficulty, (difficulty) ->
|
||||
computer2Difficulty = difficulty);
|
||||
|
||||
player2Container.addNodes(computerNameText, computerNameSeparator,
|
||||
computerDifficultyText, computerDifficultySlider);
|
||||
}
|
||||
} else {
|
||||
player2Container.addText(AppContext.getString("serverIP"), true);
|
||||
player2Container.addInput(serverIP, (ip) -> {
|
||||
final var serverIPText = NodeBuilder.text(AppContext.getString("serverIP"));
|
||||
final var serverIPSeparator = NodeBuilder.separator();
|
||||
final var serverIPInput = NodeBuilder.input(serverIP, (ip) -> {
|
||||
serverIP = ip;
|
||||
});
|
||||
|
||||
player2Container.addSeparator(true);
|
||||
|
||||
player2Container.addText(AppContext.getString("serverPort"), true);
|
||||
player2Container.addInput(serverPort, (port) -> {
|
||||
final var serverPortText = NodeBuilder.text(AppContext.getString("serverPort"));
|
||||
final var serverPortInput = NodeBuilder.input(serverPort, (port) -> {
|
||||
serverPort = port;
|
||||
});
|
||||
|
||||
player2Container.addNodes(serverIPText, serverIPInput, serverIPSeparator,
|
||||
serverPortText, serverPortInput);
|
||||
}
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
final var versusText = NodeBuilder.text("VS");
|
||||
|
||||
controlContainer.addButton(AppContext.getString("back"), () -> {
|
||||
final var connectionTypeText = NodeBuilder.text("Connection type (translate)");
|
||||
final var connectionTypeToggle = NodeBuilder.toggle(AppContext.getString("local"), AppContext.getString("server"), !isConnectionLocal, (server) -> {
|
||||
isConnectionLocal = !server;
|
||||
reload();
|
||||
});
|
||||
|
||||
final var playButton = NodeBuilder.button(isConnectionLocal ? AppContext.getString("start") : AppContext.getString("connect"), () -> {
|
||||
if (isConnectionLocal) {
|
||||
App.activate(new TicTacToeLayer(new GameInformation(
|
||||
new String[]{player1Name, player2Name},
|
||||
new boolean[]{isPlayer1Human, isPlayer2Human},
|
||||
new int[]{computer1Difficulty, computer2Difficulty},
|
||||
isConnectionLocal, serverIP, serverPort)));
|
||||
} else {
|
||||
App.activate(new TicTacToeLayer(new GameInformation(
|
||||
new String[]{player1Name, player2Name},
|
||||
new boolean[]{isPlayer1Human, isPlayer2Human},
|
||||
new int[]{computer1Difficulty, computer2Difficulty},
|
||||
isConnectionLocal, serverIP, serverPort)));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
final Container mainContainer = new VerticalContainer(10);
|
||||
final Container playersContainer = new HorizontalContainer(5);
|
||||
final Container connectionTypeContainer = new HorizontalContainer(10);
|
||||
|
||||
mainContainer.addContainer(playersContainer, true);
|
||||
mainContainer.addContainer(connectionTypeContainer, false);
|
||||
mainContainer.addNodes(playButton);
|
||||
|
||||
connectionTypeContainer.addNodes(connectionTypeText, connectionTypeToggle);
|
||||
|
||||
playersContainer.addContainer(player1Container, true);
|
||||
playersContainer.addNodes(versusText);
|
||||
playersContainer.addContainer(player2Container, true);
|
||||
|
||||
final var backButton = NodeBuilder.button(AppContext.getString("back"), () -> {
|
||||
App.activate(new MainLayer());
|
||||
});
|
||||
|
||||
final Container controlContainer = new VerticalContainer(0);
|
||||
controlContainer.addNodes(backButton);
|
||||
|
||||
addContainer(mainContainer, Pos.CENTER, 0, 0, 75, 75);
|
||||
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
|
||||
}
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
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<Locale> 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
171
app/src/main/java/org/toop/app/layer/layers/OptionsPopup.java
Normal file
171
app/src/main/java/org/toop/app/layer/layers/OptionsPopup.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package org.toop.app.layer.layers;
|
||||
|
||||
import org.toop.app.App;
|
||||
import org.toop.app.layer.Container;
|
||||
import org.toop.app.layer.NodeBuilder;
|
||||
import org.toop.app.layer.Popup;
|
||||
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 org.toop.local.AppSettings;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Slider;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public final class OptionsPopup extends Popup {
|
||||
AppSettings appSettings = new AppSettings();
|
||||
SettingsAsset settings = appSettings.getPath();
|
||||
private boolean isWindowed = !(settings.getFullscreen());
|
||||
|
||||
public OptionsPopup() {
|
||||
super(true, "bg-primary");
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
popAll();
|
||||
|
||||
final var languageHeader = NodeBuilder.header(AppContext.getString("language"));
|
||||
final var languageSeparator = NodeBuilder.separator();
|
||||
|
||||
final var volumeHeader = NodeBuilder.header(AppContext.getString("volume"));
|
||||
final var volumeSeparator = NodeBuilder.separator();
|
||||
|
||||
final var themeHeader = NodeBuilder.header(AppContext.getString("theme"));
|
||||
final var themeSeparator = NodeBuilder.separator();
|
||||
|
||||
final var layoutSizeHeader = NodeBuilder.header(AppContext.getString("layoutSize"));
|
||||
final var layoutSizeSeparator = NodeBuilder.separator();
|
||||
|
||||
final var optionsContainer = new VerticalContainer(5);
|
||||
optionsContainer.addNodes(languageHeader, languageChoiceBox(), languageSeparator);
|
||||
optionsContainer.addNodes(volumeHeader, volumeSlider(), volumeSeparator);
|
||||
optionsContainer.addNodes(themeHeader, themeChoiceBox(), themeSeparator);
|
||||
optionsContainer.addNodes(layoutSizeHeader, layoutSizeChoiceBox(), layoutSizeSeparator);
|
||||
optionsContainer.addNodes(fullscreenToggle());
|
||||
|
||||
final Container mainContainer = new VerticalContainer(50, "");
|
||||
mainContainer.addContainer(optionsContainer, true);
|
||||
|
||||
final var backButton = NodeBuilder.button(AppContext.getString("back"), () -> {
|
||||
App.pop();
|
||||
});
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
controlContainer.addNodes(backButton);
|
||||
|
||||
addContainer(mainContainer, Pos.CENTER, 0, 0, 0, 0);
|
||||
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
|
||||
}
|
||||
|
||||
private ChoiceBox<Locale> languageChoiceBox() {
|
||||
assert AppContext.getLocalization() != null;
|
||||
|
||||
final ChoiceBox<Locale> languageChoiceBox = NodeBuilder.choiceBox((locale) -> {
|
||||
if (locale == AppContext.getLocale()) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings.setLocale(locale.toString());
|
||||
AppContext.setLocale(locale);
|
||||
|
||||
App.reloadAll();
|
||||
});
|
||||
|
||||
languageChoiceBox.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;
|
||||
}
|
||||
});
|
||||
|
||||
languageChoiceBox.getItems().addAll(AppContext.getLocalization().getAvailableLocales());
|
||||
languageChoiceBox.setValue(AppContext.getLocale());
|
||||
|
||||
return languageChoiceBox;
|
||||
}
|
||||
|
||||
private Slider volumeSlider() {
|
||||
return NodeBuilder.slider(100, settings.getVolume(), (volume) -> {
|
||||
settings.setVolume(volume);
|
||||
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(volume.doubleValue())).asyncPostEvent();
|
||||
});
|
||||
}
|
||||
|
||||
private Label fullscreenToggle() {
|
||||
return NodeBuilder.toggle(AppContext.getString("windowed"), AppContext.getString("fullscreen"), !isWindowed, (fullscreen) -> {
|
||||
isWindowed = !fullscreen;
|
||||
|
||||
settings.setFullscreen(fullscreen);
|
||||
App.setFullscreen(fullscreen);
|
||||
});
|
||||
}
|
||||
|
||||
private ChoiceBox<String> themeChoiceBox() {
|
||||
final ChoiceBox<String> themeChoiceBox = NodeBuilder.choiceBox((theme) -> {
|
||||
if (theme.equalsIgnoreCase(settings.getTheme())) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings.setTheme(theme);
|
||||
App.setStyle(theme, settings.getLayoutSize());
|
||||
});
|
||||
|
||||
themeChoiceBox.setConverter(new javafx.util.StringConverter<>() {
|
||||
@Override
|
||||
public String toString(String theme) {
|
||||
return AppContext.getString(theme);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromString(String string) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
themeChoiceBox.getItems().addAll("dark", "light", "dark-hc", "light-hc");
|
||||
themeChoiceBox.setValue(settings.getTheme());
|
||||
|
||||
return themeChoiceBox;
|
||||
}
|
||||
|
||||
private ChoiceBox<String> layoutSizeChoiceBox() {
|
||||
final ChoiceBox<String> layoutSizeChoiceBox = NodeBuilder.choiceBox((layoutSize) -> {
|
||||
if (layoutSize.equalsIgnoreCase(settings.getLayoutSize())) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings.setLayoutSize(layoutSize);
|
||||
App.setStyle(settings.getTheme(), layoutSize);
|
||||
});
|
||||
|
||||
layoutSizeChoiceBox.setConverter(new javafx.util.StringConverter<>() {
|
||||
@Override
|
||||
public String toString(String layoutSize) {
|
||||
return AppContext.getString(layoutSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromString(String string) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
layoutSizeChoiceBox.getItems().addAll("small", "medium", "large");
|
||||
layoutSizeChoiceBox.setValue(settings.getLayoutSize());
|
||||
|
||||
return layoutSizeChoiceBox;
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,17 @@ 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.NodeBuilder;
|
||||
import org.toop.app.layer.Popup;
|
||||
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");
|
||||
public final class QuitPopup extends Popup {
|
||||
public QuitPopup() {
|
||||
super(true);
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -19,21 +20,23 @@ public final class QuitLayer extends Layer {
|
||||
public void reload() {
|
||||
popAll();
|
||||
|
||||
final Container mainContainer = new VerticalContainer(30);
|
||||
mainContainer.addText(AppContext.getString("quitSure"), false);
|
||||
final var sureText = NodeBuilder.header(AppContext.getString("quitSure"));
|
||||
|
||||
final Container controlContainer = new HorizontalContainer(30);
|
||||
|
||||
mainContainer.addContainer(controlContainer, false);
|
||||
|
||||
controlContainer.addButton(AppContext.getString("yes"), () -> {
|
||||
final var yesButton = NodeBuilder.button(AppContext.getString("yes"), () -> {
|
||||
App.quit();
|
||||
});
|
||||
|
||||
controlContainer.addButton(AppContext.getString("no"), () -> {
|
||||
final var noButton = NodeBuilder.button(AppContext.getString("no"), () -> {
|
||||
App.pop();
|
||||
});
|
||||
|
||||
final Container controlContainer = new HorizontalContainer(30);
|
||||
controlContainer.addNodes(yesButton, noButton);
|
||||
|
||||
final Container mainContainer = new VerticalContainer(30);
|
||||
mainContainer.addNodes(sureText);
|
||||
mainContainer.addContainer(controlContainer, false);
|
||||
|
||||
addContainer(mainContainer, Pos.CENTER, 0, 0, 30, 30);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
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.NodeBuilder;
|
||||
import org.toop.app.layer.containers.VerticalContainer;
|
||||
import org.toop.app.layer.layers.MainLayer;
|
||||
import org.toop.framework.eventbus.EventFlow;
|
||||
@@ -14,13 +17,9 @@ import org.toop.game.tictactoe.TicTacToe;
|
||||
import org.toop.game.tictactoe.TicTacToeAI;
|
||||
import org.toop.local.AppContext;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class TicTacToeLayer extends Layer {
|
||||
private TicTacToeCanvas canvas;
|
||||
@@ -37,9 +36,9 @@ public final class TicTacToeLayer extends Layer {
|
||||
private String player2Name = "";
|
||||
|
||||
public TicTacToeLayer(GameInformation information) {
|
||||
super("game.css");
|
||||
super("bg-primary");
|
||||
|
||||
canvas = new TicTacToeCanvas(Color.WHITE, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> {
|
||||
canvas = new TicTacToeCanvas(Color.LIME, (App.getHeight() / 100) * 75, (App.getHeight() / 100) * 75, (cell) -> {
|
||||
try {
|
||||
if (information.isConnectionLocal()) {
|
||||
if (ticTacToe.getCurrentTurn() == 0) {
|
||||
@@ -95,11 +94,13 @@ public final class TicTacToeLayer extends Layer {
|
||||
}
|
||||
}
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
controlContainer.addButton(AppContext.getString("back"), () -> {
|
||||
final var backButton = NodeBuilder.button(AppContext.getString("back"), () -> {
|
||||
App.activate(new MainLayer());
|
||||
});
|
||||
|
||||
final Container controlContainer = new VerticalContainer(5);
|
||||
controlContainer.addNodes(backButton);
|
||||
|
||||
addContainer(controlContainer, Pos.BOTTOM_LEFT, 2, -2, 0, 0);
|
||||
addGameCanvas(canvas, Pos.CENTER, 0, 0);
|
||||
}
|
||||
@@ -161,10 +162,12 @@ public final class TicTacToeLayer extends Layer {
|
||||
class OnlineGameState {
|
||||
public long clientId = -1;
|
||||
public long receivedMove = -1;
|
||||
public boolean firstPlayerIsMe = true;
|
||||
public boolean firstPlayerIsMe = true;
|
||||
}
|
||||
AtomicBoolean firstPlayerIsMe = new AtomicBoolean(true);
|
||||
AtomicBoolean gameHasStarted = new AtomicBoolean(false);
|
||||
|
||||
AtomicBoolean firstPlayerIsMe = new AtomicBoolean(true);
|
||||
AtomicBoolean gameHasStarted = new AtomicBoolean(false);
|
||||
|
||||
private void serverGameThread(NetworkEvents.StartClientResponse event) {
|
||||
boolean running = true;
|
||||
final long clientId = event.clientId();
|
||||
@@ -174,12 +177,12 @@ public final class TicTacToeLayer extends Layer {
|
||||
//new EventFlow()
|
||||
// .listen(NetworkEvents.GameMoveResponse.class,respEvent -> onMoveResponse(onlineGameState, respEvent));
|
||||
|
||||
new EventFlow()
|
||||
.listen(this::yourTurnResponse)
|
||||
.listen(this::handleChallengeResponse)
|
||||
.listen(this::handleServerGameStart)
|
||||
.listen(this::handleReceivedMessage)
|
||||
.listen(this::onMoveResponse);
|
||||
new EventFlow()
|
||||
.listen(this::yourTurnResponse)
|
||||
.listen(this::handleChallengeResponse)
|
||||
.listen(this::handleServerGameStart)
|
||||
.listen(this::handleReceivedMessage)
|
||||
.listen(this::onMoveResponse);
|
||||
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendLogin(clientId, information.playerName()[0]))
|
||||
.postEvent();
|
||||
@@ -188,95 +191,94 @@ public final class TicTacToeLayer extends Layer {
|
||||
.postEvent();
|
||||
|
||||
while (running) {
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
}catch (InterruptedException exception) {}
|
||||
boolean hasStarted = gameHasStarted.get();
|
||||
if (hasStarted) {
|
||||
onlineGameState.firstPlayerIsMe = firstPlayerIsMe.get();
|
||||
if (onlineGameState.firstPlayerIsMe) {
|
||||
currentPlayerMove = 'X';
|
||||
}
|
||||
else {
|
||||
currentPlayerMove = 'O';
|
||||
}
|
||||
if(!information.isPlayerHuman()[0]){
|
||||
boolean myTurn = (onlineGameState.firstPlayerIsMe && ticTacToe.getCurrentTurn() % 2 == 0)
|
||||
|| (!onlineGameState.firstPlayerIsMe && ticTacToe.getCurrentTurn() % 2 == 1);
|
||||
if (myTurn) {
|
||||
Game.Move move;
|
||||
move = ticTacToeAI.findBestMove(ticTacToe, compurterDifficultyToDepth(10, 10));
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendMove(clientId, (short) move.position()))
|
||||
.postEvent();
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
final Game.Move wants = playerMoveQueue.take();
|
||||
final Game.Move[] legalMoves = ticTacToe.getLegalMoves();
|
||||
for (final Game.Move legalMove : legalMoves) {
|
||||
if (legalMove.position() == wants.position() && legalMove.value() == wants.value()) {
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendMove(clientId, (short) wants.position()))
|
||||
.postEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException exception) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException exception) {
|
||||
}
|
||||
boolean hasStarted = gameHasStarted.get();
|
||||
if (hasStarted) {
|
||||
onlineGameState.firstPlayerIsMe = firstPlayerIsMe.get();
|
||||
if (onlineGameState.firstPlayerIsMe) {
|
||||
currentPlayerMove = 'X';
|
||||
} else {
|
||||
currentPlayerMove = 'O';
|
||||
}
|
||||
if (!information.isPlayerHuman()[0]) {
|
||||
boolean myTurn = (onlineGameState.firstPlayerIsMe && ticTacToe.getCurrentTurn() % 2 == 0)
|
||||
|| (!onlineGameState.firstPlayerIsMe && ticTacToe.getCurrentTurn() % 2 == 1);
|
||||
if (myTurn) {
|
||||
Game.Move move;
|
||||
move = ticTacToeAI.findBestMove(ticTacToe, compurterDifficultyToDepth(10, 10));
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendMove(clientId, (short) move.position()))
|
||||
.postEvent();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
final Game.Move wants = playerMoveQueue.take();
|
||||
final Game.Move[] legalMoves = ticTacToe.getLegalMoves();
|
||||
for (final Game.Move legalMove : legalMoves) {
|
||||
if (legalMove.position() == wants.position() && legalMove.value() == wants.value()) {
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendMove(clientId, (short) wants.position()))
|
||||
.postEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException exception) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void drawSymbol(Game.Move move){
|
||||
if (move.value() == 'X') {
|
||||
canvas.drawX(Color.RED, move.position());
|
||||
} else if (move.value() == 'O') {
|
||||
canvas.drawO(Color.BLUE, move.position());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleServerGameStart(NetworkEvents.GameMatchResponse resp) {
|
||||
if(resp.playerToMove().equals(resp.opponent())){
|
||||
firstPlayerIsMe.set(false);
|
||||
}
|
||||
else{
|
||||
firstPlayerIsMe.set(true);
|
||||
}
|
||||
gameHasStarted.set(true);
|
||||
}
|
||||
|
||||
private void onMoveResponse(NetworkEvents.GameMoveResponse resp) {
|
||||
char playerChar;
|
||||
if (resp.player().equals(information.playerName()[0]) && firstPlayerIsMe.get()
|
||||
|| !resp.player().equals(information.playerName()[0]) && !firstPlayerIsMe.get()) {
|
||||
playerChar = 'X';
|
||||
}
|
||||
else{
|
||||
playerChar = 'O';
|
||||
}
|
||||
Game.Move move =new Game.Move(Integer.parseInt(resp.move()),playerChar);
|
||||
Game.State state = ticTacToe.play(move);
|
||||
if (state != Game.State.NORMAL) { //todo differentiate between future draw guaranteed and is currently a draw
|
||||
gameHasStarted.set(false);
|
||||
}
|
||||
drawSymbol(move);
|
||||
private void drawSymbol(Game.Move move) {
|
||||
if (move.value() == 'X') {
|
||||
canvas.drawX(Color.RED, move.position());
|
||||
} else if (move.value() == 'O') {
|
||||
canvas.drawO(Color.BLUE, move.position());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleChallengeResponse(NetworkEvents.ChallengeResponse resp) {
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendAcceptChallenge(resp.clientId(),Integer.parseInt(resp.challengeId())))
|
||||
.postEvent();
|
||||
}
|
||||
private void handleServerGameStart(NetworkEvents.GameMatchResponse resp) {
|
||||
if (resp.playerToMove().equals(resp.opponent())) {
|
||||
firstPlayerIsMe.set(false);
|
||||
} else {
|
||||
firstPlayerIsMe.set(true);
|
||||
}
|
||||
gameHasStarted.set(true);
|
||||
}
|
||||
|
||||
private void yourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
||||
private void onMoveResponse(NetworkEvents.GameMoveResponse resp) {
|
||||
char playerChar;
|
||||
if (resp.player().equals(information.playerName()[0]) && firstPlayerIsMe.get()
|
||||
|| !resp.player().equals(information.playerName()[0]) && !firstPlayerIsMe.get()) {
|
||||
playerChar = 'X';
|
||||
} else {
|
||||
playerChar = 'O';
|
||||
}
|
||||
Game.Move move = new Game.Move(Integer.parseInt(resp.move()), playerChar);
|
||||
Game.State state = ticTacToe.play(move);
|
||||
if (state != Game.State.NORMAL) { //todo differentiate between future draw guaranteed and is currently a draw
|
||||
gameHasStarted.set(false);
|
||||
}
|
||||
drawSymbol(move);
|
||||
}
|
||||
|
||||
//new EventFlow().addPostEvent(new NetworkEvents.SendCommand(response.clientId(),"CHALLENGE banaan tic-tac-toe")).postEvent();
|
||||
//new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(),(short)2))
|
||||
// .postEvent();
|
||||
}
|
||||
private void handleReceivedMessage(NetworkEvents.ReceivedMessage msg) {
|
||||
System.out.println("Received Message: " + msg.message()); //todo add chat window
|
||||
}
|
||||
private void handleChallengeResponse(NetworkEvents.ChallengeResponse resp) {
|
||||
new EventFlow().addPostEvent(new NetworkEvents.SendAcceptChallenge(resp.clientId(), Integer.parseInt(resp.challengeId())))
|
||||
.postEvent();
|
||||
}
|
||||
|
||||
private void yourTurnResponse(NetworkEvents.YourTurnResponse response) {
|
||||
|
||||
//new EventFlow().addPostEvent(new NetworkEvents.SendCommand(response.clientId(),"CHALLENGE banaan tic-tac-toe")).postEvent();
|
||||
//new EventFlow().addPostEvent(new NetworkEvents.SendMove(response.clientId(),(short)2))
|
||||
// .postEvent();
|
||||
}
|
||||
|
||||
private void handleReceivedMessage(NetworkEvents.ReceivedMessage msg) {
|
||||
System.out.println("Received Message: " + msg.message()); //todo add chat window
|
||||
}
|
||||
|
||||
private void serverGameThreadResponseHandler(OnlineGameState ogs, NetworkEvents.ChallengeResponse msg) {
|
||||
if (msg.clientId() != ogs.clientId) return;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class AppSettings {
|
||||
AppContext.setLocale(Locale.of(settingsData.locale));
|
||||
App.setFullscreen(settingsData.fullScreen);
|
||||
new EventFlow().addPostEvent(new AudioEvents.ChangeVolume(settingsData.volume)).asyncPostEvent();
|
||||
|
||||
App.setStyle(settingsAsset.getTheme(), settingsAsset.getLayoutSize());
|
||||
}
|
||||
|
||||
public SettingsAsset getPath() {
|
||||
|
||||
Reference in New Issue
Block a user