From ad09d9e71abcf29b0bf0730d2d4a0e820a0ec841 Mon Sep 17 00:00:00 2001 From: Samiker <168203446+Samiker69@users.noreply.github.com> Date: Wed, 28 Jan 2026 00:05:50 +0300 Subject: [PATCH 1/7] =?UTF-8?q?Rebase=20(Main):=20=D0=A3=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D1=91=D0=BD=20javafx=20=D0=B8=20=D0=B2=D1=81=D0=B5=20=D1=81?= =?UTF-8?q?=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20(fxml,=20css?= =?UTF-8?q?).=20-=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=91=D0=BD=20bui?= =?UTF-8?q?ld.gradle.kts=20-=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82=20?= =?UTF-8?q?=D1=8F=D0=B2=D0=BB=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B3=D0=BB=D1=83=D1=88=D0=BA=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 130 ++--- src/main/java/module-info.java | 24 - .../xyz/samiker/theendlessweave/Main.java | 205 ++----- .../client/ClientLauncher.java | 13 +- .../client/controllers/AssetAware.java | 16 - .../client/controllers/GameDataAware.java | 14 - .../controllers/LoadingScreenController.java | 164 ------ .../controllers/MainMenuController.java | 32 -- .../client/screens/AssetAware.java | 8 + .../GameController.java | 31 +- .../client/screens/GameDataAware.java | 7 + .../GenerationSceneController.java | 2 +- .../client/screens/LoadingScreen.java | 178 ++++++ .../client/screens/MainMenuScreen.java | 106 ++++ .../SettingsController.java | 2 +- .../settings/GeneralSettingsController.java | 2 +- .../settings/VideoSettingsController.java | 2 +- .../theendlessweave/css/game-scene.css | 246 --------- .../theendlessweave/css/generation-scene.css | 510 ------------------ .../theendlessweave/css/loading-screen.css | 23 - .../samiker/theendlessweave/css/main-menu.css | 30 -- .../samiker/theendlessweave/css/settings.css | 110 ---- .../theendlessweave/fxml/game-scene.fxml | 165 ------ .../fxml/generation-scene.fxml | 243 --------- .../theendlessweave/fxml/loading-screen.fxml | 50 -- .../theendlessweave/fxml/main-menu.fxml | 26 - .../theendlessweave/fxml/settings.fxml | 25 - .../fxml/settings/settings-general.fxml | 26 - .../fxml/settings/settings-video.fxml | 51 -- 29 files changed, 395 insertions(+), 2046 deletions(-) delete mode 100644 src/main/java/module-info.java delete mode 100644 src/main/java/xyz/samiker/theendlessweave/client/controllers/AssetAware.java delete mode 100644 src/main/java/xyz/samiker/theendlessweave/client/controllers/GameDataAware.java delete mode 100644 src/main/java/xyz/samiker/theendlessweave/client/controllers/LoadingScreenController.java delete mode 100644 src/main/java/xyz/samiker/theendlessweave/client/controllers/MainMenuController.java create mode 100644 src/main/java/xyz/samiker/theendlessweave/client/screens/AssetAware.java rename src/main/java/xyz/samiker/theendlessweave/client/{controllers => screens}/GameController.java (86%) create mode 100644 src/main/java/xyz/samiker/theendlessweave/client/screens/GameDataAware.java rename src/main/java/xyz/samiker/theendlessweave/client/{controllers => screens}/GenerationSceneController.java (99%) create mode 100644 src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java create mode 100644 src/main/java/xyz/samiker/theendlessweave/client/screens/MainMenuScreen.java rename src/main/java/xyz/samiker/theendlessweave/client/{controllers => screens}/SettingsController.java (98%) rename src/main/java/xyz/samiker/theendlessweave/client/{controllers => screens}/settings/GeneralSettingsController.java (95%) rename src/main/java/xyz/samiker/theendlessweave/client/{controllers => screens}/settings/VideoSettingsController.java (98%) delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/css/game-scene.css delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/css/generation-scene.css delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/css/loading-screen.css delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/css/main-menu.css delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/css/settings.css delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/game-scene.fxml delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/generation-scene.fxml delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/loading-screen.fxml delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/main-menu.fxml delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/settings.fxml delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/settings/settings-general.fxml delete mode 100644 src/main/resources/xyz/samiker/theendlessweave/fxml/settings/settings-video.fxml diff --git a/build.gradle.kts b/build.gradle.kts index 3b16323..322be47 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,24 +3,18 @@ import java.util.Date plugins { java application - id("org.javamodularity.moduleplugin") version "1.8.15" - id("org.openjfx.javafxplugin") version "0.0.13" - id("org.beryx.jlink") version "3.2.0" + id("com.github.johnrengelman.shadow") version "8.1.1" } group = "xyz.samiker" -version = "0.2.0" +version = "0.4.0" + +val gdxVersion = "1.14.0" repositories { mavenCentral() -} - -sourceSets { - main { - resources { - srcDir(layout.buildDirectory.dir("resources/generateResourceManifest")) - } - } + maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") } + maven { url = uri("https://oss.sonatype.org/content/repositories/releases/") } } java { @@ -30,28 +24,30 @@ java { } } -tasks.withType { - options.encoding = "UTF-8" -} - application { - mainModule.set("xyz.samiker.theendlessweave") mainClass.set("xyz.samiker.theendlessweave.Launcher") } -javafx { - version = "21.0.6" - modules = listOf("javafx.controls", "javafx.fxml", "javafx.media") -} - dependencies { - implementation("org.controlsfx:controlsfx:11.2.1") + implementation("com.badlogicgames.gdx:gdx:$gdxVersion") + implementation("com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion") + implementation("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop") implementation("com.esotericsoftware:kryonet:2.22.0-RC1") } +tasks.withType { + options.encoding = "UTF-8" +} + +tasks.named("run") { + if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) { + jvmArgs("-XstartOnFirstThread") + } +} + tasks.register("buildServer") { group = "build" - description = "билдит сервер без всякого fx говна" + description = "Билдит сервер без графического бэкенда и нативов" archiveClassifier.set("server") @@ -61,34 +57,38 @@ tasks.register("buildServer") { from(sourceSets.main.get().output) { exclude("xyz/samiker/theendlessweave/client/**") + exclude("assets/**") exclude("css/**") exclude("fxml/**") - exclude("*.dll", "*.so", "*.dylib") } val serverClasspath = configurations.runtimeClasspath.get().filter { file -> val name = file.name.lowercase() - !name.contains("javafx") && - !name.contains("controlsfx") && - !name.contains("native") && - !name.contains("win") && - !name.contains("mac") && - !name.contains("linux") + !name.contains("gdx-backend-lwjgl3") && + !name.contains("natives") && + !name.contains("javafx") && + !name.contains("controlsfx") } from(serverClasspath.map { if (it.isDirectory) it else zipTree(it) }) { - exclude("module-info.class") exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") exclude("META-INF/MANIFEST.MF") - exclude("**/*.dll", "**/*.so", "**/*.dylib") + exclude("module-info.class") } duplicatesStrategy = DuplicatesStrategy.EXCLUDE } -tasks.withType { - useJUnitPlatform() +tasks.named("shadowJar") { + archiveClassifier.set("all") + configurations = listOf(project.configurations.runtimeClasspath.get()) + + mergeServiceFiles() + + manifest { + attributes["Main-Class"] = "xyz.samiker.theendlessweave.Launcher" + } } tasks.register("generateResourceManifest") { @@ -104,7 +104,6 @@ tasks.register("generateResourceManifest") { doLast { println("Generating resource manifest to: ${manifestFile.asFile.path}") - val manifestContent = StringBuilder() manifestContent.append("# Resource Manifest\n") manifestContent.append("# Generated on: ${Date()}\n\n") @@ -116,62 +115,23 @@ tasks.register("generateResourceManifest") { manifestContent.append("resource.path=${relativePath.replace(File.separatorChar, '/')}\n\n") } } - outputDir.get().asFile.mkdirs() manifestFile.asFile.writeText(manifestContent.toString()) } } -tasks.named("processResources") { - dependsOn(tasks.named("generateResourceManifest")) -} - -tasks.register("shadowJar") { - group = "build" - description = "Builds an uber-jar (fat jar) with all dependencies." - - archiveClassifier.set("all") - - manifest { - attributes["Main-Class"] = "xyz.samiker.theendlessweave.Launcher" - } - - from(sourceSets.main.get().output) - - from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) { - exclude("module-info.class", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "META-INF/substrate/config/*", "META-INF/LICENSE", "META-INF/NOTICE") +sourceSets { + main { + resources { + srcDir(layout.buildDirectory.dir("resources/generateResourceManifest")) + } } - - duplicatesStrategy = DuplicatesStrategy.EXCLUDE } -jlink { - imageZip.set(layout.buildDirectory.file("/distributions/app-${javafx.platform.classifier}.zip")) - options.set(listOf("--strip-debug", "--compress", "zip-8", "--no-header-files", "--no-man-pages")) - launcher { - name = "TheEndlessWeave" - } - - val javaToolchains = project.extensions.getByType(JavaToolchainService::class) - val javaLauncher = javaToolchains.launcherFor(java.toolchain) - javaHome.set(javaLauncher.map { it.metadata.installationPath }) - - jpackage { - imageName = "TheEndlessWeave" - if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) { - val ver = version as String - appVersion = if (ver.startsWith("0.")) "1" + ver.substring(1) else ver - } else { - appVersion = version as String? - } +tasks.named("processResources") { + dependsOn(tasks.named("generateResourceManifest")) +} - if (org.gradle.internal.os.OperatingSystem.current().isWindows) { - installerOptions = listOf( - "--win-shortcut", - "--win-menu", - "--win-dir-chooser", - "--win-menu-group", "The Endless Weave" - ) - } - } +tasks.withType { + useJUnitPlatform() } \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java deleted file mode 100644 index 69ae379..0000000 --- a/src/main/java/module-info.java +++ /dev/null @@ -1,24 +0,0 @@ -module xyz.samiker.theendlessweave { - requires javafx.controls; - requires javafx.fxml; - requires javafx.media; - requires jdk.jfr; - requires jdk.management; - requires jdk.management.agent; - requires jdk.management.jfr; - requires javafx.graphics; - requires kryo; - requires kryonet; - - opens xyz.samiker.theendlessweave to javafx.fxml; - opens xyz.samiker.theendlessweave.client.controllers to javafx.fxml; - - exports xyz.samiker.theendlessweave; - exports xyz.samiker.theendlessweave.client.assets; - exports xyz.samiker.theendlessweave.client.controllers; - exports xyz.samiker.theendlessweave.server; - opens xyz.samiker.theendlessweave.server to javafx.fxml; - exports xyz.samiker.theendlessweave.client; - opens xyz.samiker.theendlessweave.client to javafx.fxml; - -} \ No newline at end of file diff --git a/src/main/java/xyz/samiker/theendlessweave/Main.java b/src/main/java/xyz/samiker/theendlessweave/Main.java index 7a00bdf..4120793 100644 --- a/src/main/java/xyz/samiker/theendlessweave/Main.java +++ b/src/main/java/xyz/samiker/theendlessweave/Main.java @@ -1,197 +1,60 @@ package xyz.samiker.theendlessweave; -import javafx.application.Application; -import javafx.application.Platform; -import javafx.fxml.FXMLLoader; -import javafx.geometry.Rectangle2D; -import javafx.scene.Scene; -import javafx.scene.input.KeyCombination; -import javafx.stage.Screen; -import javafx.stage.Stage; -import javafx.stage.StageStyle; +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; import xyz.samiker.theendlessweave.client.assets.ManifestAssetManager; -import xyz.samiker.theendlessweave.client.controllers.AssetAware; -import xyz.samiker.theendlessweave.client.controllers.GameDataAware; -import xyz.samiker.theendlessweave.client.custom.InputManager; -import xyz.samiker.theendlessweave.client.initialization.LoadingContext; -import xyz.samiker.theendlessweave.core.GameData; +import xyz.samiker.theendlessweave.client.screens.LoadingScreen; import xyz.samiker.theendlessweave.core.settings.SettingsEnum; import xyz.samiker.theendlessweave.core.settings.SettingsManager; -import java.io.IOException; -import java.net.URL; +public class Main extends Game { + public SpriteBatch batch; -public class Main extends Application implements AssetAware { - private static Stage primaryStage; - private static Scene mainScene; - private static ManifestAssetManager assetManager; - private static final SettingsManager.Resolution resolution = new SettingsManager.Resolution(SettingsManager.getString(SettingsEnum.RESOLUTION)); - private static boolean isMobile = false; - - private static boolean isProgrammaticResize = false; + // Ваш менеджер ассетов + private ManifestAssetManager assetManager; @Override - public void start(Stage stage) throws IOException { - primaryStage = stage; - primaryStage.setOnCloseRequest(event -> { - Platform.exit(); - System.exit(0); - }); - initOS(true); - stage.setTitle("The Endless Weave"); - - FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/xyz/samiker/theendlessweave/fxml/loading-screen.fxml")); - mainScene = new Scene(fxmlLoader.load()); - - InputManager.initialize(mainScene); - - setupStageListeners(primaryStage); - boolean isBorderless = SettingsManager.getBoolean(SettingsEnum.BORDERLESS); - primaryStage.initStyle(isBorderless ? StageStyle.UNDECORATED : StageStyle.DECORATED); - - applyResolutionToStage(stage); - primaryStage.setScene(mainScene); - - updateSceneStyles("/xyz/samiker/theendlessweave/css/loading-screen.css"); - - primaryStage.show(); - } - - /** - * Настраивает слушатели событий для окна. - */ - private static void setupStageListeners(Stage stage) { - stage.widthProperty().addListener((obs, oldVal, newVal) -> { - if (!stage.isFullScreen() && !isProgrammaticResize) { - resolution.setWidth(newVal.intValue()); - } - }); - - stage.heightProperty().addListener((obs, oldVal, newVal) -> { - if (!stage.isFullScreen() && !isProgrammaticResize) { - resolution.setHeight(newVal.intValue()); - } - }); + public void create() { + batch = new SpriteBatch(); + //assetManager = new ManifestAssetManager(); - stage.fullScreenProperty().addListener((obs, wasFullScreen, isFullScreen) -> { - Rectangle2D bounds = Screen.getPrimary().getBounds(); - resolution.setHeight((int) bounds.getHeight()); - resolution.setWidth((int) bounds.getWidth()); - }); + applySettings(); + this.setScreen(new LoadingScreen(this)); } - public static void setAssetManager(LoadingContext context) { - assetManager = context.get("assetManager"); - } - - public static void showScene(String fxmlPath, String cssPath) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource(fxmlPath)); - mainScene.setRoot(fxmlLoader.load()); - - Object controller = fxmlLoader.getController(); - if (controller instanceof AssetAware) { - ((AssetAware) controller).setAssets(assetManager); - } - - updateSceneStyles(cssPath); - applyStageSettings(); - } - - public static T showSceneAndGetController(String fxmlPath, String cssPath) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource(fxmlPath)); - mainScene.setRoot(fxmlLoader.load()); - - T controller = fxmlLoader.getController(); - if (controller instanceof AssetAware) { - ((AssetAware) controller).setAssets(assetManager); - } - - updateSceneStyles(cssPath); - applyStageSettings(); - - return controller; + @Override + public void render() { + super.render(); } - public static void showGameScene(GameData data, String path, String csspath) throws IOException { - FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource(path)); - mainScene.setRoot(fxmlLoader.load()); - - Object controller = fxmlLoader.getController(); - if (controller instanceof AssetAware) { - ((AssetAware) controller).setAssets(assetManager); - } - if (controller instanceof GameDataAware) { - ((GameDataAware) controller).setData(data); + @Override + public void dispose() { + if (batch != null) batch.dispose(); + if (assetManager != null) { + assetManager.dispose(); } - - updateSceneStyles(csspath); - applyStageSettings(); + if (screen != null) screen.dispose(); } - private static void updateSceneStyles(String cssPath) { - mainScene.getStylesheets().clear(); - URL customCssUrl = Main.class.getResource(cssPath); - if (customCssUrl != null) { - mainScene.getStylesheets().add(customCssUrl.toExternalForm()); - } else { - System.err.println("WARNING: Custom stylesheet " + cssPath + " not found in resources."); - } + public ManifestAssetManager getAssetManager() { + return assetManager; } - public static void applyStageSettings() { + public void applySettings() { boolean isFullscreen = SettingsManager.getBoolean(SettingsEnum.FULLSCREEN); + boolean isBorderless = SettingsManager.getBoolean(SettingsEnum.BORDERLESS); - isProgrammaticResize = true; - - try { - if (primaryStage.isFullScreen() != isFullscreen) { - primaryStage.setFullScreenExitHint(""); - primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH); - primaryStage.setFullScreen(isFullscreen); - } + if (isFullscreen) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } else { + int width = Integer.parseInt(SettingsManager.getString(SettingsEnum.RESOLUTION).split("x")[0]); + int height = Integer.parseInt(SettingsManager.getString(SettingsEnum.RESOLUTION).split("x")[1]); + Gdx.graphics.setWindowedMode(width, height); - if (!isFullscreen) { - if (primaryStage.getWidth() != resolution.getWidth() || primaryStage.getHeight() != resolution.getHeight()) { - primaryStage.setWidth(resolution.getWidth()); - primaryStage.setHeight(resolution.getHeight()); - primaryStage.centerOnScreen(); - } + if (isBorderless) { + Gdx.graphics.setUndecorated(true); } - } finally { - isProgrammaticResize = false; } } - - private void applyResolutionToStage(Stage stage) { - stage.setWidth(resolution.getWidth()); - stage.setHeight(resolution.getHeight()); - } - - public static void initOS(boolean asMobile) { - String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("android") || os.contains("ios") || asMobile) { - isMobile = true; - } - } - - public static boolean isMobile() { - return isMobile; - } - - public static Stage getPrimaryStage() { - return primaryStage; - } - - public static Scene getMainScene() { - return mainScene; - } - - public static SettingsManager.Resolution getResolution() { - return resolution; - } - - @Override - public void setAssets(ManifestAssetManager assets) { - assetManager = assets; - } } \ No newline at end of file diff --git a/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java b/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java index 9449bd1..08a2739 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/ClientLauncher.java @@ -1,10 +1,12 @@ package xyz.samiker.theendlessweave.client; -import javafx.application.Application; import xyz.samiker.theendlessweave.Main; import xyz.samiker.theendlessweave.core.settings.SettingsEnum; import xyz.samiker.theendlessweave.core.settings.SettingsManager; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; + import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; @@ -13,15 +15,18 @@ public class ClientLauncher { public static void main(String[] args) { + Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); try { SettingsManager.loadSettings(); + String[] parts = SettingsManager.getString(SettingsEnum.RESOLUTION).split("x"); + config.setWindowedMode(Integer.parseInt(parts[0]), Integer.parseInt(parts[1])); if (!SettingsManager.getBoolean(SettingsEnum.VSYNC)) { - System.setProperty("prism.vsync", "false"); - System.setProperty("javafx.animation.framerate", String.valueOf(SettingsManager.getInt(SettingsEnum.FPS_LIMIT))); + config.useVsync(SettingsManager.getBoolean(SettingsEnum.VSYNC)); + config.setForegroundFPS(SettingsManager.getInt(SettingsEnum.FPS_LIMIT)); } - Application.launch(Main.class, args); + new Lwjgl3Application(new Main(), config); } catch (Throwable t) { logError(t); } diff --git a/src/main/java/xyz/samiker/theendlessweave/client/controllers/AssetAware.java b/src/main/java/xyz/samiker/theendlessweave/client/controllers/AssetAware.java deleted file mode 100644 index 9e13129..0000000 --- a/src/main/java/xyz/samiker/theendlessweave/client/controllers/AssetAware.java +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.samiker.theendlessweave.client.controllers; - -import xyz.samiker.theendlessweave.client.assets.ManifestAssetManager; - -/** - * Интерфейс для контроллеров, которым нужен доступ к AssetManager. - * Реализуй этот интерфейс в любом контроллере, где нужны ассеты. - */ -public interface AssetAware { - /** - * Вызывается автоматически из Main.showScene() после загрузки FXML. - * @param assets Менеджер ассетов - */ - void setAssets(ManifestAssetManager assets); -} - diff --git a/src/main/java/xyz/samiker/theendlessweave/client/controllers/GameDataAware.java b/src/main/java/xyz/samiker/theendlessweave/client/controllers/GameDataAware.java deleted file mode 100644 index 1eb263f..0000000 --- a/src/main/java/xyz/samiker/theendlessweave/client/controllers/GameDataAware.java +++ /dev/null @@ -1,14 +0,0 @@ -package xyz.samiker.theendlessweave.client.controllers; - -import xyz.samiker.theendlessweave.core.GameData; - -/** - * Интерфейс для контроллеров, которым нужно знать имя/параметры уровня. - */ -public interface GameDataAware { - /** - * Вызывается из Main.showGameScene() для передачи имени уровня. - * @param data Имя файла уровня (например, "level1.json") - */ - void setData(GameData data); -} diff --git a/src/main/java/xyz/samiker/theendlessweave/client/controllers/LoadingScreenController.java b/src/main/java/xyz/samiker/theendlessweave/client/controllers/LoadingScreenController.java deleted file mode 100644 index f2ad0c0..0000000 --- a/src/main/java/xyz/samiker/theendlessweave/client/controllers/LoadingScreenController.java +++ /dev/null @@ -1,164 +0,0 @@ -package xyz.samiker.theendlessweave.client.controllers; - -import javafx.application.Platform; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ProgressBar; -import javafx.scene.control.TextArea; -import xyz.samiker.theendlessweave.Main; -import xyz.samiker.theendlessweave.client.initialization.InitializationManager; -import xyz.samiker.theendlessweave.client.initialization.LoadingCallback; -import xyz.samiker.theendlessweave.client.initialization.stages.AssetLoadStage; -import xyz.samiker.theendlessweave.client.initialization.stages.SettingsLoadStage; -import xyz.samiker.theendlessweave.core.utils.Array; - -import java.io.IOException; -import java.net.URL; -import java.util.ResourceBundle; -import java.util.concurrent.Future; - -public class LoadingScreenController implements Initializable { - - @FXML - private ProgressBar progressBar; - - @FXML - private Label statusLabel; - - @FXML - private TextArea logTextArea; - - @FXML - private Button cancelButton; - - private InitializationManager initManager; - private Future initFuture; - - @Override - public void initialize(URL location, ResourceBundle resources) { - initManager = new InitializationManager(); - - initManager.registerStage(new SettingsLoadStage()); - initManager.registerStage(new AssetLoadStage()); - // initManager.registerStage(new MapGenerationStage()); - - LoadingCallback callback = new LoadingCallback() { - @Override - public void updateMessage(String message) { - Platform.runLater(() -> statusLabel.setText(message)); - } - - @Override - public void updateProgress(long current, long total) { - Platform.runLater(() -> { - if (total > 0) { - progressBar.setProgress((double) current / total); - } - }); - } - - @Override - public void log(LogLevel level, String message) { - Platform.runLater(() -> { - String prefix = switch (level) { - case INFO -> "[INFO] "; - case WARN -> "[WARN] "; - case ERROR -> "[ERROR] "; - case DEBUG -> "[DEBUG] "; - }; - logTextArea.appendText(prefix + message + "\n"); - }); - } - }; - - initFuture = initManager.initialize(callback); - new Thread(() -> { - try { - InitializationManager.InitializationResult result = initFuture.get(); - - Platform.runLater(() -> { - if (result.isSuccess()) { - onInitializationSuccess(); - } else { - onInitializationFailure(result); - } - }); - } catch (Exception e) { - Platform.runLater(() -> { - logError("Initialization crashed: " + e.getMessage()); - e.printStackTrace(); - }); - } - }).start(); - if (cancelButton != null) { - cancelButton.setOnAction(e -> { - initManager.cancel(); - try { - Main.showScene( - "/xyz/samiker/theendlessweave/fxml/main-menu.fxml", - "/xyz/samiker/theendlessweave/css/main-menu.css" - ); - } catch (IOException ex) { - ex.printStackTrace(); - } - }); - } - } - - /** - * Вызывается при успешной инициализации. - */ - private void onInitializationSuccess() { - statusLabel.setText("Initialization complete!"); - progressBar.setProgress(1.0); - - Main.setAssetManager(initManager.getContext()); - - new Thread(() -> { - try { - Thread.sleep(500); - Platform.runLater(() -> { - try { - Main.showScene( - "/xyz/samiker/theendlessweave/fxml/main-menu.fxml", - "/xyz/samiker/theendlessweave/css/main-menu.css" - ); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } catch (InterruptedException e) { - e.printStackTrace(); - } - }).start(); - } - - /** - * Вызывается при неудачной инициализации. - */ - private void onInitializationFailure(InitializationManager.InitializationResult result) { - statusLabel.setText("Initialization failed!"); - progressBar.setProgress(0.0); - - logError("=== INITIALIZATION FAILED ==="); - logError("Reason: " + result.getFailureReason()); - - Array errors = result.getErrors(); - for (int i = 0; i < errors.size; i++) { - InitializationManager.StageError error = errors.get(i); - logError("Stage: " + error.getStage().getStageName()); - logError("Error: " + error.getException().getMessage()); - } - - if (cancelButton != null) { - cancelButton.setText("Return to Menu"); - cancelButton.setVisible(true); - } - } - - private void logError(String message) { - logTextArea.appendText("[ERROR] " + message + "\n"); - } -} \ No newline at end of file diff --git a/src/main/java/xyz/samiker/theendlessweave/client/controllers/MainMenuController.java b/src/main/java/xyz/samiker/theendlessweave/client/controllers/MainMenuController.java deleted file mode 100644 index 0e2121f..0000000 --- a/src/main/java/xyz/samiker/theendlessweave/client/controllers/MainMenuController.java +++ /dev/null @@ -1,32 +0,0 @@ -package xyz.samiker.theendlessweave.client.controllers; - -import javafx.event.ActionEvent; -import xyz.samiker.theendlessweave.Main; -import xyz.samiker.theendlessweave.core.GameData; -import xyz.samiker.theendlessweave.core.gamemap.MapGeneratorSettings; - -import java.io.IOException; - -public class MainMenuController { - public void play(ActionEvent event) throws IOException { - Main.showScene( - "/xyz/samiker/theendlessweave/fxml/generation-scene.fxml", - "/xyz/samiker/theendlessweave/css/generation-scene.css" - ); - } - - public void toSettings(ActionEvent event) throws IOException { - Main.showScene( - "/xyz/samiker/theendlessweave/fxml/settings.fxml", - "/xyz/samiker/theendlessweave/css/settings.css" - ); - } - - public void toDevStage(ActionEvent event) throws IOException { - Main.showGameScene( - new GameData(MapGeneratorSettings.defaults(), 50, 50, System.currentTimeMillis()), - "/xyz/samiker/theendlessweave/fxml/game-scene.fxml", - "/xyz/samiker/theendlessweave/css/game-scene.css" - ); - } -} diff --git a/src/main/java/xyz/samiker/theendlessweave/client/screens/AssetAware.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/AssetAware.java new file mode 100644 index 0000000..a95d849 --- /dev/null +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/AssetAware.java @@ -0,0 +1,8 @@ +package xyz.samiker.theendlessweave.client.screens; + +import xyz.samiker.theendlessweave.client.assets.ManifestAssetManager; + +public interface AssetAware { + void setAssets(ManifestAssetManager assets); +} + diff --git a/src/main/java/xyz/samiker/theendlessweave/client/controllers/GameController.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/GameController.java similarity index 86% rename from src/main/java/xyz/samiker/theendlessweave/client/controllers/GameController.java rename to src/main/java/xyz/samiker/theendlessweave/client/screens/GameController.java index dc27a23..7b50299 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/controllers/GameController.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/GameController.java @@ -1,17 +1,6 @@ -package xyz.samiker.theendlessweave.client.controllers; - -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.canvas.Canvas; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ProgressBar; -import javafx.scene.input.KeyCode; -import javafx.scene.input.MouseButton; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.Pane; -import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; +package xyz.samiker.theendlessweave.client.screens; + +import com.badlogic.gdx.Screen; import xyz.samiker.theendlessweave.Main; import xyz.samiker.theendlessweave.client.assets.ManifestAssetManager; import xyz.samiker.theendlessweave.client.custom.InputManager; @@ -32,19 +21,7 @@ import java.net.URL; import java.util.ResourceBundle; -public class GameController implements Initializable, AssetAware, GameDataAware { - @FXML public Pane overlayUIPane; - @FXML public AnchorPane mobileControlsPane; - @FXML public Button attackBtn; - @FXML private Pane gamePane; - @FXML private Pane worldUIPane; - @FXML private ProgressBar healthBar; - @FXML private Label healthLabel; - @FXML private Label scoreLabel; - @FXML private Label levelLabel; - @FXML private VBox pauseMenu; - @FXML private Label loadingLabel; - +public class GameScreem implements Screen, AssetAware, GameDataAware { private Game game; private Loop gameLoop; private GameClient client; diff --git a/src/main/java/xyz/samiker/theendlessweave/client/screens/GameDataAware.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/GameDataAware.java new file mode 100644 index 0000000..ff51991 --- /dev/null +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/GameDataAware.java @@ -0,0 +1,7 @@ +package xyz.samiker.theendlessweave.client.screens; + +import xyz.samiker.theendlessweave.core.GameData; + +public interface GameDataAware { + void setData(GameData data); +} diff --git a/src/main/java/xyz/samiker/theendlessweave/client/controllers/GenerationSceneController.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/GenerationSceneController.java similarity index 99% rename from src/main/java/xyz/samiker/theendlessweave/client/controllers/GenerationSceneController.java rename to src/main/java/xyz/samiker/theendlessweave/client/screens/GenerationSceneController.java index 32e8f42..67ccd60 100644 --- a/src/main/java/xyz/samiker/theendlessweave/client/controllers/GenerationSceneController.java +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/GenerationSceneController.java @@ -1,4 +1,4 @@ -package xyz.samiker.theendlessweave.client.controllers; +package xyz.samiker.theendlessweave.client.screens; import javafx.fxml.FXML; import javafx.scene.control.*; diff --git a/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java b/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java new file mode 100644 index 0000000..0acc254 --- /dev/null +++ b/src/main/java/xyz/samiker/theendlessweave/client/screens/LoadingScreen.java @@ -0,0 +1,178 @@ +package xyz.samiker.theendlessweave.client.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.ScreenUtils; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import xyz.samiker.theendlessweave.Main; +import xyz.samiker.theendlessweave.client.initialization.InitializationManager; +import xyz.samiker.theendlessweave.client.initialization.LoadingCallback; +import xyz.samiker.theendlessweave.client.initialization.stages.AssetLoadStage; +import xyz.samiker.theendlessweave.client.initialization.stages.SettingsLoadStage; +import xyz.samiker.theendlessweave.core.utils.Array; + +public class LoadingScreen implements Screen { + private final Main game; + private Stage stage; + private Skin skin; + + private ProgressBar progressBar; + private Label statusLabel; + private TextArea logTextArea; + private TextButton cancelButton; + private ScrollPane logScroll; + + private InitializationManager initManager; + private boolean isFinished = false; + + public LoadingScreen(Main game) { + this.game = game; + } + + @Override + public void show() { + stage = new Stage(new ScreenViewport()); + Gdx.input.setInputProcessor(stage); + + skin = new Skin(Gdx.files.internal("ui/uiskin.json")); + + buildUI(); + startInitialization(); + } + + private void buildUI() { + Table root = new Table(); + root.setFillParent(true); + stage.addActor(root); + + statusLabel = new Label("Initializing...", skin); + progressBar = new ProgressBar(0, 1, 0.01f, false, skin); + + // Лог действий + logTextArea = new TextArea("", skin); + logTextArea.setDisabled(true); + logScroll = new ScrollPane(logTextArea, skin); + logScroll.setFadeScrollBars(false); + + cancelButton = new TextButton("Cancel", skin); + cancelButton.setVisible(false); + cancelButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (initManager != null) initManager.cancel(); + game.setScreen(new MainMenuScreen(game)); + } + }); + + root.add(statusLabel).pad(10).row(); + root.add(progressBar).width(400).pad(10).row(); + root.add(logScroll).width(600).height(300).pad(10).row(); + root.add(cancelButton).pad(10); + } + + private void startInitialization() { + initManager = new InitializationManager(); + initManager.registerStage(new SettingsLoadStage()); + initManager.registerStage(new AssetLoadStage()); + + LoadingCallback callback = new LoadingCallback() { + @Override + public void updateMessage(String message) { + Gdx.app.postRunnable(() -> statusLabel.setText(message)); + } + + @Override + public void updateProgress(long current, long total) { + Gdx.app.postRunnable(() -> { + if (total > 0) { + progressBar.setValue((float) current / total); + } + }); + } + + @Override + public void log(LogLevel level, String message) { + Gdx.app.postRunnable(() -> { + String prefix = "[" + level.name() + "] "; + String currentText = logTextArea.getText(); + logTextArea.setText(currentText + prefix + message + "\n"); + logScroll.setScrollPercentY(100); + }); + } + }; + + new Thread(() -> { + try { + var future = initManager.initialize(callback); + var result = future.get(); + + Gdx.app.postRunnable(() -> { + if (result.isSuccess()) { + onSuccess(); + } else { + onFailure(result); + } + }); + } catch (Exception e) { + Gdx.app.postRunnable(() -> { + logTextArea.setText(logTextArea.getText() + "[CRASH] " + e.getMessage()); + e.printStackTrace(); + }); + } + }).start(); + } + + private void onSuccess() { + statusLabel.setText("Initialization complete!"); + progressBar.setValue(1.0f); + + stage.addAction(com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence( + com.badlogic.gdx.scenes.scene2d.actions.Actions.delay(0.5f), + com.badlogic.gdx.scenes.scene2d.actions.Actions.run(() -> game.setScreen(new MainMenuScreen(game))) + )); + } + + private void onFailure(InitializationManager.InitializationResult result) { + statusLabel.setText("Initialization failed!"); + progressBar.setValue(0f); + cancelButton.setVisible(true); + cancelButton.setText("Return to Menu"); + + StringBuilder sb = new StringBuilder(logTextArea.getText()); + sb.append("\n=== FAILED: ").append(result.getFailureReason()).append(" ===\n"); + Array errors = result.getErrors(); + for(int i=0; i .bar { - -fx-accent: #44ff44; -} -.health-bar.hp-medium > .bar { - -fx-accent: #ffaa00; -} -.health-bar.hp-low > .bar { - -fx-accent: #ff4444; -} - -.health-bar .track { - -fx-background-color: rgba(100, 20, 20, 0.5); - -fx-background-insets: 0; - -fx-background-radius: 4; - -fx-border-color: rgba(255, 68, 68, 0.3); - -fx-border-width: 1; - -fx-border-radius: 4; -} - -/* ============================================ - НИЖНЯЯ ПАНЕЛЬ (Способности и инвентарь) - ============================================ */ - -.bottom-panel { - -fx-background-color: linear-gradient(to bottom, - rgba(29, 29, 29, 0.26) 0%, - rgba(19, 14, 20, 0.207) 100%); - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.8), 20, 0.5, 0, 5); - -fx-border-color: rgba(22, 22, 25, 0.3); - -fx-border-width: 0 0 2 0; -} - -/* ============================================ - СЛОТЫ СПОСОБНОСТЕЙ - ============================================ */ - -.ability-bar { - -fx-background-color: rgba(30, 30, 40, 0.6); - -fx-background-radius: 10; - -fx-padding: 8; - -fx-effect: innershadow(gaussian, rgba(0, 0, 0, 0.7), 10, 0.3, 0, 2); -} - -.ability-slot { - -fx-min-width: 64; - -fx-min-height: 64; - -fx-max-width: 64; - -fx-max-height: 64; - -fx-background-color: linear-gradient(to bottom, - rgba(50, 50, 70, 0.9), - rgba(30, 30, 50, 0.9)); - -fx-background-radius: 8; - -fx-border-color: linear-gradient(to bottom, - rgba(100, 100, 150, 0.5), - rgba(60, 60, 100, 0.5)); - -fx-border-width: 2; - -fx-border-radius: 8; - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.6), 8, 0.4, 0, 3); -} - -.ability-slot:hover { - -fx-background-color: linear-gradient(to bottom, - rgba(70, 70, 100, 0.9), - rgba(50, 50, 80, 0.9)); - -fx-border-color: rgba(150, 150, 200, 0.7); - -fx-effect: dropshadow(gaussian, rgba(100, 100, 200, 0.8), 12, 0.6, 0, 0); - -fx-cursor: hand; -} - -.ability-key { - -fx-text-fill: #aaaacc; - -fx-font-size: 14; - -fx-font-weight: bold; - -fx-translate-x: 4; - -fx-translate-y: 4; - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.8), 2, 0.5, 0, 1); -} - -/* ============================================ - СЛОТЫ ИНВЕНТАРЯ - ============================================ */ - -.inventory-bar { - -fx-background-color: rgba(30, 30, 40, 0.6); - -fx-background-radius: 10; - -fx-padding: 8; - -fx-effect: innershadow(gaussian, rgba(0, 0, 0, 0.7), 10, 0.3, 0, 2); -} - -.inventory-slot { - -fx-min-width: 56; - -fx-min-height: 56; - -fx-max-width: 56; - -fx-max-height: 56; - -fx-background-color: linear-gradient(to bottom, - rgba(40, 40, 50, 0.9), - rgba(25, 25, 35, 0.9)); - -fx-background-radius: 6; - -fx-border-color: rgba(80, 80, 100, 0.5); - -fx-border-width: 2; - -fx-border-radius: 6; - -fx-effect: innershadow(gaussian, rgba(0, 0, 0, 0.8), 5, 0.5, 0, 2); -} - -.inventory-slot:hover { - -fx-background-color: linear-gradient(to bottom, - rgba(60, 60, 80, 0.9), - rgba(40, 40, 60, 0.9)); - -fx-border-color: rgba(150, 150, 180, 0.7); - -fx-cursor: hand; -} - -.inventory-key { - -fx-text-fill: #888899; - -fx-font-size: 12; - -fx-font-weight: bold; - -fx-translate-x: 4; - -fx-translate-y: 4; - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.8), 2, 0.5, 0, 1); -} - -/* ============================================ - ЭФФЕКТЫ ДЛЯ АКТИВНЫХ СПОСОБНОСТЕЙ - ============================================ */ - -.ability-slot.active { - -fx-background-color: linear-gradient(to bottom, - rgba(100, 100, 150, 0.9), - rgba(60, 60, 120, 0.9)); - -fx-border-color: rgba(150, 200, 255, 1.0); - -fx-effect: dropshadow(gaussian, rgba(150, 200, 255, 1.0), 15, 0.8, 0, 0); -} - -.ability-slot.cooldown { - -fx-opacity: 0.4; -} - -/* ============================================ - АНИМАЦИИ (через JavaFX transitions) - ============================================ */ - -.ability-slot.pulsing { - -fx-effect: dropshadow(gaussian, rgba(255, 200, 100, 0.8), 20, 0.8, 0, 0); -} - - -.mobile-attack-btn { - -fx-background-color: rgba(255, 68, 68, 0.6); - -fx-text-fill: white; - -fx-font-size: 24px; - -fx-font-weight: bold; - -fx-background-radius: 50%; - -fx-min-width: 80px; - -fx-min-height: 80px; - -fx-max-width: 80px; - -fx-max-height: 80px; - -fx-border-color: rgba(255, 255, 255, 0.5); - -fx-border-radius: 50%; - -fx-border-width: 2px; -} - -.mobile-attack-btn:pressed { - -fx-background-color: rgba(255, 0, 0, 0.8); - -fx-scale-x: 0.95; - -fx-scale-y: 0.95; -} - -.joystick-base { - -fx-fill: rgba(0, 0, 0, 0.3); - -fx-stroke: rgba(255, 255, 255, 0.4); - -fx-stroke-width: 2px; -} - -.joystick-knob { - -fx-fill: rgba(255, 255, 255, 0.8); - -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.5), 5, 0, 0, 0); -} \ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/css/generation-scene.css b/src/main/resources/xyz/samiker/theendlessweave/css/generation-scene.css deleted file mode 100644 index 77ccece..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/css/generation-scene.css +++ /dev/null @@ -1,510 +0,0 @@ -.root-container { - /* Почти черный фон вместо синего */ - -fx-background-color: #050505; - -fx-padding: 20; -} - -.header-container { - /* Очень темный серый */ - -fx-background-color: #111111; - -fx-padding: 20; - -fx-background-radius: 10; - /* Тень более строгая, черная */ - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.8), 15, 0, 0, 4); - -fx-border-color: #222222; - -fx-border-width: 1; - -fx-border-radius: 10; -} - -.header-title { - -fx-font-size: 32px; - -fx-font-weight: bold; - -fx-fill: #e0e0e0; - -fx-effect: dropshadow(gaussian, rgba(183, 28, 28, 0.3), 10, 0, 0, 0); -} - -/* ============================================ */ -/* ВКЛАДКИ (Исправлено) */ -/* ============================================ */ - -/* 1. Сам контейнер TabPane */ -.main-tab-pane { - -fx-background-color: transparent; -} - -.main-tab-pane .tab-header-area { - -fx-background-color: #111111; - -fx-padding: 5 5 0 5; -} - -.main-tab-pane .tab-header-background { - -fx-background-color: #111111; -} - -/* 4. Сама вкладка (неактивная) */ -.main-tab-pane .tab { - -fx-background-color: #1a1a1a; - -fx-background-radius: 5 5 0 0; - -fx-background-insets: 0 1 0 0; - -fx-padding: 8 20; - -fx-border-color: #333333; - -fx-border-width: 1 1 0 1; - -fx-border-radius: 5 5 0 0; -} - -.main-tab-pane .tab:selected { - -fx-background-color: #111111; - -fx-border-color: #b71c1c; - -fx-border-width: 2 0 0 0; - -fx-background-insets: 0; -} - -.main-tab-pane .tab .tab-label { - -fx-text-fill: #808080; - -fx-font-size: 14px; - -fx-font-weight: bold; -} - -.main-tab-pane .tab:selected .tab-label { - -fx-text-fill: #ffffff; -} - -.main-tab-pane .tab-content-area { - -fx-background-color: #111111; - -fx-border-color: #333333; - -fx-border-width: 0 1 1 1; - -fx-padding: 0; -} - -/* ============================================ */ -/* СЕКЦИИ */ -/* ============================================ */ - -.section { - -fx-background-color: #161616; - -fx-padding: 20; - -fx-background-radius: 8; - -fx-border-color: #252525; - -fx-border-width: 1; - -fx-border-radius: 8; - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 10, 0, 0, 2); -} - -.section-label { - -fx-font-size: 18px; - -fx-font-weight: bold; - -fx-text-fill: #ef5350; -} - -.section-hint { - -fx-fill: #666666; - -fx-font-size: 12px; - -fx-font-style: italic; -} - -.detailed-section { - -fx-background-color: #161616; - -fx-padding: 15; - -fx-background-radius: 8; - -fx-border-color: #252525; - -fx-border-width: 1; -} - -.detailed-section-label { - -fx-font-size: 16px; - -fx-font-weight: bold; - -fx-text-fill: #ef5350; -} - -/* ============================================ */ -/* COMBOBOX */ -/* ============================================ */ - -.preset-combo { - -fx-background-color: #000000; - -fx-text-fill: #ffffff; - -fx-font-size: 14px; - -fx-pref-height: 40; - -fx-background-radius: 5; - /* Темно-серый бордюр вместо яркого */ - -fx-border-color: #424242; - -fx-border-width: 1; - -fx-border-radius: 5; -} - -.preset-combo:hover { - -fx-border-color: #757575; -} - -.preset-combo .list-cell { - -fx-background-color: #1a1a1a; - -fx-text-fill: #b0b0b0; -} - -.preset-combo .list-cell:hover { - -fx-background-color: #333333; - -fx-text-fill: #ffffff; -} - -.preset-combo .list-cell:selected { - -fx-background-color: #b71c1c; - -fx-text-fill: #ffffff; -} - -/* ============================================ */ -/* КНОПКИ СЛОЖНОСТИ */ -/* ============================================ */ - -.difficulty-button { - -fx-background-color: #1a1a1a; - -fx-text-fill: #808080; - -fx-font-size: 14px; - -fx-font-weight: bold; - -fx-pref-width: 130; - -fx-pref-height: 40; - -fx-background-radius: 5; - -fx-border-width: 1; - -fx-border-radius: 5; - -fx-cursor: hand; -} - -.difficulty-easy { - -fx-border-color: #2e7d32; /* Темно-зеленый */ -} - -.difficulty-easy:selected { - -fx-background-color: #1b5e20; - -fx-text-fill: #e8f5e9; - -fx-border-color: #4caf50; -} - -.difficulty-normal { - -fx-border-color: #f9a825; /* Темно-желтый */ -} - -.difficulty-normal:selected { - -fx-background-color: #e65100; - -fx-text-fill: #fff3e0; - -fx-border-color: #ff9800; -} - -.difficulty-hard { - -fx-border-color: #c62828; /* Темно-красный */ -} - -.difficulty-hard:selected { - -fx-background-color: #b71c1c; - -fx-text-fill: #ffebee; - -fx-border-color: #ff5252; -} - -.difficulty-button:hover { - -fx-background-color: #252525; -} - -.difficulty-button:selected:hover { - -fx-effect: dropshadow(gaussian, rgba(255, 255, 255, 0.1), 5, 0, 0, 0); -} - -/* ============================================ */ -/* КНОПКИ РЕЖИМА ИГРЫ */ -/* ============================================ */ - -.mode-button { - -fx-background-color: #1a1a1a; - -fx-text-fill: #a0a0a0; - -fx-font-size: 14px; - -fx-font-weight: bold; - -fx-pref-width: 150; - -fx-pref-height: 40; - -fx-background-radius: 5; - -fx-border-color: #424242; - -fx-border-width: 1; - -fx-border-radius: 5; - -fx-cursor: hand; -} - -.mode-button:selected { - -fx-background-color: #b71c1c; /* Активный красный */ - -fx-text-fill: #ffffff; - -fx-border-color: #d32f2f; -} - -.mode-button:disabled { - -fx-opacity: 0.3; - -fx-cursor: default; - -fx-background-color: #0f0f0f; -} - -.mode-button:hover { - -fx-border-color: #ef5350; -} - -.mode-description { - -fx-fill: #cccccc; - -fx-font-size: 12px; -} - -.mode-description-disabled { - -fx-fill: #444444; - -fx-font-size: 12px; - -fx-font-style: italic; -} - -/* ============================================ */ -/* СЛАЙДЕРЫ */ -/* ============================================ */ - -.slider { - -fx-pref-width: 300; -} - -.slider .track { - -fx-background-color: #2c2c2c; /* Темный трек */ - -fx-background-radius: 3; -} - -.slider .thumb { - -fx-background-color: #b71c1c; /* Красный ползунок */ - -fx-background-radius: 10; - -fx-pref-width: 20; - -fx-pref-height: 20; - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.5), 3, 0, 0, 1); -} - -.slider .thumb:hover { - -fx-background-color: #d32f2f; - -fx-effect: dropshadow(gaussian, rgba(211, 47, 47, 0.4), 8, 0, 0, 0); -} - -.map-size-slider, -.intensity-slider, -.spawn-slider { - -fx-pref-width: 250; -} - -/* ============================================ */ -/* SPINNERS */ -/* ============================================ */ - -.spinner { - -fx-background-color: #000000; - -fx-background-radius: 5; - -fx-border-color: #333333; - -fx-border-width: 1; - -fx-border-radius: 5; -} - -.spinner .text-field { - -fx-background-color: #000000; - -fx-text-fill: #ffffff; - -fx-font-size: 14px; - -fx-background-radius: 4 0 0 4; -} - -.spinner .increment-arrow-button, -.spinner .decrement-arrow-button { - -fx-background-color: #1a1a1a; - -fx-background-radius: 0; -} - -.spinner .increment-arrow-button:hover, -.spinner .decrement-arrow-button:hover { - -fx-background-color: #b71c1c; -} - -.spinner .increment-arrow-button .increment-arrow, -.spinner .decrement-arrow-button .decrement-arrow { - -fx-background-color: #ffffff; -} - -.detail-spinner { - -fx-pref-width: 120; -} - -/* ============================================ */ -/* CHECKBOX */ -/* ============================================ */ - -.check-box { - -fx-text-fill: #cccccc; - -fx-font-size: 13px; -} - -.check-box .box { - -fx-background-color: #000000; - -fx-border-color: #555555; - -fx-border-width: 1; - -fx-border-radius: 3; - -fx-background-radius: 3; -} - -.check-box:selected .mark { - -fx-background-color: #ef5350; /* Красная галочка */ -} - -.check-box:hover .box { - -fx-border-color: #ef5350; -} - -.detail-checkbox { - -fx-font-size: 13px; -} - -/* ============================================ */ -/* TEXTFIELD */ -/* ============================================ */ - -.text-field { - -fx-background-color: #000000; - -fx-text-fill: #ffffff; - -fx-font-size: 14px; - -fx-background-radius: 5; - -fx-border-color: #333333; - -fx-border-width: 1; - -fx-border-radius: 5; - -fx-padding: 8; -} - -.text-field:focused { - -fx-border-color: #ef5350; - -fx-effect: dropshadow(gaussian, rgba(239, 83, 80, 0.2), 8, 0, 0, 0); -} - -.seed-textfield { - -fx-pref-width: 300; -} - -.seed-hint { - -fx-fill: #666666; - -fx-font-size: 11px; - -fx-font-style: italic; -} - -/* ============================================ */ -/* LABELS */ -/* ============================================ */ - -.label { - -fx-text-fill: #e0e0e0; - -fx-font-size: 13px; -} - -.quick-label { - -fx-font-weight: bold; - -fx-text-fill: #ffffff; -} - -.quick-value-label, -.slider-value-label { - -fx-font-weight: bold; - -fx-text-fill: #ef5350; - -fx-font-size: 14px; - -fx-min-width: 50; -} - -/* ============================================ */ -/* КНОПКИ */ -/* ============================================ */ - -.button { - -fx-background-radius: 5; - -fx-font-size: 14px; - -fx-font-weight: bold; - -fx-cursor: hand; - -fx-padding: 10 20; -} - -.start-button { - /* Градиент от темно-красного к красному */ - -fx-background-color: linear-gradient(to bottom, #d32f2f, #b71c1c); - -fx-text-fill: #ffffff; - -fx-pref-height: 50; - -fx-font-size: 16px; - -fx-border-color: #b71c1c; - -fx-border-width: 1; - -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.6), 10, 0, 0, 2); -} - -.start-button:hover { - -fx-background-color: linear-gradient(to bottom, #ef5350, #c62828); - -fx-effect: dropshadow(gaussian, rgba(211, 47, 47, 0.4), 15, 0, 0, 1); -} - -.start-button:pressed { - -fx-background-color: #8e0000; - -fx-translate-y: 2; -} - -.reset-button { - -fx-background-color: transparent; - -fx-text-fill: #b0b0b0; - -fx-border-color: #424242; - -fx-border-width: 1; - -fx-border-radius: 5; -} - -.reset-button:hover { - -fx-background-color: #1a1a1a; - -fx-text-fill: #ffffff; - -fx-border-color: #757575; -} - -.random-seed-button { - -fx-background-color: #212121; - -fx-text-fill: #ffffff; - -fx-border-color: #424242; - -fx-border-width: 1; -} - -.random-seed-button:hover { - -fx-background-color: #333333; - -fx-border-color: #666666; -} - -/* ============================================ */ -/* SCROLLPANE */ -/* ============================================ */ - -.scroll-pane { - -fx-background-color: transparent; - -fx-background: transparent; -} - -.scroll-pane .viewport { - -fx-background-color: transparent; -} - -.scroll-pane .scroll-bar:vertical { - -fx-background-color: #0f0f0f; - -fx-border-color: #222222; - -fx-border-width: 0 0 0 1; -} - -.scroll-pane .scroll-bar:vertical .thumb { - -fx-background-color: #333333; - -fx-background-radius: 5; -} - -.scroll-pane .scroll-bar:vertical .thumb:hover { - -fx-background-color: #b71c1c; -} - -.detailed-scroll { - -fx-fit-to-width: true; -} - -/* ============================================ */ -/* ДОПОЛНИТЕЛЬНО */ -/* ============================================ */ - -.button-container { - -fx-padding: 20 0 0 0; -} - -/* Hover эффекты */ -.spinner:hover, -.text-field:hover, -.check-box:hover { - -fx-cursor: hand; -} \ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/css/loading-screen.css b/src/main/resources/xyz/samiker/theendlessweave/css/loading-screen.css deleted file mode 100644 index 1e87db0..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/css/loading-screen.css +++ /dev/null @@ -1,23 +0,0 @@ -.root { - -fx-background-color: #1a1a1a; -} - -.progress-bar { - -fx-accent: #007bff; -} - -.log-text-area { - -fx-background-color: rgba(0, 0, 0, 0.4); - -fx-border-color: #333333; - -fx-border-width: 1px; -} - -.log-text-area .content { - -fx-background-color: transparent; -} - -.log-text-area .text { - -fx-fill: #99ff99; /* Светло-зеленый текст логов */ - -fx-font-family: "Consolas", monospace; - -fx-font-size: 11px; -} \ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/css/main-menu.css b/src/main/resources/xyz/samiker/theendlessweave/css/main-menu.css deleted file mode 100644 index 595a458..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/css/main-menu.css +++ /dev/null @@ -1,30 +0,0 @@ -.root { - -fx-background-color: #1a1a1a; -} - -.menu-container { - -fx-min-width: 20%; - -fx-max-width: 400px; - -fx-pref-width: 30%; -} - -.menu-button { - -fx-background-color: #272348; - -fx-text-fill: #e6e6e6; - -fx-font-size: 1.2em; - -fx-font-weight: bold; - -fx-padding: 1em 2em; - -fx-background-radius: 0.5em; - -fx-cursor: hand; -} - -.menu-button:hover { - -fx-background-color: #1c1a32; - -fx-scale-x: 1.05; - -fx-scale-y: 1.05; -} - -.menu-button:pressed { - -fx-scale-x: 0.95; - -fx-scale-y: 0.95; -} \ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/css/settings.css b/src/main/resources/xyz/samiker/theendlessweave/css/settings.css deleted file mode 100644 index d359fed..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/css/settings.css +++ /dev/null @@ -1,110 +0,0 @@ -.root { - -fx-background-color: #1a1a1a; - -fx-font-family: "Segoe UI", sans-serif; -} - -/* --- TabPane Styling --- */ -.tab-pane .tab-header-area .tab-header-background { - -fx-background-color: #252525; -} - -.tab-pane .tab { - -fx-background-color: #333333; - -fx-text-fill: #aaaaaa; - -fx-padding: 10 20; -} - -.tab-pane .tab:selected { - -fx-background-color: #1a1a1a; /* Цвет фона сцены, чтобы сливалось */ - -fx-border-color: #0078d7 transparent transparent transparent; /* Акцент сверху */ - -fx-border-width: 2; -} - -.tab-pane .tab:selected .tab-label { - -fx-text-fill: white; -} - -.tab-pane .tab .tab-label { - -fx-text-fill: #bbbbbb; - -fx-font-size: 14px; -} - -/* --- Controls Styling --- */ -.label { - -fx-text-fill: white; - -fx-font-size: 14px; -} - -.header-label { - -fx-font-size: 18px; - -fx-font-weight: bold; - -fx-text-fill: #0078d7; - -fx-padding: 0 0 10 0; -} - -.button { - -fx-background-color: #333333; - -fx-text-fill: white; - -fx-border-color: #555555; - -fx-border-radius: 3; - -fx-background-radius: 3; - -fx-cursor: hand; -} - -.button:hover { - -fx-background-color: #444444; - -fx-border-color: #0078d7; -} - -.button:pressed { - -fx-background-color: #0078d7; -} - -.check-box .box { - -fx-background-color: #333333; - -fx-border-color: #555555; -} - -.check-box:selected .mark { - -fx-background-color: white; -} - -.check-box .text { - -fx-fill: white; -} - -.combo-box { - -fx-background-color: #333333; - -fx-text-fill: white; - -fx-border-color: #555555; -} - -.combo-box .cell { - -fx-text-fill: white; -} - -.combo-box-popup .list-view { - -fx-background-color: #252525; - -fx-text-fill: white; -} - -.combo-box-popup .list-cell { - -fx-text-fill: white; -} - -.combo-box-popup .list-cell:hover { - -fx-background-color: #444444; -} - -.text-field { - -fx-background-color: #333333; - -fx-text-fill: white; - -fx-border-color: #555555; -} - -.slider .track { - -fx-background-color: #333333; -} -.slider .thumb { - -fx-background-color: #0078d7; -} \ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/fxml/game-scene.fxml b/src/main/resources/xyz/samiker/theendlessweave/fxml/game-scene.fxml deleted file mode 100644 index bac516b..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/fxml/game-scene.fxml +++ /dev/null @@ -1,165 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/fxml/main-menu.fxml b/src/main/resources/xyz/samiker/theendlessweave/fxml/main-menu.fxml deleted file mode 100644 index e7ba140..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/fxml/main-menu.fxml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - -
- - - - - - - -
-
\ No newline at end of file diff --git a/src/main/resources/xyz/samiker/theendlessweave/fxml/settings.fxml b/src/main/resources/xyz/samiker/theendlessweave/fxml/settings.fxml deleted file mode 100644 index bf407d6..0000000 --- a/src/main/resources/xyz/samiker/theendlessweave/fxml/settings.fxml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - -
- -
- - - -