main menu done(?). probably not but fine for now

This commit is contained in:
ramollia
2025-10-01 19:25:19 +02:00
parent 99a3b7e85b
commit 258ce964c9
21 changed files with 360 additions and 171 deletions

View File

@@ -4,7 +4,7 @@ import org.toop.app.App;
import org.toop.framework.networking.NetworkingClientManager;
import org.toop.framework.networking.NetworkingInitializationException;
public class Main {
public final class Main {
static void main(String[] args) {
initSystems();
App.run(args);

View File

@@ -2,18 +2,50 @@ package org.toop.app;
import org.toop.app.menu.MainMenu;
import org.toop.app.menu.Menu;
import org.toop.app.menu.QuitMenu;
import javafx.application.Application;
import javafx.scene.layout.StackPane;
import javafx.geometry.Pos;
import javafx.scene.Scene;
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 javafx.stage.Stage;
public class App extends Application {
public final class App extends Application {
private static Stage stage;
private static Scene scene;
private static StackPane root;
private static int width;
private static int height;
private static boolean isQuitting;
private static class QuitMenu extends Menu {
public QuitMenu() {
final Region background = createBackground("quit_background");
final Text sure = createText("Are you sure?");
final Button yes = createButton("Yes", () -> { stage.close(); });
final Button no = createButton("No", () -> { pop(); isQuitting = false; });
final HBox buttons = new HBox(50, yes, no);
buttons.setAlignment(Pos.CENTER);
final VBox box = new VBox(35, sure, buttons);
box.getStyleClass().add("quit_box");
box.setAlignment(Pos.CENTER);
box.setMaxWidth(350);
box.setMaxHeight(200);
pane = new StackPane(background, box);
pane.getStylesheets().add(App.class.getResource("/style/quit.css").toExternalForm());
}
}
public static void run(String[] args) {
launch(args);
}
@@ -21,7 +53,9 @@ public class App extends Application {
@Override
public void start(Stage stage) throws Exception {
final StackPane root = new StackPane(new MainMenu().getPane());
final Scene scene = new Scene(root);
scene.getStylesheets().add(App.class.getResource("/style/app.css").toExternalForm());
stage.setTitle("pism");
stage.setMinWidth(1080);
@@ -29,7 +63,10 @@ public class App extends Application {
stage.setOnCloseRequest(event -> {
event.consume();
push(new QuitMenu());
if (!isQuitting) {
quitPopup();
}
});
stage.setScene(scene);
@@ -38,25 +75,32 @@ public class App extends Application {
stage.show();
App.stage = stage;
App.scene = scene;
App.root = root;
App.width = (int)stage.getWidth();
App.height = (int)stage.getHeight();
App.isQuitting = false;
}
public static void quitPopup() {
isQuitting = true;
push(new QuitMenu());
}
public static void activate(Menu menu) {
scene.setRoot(menu.getPane());
pop();
push(menu);
}
public static void push(Menu menu) {
root.getChildren().add(menu.getPane());
root.getChildren().addLast(menu.getPane());
}
public static void pop() {
root.getChildren().removeLast();
}
public static void quit() {
stage.close();
}
public static StackPane getRoot() { return root; }
public static int getWidth() { return width; }
public static int getHeight() { return height; }
}

View File

@@ -0,0 +1,21 @@
package org.toop.app;
public enum GameType {
TICTACTOE, REVERSI;
public static String toName(GameType type) {
return switch (type) {
case TICTACTOE -> "Tic Tac Toe";
case REVERSI -> "Reversi";
};
}
public static GameType toType(String name) {
return switch (name) {
case "Tic Tac Toe" -> TICTACTOE;
case "Reversi" -> REVERSI;
default -> TICTACTOE;
};
}
}

View File

@@ -0,0 +1,22 @@
package org.toop.app.menu;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import org.toop.app.GameType;
public class GameMenu extends Menu {
public GameMenu(GameType type) {
final Region background = createBackground();
ComboBox<String> selectedGame = new ComboBox<>();
TextField serverIpField = new TextField();
serverIpField.setPromptText("Enter here your server ip address");
VBox box = new VBox(selectedGame, serverIpField);
pane = new StackPane(background, box);
}
}

View File

@@ -1,31 +1,45 @@
package org.toop.app.menu;
import org.toop.app.App;
import org.toop.app.GameType;
import org.toop.app.screen.TicTacToeScreen;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
public final class MainMenu extends Menu {
public MainMenu() {
final ImageView background = new ImageView();
final Region background = createBackground();
final Button tictactoe = createButton("Tic Tac Toe", () -> {});
final Button reversi = createButton("Reversi", () -> {});
final Button sudoku = createButton("Sudoku", () -> {});
final Button battleship = createButton("Battleship", () -> {});
final Button other = createButton("Other", () -> {});
final Button tictactoe = createButton("Tic Tac Toe", () -> { App.activate(new GameMenu(GameType.TICTACTOE)); });
final Button reversi = createButton("Reversi", () -> { App.activate(new GameMenu(GameType.REVERSI)); });
final VBox gamesBox = new VBox(tictactoe, reversi, sudoku, background, other);
gamesBox.setAlignment(Pos.TOP_CENTER);
final VBox gamesBox = new VBox(10, tictactoe, reversi);
gamesBox.setAlignment(Pos.TOP_LEFT);
gamesBox.setPickOnBounds(false);
gamesBox.setTranslateY(50);
gamesBox.setTranslateX(25);
final Button credits = createButton("Credits", () -> {});
final Button options = createButton("Options", () -> {});
final Button quit = createButton("Quit", () -> {});
final Button credits = createButton("Credits", () -> { App.push(new CreditsMenu()); });
final Button options = createButton("Options", () -> { App.push(new OptionsMenu()); });
final Button quit = createButton("Quit", () -> { App.quitPopup(); });
final VBox creditsBox = new VBox(10, credits, options, quit);
creditsBox.setAlignment(Pos.BOTTOM_CENTER);
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, grid);
pane.getStylesheets().add(getClass().getResource("/style/main.css").toExternalForm());
pane = new StackPane(background, gamesBox, controlBox);
tictactoe.setOnMouseEntered(_ -> {
final TicTacToeScreen screen = new TicTacToeScreen((int)pane.getHeight());
screen.simulate(1000);
push(screen.getCanvas());
});
tictactoe.setOnMouseExited(_ -> { pop(); });
}
}

View File

@@ -1,27 +1,55 @@
package org.toop.app.menu;
import org.toop.app.App;
import javafx.animation.FadeTransition;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.util.Duration;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
public abstract class Menu {
protected Pane pane;
public Pane getPane() { return pane; }
public void fadeBackgroundImage(String imagePath, float from, float to, float milliseconds) {
final FadeTransition fade = new FadeTransition(Duration.millis(milliseconds), App.getRoot());
fade.setFromValue(from);
fade.setToValue(to);
fade.play();
public void push(Node node) {
pane.getChildren().addLast(node);
}
public Button createButton(String text, Runnable runnable) {
final Button button = new Button(text);
public void pop() {
pane.getChildren().removeLast();
}
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(_ -> runnable.run());
button.getStyleClass().add("button");
button.getStyleClass().add(css);
return button;
}
public Button createButton(String x, Runnable runnable) {
return createButton("button", x, runnable);
}
}

View File

@@ -1,48 +0,0 @@
package org.toop.app.menu;
import javafx.geometry.Pos;
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;
public final class QuitMenu extends Menu {
public QuitMenu() {
final Region background = new Region();
background.getStyleClass().add("quit-background");
background.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
final Text sure = new Text("Are you sure?");
sure.getStyleClass().add("quit-text");
final Button yes = new Button("Yes");
yes.getStyleClass().add("quit-button");
yes.setOnAction(_ -> {
App.quit();
});
final Button no = new Button("No");
no.getStyleClass().add("quit-button");
no.setOnAction(_ -> {
App.pop();
});
final HBox buttons = new HBox(10, yes, no);
buttons.setAlignment(Pos.CENTER);
VBox box = new VBox(43, sure, buttons);
box.setAlignment(Pos.CENTER);
box.getStyleClass().add("quit-box");
box.setMaxWidth(350);
box.setMaxHeight(200);
StackPane modalContainer = new StackPane(background, box);
StackPane.setAlignment(box, Pos.CENTER);
pane = modalContainer;
pane.getStylesheets().add(getClass().getResource("/style/quit.css").toExternalForm());
}
}

View File

@@ -0,0 +1,71 @@
package org.toop.app.screen;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
public abstract class Screen {
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(int x, int y) {
return x >= this.x && y >= this.y && x <= this.x + width && y <= this.y + height;
}
}
protected final Canvas canvas;
protected final GraphicsContext graphics;
protected final int width;
protected final int height;
protected final int rowSize;
protected final int columnSize;
protected final int gapSize;
protected final Cell[] cells;
protected Screen(int width, int height, int rowSize, int columnSize, int gapSize) {
final Canvas canvas = new Canvas(width, height);
final GraphicsContext graphics = canvas.getGraphicsContext2D();
this.canvas = canvas;
this.graphics = graphics;
this.width = width;
this.height = height;
this.rowSize = rowSize;
this.columnSize = columnSize;
this.gapSize = gapSize;
cells = new Cell[rowSize * columnSize];
final float cellWidth = ((float)width - (rowSize - 1) * gapSize) / rowSize;
final float cellHeight = ((float)height - (columnSize - 1) * gapSize) / rowSize;
for (int y = 0; y < columnSize; y++) {
final float startY = y * cellHeight + y * gapSize;
for (int x = 0; x < rowSize; x++) {
final float startX = x * cellWidth + x * gapSize;
cells[y * rowSize + x] = new Cell(startX, startY, cellWidth, cellHeight);
}
}
}
public Canvas getCanvas() { return canvas; }
}

View File

@@ -0,0 +1,78 @@
package org.toop.app.screen;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TicTacToeScreen extends Screen {
public TicTacToeScreen(int size) {
super(size, size, 3, 3, 10);
graphics.setFill(Color.CYAN);
for (int x = 1; x < rowSize; x++) {
graphics.fillRect(cells[x].x - gapSize, 0, gapSize, height - gapSize);
}
for (int y = 1; y < columnSize; y++) {
graphics.fillRect(0, cells[y * rowSize].y - gapSize, width - gapSize, gapSize);
}
}
public void placeX(int cell) {
graphics.setFill(Color.WHITE);
graphics.setLineWidth(gapSize);
final float x = cells[cell].x;
final float y = cells[cell].y;
final float width = cells[cell].width;
final float height = cells[cell].height;
graphics.strokeLine(x, y, x + width, y + height);
graphics.strokeLine(x + width, y, x, y + height);
}
public void placeO(int cell) {
graphics.setFill(Color.WHITE);
graphics.setLineWidth(gapSize);
final float x = cells[cell].x;
final float y = cells[cell].y;
final float width = cells[cell].width;
final float height = cells[cell].height;
graphics.strokeOval(x, y, width, height);
}
public void simulate(int speedInMilliseconds) {
final Random random = new Random();
final List<Integer> playedCells = new ArrayList<>();
final Timeline timeline = new Timeline(new KeyFrame(Duration.millis(speedInMilliseconds), _ ->{
int cell;
do {
cell = random.nextInt(cells.length);
} while (playedCells.contains(cell));
if (playedCells.size() % 2 == 0) {
placeX(cell);
} else {
placeO(cell);
}
playedCells.add(cell);
}));
timeline.setCycleCount(9);
timeline.play();
}
}